forked from OSchip/llvm-project
[AST] Rename RecordLayoutBuilder to ItaniumRecordLayoutBuilder
RecordLayoutBuilder is an inaccruate name because it does not build all records. It only builds layouts for targets using the Itanium C++ ABI. llvm-svn: 243225
This commit is contained in:
parent
640e7c99cc
commit
3b1c990dcc
|
@ -1774,7 +1774,6 @@ public:
|
|||
/// record (struct/union/class) \p D, which indicates its size and field
|
||||
/// position information.
|
||||
const ASTRecordLayout &getASTRecordLayout(const RecordDecl *D) const;
|
||||
const ASTRecordLayout *BuildMicrosoftASTRecordLayout(const RecordDecl *D) const;
|
||||
|
||||
/// \brief Get or compute information about the layout of the specified
|
||||
/// Objective-C interface.
|
||||
|
|
|
@ -564,7 +564,7 @@ void EmptySubobjectMap::UpdateEmptyFieldSubobjects(const FieldDecl *FD,
|
|||
|
||||
typedef llvm::SmallPtrSet<const CXXRecordDecl*, 4> ClassSetTy;
|
||||
|
||||
class RecordLayoutBuilder {
|
||||
class ItaniumRecordLayoutBuilder {
|
||||
protected:
|
||||
// FIXME: Remove this and make the appropriate fields public.
|
||||
friend class clang::ASTContext;
|
||||
|
@ -655,19 +655,18 @@ protected:
|
|||
/// Valid if UseExternalLayout is true.
|
||||
ExternalLayout External;
|
||||
|
||||
RecordLayoutBuilder(const ASTContext &Context,
|
||||
EmptySubobjectMap *EmptySubobjects)
|
||||
: Context(Context), EmptySubobjects(EmptySubobjects), Size(0),
|
||||
Alignment(CharUnits::One()), UnpackedAlignment(CharUnits::One()),
|
||||
UseExternalLayout(false), InferAlignment(false),
|
||||
Packed(false), IsUnion(false), IsMac68kAlign(false), IsMsStruct(false),
|
||||
UnfilledBitsInLastUnit(0), LastBitfieldTypeSize(0),
|
||||
MaxFieldAlignment(CharUnits::Zero()),
|
||||
DataSize(0), NonVirtualSize(CharUnits::Zero()),
|
||||
NonVirtualAlignment(CharUnits::One()),
|
||||
PrimaryBase(nullptr), PrimaryBaseIsVirtual(false),
|
||||
HasOwnVFPtr(false),
|
||||
FirstNearlyEmptyVBase(nullptr) {}
|
||||
ItaniumRecordLayoutBuilder(const ASTContext &Context,
|
||||
EmptySubobjectMap *EmptySubobjects)
|
||||
: Context(Context), EmptySubobjects(EmptySubobjects), Size(0),
|
||||
Alignment(CharUnits::One()), UnpackedAlignment(CharUnits::One()),
|
||||
UseExternalLayout(false), InferAlignment(false), Packed(false),
|
||||
IsUnion(false), IsMac68kAlign(false), IsMsStruct(false),
|
||||
UnfilledBitsInLastUnit(0), LastBitfieldTypeSize(0),
|
||||
MaxFieldAlignment(CharUnits::Zero()), DataSize(0),
|
||||
NonVirtualSize(CharUnits::Zero()),
|
||||
NonVirtualAlignment(CharUnits::One()), PrimaryBase(nullptr),
|
||||
PrimaryBaseIsVirtual(false), HasOwnVFPtr(false),
|
||||
FirstNearlyEmptyVBase(nullptr) {}
|
||||
|
||||
void Layout(const RecordDecl *D);
|
||||
void Layout(const CXXRecordDecl *D);
|
||||
|
@ -781,13 +780,12 @@ protected:
|
|||
void setDataSize(CharUnits NewSize) { DataSize = Context.toBits(NewSize); }
|
||||
void setDataSize(uint64_t NewSize) { DataSize = NewSize; }
|
||||
|
||||
RecordLayoutBuilder(const RecordLayoutBuilder &) = delete;
|
||||
void operator=(const RecordLayoutBuilder &) = delete;
|
||||
ItaniumRecordLayoutBuilder(const ItaniumRecordLayoutBuilder &) = delete;
|
||||
void operator=(const ItaniumRecordLayoutBuilder &) = delete;
|
||||
};
|
||||
} // end anonymous namespace
|
||||
|
||||
void
|
||||
RecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD) {
|
||||
void ItaniumRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD) {
|
||||
for (const auto &I : RD->bases()) {
|
||||
assert(!I.getType()->isDependentType() &&
|
||||
"Cannot layout class with dependent bases.");
|
||||
|
@ -816,7 +814,7 @@ RecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD) {
|
|||
}
|
||||
|
||||
/// DeterminePrimaryBase - Determine the primary base of the given class.
|
||||
void RecordLayoutBuilder::DeterminePrimaryBase(const CXXRecordDecl *RD) {
|
||||
void ItaniumRecordLayoutBuilder::DeterminePrimaryBase(const CXXRecordDecl *RD) {
|
||||
// If the class isn't dynamic, it won't have a primary base.
|
||||
if (!RD->isDynamicClass())
|
||||
return;
|
||||
|
@ -863,10 +861,8 @@ void RecordLayoutBuilder::DeterminePrimaryBase(const CXXRecordDecl *RD) {
|
|||
assert(!PrimaryBase && "Should not get here with a primary base!");
|
||||
}
|
||||
|
||||
BaseSubobjectInfo *
|
||||
RecordLayoutBuilder::ComputeBaseSubobjectInfo(const CXXRecordDecl *RD,
|
||||
bool IsVirtual,
|
||||
BaseSubobjectInfo *Derived) {
|
||||
BaseSubobjectInfo *ItaniumRecordLayoutBuilder::ComputeBaseSubobjectInfo(
|
||||
const CXXRecordDecl *RD, bool IsVirtual, BaseSubobjectInfo *Derived) {
|
||||
BaseSubobjectInfo *Info;
|
||||
|
||||
if (IsVirtual) {
|
||||
|
@ -942,7 +938,8 @@ RecordLayoutBuilder::ComputeBaseSubobjectInfo(const CXXRecordDecl *RD,
|
|||
return Info;
|
||||
}
|
||||
|
||||
void RecordLayoutBuilder::ComputeBaseSubobjectInfo(const CXXRecordDecl *RD) {
|
||||
void ItaniumRecordLayoutBuilder::ComputeBaseSubobjectInfo(
|
||||
const CXXRecordDecl *RD) {
|
||||
for (const auto &I : RD->bases()) {
|
||||
bool IsVirtual = I.isVirtual();
|
||||
|
||||
|
@ -965,8 +962,8 @@ void RecordLayoutBuilder::ComputeBaseSubobjectInfo(const CXXRecordDecl *RD) {
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
RecordLayoutBuilder::EnsureVTablePointerAlignment(CharUnits UnpackedBaseAlign) {
|
||||
void ItaniumRecordLayoutBuilder::EnsureVTablePointerAlignment(
|
||||
CharUnits UnpackedBaseAlign) {
|
||||
CharUnits BaseAlign = (Packed) ? CharUnits::One() : UnpackedBaseAlign;
|
||||
|
||||
// The maximum field alignment overrides base align.
|
||||
|
@ -983,8 +980,8 @@ RecordLayoutBuilder::EnsureVTablePointerAlignment(CharUnits UnpackedBaseAlign) {
|
|||
UpdateAlignment(BaseAlign, UnpackedBaseAlign);
|
||||
}
|
||||
|
||||
void
|
||||
RecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) {
|
||||
void ItaniumRecordLayoutBuilder::LayoutNonVirtualBases(
|
||||
const CXXRecordDecl *RD) {
|
||||
// Then, determine the primary base class.
|
||||
DeterminePrimaryBase(RD);
|
||||
|
||||
|
@ -1053,7 +1050,8 @@ RecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) {
|
|||
}
|
||||
}
|
||||
|
||||
void RecordLayoutBuilder::LayoutNonVirtualBase(const BaseSubobjectInfo *Base) {
|
||||
void ItaniumRecordLayoutBuilder::LayoutNonVirtualBase(
|
||||
const BaseSubobjectInfo *Base) {
|
||||
// Layout the base.
|
||||
CharUnits Offset = LayoutBase(Base);
|
||||
|
||||
|
@ -1064,9 +1062,8 @@ void RecordLayoutBuilder::LayoutNonVirtualBase(const BaseSubobjectInfo *Base) {
|
|||
AddPrimaryVirtualBaseOffsets(Base, Offset);
|
||||
}
|
||||
|
||||
void
|
||||
RecordLayoutBuilder::AddPrimaryVirtualBaseOffsets(const BaseSubobjectInfo *Info,
|
||||
CharUnits Offset) {
|
||||
void ItaniumRecordLayoutBuilder::AddPrimaryVirtualBaseOffsets(
|
||||
const BaseSubobjectInfo *Info, CharUnits Offset) {
|
||||
// This base isn't interesting, it has no virtual bases.
|
||||
if (!Info->Class->getNumVBases())
|
||||
return;
|
||||
|
@ -1098,9 +1095,8 @@ RecordLayoutBuilder::AddPrimaryVirtualBaseOffsets(const BaseSubobjectInfo *Info,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
RecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD,
|
||||
const CXXRecordDecl *MostDerivedClass) {
|
||||
void ItaniumRecordLayoutBuilder::LayoutVirtualBases(
|
||||
const CXXRecordDecl *RD, const CXXRecordDecl *MostDerivedClass) {
|
||||
const CXXRecordDecl *PrimaryBase;
|
||||
bool PrimaryBaseIsVirtual;
|
||||
|
||||
|
@ -1145,7 +1141,8 @@ RecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD,
|
|||
}
|
||||
}
|
||||
|
||||
void RecordLayoutBuilder::LayoutVirtualBase(const BaseSubobjectInfo *Base) {
|
||||
void ItaniumRecordLayoutBuilder::LayoutVirtualBase(
|
||||
const BaseSubobjectInfo *Base) {
|
||||
assert(!Base->Derived && "Trying to lay out a primary virtual base!");
|
||||
|
||||
// Layout the base.
|
||||
|
@ -1159,7 +1156,8 @@ void RecordLayoutBuilder::LayoutVirtualBase(const BaseSubobjectInfo *Base) {
|
|||
AddPrimaryVirtualBaseOffsets(Base, Offset);
|
||||
}
|
||||
|
||||
CharUnits RecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) {
|
||||
CharUnits
|
||||
ItaniumRecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) {
|
||||
const ASTRecordLayout &Layout = Context.getASTRecordLayout(Base->Class);
|
||||
|
||||
|
||||
|
@ -1228,7 +1226,7 @@ CharUnits RecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) {
|
|||
return Offset;
|
||||
}
|
||||
|
||||
void RecordLayoutBuilder::InitializeLayout(const Decl *D) {
|
||||
void ItaniumRecordLayoutBuilder::InitializeLayout(const Decl *D) {
|
||||
if (const RecordDecl *RD = dyn_cast<RecordDecl>(D)) {
|
||||
IsUnion = RD->isUnion();
|
||||
IsMsStruct = RD->isMsStruct(Context);
|
||||
|
@ -1276,7 +1274,7 @@ void RecordLayoutBuilder::InitializeLayout(const Decl *D) {
|
|||
}
|
||||
}
|
||||
|
||||
void RecordLayoutBuilder::Layout(const RecordDecl *D) {
|
||||
void ItaniumRecordLayoutBuilder::Layout(const RecordDecl *D) {
|
||||
InitializeLayout(D);
|
||||
LayoutFields(D);
|
||||
|
||||
|
@ -1285,7 +1283,7 @@ void RecordLayoutBuilder::Layout(const RecordDecl *D) {
|
|||
FinishLayout(D);
|
||||
}
|
||||
|
||||
void RecordLayoutBuilder::Layout(const CXXRecordDecl *RD) {
|
||||
void ItaniumRecordLayoutBuilder::Layout(const CXXRecordDecl *RD) {
|
||||
InitializeLayout(RD);
|
||||
|
||||
// Lay out the vtable and the non-virtual bases.
|
||||
|
@ -1325,7 +1323,7 @@ void RecordLayoutBuilder::Layout(const CXXRecordDecl *RD) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void RecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D) {
|
||||
void ItaniumRecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D) {
|
||||
if (ObjCInterfaceDecl *SD = D->getSuperClass()) {
|
||||
const ASTRecordLayout &SL = Context.getASTObjCInterfaceLayout(SD);
|
||||
|
||||
|
@ -1348,7 +1346,7 @@ void RecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D) {
|
|||
FinishLayout(D);
|
||||
}
|
||||
|
||||
void RecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
|
||||
void ItaniumRecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
|
||||
// Layout each field, for now, just sequentially, respecting alignment. In
|
||||
// the future, this will need to be tweakable by targets.
|
||||
bool InsertExtraPadding = D->mayInsertExtraPadding(/*EmitRemark=*/true);
|
||||
|
@ -1369,10 +1367,10 @@ roundUpSizeToCharAlignment(uint64_t Size,
|
|||
return llvm::RoundUpToAlignment(Size, CharAlignment);
|
||||
}
|
||||
|
||||
void RecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize,
|
||||
uint64_t TypeSize,
|
||||
bool FieldPacked,
|
||||
const FieldDecl *D) {
|
||||
void ItaniumRecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize,
|
||||
uint64_t TypeSize,
|
||||
bool FieldPacked,
|
||||
const FieldDecl *D) {
|
||||
assert(Context.getLangOpts().CPlusPlus &&
|
||||
"Can only have wide bit-fields in C++!");
|
||||
|
||||
|
@ -1436,7 +1434,7 @@ void RecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize,
|
|||
UpdateAlignment(TypeAlign);
|
||||
}
|
||||
|
||||
void RecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
|
||||
void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
|
||||
bool FieldPacked = Packed || D->hasAttr<PackedAttr>();
|
||||
uint64_t FieldSize = D->getBitWidthValue(Context);
|
||||
TypeInfo FieldInfo = Context.getTypeInfo(D->getType());
|
||||
|
@ -1671,8 +1669,8 @@ void RecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
|
|||
Context.toCharUnitsFromBits(UnpackedFieldAlign));
|
||||
}
|
||||
|
||||
void RecordLayoutBuilder::LayoutField(const FieldDecl *D,
|
||||
bool InsertExtraPadding) {
|
||||
void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D,
|
||||
bool InsertExtraPadding) {
|
||||
if (D->isBitField()) {
|
||||
LayoutBitField(D);
|
||||
return;
|
||||
|
@ -1799,7 +1797,7 @@ void RecordLayoutBuilder::LayoutField(const FieldDecl *D,
|
|||
UpdateAlignment(FieldAlign, UnpackedFieldAlign);
|
||||
}
|
||||
|
||||
void RecordLayoutBuilder::FinishLayout(const NamedDecl *D) {
|
||||
void ItaniumRecordLayoutBuilder::FinishLayout(const NamedDecl *D) {
|
||||
// In C++, records cannot be of size 0.
|
||||
if (Context.getLangOpts().CPlusPlus && getSizeInBits() == 0) {
|
||||
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
|
||||
|
@ -1863,8 +1861,8 @@ void RecordLayoutBuilder::FinishLayout(const NamedDecl *D) {
|
|||
}
|
||||
}
|
||||
|
||||
void RecordLayoutBuilder::UpdateAlignment(CharUnits NewAlignment,
|
||||
CharUnits UnpackedNewAlignment) {
|
||||
void ItaniumRecordLayoutBuilder::UpdateAlignment(
|
||||
CharUnits NewAlignment, CharUnits UnpackedNewAlignment) {
|
||||
// The alignment is not modified when using 'mac68k' alignment or when
|
||||
// we have an externally-supplied layout that also provides overall alignment.
|
||||
if (IsMac68kAlign || (UseExternalLayout && !InferAlignment))
|
||||
|
@ -1884,8 +1882,8 @@ void RecordLayoutBuilder::UpdateAlignment(CharUnits NewAlignment,
|
|||
}
|
||||
|
||||
uint64_t
|
||||
RecordLayoutBuilder::updateExternalFieldOffset(const FieldDecl *Field,
|
||||
uint64_t ComputedOffset) {
|
||||
ItaniumRecordLayoutBuilder::updateExternalFieldOffset(const FieldDecl *Field,
|
||||
uint64_t ComputedOffset) {
|
||||
uint64_t ExternalFieldOffset = External.getExternalFieldOffset(Field);
|
||||
|
||||
if (InferAlignment && ExternalFieldOffset < ComputedOffset) {
|
||||
|
@ -1913,12 +1911,9 @@ static unsigned getPaddingDiagFromTagKind(TagTypeKind Tag) {
|
|||
}
|
||||
}
|
||||
|
||||
void RecordLayoutBuilder::CheckFieldPadding(uint64_t Offset,
|
||||
uint64_t UnpaddedOffset,
|
||||
uint64_t UnpackedOffset,
|
||||
unsigned UnpackedAlign,
|
||||
bool isPacked,
|
||||
const FieldDecl *D) {
|
||||
void ItaniumRecordLayoutBuilder::CheckFieldPadding(
|
||||
uint64_t Offset, uint64_t UnpaddedOffset, uint64_t UnpackedOffset,
|
||||
unsigned UnpackedAlign, bool isPacked, const FieldDecl *D) {
|
||||
// We let objc ivars without warning, objc interfaces generally are not used
|
||||
// for padding tricks.
|
||||
if (isa<ObjCIvarDecl>(D))
|
||||
|
@ -2020,8 +2015,8 @@ static const CXXMethodDecl *computeKeyFunction(ASTContext &Context,
|
|||
return nullptr;
|
||||
}
|
||||
|
||||
DiagnosticBuilder
|
||||
RecordLayoutBuilder::Diag(SourceLocation Loc, unsigned DiagID) {
|
||||
DiagnosticBuilder ItaniumRecordLayoutBuilder::Diag(SourceLocation Loc,
|
||||
unsigned DiagID) {
|
||||
return Context.getDiagnostics().Report(Loc, DiagID);
|
||||
}
|
||||
|
||||
|
@ -2067,8 +2062,8 @@ static bool mustSkipTailPadding(TargetCXXABI ABI, const CXXRecordDecl *RD) {
|
|||
llvm_unreachable("bad tail-padding use kind");
|
||||
}
|
||||
|
||||
static bool isMsLayout(const RecordDecl* D) {
|
||||
return D->getASTContext().getTargetInfo().getCXXABI().isMicrosoft();
|
||||
static bool isMsLayout(const ASTContext &Context) {
|
||||
return Context.getTargetInfo().getCXXABI().isMicrosoft();
|
||||
}
|
||||
|
||||
// This section contains an implementation of struct layout that is, up to the
|
||||
|
@ -2833,32 +2828,6 @@ void MicrosoftRecordLayoutBuilder::computeVtorDispSet(
|
|||
}
|
||||
}
|
||||
|
||||
/// \brief Get or compute information about the layout of the specified record
|
||||
/// (struct/union/class), which indicates its size and field position
|
||||
/// information.
|
||||
const ASTRecordLayout *
|
||||
ASTContext::BuildMicrosoftASTRecordLayout(const RecordDecl *D) const {
|
||||
MicrosoftRecordLayoutBuilder Builder(*this);
|
||||
if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
|
||||
Builder.cxxLayout(RD);
|
||||
return new (*this) ASTRecordLayout(
|
||||
*this, Builder.Size, Builder.Alignment, Builder.RequiredAlignment,
|
||||
Builder.HasOwnVFPtr,
|
||||
Builder.HasOwnVFPtr || Builder.PrimaryBase,
|
||||
Builder.VBPtrOffset, Builder.NonVirtualSize, Builder.FieldOffsets.data(),
|
||||
Builder.FieldOffsets.size(), Builder.NonVirtualSize,
|
||||
Builder.Alignment, CharUnits::Zero(), Builder.PrimaryBase,
|
||||
false, Builder.SharedVBPtrBase,
|
||||
Builder.EndsWithZeroSizedObject, Builder.LeadsWithZeroSizedBase,
|
||||
Builder.Bases, Builder.VBases);
|
||||
} else {
|
||||
Builder.layout(D);
|
||||
return new (*this) ASTRecordLayout(
|
||||
*this, Builder.Size, Builder.Alignment, Builder.RequiredAlignment,
|
||||
Builder.Size, Builder.FieldOffsets.data(), Builder.FieldOffsets.size());
|
||||
}
|
||||
}
|
||||
|
||||
/// getASTRecordLayout - Get or compute information about the layout of the
|
||||
/// specified record (struct/union/class), which indicates its size and field
|
||||
/// position information.
|
||||
|
@ -2885,54 +2854,63 @@ ASTContext::getASTRecordLayout(const RecordDecl *D) const {
|
|||
|
||||
const ASTRecordLayout *NewEntry = nullptr;
|
||||
|
||||
if (isMsLayout(D)) {
|
||||
NewEntry = BuildMicrosoftASTRecordLayout(D);
|
||||
} else if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
|
||||
EmptySubobjectMap EmptySubobjects(*this, RD);
|
||||
RecordLayoutBuilder Builder(*this, &EmptySubobjects);
|
||||
Builder.Layout(RD);
|
||||
|
||||
// In certain situations, we are allowed to lay out objects in the
|
||||
// tail-padding of base classes. This is ABI-dependent.
|
||||
// FIXME: this should be stored in the record layout.
|
||||
bool skipTailPadding =
|
||||
mustSkipTailPadding(getTargetInfo().getCXXABI(), cast<CXXRecordDecl>(D));
|
||||
|
||||
// FIXME: This should be done in FinalizeLayout.
|
||||
CharUnits DataSize =
|
||||
skipTailPadding ? Builder.getSize() : Builder.getDataSize();
|
||||
CharUnits NonVirtualSize =
|
||||
skipTailPadding ? DataSize : Builder.NonVirtualSize;
|
||||
NewEntry =
|
||||
new (*this) ASTRecordLayout(*this, Builder.getSize(),
|
||||
Builder.Alignment,
|
||||
/*RequiredAlignment : used by MS-ABI)*/
|
||||
Builder.Alignment,
|
||||
Builder.HasOwnVFPtr,
|
||||
RD->isDynamicClass(),
|
||||
CharUnits::fromQuantity(-1),
|
||||
DataSize,
|
||||
Builder.FieldOffsets.data(),
|
||||
Builder.FieldOffsets.size(),
|
||||
NonVirtualSize,
|
||||
Builder.NonVirtualAlignment,
|
||||
EmptySubobjects.SizeOfLargestEmptySubobject,
|
||||
Builder.PrimaryBase,
|
||||
Builder.PrimaryBaseIsVirtual,
|
||||
nullptr, false, false,
|
||||
Builder.Bases, Builder.VBases);
|
||||
if (isMsLayout(*this)) {
|
||||
MicrosoftRecordLayoutBuilder Builder(*this);
|
||||
if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) {
|
||||
Builder.cxxLayout(RD);
|
||||
NewEntry = new (*this) ASTRecordLayout(
|
||||
*this, Builder.Size, Builder.Alignment, Builder.RequiredAlignment,
|
||||
Builder.HasOwnVFPtr, Builder.HasOwnVFPtr || Builder.PrimaryBase,
|
||||
Builder.VBPtrOffset, Builder.NonVirtualSize,
|
||||
Builder.FieldOffsets.data(), Builder.FieldOffsets.size(),
|
||||
Builder.NonVirtualSize, Builder.Alignment, CharUnits::Zero(),
|
||||
Builder.PrimaryBase, false, Builder.SharedVBPtrBase,
|
||||
Builder.EndsWithZeroSizedObject, Builder.LeadsWithZeroSizedBase,
|
||||
Builder.Bases, Builder.VBases);
|
||||
} else {
|
||||
Builder.layout(D);
|
||||
NewEntry = new (*this) ASTRecordLayout(
|
||||
*this, Builder.Size, Builder.Alignment, Builder.RequiredAlignment,
|
||||
Builder.Size, Builder.FieldOffsets.data(),
|
||||
Builder.FieldOffsets.size());
|
||||
}
|
||||
} else {
|
||||
RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/nullptr);
|
||||
Builder.Layout(D);
|
||||
if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) {
|
||||
EmptySubobjectMap EmptySubobjects(*this, RD);
|
||||
ItaniumRecordLayoutBuilder Builder(*this, &EmptySubobjects);
|
||||
Builder.Layout(RD);
|
||||
|
||||
NewEntry =
|
||||
new (*this) ASTRecordLayout(*this, Builder.getSize(),
|
||||
Builder.Alignment,
|
||||
/*RequiredAlignment : used by MS-ABI)*/
|
||||
Builder.Alignment,
|
||||
Builder.getSize(),
|
||||
Builder.FieldOffsets.data(),
|
||||
Builder.FieldOffsets.size());
|
||||
// In certain situations, we are allowed to lay out objects in the
|
||||
// tail-padding of base classes. This is ABI-dependent.
|
||||
// FIXME: this should be stored in the record layout.
|
||||
bool skipTailPadding =
|
||||
mustSkipTailPadding(getTargetInfo().getCXXABI(), RD);
|
||||
|
||||
// FIXME: This should be done in FinalizeLayout.
|
||||
CharUnits DataSize =
|
||||
skipTailPadding ? Builder.getSize() : Builder.getDataSize();
|
||||
CharUnits NonVirtualSize =
|
||||
skipTailPadding ? DataSize : Builder.NonVirtualSize;
|
||||
NewEntry = new (*this) ASTRecordLayout(
|
||||
*this, Builder.getSize(), Builder.Alignment,
|
||||
/*RequiredAlignment : used by MS-ABI)*/
|
||||
Builder.Alignment, Builder.HasOwnVFPtr, RD->isDynamicClass(),
|
||||
CharUnits::fromQuantity(-1), DataSize, Builder.FieldOffsets.data(),
|
||||
Builder.FieldOffsets.size(), NonVirtualSize,
|
||||
Builder.NonVirtualAlignment,
|
||||
EmptySubobjects.SizeOfLargestEmptySubobject, Builder.PrimaryBase,
|
||||
Builder.PrimaryBaseIsVirtual, nullptr, false, false, Builder.Bases,
|
||||
Builder.VBases);
|
||||
} else {
|
||||
ItaniumRecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/nullptr);
|
||||
Builder.Layout(D);
|
||||
|
||||
NewEntry = new (*this) ASTRecordLayout(
|
||||
*this, Builder.getSize(), Builder.Alignment,
|
||||
/*RequiredAlignment : used by MS-ABI)*/
|
||||
Builder.Alignment, Builder.getSize(), Builder.FieldOffsets.data(),
|
||||
Builder.FieldOffsets.size());
|
||||
}
|
||||
}
|
||||
|
||||
ASTRecordLayouts[D] = NewEntry;
|
||||
|
@ -3042,7 +3020,7 @@ ASTContext::getObjCLayout(const ObjCInterfaceDecl *D,
|
|||
return getObjCLayout(D, nullptr);
|
||||
}
|
||||
|
||||
RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/nullptr);
|
||||
ItaniumRecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/nullptr);
|
||||
Builder.Layout(D);
|
||||
|
||||
const ASTRecordLayout *NewEntry =
|
||||
|
@ -3093,7 +3071,7 @@ static void DumpCXXRecordLayout(raw_ostream &OS,
|
|||
bool HasOwnVBPtr = Layout.hasOwnVBPtr();
|
||||
|
||||
// Vtable pointer.
|
||||
if (RD->isDynamicClass() && !PrimaryBase && !isMsLayout(RD)) {
|
||||
if (RD->isDynamicClass() && !PrimaryBase && !isMsLayout(C)) {
|
||||
PrintOffset(OS, Offset, IndentLevel);
|
||||
OS << '(' << *RD << " vtable pointer)\n";
|
||||
} else if (HasOwnVFPtr) {
|
||||
|
@ -3175,7 +3153,7 @@ static void DumpCXXRecordLayout(raw_ostream &OS,
|
|||
|
||||
PrintIndentNoOffset(OS, IndentLevel - 1);
|
||||
OS << "[sizeof=" << Layout.getSize().getQuantity();
|
||||
if (!isMsLayout(RD))
|
||||
if (!isMsLayout(C))
|
||||
OS << ", dsize=" << Layout.getDataSize().getQuantity();
|
||||
OS << ", align=" << Layout.getAlignment().getQuantity() << '\n';
|
||||
|
||||
|
@ -3202,7 +3180,7 @@ void ASTContext::DumpRecordLayout(const RecordDecl *RD,
|
|||
OS << "\nLayout: ";
|
||||
OS << "<ASTRecordLayout\n";
|
||||
OS << " Size:" << toBits(Info.getSize()) << "\n";
|
||||
if (!isMsLayout(RD))
|
||||
if (!isMsLayout(*this))
|
||||
OS << " DataSize:" << toBits(Info.getDataSize()) << "\n";
|
||||
OS << " Alignment:" << toBits(Info.getAlignment()) << "\n";
|
||||
OS << " FieldOffsets: [";
|
||||
|
|
Loading…
Reference in New Issue