diff --git a/clang/include/clang/AST/CXXInheritance.h b/clang/include/clang/AST/CXXInheritance.h index bb2ad9c64d3b95..f223c1f2f4f0af 100644 --- a/clang/include/clang/AST/CXXInheritance.h +++ b/clang/include/clang/AST/CXXInheritance.h @@ -372,6 +372,30 @@ class CXXFinalOverriderMap class CXXIndirectPrimaryBaseSet : public llvm::SmallSet {}; +inline bool +inheritanceModelHasVBPtrOffsetField(MSInheritanceModel Inheritance) { + return Inheritance == MSInheritanceModel::Unspecified; +} + +// Only member pointers to functions need a this adjustment, since it can be +// combined with the field offset for data pointers. +inline bool inheritanceModelHasNVOffsetField(bool IsMemberFunction, + MSInheritanceModel Inheritance) { + return IsMemberFunction && Inheritance >= MSInheritanceModel::Multiple; +} + +inline bool +inheritanceModelHasVBTableOffsetField(MSInheritanceModel Inheritance) { + return Inheritance >= MSInheritanceModel::Virtual; +} + +inline bool inheritanceModelHasOnlyOneField(bool IsMemberFunction, + MSInheritanceModel Inheritance) { + if (IsMemberFunction) + return Inheritance <= MSInheritanceModel::Single; + return Inheritance <= MSInheritanceModel::Multiple; +} + } // namespace clang #endif // LLVM_CLANG_AST_CXXINHERITANCE_H diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h index e7845adc961309..4960eccbd520c9 100644 --- a/clang/include/clang/AST/DeclCXX.h +++ b/clang/include/clang/AST/DeclCXX.h @@ -1736,10 +1736,10 @@ class CXXRecordDecl : public RecordDecl { } /// Returns the inheritance model used for this record. - MSInheritanceAttr::Spelling getMSInheritanceModel() const; + MSInheritanceModel getMSInheritanceModel() const; /// Calculate what the inheritance model would be for this class. - MSInheritanceAttr::Spelling calculateInheritanceModel() const; + MSInheritanceModel calculateInheritanceModel() const; /// In the Microsoft C++ ABI, use zero for the field offset of a null data /// member pointer if we can guarantee that zero is not a valid field offset, @@ -1747,11 +1747,7 @@ class CXXRecordDecl : public RecordDecl { /// vfptr at offset zero, so we can use zero for null. If there are multiple /// fields, we can use zero even if it is a valid field offset because /// null-ness testing will check the other fields. - bool nullFieldOffsetIsZero() const { - return !MSInheritanceAttr::hasOnlyOneField(/*IsMemberFunction=*/false, - getMSInheritanceModel()) || - (hasDefinition() && isPolymorphic()); - } + bool nullFieldOffsetIsZero() const; /// Controls when vtordisps will be emitted if this record is used as a /// virtual base. diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td index 70df86126a1104..5d9e5dd59596c1 100644 --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -2990,25 +2990,9 @@ def MSInheritance : InheritableAttr { Keyword<"__virtual_inheritance">, Keyword<"__unspecified_inheritance">]; let AdditionalMembers = [{ - static bool hasVBPtrOffsetField(Spelling Inheritance) { - return Inheritance == Keyword_unspecified_inheritance; - } - - // Only member pointers to functions need a this adjustment, since it can be - // combined with the field offset for data pointers. - static bool hasNVOffsetField(bool IsMemberFunction, Spelling Inheritance) { - return IsMemberFunction && Inheritance >= Keyword_multiple_inheritance; - } - - static bool hasVBTableOffsetField(Spelling Inheritance) { - return Inheritance >= Keyword_virtual_inheritance; - } - - static bool hasOnlyOneField(bool IsMemberFunction, - Spelling Inheritance) { - if (IsMemberFunction) - return Inheritance <= Keyword_single_inheritance; - return Inheritance <= Keyword_multiple_inheritance; + MSInheritanceModel getInheritanceModel() const { + // The spelling enum should agree with MSInheritanceModel. + return MSInheritanceModel(getSemanticSpelling()); } }]; let Documentation = [MSInheritanceDocs]; diff --git a/clang/include/clang/Basic/Specifiers.h b/clang/include/clang/Basic/Specifiers.h index fad97a26d9572d..73823dc01ec7c8 100644 --- a/clang/include/clang/Basic/Specifiers.h +++ b/clang/include/clang/Basic/Specifiers.h @@ -354,6 +354,15 @@ namespace clang { SwiftContext }; + /// Assigned inheritance model for a class in the MS C++ ABI. Must match order + /// of spellings in MSInheritanceAttr. + enum class MSInheritanceModel { + Single = 0, + Multiple = 1, + Virtual = 2, + Unspecified = 3, + }; + llvm::StringRef getParameterABISpelling(ParameterABI kind); } // end namespace clang diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h index 111c91088accca..0a6f58a484ae3e 100644 --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -2800,9 +2800,10 @@ class Sema final { StringRef Uuid); DLLImportAttr *mergeDLLImportAttr(Decl *D, const AttributeCommonInfo &CI); DLLExportAttr *mergeDLLExportAttr(Decl *D, const AttributeCommonInfo &CI); - MSInheritanceAttr * - mergeMSInheritanceAttr(Decl *D, const AttributeCommonInfo &CI, bool BestCase, - MSInheritanceAttr::Spelling SemanticSpelling); + MSInheritanceAttr *mergeMSInheritanceAttr(Decl *D, + const AttributeCommonInfo &CI, + bool BestCase, + MSInheritanceModel Model); FormatAttr *mergeFormatAttr(Decl *D, const AttributeCommonInfo &CI, IdentifierInfo *Format, int FormatIdx, int FirstArg); @@ -3740,7 +3741,7 @@ class Sema final { bool checkTargetAttr(SourceLocation LiteralLoc, StringRef Str); bool checkMSInheritanceAttrOnDefinition( CXXRecordDecl *RD, SourceRange Range, bool BestCase, - MSInheritanceAttr::Spelling SemanticSpelling); + MSInheritanceModel SemanticSpelling); void CheckAlignasUnderalignment(Decl *D); diff --git a/clang/lib/AST/MicrosoftCXXABI.cpp b/clang/lib/AST/MicrosoftCXXABI.cpp index 4b15b7ea3690ec..f9f9fe985b6f9e 100644 --- a/clang/lib/AST/MicrosoftCXXABI.cpp +++ b/clang/lib/AST/MicrosoftCXXABI.cpp @@ -14,6 +14,7 @@ #include "CXXABI.h" #include "clang/AST/ASTContext.h" #include "clang/AST/Attr.h" +#include "clang/AST/CXXInheritance.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/MangleNumberingContext.h" #include "clang/AST/RecordLayout.h" @@ -154,21 +155,26 @@ static bool usesMultipleInheritanceModel(const CXXRecordDecl *RD) { return false; } -MSInheritanceAttr::Spelling CXXRecordDecl::calculateInheritanceModel() const { +MSInheritanceModel CXXRecordDecl::calculateInheritanceModel() const { if (!hasDefinition() || isParsingBaseSpecifiers()) - return MSInheritanceAttr::Keyword_unspecified_inheritance; + return MSInheritanceModel::Unspecified; if (getNumVBases() > 0) - return MSInheritanceAttr::Keyword_virtual_inheritance; + return MSInheritanceModel::Virtual; if (usesMultipleInheritanceModel(this)) - return MSInheritanceAttr::Keyword_multiple_inheritance; - return MSInheritanceAttr::Keyword_single_inheritance; + return MSInheritanceModel::Multiple; + return MSInheritanceModel::Single; } -MSInheritanceAttr::Spelling -CXXRecordDecl::getMSInheritanceModel() const { +MSInheritanceModel CXXRecordDecl::getMSInheritanceModel() const { MSInheritanceAttr *IA = getAttr(); assert(IA && "Expected MSInheritanceAttr on the CXXRecordDecl!"); - return IA->getSemanticSpelling(); + return IA->getInheritanceModel(); +} + +bool CXXRecordDecl::nullFieldOffsetIsZero() const { + return !inheritanceModelHasOnlyOneField(/*IsMemberFunction=*/false, + getMSInheritanceModel()) || + (hasDefinition() && isPolymorphic()); } MSVtorDispMode CXXRecordDecl::getMSVtorDispMode() const { @@ -209,19 +215,19 @@ MSVtorDispMode CXXRecordDecl::getMSVtorDispMode() const { static std::pair getMSMemberPointerSlots(const MemberPointerType *MPT) { const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl(); - MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel(); + MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); unsigned Ptrs = 0; unsigned Ints = 0; if (MPT->isMemberFunctionPointer()) Ptrs = 1; else Ints = 1; - if (MSInheritanceAttr::hasNVOffsetField(MPT->isMemberFunctionPointer(), + if (inheritanceModelHasNVOffsetField(MPT->isMemberFunctionPointer(), Inheritance)) Ints++; - if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance)) + if (inheritanceModelHasVBPtrOffsetField(Inheritance)) Ints++; - if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance)) + if (inheritanceModelHasVBTableOffsetField(Inheritance)) Ints++; return std::make_pair(Ptrs, Ints); } diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp index f871a1b9990063..9f692d8107cbfa 100644 --- a/clang/lib/AST/MicrosoftMangle.cpp +++ b/clang/lib/AST/MicrosoftMangle.cpp @@ -592,7 +592,7 @@ void MicrosoftCXXNameMangler::mangleMemberDataPointer(const CXXRecordDecl *RD, int64_t FieldOffset; int64_t VBTableOffset; - MSInheritanceAttr::Spelling IM = RD->getMSInheritanceModel(); + MSInheritanceModel IM = RD->getMSInheritanceModel(); if (VD) { FieldOffset = getASTContext().getFieldOffset(VD); assert(FieldOffset % getASTContext().getCharWidth() == 0 && @@ -601,7 +601,7 @@ void MicrosoftCXXNameMangler::mangleMemberDataPointer(const CXXRecordDecl *RD, VBTableOffset = 0; - if (IM == MSInheritanceAttr::Keyword_virtual_inheritance) + if (IM == MSInheritanceModel::Virtual) FieldOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity(); } else { FieldOffset = RD->nullFieldOffsetIsZero() ? 0 : -1; @@ -611,12 +611,10 @@ void MicrosoftCXXNameMangler::mangleMemberDataPointer(const CXXRecordDecl *RD, char Code = '\0'; switch (IM) { - case MSInheritanceAttr::Keyword_single_inheritance: Code = '0'; break; - case MSInheritanceAttr::Keyword_multiple_inheritance: Code = '0'; break; - case MSInheritanceAttr::Keyword_virtual_inheritance: Code = 'F'; break; - case MSInheritanceAttr::Keyword_unspecified_inheritance: Code = 'G'; break; - case MSInheritanceAttr::SpellingNotCalculated: - llvm_unreachable("not reachable"); + case MSInheritanceModel::Single: Code = '0'; break; + case MSInheritanceModel::Multiple: Code = '0'; break; + case MSInheritanceModel::Virtual: Code = 'F'; break; + case MSInheritanceModel::Unspecified: Code = 'G'; break; } Out << '$' << Code; @@ -626,9 +624,9 @@ void MicrosoftCXXNameMangler::mangleMemberDataPointer(const CXXRecordDecl *RD, // The C++ standard doesn't allow base-to-derived member pointer conversions // in template parameter contexts, so the vbptr offset of data member pointers // is always zero. - if (MSInheritanceAttr::hasVBPtrOffsetField(IM)) + if (inheritanceModelHasVBPtrOffsetField(IM)) mangleNumber(0); - if (MSInheritanceAttr::hasVBTableOffsetField(IM)) + if (inheritanceModelHasVBTableOffsetField(IM)) mangleNumber(VBTableOffset); } @@ -640,16 +638,14 @@ MicrosoftCXXNameMangler::mangleMemberFunctionPointer(const CXXRecordDecl *RD, // ::= $I? // ::= $J? - MSInheritanceAttr::Spelling IM = RD->getMSInheritanceModel(); + MSInheritanceModel IM = RD->getMSInheritanceModel(); char Code = '\0'; switch (IM) { - case MSInheritanceAttr::Keyword_single_inheritance: Code = '1'; break; - case MSInheritanceAttr::Keyword_multiple_inheritance: Code = 'H'; break; - case MSInheritanceAttr::Keyword_virtual_inheritance: Code = 'I'; break; - case MSInheritanceAttr::Keyword_unspecified_inheritance: Code = 'J'; break; - case MSInheritanceAttr::SpellingNotCalculated: - llvm_unreachable("not reachable"); + case MSInheritanceModel::Single: Code = '1'; break; + case MSInheritanceModel::Multiple: Code = 'H'; break; + case MSInheritanceModel::Virtual: Code = 'I'; break; + case MSInheritanceModel::Unspecified: Code = 'J'; break; } // If non-virtual, mangle the name. If virtual, mangle as a virtual memptr @@ -676,25 +672,24 @@ MicrosoftCXXNameMangler::mangleMemberFunctionPointer(const CXXRecordDecl *RD, mangleFunctionEncoding(MD, /*ShouldMangle=*/true); } - if (VBTableOffset == 0 && - IM == MSInheritanceAttr::Keyword_virtual_inheritance) + if (VBTableOffset == 0 && IM == MSInheritanceModel::Virtual) NVOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity(); } else { // Null single inheritance member functions are encoded as a simple nullptr. - if (IM == MSInheritanceAttr::Keyword_single_inheritance) { + if (IM == MSInheritanceModel::Single) { Out << "$0A@"; return; } - if (IM == MSInheritanceAttr::Keyword_unspecified_inheritance) + if (IM == MSInheritanceModel::Unspecified) VBTableOffset = -1; Out << '$' << Code; } - if (MSInheritanceAttr::hasNVOffsetField(/*IsMemberFunction=*/true, IM)) + if (inheritanceModelHasNVOffsetField(/*IsMemberFunction=*/true, IM)) mangleNumber(static_cast(NVOffset)); - if (MSInheritanceAttr::hasVBPtrOffsetField(IM)) + if (inheritanceModelHasVBPtrOffsetField(IM)) mangleNumber(VBPtrOffset); - if (MSInheritanceAttr::hasVBTableOffsetField(IM)) + if (inheritanceModelHasVBTableOffsetField(IM)) mangleNumber(VBTableOffset); } diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp index a8d4ed12808e79..db5893a7b51f24 100644 --- a/clang/lib/CodeGen/CGDebugInfo.cpp +++ b/clang/lib/CodeGen/CGDebugInfo.cpp @@ -2733,19 +2733,17 @@ llvm::DIType *CGDebugInfo::CreateType(const MemberPointerType *Ty, // Set the MS inheritance model. There is no flag for the unspecified model. if (CGM.getTarget().getCXXABI().isMicrosoft()) { switch (Ty->getMostRecentCXXRecordDecl()->getMSInheritanceModel()) { - case MSInheritanceAttr::Keyword_single_inheritance: + case MSInheritanceModel::Single: Flags |= llvm::DINode::FlagSingleInheritance; break; - case MSInheritanceAttr::Keyword_multiple_inheritance: + case MSInheritanceModel::Multiple: Flags |= llvm::DINode::FlagMultipleInheritance; break; - case MSInheritanceAttr::Keyword_virtual_inheritance: + case MSInheritanceModel::Virtual: Flags |= llvm::DINode::FlagVirtualInheritance; break; - case MSInheritanceAttr::Keyword_unspecified_inheritance: + case MSInheritanceModel::Unspecified: break; - case MSInheritanceAttr::SpellingNotCalculated: - llvm_unreachable("Spelling not yet calculated"); } } } diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp index 7ec3950bc6f9c9..8196df614cee81 100644 --- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp +++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp @@ -19,11 +19,12 @@ #include "CodeGenModule.h" #include "CodeGenTypes.h" #include "TargetInfo.h" -#include "clang/CodeGen/ConstantInitBuilder.h" +#include "clang/AST/CXXInheritance.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/StmtCXX.h" #include "clang/AST/VTableBuilder.h" +#include "clang/CodeGen/ConstantInitBuilder.h" #include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringSet.h" #include "llvm/IR/Intrinsics.h" @@ -2604,27 +2605,27 @@ bool MicrosoftCXXABI::isZeroInitializable(const MemberPointerType *MPT) { // we can't zero initialize. The field offset is sometimes also -1 if 0 is a // valid field offset. const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl(); - MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel(); - return (!MSInheritanceAttr::hasVBTableOffsetField(Inheritance) && + MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); + return (!inheritanceModelHasVBTableOffsetField(Inheritance) && RD->nullFieldOffsetIsZero()); } llvm::Type * MicrosoftCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) { const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl(); - MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel(); + MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); llvm::SmallVector fields; if (MPT->isMemberFunctionPointer()) fields.push_back(CGM.VoidPtrTy); // FunctionPointerOrVirtualThunk else fields.push_back(CGM.IntTy); // FieldOffset - if (MSInheritanceAttr::hasNVOffsetField(MPT->isMemberFunctionPointer(), - Inheritance)) + if (inheritanceModelHasNVOffsetField(MPT->isMemberFunctionPointer(), + Inheritance)) fields.push_back(CGM.IntTy); - if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance)) + if (inheritanceModelHasVBPtrOffsetField(Inheritance)) fields.push_back(CGM.IntTy); - if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance)) + if (inheritanceModelHasVBTableOffsetField(Inheritance)) fields.push_back(CGM.IntTy); // VirtualBaseAdjustmentOffset if (fields.size() == 1) @@ -2637,7 +2638,7 @@ GetNullMemberPointerFields(const MemberPointerType *MPT, llvm::SmallVectorImpl &fields) { assert(fields.empty()); const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl(); - MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel(); + MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); if (MPT->isMemberFunctionPointer()) { // FunctionPointerOrVirtualThunk fields.push_back(llvm::Constant::getNullValue(CGM.VoidPtrTy)); @@ -2648,12 +2649,12 @@ GetNullMemberPointerFields(const MemberPointerType *MPT, fields.push_back(getAllOnesInt()); // FieldOffset } - if (MSInheritanceAttr::hasNVOffsetField(MPT->isMemberFunctionPointer(), - Inheritance)) + if (inheritanceModelHasNVOffsetField(MPT->isMemberFunctionPointer(), + Inheritance)) fields.push_back(getZeroInt()); - if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance)) + if (inheritanceModelHasVBPtrOffsetField(Inheritance)) fields.push_back(getZeroInt()); - if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance)) + if (inheritanceModelHasVBTableOffsetField(Inheritance)) fields.push_back(getAllOnesInt()); } @@ -2674,21 +2675,21 @@ MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField, const CXXRecordDecl *RD, CharUnits NonVirtualBaseAdjustment, unsigned VBTableIndex) { - MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel(); + MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); // Single inheritance class member pointer are represented as scalars instead // of aggregates. - if (MSInheritanceAttr::hasOnlyOneField(IsMemberFunction, Inheritance)) + if (inheritanceModelHasOnlyOneField(IsMemberFunction, Inheritance)) return FirstField; llvm::SmallVector fields; fields.push_back(FirstField); - if (MSInheritanceAttr::hasNVOffsetField(IsMemberFunction, Inheritance)) + if (inheritanceModelHasNVOffsetField(IsMemberFunction, Inheritance)) fields.push_back(llvm::ConstantInt::get( CGM.IntTy, NonVirtualBaseAdjustment.getQuantity())); - if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance)) { + if (inheritanceModelHasVBPtrOffsetField(Inheritance)) { CharUnits Offs = CharUnits::Zero(); if (VBTableIndex) Offs = getContext().getASTRecordLayout(RD).getVBPtrOffset(); @@ -2696,7 +2697,7 @@ MicrosoftCXXABI::EmitFullMemberPointer(llvm::Constant *FirstField, } // The rest of the fields are adjusted by conversions to a more derived class. - if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance)) + if (inheritanceModelHasVBTableOffsetField(Inheritance)) fields.push_back(llvm::ConstantInt::get(CGM.IntTy, VBTableIndex)); return llvm::ConstantStruct::getAnon(fields); @@ -2711,7 +2712,7 @@ MicrosoftCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT, llvm::Constant *MicrosoftCXXABI::EmitMemberDataPointer(const CXXRecordDecl *RD, CharUnits offset) { if (RD->getMSInheritanceModel() == - MSInheritanceAttr::Keyword_virtual_inheritance) + MSInheritanceModel::Virtual) offset -= getContext().getOffsetOfBaseWithVBPtr(RD); llvm::Constant *FirstField = llvm::ConstantInt::get(CGM.IntTy, offset.getQuantity()); @@ -2817,7 +2818,7 @@ MicrosoftCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) { if (VBTableIndex == 0 && RD->getMSInheritanceModel() == - MSInheritanceAttr::Keyword_virtual_inheritance) + MSInheritanceModel::Virtual) NonVirtualBaseAdjustment -= getContext().getOffsetOfBaseWithVBPtr(RD); // The rest of the fields are common with data member pointers. @@ -2853,9 +2854,9 @@ MicrosoftCXXABI::EmitMemberPointerComparison(CodeGenFunction &CGF, // If this is a single field member pointer (single inheritance), this is a // single icmp. const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl(); - MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel(); - if (MSInheritanceAttr::hasOnlyOneField(MPT->isMemberFunctionPointer(), - Inheritance)) + MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); + if (inheritanceModelHasOnlyOneField(MPT->isMemberFunctionPointer(), + Inheritance)) return Builder.CreateICmp(Eq, L, R); // Compare the first field. @@ -3055,7 +3056,7 @@ llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress( CGF.ConvertTypeForMem(MPT->getPointeeType())->getPointerTo(AS); CGBuilderTy &Builder = CGF.Builder; const CXXRecordDecl *RD = MPT->getMostRecentCXXRecordDecl(); - MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel(); + MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); // Extract the fields we need, regardless of model. We'll apply them if we // have them. @@ -3066,9 +3067,9 @@ llvm::Value *MicrosoftCXXABI::EmitMemberDataPointerAddress( // We need to extract values. unsigned I = 0; FieldOffset = Builder.CreateExtractValue(MemPtr, I++); - if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance)) + if (inheritanceModelHasVBPtrOffsetField(Inheritance)) VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++); - if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance)) + if (inheritanceModelHasVBTableOffsetField(Inheritance)) VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++); } @@ -3163,8 +3164,8 @@ llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion( CGBuilderTy &Builder) { const CXXRecordDecl *SrcRD = SrcTy->getMostRecentCXXRecordDecl(); const CXXRecordDecl *DstRD = DstTy->getMostRecentCXXRecordDecl(); - MSInheritanceAttr::Spelling SrcInheritance = SrcRD->getMSInheritanceModel(); - MSInheritanceAttr::Spelling DstInheritance = DstRD->getMSInheritanceModel(); + MSInheritanceModel SrcInheritance = SrcRD->getMSInheritanceModel(); + MSInheritanceModel DstInheritance = DstRD->getMSInheritanceModel(); bool IsFunc = SrcTy->isMemberFunctionPointer(); bool IsConstant = isa(Src); @@ -3173,15 +3174,15 @@ llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion( llvm::Value *NonVirtualBaseAdjustment = getZeroInt(); llvm::Value *VirtualBaseAdjustmentOffset = getZeroInt(); llvm::Value *VBPtrOffset = getZeroInt(); - if (!MSInheritanceAttr::hasOnlyOneField(IsFunc, SrcInheritance)) { + if (!inheritanceModelHasOnlyOneField(IsFunc, SrcInheritance)) { // We need to extract values. unsigned I = 0; FirstField = Builder.CreateExtractValue(Src, I++); - if (MSInheritanceAttr::hasNVOffsetField(IsFunc, SrcInheritance)) + if (inheritanceModelHasNVOffsetField(IsFunc, SrcInheritance)) NonVirtualBaseAdjustment = Builder.CreateExtractValue(Src, I++); - if (MSInheritanceAttr::hasVBPtrOffsetField(SrcInheritance)) + if (inheritanceModelHasVBPtrOffsetField(SrcInheritance)) VBPtrOffset = Builder.CreateExtractValue(Src, I++); - if (MSInheritanceAttr::hasVBTableOffsetField(SrcInheritance)) + if (inheritanceModelHasVBTableOffsetField(SrcInheritance)) VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(Src, I++); } @@ -3200,7 +3201,7 @@ llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion( // adjustment to normalize the member pointer. llvm::Value *SrcVBIndexEqZero = Builder.CreateICmpEQ(VirtualBaseAdjustmentOffset, getZeroInt()); - if (SrcInheritance == MSInheritanceAttr::Keyword_virtual_inheritance) { + if (SrcInheritance == MSInheritanceModel::Virtual) { if (int64_t SrcOffsetToFirstVBase = getContext().getOffsetOfBaseWithVBPtr(SrcRD).getQuantity()) { llvm::Value *UndoSrcAdjustment = Builder.CreateSelect( @@ -3234,8 +3235,8 @@ llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion( // Update the vbindex to an appropriate value in the destination because // SrcRD's vbtable might not be a strict prefix of the one in DstRD. llvm::Value *DstVBIndexEqZero = SrcVBIndexEqZero; - if (MSInheritanceAttr::hasVBTableOffsetField(DstInheritance) && - MSInheritanceAttr::hasVBTableOffsetField(SrcInheritance)) { + if (inheritanceModelHasVBTableOffsetField(DstInheritance) && + inheritanceModelHasVBTableOffsetField(SrcInheritance)) { if (llvm::GlobalVariable *VDispMap = getAddrOfVirtualDisplacementMap(SrcRD, DstRD)) { llvm::Value *VBIndex = Builder.CreateExactUDiv( @@ -3258,7 +3259,7 @@ llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion( // Set the VBPtrOffset to zero if the vbindex is zero. Otherwise, initialize // it to the offset of the vbptr. - if (MSInheritanceAttr::hasVBPtrOffsetField(DstInheritance)) { + if (inheritanceModelHasVBPtrOffsetField(DstInheritance)) { llvm::Value *DstVBPtrOffset = llvm::ConstantInt::get( CGM.IntTy, getContext().getASTRecordLayout(DstRD).getVBPtrOffset().getQuantity()); @@ -3269,7 +3270,7 @@ llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion( // Likewise, apply a similar adjustment so that dereferencing the member // pointer correctly accounts for the distance between the start of the first // virtual base and the top of the MDC. - if (DstInheritance == MSInheritanceAttr::Keyword_virtual_inheritance) { + if (DstInheritance == MSInheritanceModel::Virtual) { if (int64_t DstOffsetToFirstVBase = getContext().getOffsetOfBaseWithVBPtr(DstRD).getQuantity()) { llvm::Value *DoDstAdjustment = Builder.CreateSelect( @@ -3282,17 +3283,17 @@ llvm::Value *MicrosoftCXXABI::EmitNonNullMemberPointerConversion( // Recompose dst from the null struct and the adjusted fields from src. llvm::Value *Dst; - if (MSInheritanceAttr::hasOnlyOneField(IsFunc, DstInheritance)) { + if (inheritanceModelHasOnlyOneField(IsFunc, DstInheritance)) { Dst = FirstField; } else { Dst = llvm::UndefValue::get(ConvertMemberPointerType(DstTy)); unsigned Idx = 0; Dst = Builder.CreateInsertValue(Dst, FirstField, Idx++); - if (MSInheritanceAttr::hasNVOffsetField(IsFunc, DstInheritance)) + if (inheritanceModelHasNVOffsetField(IsFunc, DstInheritance)) Dst = Builder.CreateInsertValue(Dst, NonVirtualBaseAdjustment, Idx++); - if (MSInheritanceAttr::hasVBPtrOffsetField(DstInheritance)) + if (inheritanceModelHasVBPtrOffsetField(DstInheritance)) Dst = Builder.CreateInsertValue(Dst, VBPtrOffset, Idx++); - if (MSInheritanceAttr::hasVBTableOffsetField(DstInheritance)) + if (inheritanceModelHasVBTableOffsetField(DstInheritance)) Dst = Builder.CreateInsertValue(Dst, VirtualBaseAdjustmentOffset, Idx++); } return Dst; @@ -3348,7 +3349,7 @@ CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer( CGM.getTypes().arrangeCXXMethodType(RD, FPT, /*FD=*/nullptr)); CGBuilderTy &Builder = CGF.Builder; - MSInheritanceAttr::Spelling Inheritance = RD->getMSInheritanceModel(); + MSInheritanceModel Inheritance = RD->getMSInheritanceModel(); // Extract the fields we need, regardless of model. We'll apply them if we // have them. @@ -3360,11 +3361,11 @@ CGCallee MicrosoftCXXABI::EmitLoadOfMemberFunctionPointer( // We need to extract values. unsigned I = 0; FunctionPointer = Builder.CreateExtractValue(MemPtr, I++); - if (MSInheritanceAttr::hasNVOffsetField(MPT, Inheritance)) + if (inheritanceModelHasNVOffsetField(MPT, Inheritance)) NonVirtualBaseAdjustment = Builder.CreateExtractValue(MemPtr, I++); - if (MSInheritanceAttr::hasVBPtrOffsetField(Inheritance)) + if (inheritanceModelHasVBPtrOffsetField(Inheritance)) VBPtrOffset = Builder.CreateExtractValue(MemPtr, I++); - if (MSInheritanceAttr::hasVBTableOffsetField(Inheritance)) + if (inheritanceModelHasVBTableOffsetField(Inheritance)) VirtualBaseAdjustmentOffset = Builder.CreateExtractValue(MemPtr, I++); } diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp index 47c05d5d2eaa1a..6ea4923dc2ba28 100644 --- a/clang/lib/Sema/SemaDecl.cpp +++ b/clang/lib/Sema/SemaDecl.cpp @@ -2549,7 +2549,7 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D, NewAttr = S.mergeCodeSegAttr(D, *CSA, CSA->getName()); else if (const auto *IA = dyn_cast(Attr)) NewAttr = S.mergeMSInheritanceAttr(D, *IA, IA->getBestCase(), - IA->getSemanticSpelling()); + IA->getInheritanceModel()); else if (const auto *AA = dyn_cast(Attr)) NewAttr = S.mergeAlwaysInlineAttr(D, *AA, &S.Context.Idents.get(AA->getSpelling())); @@ -16760,7 +16760,7 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl, if (const MSInheritanceAttr *IA = Record->getAttr()) checkMSInheritanceAttrOnDefinition(cast(Record), IA->getRange(), IA->getBestCase(), - IA->getSemanticSpelling()); + IA->getInheritanceModel()); } // Check if the structure/union declaration is a type that can have zero diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp index d16913e2d0e912..3ad01bdca200f5 100644 --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -3885,7 +3885,7 @@ void Sema::CheckAlignasUnderalignment(Decl *D) { bool Sema::checkMSInheritanceAttrOnDefinition( CXXRecordDecl *RD, SourceRange Range, bool BestCase, - MSInheritanceAttr::Spelling SemanticSpelling) { + MSInheritanceModel ExplicitModel) { assert(RD->hasDefinition() && "RD has no definition!"); // We may not have seen base specifiers or any virtual methods yet. We will @@ -3894,14 +3894,14 @@ bool Sema::checkMSInheritanceAttrOnDefinition( return false; // The unspecified model never matches what a definition could need. - if (SemanticSpelling == MSInheritanceAttr::Keyword_unspecified_inheritance) + if (ExplicitModel == MSInheritanceModel::Unspecified) return false; if (BestCase) { - if (RD->calculateInheritanceModel() == SemanticSpelling) + if (RD->calculateInheritanceModel() == ExplicitModel) return false; } else { - if (RD->calculateInheritanceModel() <= SemanticSpelling) + if (RD->calculateInheritanceModel() <= ExplicitModel) return false; } @@ -5458,8 +5458,7 @@ static void handleMSInheritanceAttr(Sema &S, Decl *D, const ParsedAttr &AL) { return; } MSInheritanceAttr *IA = S.mergeMSInheritanceAttr( - D, AL, /*BestCase=*/true, - (MSInheritanceAttr::Spelling)AL.getSemanticSpelling()); + D, AL, /*BestCase=*/true, (MSInheritanceModel)AL.getSemanticSpelling()); if (IA) { D->addAttr(IA); S.Consumer.AssignInheritanceModel(cast(D)); @@ -6112,9 +6111,9 @@ static void handleDLLAttr(Sema &S, Decl *D, const ParsedAttr &A) { MSInheritanceAttr * Sema::mergeMSInheritanceAttr(Decl *D, const AttributeCommonInfo &CI, bool BestCase, - MSInheritanceAttr::Spelling SemanticSpelling) { + MSInheritanceModel Model) { if (MSInheritanceAttr *IA = D->getAttr()) { - if (IA->getSemanticSpelling() == SemanticSpelling) + if (IA->getInheritanceModel() == Model) return nullptr; Diag(IA->getLocation(), diag::err_mismatched_ms_inheritance) << 1 /*previous declaration*/; @@ -6125,7 +6124,7 @@ Sema::mergeMSInheritanceAttr(Decl *D, const AttributeCommonInfo &CI, auto *RD = cast(D); if (RD->hasDefinition()) { if (checkMSInheritanceAttrOnDefinition(RD, CI.getRange(), BestCase, - SemanticSpelling)) { + Model)) { return nullptr; } } else { diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 06f5e6f9ee3443..b87978035ad8b0 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -7952,20 +7952,21 @@ bool Sema::hasVisibleDefinition(NamedDecl *D, NamedDecl **Suggested, static void assignInheritanceModel(Sema &S, CXXRecordDecl *RD) { RD = RD->getMostRecentNonInjectedDecl(); if (!RD->hasAttr()) { - MSInheritanceAttr::Spelling IM; - + MSInheritanceModel IM; + bool BestCase = false; switch (S.MSPointerToMemberRepresentationMethod) { case LangOptions::PPTMK_BestCase: + BestCase = true; IM = RD->calculateInheritanceModel(); break; case LangOptions::PPTMK_FullGeneralitySingleInheritance: - IM = MSInheritanceAttr::Keyword_single_inheritance; + IM = MSInheritanceModel::Single; break; case LangOptions::PPTMK_FullGeneralityMultipleInheritance: - IM = MSInheritanceAttr::Keyword_multiple_inheritance; + IM = MSInheritanceModel::Multiple; break; case LangOptions::PPTMK_FullGeneralityVirtualInheritance: - IM = MSInheritanceAttr::Keyword_unspecified_inheritance; + IM = MSInheritanceModel::Unspecified; break; } @@ -7973,10 +7974,8 @@ static void assignInheritanceModel(Sema &S, CXXRecordDecl *RD) { ? S.ImplicitMSInheritanceAttrLoc : RD->getSourceRange(); RD->addAttr(MSInheritanceAttr::CreateImplicit( - S.getASTContext(), - /*BestCase=*/S.MSPointerToMemberRepresentationMethod == - LangOptions::PPTMK_BestCase, - Loc, AttributeCommonInfo::AS_Microsoft, IM)); + S.getASTContext(), BestCase, Loc, AttributeCommonInfo::AS_Microsoft, + MSInheritanceAttr::Spelling(IM))); S.Consumer.AssignInheritanceModel(RD); } }