summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/MicrosoftCXXABI.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/MicrosoftCXXABI.cpp')
-rw-r--r--clang/lib/AST/MicrosoftCXXABI.cpp82
1 files changed, 50 insertions, 32 deletions
diff --git a/clang/lib/AST/MicrosoftCXXABI.cpp b/clang/lib/AST/MicrosoftCXXABI.cpp
index 26e967570a0..c3478747a69 100644
--- a/clang/lib/AST/MicrosoftCXXABI.cpp
+++ b/clang/lib/AST/MicrosoftCXXABI.cpp
@@ -92,28 +92,43 @@ static bool usesMultipleInheritanceModel(const CXXRecordDecl *RD) {
return false;
}
-static MSInheritanceModel MSInheritanceAttrToModel(MSInheritanceAttr *Attr) {
+static MSInheritanceAttr::Spelling
+MSInheritanceAttrToModel(const MSInheritanceAttr *Attr) {
if (Attr->IsSingle())
- return MSIM_Single;
+ return MSInheritanceAttr::Keyword_single_inheritance;
else if (Attr->IsMultiple())
- return MSIM_Multiple;
+ return MSInheritanceAttr::Keyword_multiple_inheritance;
else if (Attr->IsVirtual())
- return MSIM_Virtual;
+ return MSInheritanceAttr::Keyword_virtual_inheritance;
assert(Attr->IsUnspecified() && "Expected unspecified inheritance attr");
- return MSIM_Unspecified;
+ return MSInheritanceAttr::Keyword_unspecified_inheritance;
}
-MSInheritanceModel CXXRecordDecl::getMSInheritanceModel() const {
- if (MSInheritanceAttr *IA = this->getAttr<MSInheritanceAttr>())
- return MSInheritanceAttrToModel(IA);
- // If there was no explicit attribute, the record must be defined already, and
- // we can figure out the inheritance model from its other properties.
- if (this->getNumVBases() > 0)
- return MSIM_Virtual;
- if (usesMultipleInheritanceModel(this))
- return this->isPolymorphic() ? MSIM_MultiplePolymorphic : MSIM_Multiple;
- return this->isPolymorphic() ? MSIM_SinglePolymorphic : MSIM_Single;
+static MSInheritanceAttr::Spelling
+calculateInheritanceModel(const CXXRecordDecl *RD) {
+ if (!RD->hasDefinition())
+ return MSInheritanceAttr::Keyword_unspecified_inheritance;
+ if (RD->getNumVBases() > 0)
+ return MSInheritanceAttr::Keyword_virtual_inheritance;
+ if (usesMultipleInheritanceModel(RD))
+ return MSInheritanceAttr::Keyword_multiple_inheritance;
+ return MSInheritanceAttr::Keyword_single_inheritance;
+}
+
+MSInheritanceAttr::Spelling
+CXXRecordDecl::getMSInheritanceModel() const {
+ MSInheritanceAttr *IA = getAttr<MSInheritanceAttr>();
+ assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!");
+ return MSInheritanceAttrToModel(IA);
+}
+
+void CXXRecordDecl::setMSInheritanceModel() {
+ if (hasAttr<MSInheritanceAttr>())
+ return;
+
+ addAttr(MSInheritanceAttr::CreateImplicit(
+ getASTContext(), calculateInheritanceModel(this), getSourceRange()));
}
// Returns the number of pointer and integer slots used to represent a member
@@ -146,9 +161,9 @@ MSInheritanceModel CXXRecordDecl::getMSInheritanceModel() const {
// };
static std::pair<unsigned, unsigned>
getMSMemberPointerSlots(const MemberPointerType *MPT) {
- const CXXRecordDecl *RD = MPT->getClass()->getAsCXXRecordDecl();
- MSInheritanceModel Inheritance = RD->getMSInheritanceModel();
- unsigned Ptrs;
+ const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl();
+ MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel();
+ unsigned Ptrs = 0;
unsigned Ints = 0;
if (MPT->isMemberFunctionPointer()) {
// Member function pointers are a struct of a function pointer followed by a
@@ -156,26 +171,29 @@ getMSMemberPointerSlots(const MemberPointerType *MPT) {
// function pointer is a real function if it is non-virtual and a vftable
// slot thunk if it is virtual. The ints select the object base passed for
// the 'this' pointer.
- Ptrs = 1; // First slot is always a function pointer.
+ Ptrs = 1; // First slot is always a function pointer.
switch (Inheritance) {
- case MSIM_Unspecified: ++Ints; // VBTableOffset
- case MSIM_Virtual: ++Ints; // VirtualBaseAdjustmentOffset
- case MSIM_MultiplePolymorphic:
- case MSIM_Multiple: ++Ints; // NonVirtualBaseAdjustment
- case MSIM_SinglePolymorphic:
- case MSIM_Single: break; // Nothing
+ case MSInheritanceAttr::Keyword_unspecified_inheritance:
+ ++Ints; // VBTableOffset
+ case MSInheritanceAttr::Keyword_virtual_inheritance:
+ ++Ints; // VirtualBaseAdjustmentOffset
+ case MSInheritanceAttr::Keyword_multiple_inheritance:
+ ++Ints; // NonVirtualBaseAdjustment
+ case MSInheritanceAttr::Keyword_single_inheritance:
+ break; // Nothing
}
} else {
// Data pointers are an aggregate of ints. The first int is an offset
// followed by vbtable-related offsets.
- Ptrs = 0;
+ Ints = 1; // We always have a field offset.
switch (Inheritance) {
- case MSIM_Unspecified: ++Ints; // VBTableOffset
- case MSIM_Virtual: ++Ints; // VirtualBaseAdjustmentOffset
- case MSIM_MultiplePolymorphic:
- case MSIM_Multiple: // Nothing
- case MSIM_SinglePolymorphic:
- case MSIM_Single: ++Ints; // Field offset
+ case MSInheritanceAttr::Keyword_unspecified_inheritance:
+ ++Ints; // VBTableOffset
+ case MSInheritanceAttr::Keyword_virtual_inheritance:
+ ++Ints; // VirtualBaseAdjustmentOffset
+ case MSInheritanceAttr::Keyword_multiple_inheritance:
+ case MSInheritanceAttr::Keyword_single_inheritance:
+ break; // Nothing
}
}
return std::make_pair(Ptrs, Ints);
OpenPOWER on IntegriCloud