class CXXIndirectPrimaryBaseSet
: public llvm::SmallSet<const CXXRecordDecl*, 32> {};
+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
}
/// 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,
/// 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.
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];
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
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);
bool checkTargetAttr(SourceLocation LiteralLoc, StringRef Str);
bool checkMSInheritanceAttrOnDefinition(
CXXRecordDecl *RD, SourceRange Range, bool BestCase,
- MSInheritanceAttr::Spelling SemanticSpelling);
+ MSInheritanceModel SemanticSpelling);
void CheckAlignasUnderalignment(Decl *D);
#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"
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<MSInheritanceAttr>();
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 {
static std::pair<unsigned, unsigned>
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);
}
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 &&
VBTableOffset = 0;
- if (IM == MSInheritanceAttr::Keyword_virtual_inheritance)
+ if (IM == MSInheritanceModel::Virtual)
FieldOffset -= getASTContext().getOffsetOfBaseWithVBPtr(RD).getQuantity();
} else {
FieldOffset = RD->nullFieldOffsetIsZero() ? 0 : -1;
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;
// 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);
}
// ::= $I? <name> <number> <number>
// ::= $J? <name> <number> <number> <number>
- 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
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<uint32_t>(NVOffset));
- if (MSInheritanceAttr::hasVBPtrOffsetField(IM))
+ if (inheritanceModelHasVBPtrOffsetField(IM))
mangleNumber(VBPtrOffset);
- if (MSInheritanceAttr::hasVBTableOffsetField(IM))
+ if (inheritanceModelHasVBTableOffsetField(IM))
mangleNumber(VBTableOffset);
}
// 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");
}
}
}
#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"
// 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<llvm::Type *, 4> 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)
llvm::SmallVectorImpl<llvm::Constant *> &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));
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());
}
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<llvm::Constant *, 4> 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();
}
// 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);
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());
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.
// 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.
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.
// 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++);
}
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<llvm::Constant>(Src);
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++);
}
// 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(
// 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(
// 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());
// 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(
// 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;
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.
// 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++);
}
NewAttr = S.mergeCodeSegAttr(D, *CSA, CSA->getName());
else if (const auto *IA = dyn_cast<MSInheritanceAttr>(Attr))
NewAttr = S.mergeMSInheritanceAttr(D, *IA, IA->getBestCase(),
- IA->getSemanticSpelling());
+ IA->getInheritanceModel());
else if (const auto *AA = dyn_cast<AlwaysInlineAttr>(Attr))
NewAttr = S.mergeAlwaysInlineAttr(D, *AA,
&S.Context.Idents.get(AA->getSpelling()));
if (const MSInheritanceAttr *IA = Record->getAttr<MSInheritanceAttr>())
checkMSInheritanceAttrOnDefinition(cast<CXXRecordDecl>(Record),
IA->getRange(), IA->getBestCase(),
- IA->getSemanticSpelling());
+ IA->getInheritanceModel());
}
// Check if the structure/union declaration is a type that can have zero
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
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;
}
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<CXXRecordDecl>(D));
MSInheritanceAttr *
Sema::mergeMSInheritanceAttr(Decl *D, const AttributeCommonInfo &CI,
bool BestCase,
- MSInheritanceAttr::Spelling SemanticSpelling) {
+ MSInheritanceModel Model) {
if (MSInheritanceAttr *IA = D->getAttr<MSInheritanceAttr>()) {
- if (IA->getSemanticSpelling() == SemanticSpelling)
+ if (IA->getInheritanceModel() == Model)
return nullptr;
Diag(IA->getLocation(), diag::err_mismatched_ms_inheritance)
<< 1 /*previous declaration*/;
auto *RD = cast<CXXRecordDecl>(D);
if (RD->hasDefinition()) {
if (checkMSInheritanceAttrOnDefinition(RD, CI.getRange(), BestCase,
- SemanticSpelling)) {
+ Model)) {
return nullptr;
}
} else {
static void assignInheritanceModel(Sema &S, CXXRecordDecl *RD) {
RD = RD->getMostRecentNonInjectedDecl();
if (!RD->hasAttr<MSInheritanceAttr>()) {
- 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;
}
? 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);
}
}