;
38structBaseSubobjectInfo {
50BaseSubobjectInfo *PrimaryVirtualBaseInfo;
53 constBaseSubobjectInfo *Derived;
59structExternalLayout {
60ExternalLayout() =
default;
69llvm::DenseMap<const FieldDecl *, uint64_t> FieldOffsets;
72llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsets;
75llvm::DenseMap<const CXXRecordDecl *, CharUnits> VirtualBaseOffsets;
80assert(FieldOffsets.count(FD) &&
81 "Field does not have an external offset");
82 returnFieldOffsets[FD];
86 autoKnown = BaseOffsets.find(RD);
87 if(Known == BaseOffsets.end())
89BaseOffset = Known->second;
94 autoKnown = VirtualBaseOffsets.find(RD);
95 if(Known == VirtualBaseOffsets.end())
97BaseOffset = Known->second;
104classEmptySubobjectMap {
112 typedefllvm::TinyPtrVector<const CXXRecordDecl *> ClassVectorTy;
113 typedefllvm::DenseMap<CharUnits, ClassVectorTy> EmptyClassOffsetsMapTy;
114EmptyClassOffsetsMapTy EmptyClassOffsets;
122 voidComputeEmptySubobjectSizes();
126 voidUpdateEmptyBaseSubobjects(
constBaseSubobjectInfo *Info,
127 CharUnitsOffset,
boolPlacingEmptyBase);
131 boolPlacingOverlappingField);
133 boolPlacingOverlappingField);
137 boolAnyEmptySubobjectsBeyondOffset(
CharUnitsOffset)
const{
138 returnOffset <= MaxEmptyClassOffset;
144assert(FieldOffset % CharWidth == 0 &&
145 "Field offset not at char boundary!");
154 boolCanPlaceBaseSubobjectAtOffset(
constBaseSubobjectInfo *Info,
157 boolCanPlaceFieldSubobjectAtOffset(
const CXXRecordDecl*RD,
160 boolCanPlaceFieldSubobjectAtOffset(
const FieldDecl*FD,
171ComputeEmptySubobjectSizes();
178 boolCanPlaceBaseAtOffset(
constBaseSubobjectInfo *Info,
186voidEmptySubobjectMap::ComputeEmptySubobjectSizes() {
195EmptySize = Layout.
getSize();
201 if(EmptySize > SizeOfLargestEmptySubobject)
202SizeOfLargestEmptySubobject = EmptySize;
219EmptySize = Layout.
getSize();
225 if(EmptySize > SizeOfLargestEmptySubobject)
226SizeOfLargestEmptySubobject = EmptySize;
231EmptySubobjectMap::CanPlaceSubobjectAtOffset(
const CXXRecordDecl*RD,
237EmptyClassOffsetsMapTy::const_iterator I = EmptyClassOffsets.find(Offset);
238 if(I == EmptyClassOffsets.end())
241 constClassVectorTy &Classes = I->second;
242 if(!llvm::is_contained(Classes, RD))
249voidEmptySubobjectMap::AddSubobjectAtOffset(
const CXXRecordDecl*RD,
257ClassVectorTy &Classes = EmptyClassOffsets[Offset];
258 if(llvm::is_contained(Classes, RD))
261Classes.push_back(RD);
264 if(Offset > MaxEmptyClassOffset)
265MaxEmptyClassOffset = Offset;
269EmptySubobjectMap::CanPlaceBaseSubobjectAtOffset(
constBaseSubobjectInfo *Info,
273 if(!AnyEmptySubobjectsBeyondOffset(Offset))
276 if(!CanPlaceSubobjectAtOffset(Info->Class, Offset))
281 for(
constBaseSubobjectInfo *
Base: Info->Bases) {
282 if(
Base->IsVirtual)
287 if(!CanPlaceBaseSubobjectAtOffset(
Base, BaseOffset))
291 if(Info->PrimaryVirtualBaseInfo) {
292BaseSubobjectInfo *PrimaryVirtualBaseInfo = Info->PrimaryVirtualBaseInfo;
294 if(Info == PrimaryVirtualBaseInfo->Derived) {
295 if(!CanPlaceBaseSubobjectAtOffset(PrimaryVirtualBaseInfo, Offset))
301 for(
const FieldDecl*Field : Info->Class->fields()) {
302 if(
Field->isBitField())
306 if(!CanPlaceFieldSubobjectAtOffset(Field, FieldOffset))
313voidEmptySubobjectMap::UpdateEmptyBaseSubobjects(
constBaseSubobjectInfo *Info,
315 boolPlacingEmptyBase) {
316 if(!PlacingEmptyBase && Offset >= SizeOfLargestEmptySubobject) {
325AddSubobjectAtOffset(Info->Class, Offset);
329 for(
constBaseSubobjectInfo *
Base: Info->Bases) {
330 if(
Base->IsVirtual)
334UpdateEmptyBaseSubobjects(
Base, BaseOffset, PlacingEmptyBase);
337 if(Info->PrimaryVirtualBaseInfo) {
338BaseSubobjectInfo *PrimaryVirtualBaseInfo = Info->PrimaryVirtualBaseInfo;
340 if(Info == PrimaryVirtualBaseInfo->Derived)
341UpdateEmptyBaseSubobjects(PrimaryVirtualBaseInfo, Offset,
346 for(
const FieldDecl*Field : Info->Class->fields()) {
347 if(
Field->isBitField())
351UpdateEmptyFieldSubobjects(Field, FieldOffset, PlacingEmptyBase);
355boolEmptySubobjectMap::CanPlaceBaseAtOffset(
constBaseSubobjectInfo *Info,
359 if(SizeOfLargestEmptySubobject.isZero())
362 if(!CanPlaceBaseSubobjectAtOffset(Info, Offset))
367UpdateEmptyBaseSubobjects(Info, Offset, Info->Class->isEmpty());
372EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(
const CXXRecordDecl*RD,
377 if(!AnyEmptySubobjectsBeyondOffset(Offset))
380 if(!CanPlaceSubobjectAtOffset(RD, Offset))
387 if(
Base.isVirtual())
393 if(!CanPlaceFieldSubobjectAtOffset(BaseDecl, Class, BaseOffset))
403 if(!CanPlaceFieldSubobjectAtOffset(VBaseDecl, Class, VBaseOffset))
410 if(
Field->isBitField())
414 if(!CanPlaceFieldSubobjectAtOffset(Field, FieldOffset))
422EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(
const FieldDecl*FD,
426 if(!AnyEmptySubobjectsBeyondOffset(Offset))
431 returnCanPlaceFieldSubobjectAtOffset(RD, RD, Offset);
445 for(uint64_t I = 0; I != NumElements; ++I) {
448 if(!AnyEmptySubobjectsBeyondOffset(ElementOffset))
451 if(!CanPlaceFieldSubobjectAtOffset(RD, RD, ElementOffset))
454ElementOffset += Layout.
getSize();
461boolEmptySubobjectMap::CanPlaceFieldAtOffset(
const FieldDecl*FD,
463 if(!CanPlaceFieldSubobjectAtOffset(FD, Offset))
468UpdateEmptyFieldSubobjects(FD, Offset, FD->
hasAttr<NoUniqueAddressAttr>());
472voidEmptySubobjectMap::UpdateEmptyFieldSubobjects(
474 boolPlacingOverlappingField) {
485 if(!PlacingOverlappingField && Offset >= SizeOfLargestEmptySubobject)
488AddSubobjectAtOffset(RD, Offset);
494 if(
Base.isVirtual())
500UpdateEmptyFieldSubobjects(BaseDecl, Class, BaseOffset,
501PlacingOverlappingField);
510UpdateEmptyFieldSubobjects(VBaseDecl, Class, VBaseOffset,
511PlacingOverlappingField);
517 if(
Field->isBitField())
521UpdateEmptyFieldSubobjects(Field, FieldOffset, PlacingOverlappingField);
525voidEmptySubobjectMap::UpdateEmptyFieldSubobjects(
529UpdateEmptyFieldSubobjects(RD, RD, Offset, PlacingOverlappingField);
546 for(uint64_t I = 0; I != NumElements; ++I) {
552 if(!PlacingOverlappingField &&
553ElementOffset >= SizeOfLargestEmptySubobject)
556UpdateEmptyFieldSubobjects(RD, RD, ElementOffset,
557PlacingOverlappingField);
558ElementOffset += Layout.
getSize();
565classItaniumRecordLayoutBuilder {
572EmptySubobjectMap *EmptySubobjects;
593LLVM_PREFERRED_TYPE(
bool)
594 unsignedUseExternalLayout : 1;
598LLVM_PREFERRED_TYPE(
bool)
599 unsignedInferAlignment : 1;
602LLVM_PREFERRED_TYPE(
bool)
605LLVM_PREFERRED_TYPE(
bool)
606 unsignedIsUnion : 1;
608LLVM_PREFERRED_TYPE(
bool)
609 unsignedIsMac68kAlign : 1;
611LLVM_PREFERRED_TYPE(
bool)
612 unsignedIsNaturalAlign : 1;
614LLVM_PREFERRED_TYPE(
bool)
615 unsignedIsMsStruct : 1;
621 unsigned charUnfilledBitsInLastUnit;
625 unsigned charLastBitfieldStorageUnitSize;
648 boolPrimaryBaseIsVirtual;
661 boolHandledFirstNonOverlappingEmptyField;
663 typedefllvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy;
666BaseOffsetsMapTy Bases;
686ItaniumRecordLayoutBuilder(
const ASTContext&Context,
687EmptySubobjectMap *EmptySubobjects)
688: Context(Context), EmptySubobjects(EmptySubobjects),
Size(0),
691UnadjustedAlignment(
CharUnits::One()), UseExternalLayout(
false),
693IsMac68kAlign(
false),
694IsNaturalAlign(!Context.getTargetInfo().getTriple().isOSAIX()),
695IsMsStruct(
false), UnfilledBitsInLastUnit(0),
696LastBitfieldStorageUnitSize(0), MaxFieldAlignment(
CharUnits::
Zero()),
699PreferredNVAlignment(
CharUnits::One()),
700PaddedFieldSize(
CharUnits::
Zero()), PrimaryBase(nullptr),
701PrimaryBaseIsVirtual(
false), HasOwnVFPtr(
false), HasPackedField(
false),
702HandledFirstNonOverlappingEmptyField(
false),
703FirstNearlyEmptyVBase(nullptr) {}
710 voidLayoutField(
const FieldDecl*
D,
boolInsertExtraPadding);
711 voidLayoutWideBitField(uint64_t FieldSize, uint64_t StorageUnitSize,
720llvm::SpecificBumpPtrAllocator<BaseSubobjectInfo> BaseSubobjectInfoAllocator;
722 typedefllvm::DenseMap<const CXXRecordDecl *, BaseSubobjectInfo *>
723BaseSubobjectInfoMapTy;
731BaseSubobjectInfoMapTy NonVirtualBaseInfo;
739BaseSubobjectInfo *ComputeBaseSubobjectInfo(
const CXXRecordDecl*RD,
741BaseSubobjectInfo *Derived);
748 voidEnsureVTablePointerAlignment(
CharUnitsUnpackedBaseAlign);
755 voidLayoutNonVirtualBase(
constBaseSubobjectInfo *
Base);
757 voidAddPrimaryVirtualBaseOffsets(
constBaseSubobjectInfo *Info,
765 voidLayoutVirtualBase(
constBaseSubobjectInfo *
Base);
772 voidInitializeLayout(
const Decl*
D);
781UpdateAlignment(NewAlignment, UnpackedNewAlignment, NewAlignment);
783 voidUpdateAlignment(
CharUnitsNewAlignment) {
784UpdateAlignment(NewAlignment, NewAlignment, NewAlignment);
793uint64_t ComputedOffset);
795 voidCheckFieldPadding(uint64_t Offset, uint64_t UnpaddedOffset,
796uint64_t UnpackedOffset,
unsignedUnpackedAlign,
808 voidsetSize(uint64_t NewSize) {
Size= NewSize; }
810 CharUnitsgetAlignment()
const{
returnAlignment; }
816 uint64_tgetDataSizeInBits()
const{
returnDataSize; }
818 voidsetDataSize(
CharUnitsNewSize) { DataSize = Context.
toBits(NewSize); }
819 voidsetDataSize(uint64_t NewSize) { DataSize = NewSize; }
821ItaniumRecordLayoutBuilder(
constItaniumRecordLayoutBuilder &) =
delete;
822 voidoperator=(
constItaniumRecordLayoutBuilder &) =
delete;
826voidItaniumRecordLayoutBuilder::SelectPrimaryVBase(
const CXXRecordDecl*RD) {
827 for(
const auto&I : RD->
bases()) {
828assert(!I.getType()->isDependentType() &&
829 "Cannot layout class with dependent bases.");
837 if(!IndirectPrimaryBases.count(
Base)) {
839PrimaryBaseIsVirtual =
true;
844 if(!FirstNearlyEmptyVBase)
845FirstNearlyEmptyVBase =
Base;
848SelectPrimaryVBase(
Base);
855voidItaniumRecordLayoutBuilder::DeterminePrimaryBase(
const CXXRecordDecl*RD) {
867 for(
const auto&I : RD->
bases()) {
874 if(
Base->isDynamicClass()) {
877PrimaryBaseIsVirtual =
false;
887SelectPrimaryVBase(RD);
893 if(FirstNearlyEmptyVBase) {
894PrimaryBase = FirstNearlyEmptyVBase;
895PrimaryBaseIsVirtual =
true;
899assert(!PrimaryBase &&
"Should not get here with a primary base!");
902BaseSubobjectInfo *ItaniumRecordLayoutBuilder::ComputeBaseSubobjectInfo(
903 const CXXRecordDecl*RD,
boolIsVirtual, BaseSubobjectInfo *Derived) {
904BaseSubobjectInfo *Info;
910assert(InfoSlot->Class == RD &&
"Wrong class for virtual base info!");
915InfoSlot =
new(BaseSubobjectInfoAllocator.Allocate()) BaseSubobjectInfo;
918Info =
new(BaseSubobjectInfoAllocator.Allocate()) BaseSubobjectInfo;
922Info->IsVirtual = IsVirtual;
923Info->Derived =
nullptr;
924Info->PrimaryVirtualBaseInfo =
nullptr;
927BaseSubobjectInfo *PrimaryVirtualBaseInfo =
nullptr;
935assert(PrimaryVirtualBase &&
"Didn't have a primary virtual base!");
940 if(PrimaryVirtualBaseInfo) {
941 if(PrimaryVirtualBaseInfo->Derived) {
945PrimaryVirtualBase =
nullptr;
948Info->PrimaryVirtualBaseInfo = PrimaryVirtualBaseInfo;
949PrimaryVirtualBaseInfo->Derived = Info;
956 for(
const auto&I : RD->
bases()) {
957 boolIsVirtual = I.isVirtual();
959 const CXXRecordDecl*BaseDecl = I.getType()->getAsCXXRecordDecl();
961Info->Bases.push_back(ComputeBaseSubobjectInfo(BaseDecl, IsVirtual, Info));
964 if(PrimaryVirtualBase && !PrimaryVirtualBaseInfo) {
968assert(PrimaryVirtualBaseInfo &&
969 "Did not create a primary virtual base!");
972Info->PrimaryVirtualBaseInfo = PrimaryVirtualBaseInfo;
973PrimaryVirtualBaseInfo->Derived = Info;
979voidItaniumRecordLayoutBuilder::ComputeBaseSubobjectInfo(
981 for(
const auto&I : RD->
bases()) {
982 boolIsVirtual = I.isVirtual();
984 const CXXRecordDecl*BaseDecl = I.getType()->getAsCXXRecordDecl();
987BaseSubobjectInfo *Info = ComputeBaseSubobjectInfo(BaseDecl, IsVirtual,
993 "Did not add virtual base!");
996assert(!NonVirtualBaseInfo.count(BaseDecl) &&
997 "Non-virtual base already exists!");
998NonVirtualBaseInfo.insert(std::make_pair(BaseDecl, Info));
1003voidItaniumRecordLayoutBuilder::EnsureVTablePointerAlignment(
1008 if(!MaxFieldAlignment.
isZero()) {
1009BaseAlign = std::min(BaseAlign, MaxFieldAlignment);
1010UnpackedBaseAlign = std::min(UnpackedBaseAlign, MaxFieldAlignment);
1014setSize(getSize().alignTo(BaseAlign));
1017UpdateAlignment(BaseAlign, UnpackedBaseAlign, BaseAlign);
1020voidItaniumRecordLayoutBuilder::LayoutNonVirtualBases(
1023DeterminePrimaryBase(RD);
1026ComputeBaseSubobjectInfo(RD);
1030 if(PrimaryBaseIsVirtual) {
1033BaseSubobjectInfo *PrimaryBaseInfo =
VirtualBaseInfo.lookup(PrimaryBase);
1034PrimaryBaseInfo->Derived =
nullptr;
1037IndirectPrimaryBases.insert(PrimaryBase);
1039assert(!VisitedVirtualBases.count(PrimaryBase) &&
1040 "vbase already visited!");
1041VisitedVirtualBases.insert(PrimaryBase);
1043LayoutVirtualBase(PrimaryBaseInfo);
1045BaseSubobjectInfo *PrimaryBaseInfo =
1046NonVirtualBaseInfo.lookup(PrimaryBase);
1047assert(PrimaryBaseInfo &&
1048 "Did not find base info for non-virtual primary base!");
1050LayoutNonVirtualBase(PrimaryBaseInfo);
1056assert(DataSize == 0 &&
"Vtable pointer must be at offset zero!");
1061EnsureVTablePointerAlignment(PtrAlign);
1062HasOwnVFPtr =
true;
1064assert(!IsUnion &&
"Unions cannot be dynamic classes.");
1065HandledFirstNonOverlappingEmptyField =
true;
1067setSize(getSize() + PtrWidth);
1068setDataSize(getSize());
1072 for(
const auto&I : RD->
bases()) {
1078 const CXXRecordDecl*BaseDecl = I.getType()->getAsCXXRecordDecl();
1083 if(BaseDecl == PrimaryBase && !PrimaryBaseIsVirtual)
1087BaseSubobjectInfo *BaseInfo = NonVirtualBaseInfo.
lookup(BaseDecl);
1088assert(BaseInfo &&
"Did not find base info for non-virtual base!");
1090LayoutNonVirtualBase(BaseInfo);
1094voidItaniumRecordLayoutBuilder::LayoutNonVirtualBase(
1095 constBaseSubobjectInfo *
Base) {
1100assert(!Bases.count(
Base->Class) &&
"base offset already exists!");
1101Bases.insert(std::make_pair(
Base->Class, Offset));
1103AddPrimaryVirtualBaseOffsets(
Base, Offset);
1106voidItaniumRecordLayoutBuilder::AddPrimaryVirtualBaseOffsets(
1107 constBaseSubobjectInfo *Info,
CharUnitsOffset) {
1109 if(!Info->Class->getNumVBases())
1113 if(Info->PrimaryVirtualBaseInfo) {
1114assert(Info->PrimaryVirtualBaseInfo->IsVirtual &&
1115 "Primary virtual base is not virtual!");
1116 if(Info->PrimaryVirtualBaseInfo->Derived == Info) {
1118assert(!VBases.count(Info->PrimaryVirtualBaseInfo->Class) &&
1119 "primary vbase offset already exists!");
1120VBases.insert(std::make_pair(Info->PrimaryVirtualBaseInfo->Class,
1124AddPrimaryVirtualBaseOffsets(Info->PrimaryVirtualBaseInfo, Offset);
1130 for(
constBaseSubobjectInfo *
Base: Info->Bases) {
1131 if(
Base->IsVirtual)
1135AddPrimaryVirtualBaseOffsets(
Base, BaseOffset);
1139voidItaniumRecordLayoutBuilder::LayoutVirtualBases(
1142 boolPrimaryBaseIsVirtual;
1144 if(MostDerivedClass == RD) {
1145PrimaryBase = this->PrimaryBase;
1146PrimaryBaseIsVirtual = this->PrimaryBaseIsVirtual;
1154assert(!
Base.getType()->isDependentType() &&
1155 "Cannot layout class with dependent bases.");
1159 if(
Base.isVirtual()) {
1160 if(PrimaryBase != BaseDecl || !PrimaryBaseIsVirtual) {
1161 boolIndirectPrimaryBase = IndirectPrimaryBases.count(BaseDecl);
1164 if(!IndirectPrimaryBase) {
1166 if(!VisitedVirtualBases.insert(BaseDecl).second)
1169 constBaseSubobjectInfo *BaseInfo =
VirtualBaseInfo.lookup(BaseDecl);
1170assert(BaseInfo &&
"Did not find virtual base info!");
1171LayoutVirtualBase(BaseInfo);
1181LayoutVirtualBases(BaseDecl, MostDerivedClass);
1185voidItaniumRecordLayoutBuilder::LayoutVirtualBase(
1186 constBaseSubobjectInfo *
Base) {
1187assert(!
Base->Derived &&
"Trying to lay out a primary virtual base!");
1193assert(!VBases.count(
Base->Class) &&
"vbase offset already exists!");
1194VBases.insert(std::make_pair(
Base->Class,
1197AddPrimaryVirtualBaseOffsets(
Base, Offset);
1201ItaniumRecordLayoutBuilder::LayoutBase(
constBaseSubobjectInfo *
Base) {
1202assert(!IsUnion &&
"Unions cannot have base classes.");
1208 boolHasExternalLayout =
false;
1209 if(UseExternalLayout) {
1210 if(
Base->IsVirtual)
1211HasExternalLayout =
External.getExternalVBaseOffset(
Base->Class, Offset);
1213HasExternalLayout =
External.getExternalNVBaseOffset(
Base->Class, Offset);
1216 autogetBaseOrPreferredBaseAlignFromUnpacked = [&](
CharUnitsUnpackedAlign) {
1219 return(Packed && ((Context.
getLangOpts().getClangABICompat() <=
1230getBaseOrPreferredBaseAlignFromUnpacked(UnpackedBaseAlign);
1232getBaseOrPreferredBaseAlignFromUnpacked(UnpackedPreferredBaseAlign);
1234 const boolDefaultsToAIXPowerAlignment =
1236 if(DefaultsToAIXPowerAlignment) {
1241 if(!
Base->Class->isEmpty() && !HandledFirstNonOverlappingEmptyField) {
1244HandledFirstNonOverlappingEmptyField =
true;
1245}
else if(!IsNaturalAlign) {
1246UnpackedPreferredBaseAlign = UnpackedBaseAlign;
1247PreferredBaseAlign = BaseAlign;
1251 CharUnitsUnpackedAlignTo = !DefaultsToAIXPowerAlignment
1253: UnpackedPreferredBaseAlign;
1255 if(
Base->Class->isEmpty() &&
1258setSize(std::max(getSize(), Layout.
getSize()));
1261UpdateAlignment(BaseAlign, UnpackedAlignTo, PreferredBaseAlign);
1268 if(!MaxFieldAlignment.
isZero()) {
1269BaseAlign = std::min(BaseAlign, MaxFieldAlignment);
1270PreferredBaseAlign = std::min(PreferredBaseAlign, MaxFieldAlignment);
1271UnpackedAlignTo = std::min(UnpackedAlignTo, MaxFieldAlignment);
1275!DefaultsToAIXPowerAlignment ? BaseAlign : PreferredBaseAlign;
1276 if(!HasExternalLayout) {
1278Offset = getDataSize().alignTo(AlignTo);
1281 while(!EmptySubobjects->CanPlaceBaseAtOffset(
Base, Offset))
1284 boolAllowed = EmptySubobjects->CanPlaceBaseAtOffset(
Base, Offset);
1286assert(Allowed &&
"Base subobject externally placed at overlapping offset");
1288 if(InferAlignment && Offset < getDataSize().alignTo(AlignTo)) {
1292InferAlignment =
false;
1296 if(!
Base->Class->isEmpty()) {
1300setSize(std::max(getSize(), getDataSize()));
1302setSize(std::max(getSize(), Offset + Layout.
getSize()));
1305UpdateAlignment(BaseAlign, UnpackedAlignTo, PreferredBaseAlign);
1310voidItaniumRecordLayoutBuilder::InitializeLayout(
const Decl*
D) {
1311 if(
const RecordDecl*RD = dyn_cast<RecordDecl>(
D)) {
1316Packed =
D->
hasAttr<PackedAttr>();
1319 if(
unsignedDefaultMaxFieldAlignment = Context.
getLangOpts().PackStruct) {
1327 if(
D->
hasAttr<AlignMac68kAttr>()) {
1329!
D->
hasAttr<AlignNaturalAttr>() &&
1330 "Having both mac68k and natural alignment on a decl is not allowed.");
1331IsMac68kAlign =
true;
1336 if(
D->
hasAttr<AlignNaturalAttr>())
1337IsNaturalAlign =
true;
1339 if(
constMaxFieldAlignmentAttr *MFAA =
D->
getAttr<MaxFieldAlignmentAttr>())
1346HandledFirstNonOverlappingEmptyField =
1350 if(
const RecordDecl*RD = dyn_cast<RecordDecl>(
D))
1352UseExternalLayout = Source->layoutRecordType(
1357 if(UseExternalLayout) {
1363InferAlignment =
true;
1369voidItaniumRecordLayoutBuilder::Layout(
const RecordDecl*
D) {
1370InitializeLayout(
D);
1378voidItaniumRecordLayoutBuilder::Layout(
const CXXRecordDecl*RD) {
1379InitializeLayout(RD);
1382LayoutNonVirtualBases(RD);
1388NonVirtualAlignment = Alignment;
1389PreferredNVAlignment = PreferredAlignment;
1392LayoutVirtualBases(RD, RD);
1401 if(
Base.isVirtual())
1406assert(Bases.count(BaseDecl) &&
"Did not find base offset!");
1413assert(VBases.count(BaseDecl) &&
"Did not find base offset!");
1427setSize(getDataSize());
1430InitializeLayout(
D);
1432 for(
const ObjCIvarDecl*IVD =
D->all_declared_ivar_begin(); IVD;
1433IVD = IVD->getNextIvar())
1434LayoutField(IVD,
false);
1441voidItaniumRecordLayoutBuilder::LayoutFields(
const RecordDecl*
D) {
1444 boolInsertExtraPadding =
D->mayInsertExtraPadding(
true);
1445 boolHasFlexibleArrayMember =
D->hasFlexibleArrayMember();
1446 for(
autoI =
D->field_begin(), End =
D->field_end(); I != End; ++I) {
1447LayoutField(*I, InsertExtraPadding &&
1448(std::next(I) != End || !HasFlexibleArrayMember));
1457 returnllvm::alignTo(Size, CharAlignment);
1460voidItaniumRecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize,
1461uint64_t StorageUnitSize,
1465 "Can only have wide bit-fields in C++!");
1477 for(
const QualType&QT : IntegralPODTypes) {
1480 if(Size > FieldSize)
1485assert(!
Type.isNull() &&
"Did not find a type!");
1490UnfilledBitsInLastUnit = 0;
1491LastBitfieldStorageUnitSize = 0;
1494 uint64_tUnpaddedFieldOffset = getDataSizeInBits() - UnfilledBitsInLastUnit;
1499setDataSize(std::max(getDataSizeInBits(), RoundedFieldSize));
1504FieldOffset = llvm::alignTo(getDataSizeInBits(), Context.
toBits(TypeAlign));
1506 uint64_tNewSizeInBits = FieldOffset + FieldSize;
1510UnfilledBitsInLastUnit = getDataSizeInBits() - NewSizeInBits;
1514FieldOffsets.push_back(FieldOffset);
1516CheckFieldPadding(FieldOffset, UnpaddedFieldOffset, FieldOffset,
1517Context.
toBits(TypeAlign), FieldPacked,
D);
1520setSize(std::max(getSizeInBits(), getDataSizeInBits()));
1523UpdateAlignment(TypeAlign);
1530voidItaniumRecordLayoutBuilder::LayoutBitField(
const FieldDecl*
D) {
1531 boolFieldPacked = Packed ||
D->
hasAttr<PackedAttr>();
1532 uint64_tFieldSize =
D->getBitWidthValue();
1535 unsignedFieldAlign = FieldInfo.
Align;
1598FieldAlign = StorageUnitSize;
1603 if(LastBitfieldStorageUnitSize != StorageUnitSize ||
1604UnfilledBitsInLastUnit < FieldSize) {
1606 if(!LastBitfieldStorageUnitSize && !FieldSize)
1609UnfilledBitsInLastUnit = 0;
1610LastBitfieldStorageUnitSize = 0;
1624StorageUnitSize = 32;
1626 if(!AlignIsRequired)
1630 if(FieldAlign < StorageUnitSize) {
1633FieldAlign = StorageUnitSize;
1640 if(FieldSize > StorageUnitSize && !
isAIXLayout(Context)) {
1641LayoutWideBitField(FieldSize, StorageUnitSize, FieldPacked,
D);
1647IsUnion ? 0 : (getDataSizeInBits() - UnfilledBitsInLastUnit);
1652 if(FieldSize == 0 &&
1655 if(!IsUnion && FieldOffset == 0 &&
1661 unsignedZeroLengthBitfieldBoundary =
1663FieldAlign = std::max(FieldAlign, ZeroLengthBitfieldBoundary);
1672 unsignedUnpackedFieldAlign = FieldAlign;
1675 if(!IsMsStruct && FieldPacked && FieldSize != 0)
1680 if(ExplicitFieldAlign) {
1681FieldAlign = std::max(FieldAlign, ExplicitFieldAlign);
1682UnpackedFieldAlign = std::max(UnpackedFieldAlign, ExplicitFieldAlign);
1687 unsignedMaxFieldAlignmentInBits = Context.
toBits(MaxFieldAlignment);
1688 if(!MaxFieldAlignment.
isZero() && FieldSize) {
1689UnpackedFieldAlign = std::min(UnpackedFieldAlign, MaxFieldAlignmentInBits);
1691FieldAlign = UnpackedFieldAlign;
1693FieldAlign = std::min(FieldAlign, MaxFieldAlignmentInBits);
1698 if(IsMsStruct && IsUnion) {
1699FieldAlign = UnpackedFieldAlign = 1;
1705 uint64_tUnpaddedFieldOffset = FieldOffset;
1706 uint64_tUnpackedFieldOffset = FieldOffset;
1716 if(FieldSize == 0 || FieldSize > UnfilledBitsInLastUnit) {
1717FieldOffset = llvm::alignTo(FieldOffset, FieldAlign);
1718UnpackedFieldOffset =
1719llvm::alignTo(UnpackedFieldOffset, UnpackedFieldAlign);
1720UnfilledBitsInLastUnit = 0;
1725 boolAllowPadding = MaxFieldAlignment.
isZero();
1728 if(FieldSize == 0 ||
1730(FieldOffset & (FieldAlign - 1)) + FieldSize > StorageUnitSize)) {
1731FieldOffset = llvm::alignTo(FieldOffset, FieldAlign);
1732}
else if(ExplicitFieldAlign &&
1733(MaxFieldAlignmentInBits == 0 ||
1734ExplicitFieldAlign <= MaxFieldAlignmentInBits) &&
1738FieldOffset = llvm::alignTo(FieldOffset, ExplicitFieldAlign);
1742 if(FieldSize == 0 ||
1744(UnpackedFieldOffset & (UnpackedFieldAlign - 1)) + FieldSize >
1746UnpackedFieldOffset =
1747llvm::alignTo(UnpackedFieldOffset, UnpackedFieldAlign);
1748 else if(ExplicitFieldAlign &&
1749(MaxFieldAlignmentInBits == 0 ||
1750ExplicitFieldAlign <= MaxFieldAlignmentInBits) &&
1752UnpackedFieldOffset =
1753llvm::alignTo(UnpackedFieldOffset, ExplicitFieldAlign);
1758 if(UseExternalLayout)
1759FieldOffset = updateExternalFieldOffset(
D, FieldOffset);
1762FieldOffsets.push_back(FieldOffset);
1770!
D->getIdentifier())
1771FieldAlign = UnpackedFieldAlign = 1;
1779 if(!MaxFieldAlignment.
isZero()) {
1780UnpackedFieldAlign =
1781std::min(UnpackedFieldAlign, MaxFieldAlignmentInBits);
1782FieldAlign = std::min(FieldAlign, MaxFieldAlignmentInBits);
1787 if(!UseExternalLayout)
1788CheckFieldPadding(FieldOffset, UnpaddedFieldOffset, UnpackedFieldOffset,
1789UnpackedFieldAlign, FieldPacked,
D);
1799RoundedFieldSize = (FieldSize ? StorageUnitSize
1807setDataSize(std::max(getDataSizeInBits(), RoundedFieldSize));
1811}
else if(IsMsStruct && FieldSize) {
1814 if(!UnfilledBitsInLastUnit) {
1815setDataSize(FieldOffset + StorageUnitSize);
1816UnfilledBitsInLastUnit = StorageUnitSize;
1818UnfilledBitsInLastUnit -= FieldSize;
1819LastBitfieldStorageUnitSize = StorageUnitSize;
1825 uint64_tNewSizeInBits = FieldOffset + FieldSize;
1827setDataSize(llvm::alignTo(NewSizeInBits, CharAlignment));
1828UnfilledBitsInLastUnit = getDataSizeInBits() - NewSizeInBits;
1833LastBitfieldStorageUnitSize = 0;
1837setSize(std::max(getSizeInBits(), getDataSizeInBits()));
1840UnadjustedAlignment =
1846voidItaniumRecordLayoutBuilder::LayoutField(
const FieldDecl*
D,
1847 boolInsertExtraPadding) {
1848 auto*FieldClass =
D->getType()->getAsCXXRecordDecl();
1849 boolIsOverlappingEmptyField =
1850 D->isPotentiallyOverlapping() && FieldClass->isEmpty();
1853(IsUnion || IsOverlappingEmptyField) ?
CharUnits::Zero() : getDataSize();
1855 const boolDefaultsToAIXPowerAlignment =
1857 boolFoundFirstNonOverlappingEmptyFieldForAIX =
false;
1858 if(DefaultsToAIXPowerAlignment && !HandledFirstNonOverlappingEmptyField) {
1860 "The first non-overlapping empty field should have been handled.");
1862 if(!IsOverlappingEmptyField) {
1863FoundFirstNonOverlappingEmptyFieldForAIX =
true;
1870HandledFirstNonOverlappingEmptyField = !IsUnion;
1874 if(
D->isBitField()) {
1875LayoutBitField(
D);
1879 uint64_tUnpaddedFieldOffset = getDataSizeInBits() - UnfilledBitsInLastUnit;
1881UnfilledBitsInLastUnit = 0;
1882LastBitfieldStorageUnitSize = 0;
1894 autosetDeclInfo = [&](
boolIsIncompleteArrayType) {
1896FieldAlign = TI.Align;
1899EffectiveFieldSize = FieldSize =
1901AlignRequirement = TI.AlignRequirement;
1904 if(
D->getType()->isIncompleteArrayType()) {
1905setDeclInfo(
true);
1907setDeclInfo(
false);
1911 if(
D->isPotentiallyOverlapping()) {
1913EffectiveFieldSize =
1927 if(!llvm::isPowerOf2_64(TypeSize.
getQuantity())) {
1930 "Non PowerOf2 size in MSVC mode");
1952 if(TypeSize > FieldAlign &&
1954FieldAlign = TypeSize;
1959 boolFieldPacked = (Packed && (!FieldClass || FieldClass->isPOD() ||
1960FieldClass->hasAttr<PackedAttr>() ||
1971 autoalignedAttrCanDecreaseAIXAlignment = [AlignRequirement, FieldPacked] {
1990 if(DefaultsToAIXPowerAlignment && !alignedAttrCanDecreaseAIXAlignment() &&
1991(FoundFirstNonOverlappingEmptyFieldForAIX || IsNaturalAlign)) {
1992 autoperformBuiltinTypeAlignmentUpgrade = [&](
const BuiltinType*BTy) {
1993 if(BTy->getKind() == BuiltinType::Double ||
1994BTy->getKind() == BuiltinType::LongDouble) {
1996 "No need to upgrade the alignment value.");
2001 const Type*BaseTy =
D->getType()->getBaseElementTypeUnsafe();
2003performBuiltinTypeAlignmentUpgrade(
2006performBuiltinTypeAlignmentUpgrade(BTy);
2009assert(RD &&
"Expected non-null RecordDecl.");
2017 CharUnitsUnpackedFieldAlign = FieldAlign;
2019 CharUnitsUnpackedFieldOffset = FieldOffset;
2020 CharUnitsOriginalFieldAlign = UnpackedFieldAlign;
2024PackedFieldAlign = std::max(PackedFieldAlign, MaxAlignmentInChars);
2025PreferredAlign = std::max(PreferredAlign, MaxAlignmentInChars);
2026UnpackedFieldAlign = std::max(UnpackedFieldAlign, MaxAlignmentInChars);
2029 if(!MaxFieldAlignment.
isZero()) {
2030PackedFieldAlign = std::min(PackedFieldAlign, MaxFieldAlignment);
2031PreferredAlign = std::min(PreferredAlign, MaxFieldAlignment);
2032UnpackedFieldAlign = std::min(UnpackedFieldAlign, MaxFieldAlignment);
2037FieldAlign = UnpackedFieldAlign;
2038 if(DefaultsToAIXPowerAlignment)
2039UnpackedFieldAlign = PreferredAlign;
2041PreferredAlign = PackedFieldAlign;
2042FieldAlign = PackedFieldAlign;
2046!DefaultsToAIXPowerAlignment ? FieldAlign : PreferredAlign;
2048FieldOffset = FieldOffset.
alignTo(AlignTo);
2049UnpackedFieldOffset = UnpackedFieldOffset.
alignTo(UnpackedFieldAlign);
2051 if(UseExternalLayout) {
2053updateExternalFieldOffset(
D, Context.
toBits(FieldOffset)));
2055 if(!IsUnion && EmptySubobjects) {
2057 boolAllowed = EmptySubobjects->CanPlaceFieldAtOffset(
D, FieldOffset);
2059assert(Allowed &&
"Externally-placed field cannot be placed here");
2062 if(!IsUnion && EmptySubobjects) {
2064 while(!EmptySubobjects->CanPlaceFieldAtOffset(
D, FieldOffset)) {
2069FieldOffset = getDataSize().
alignTo(AlignTo);
2071FieldOffset += AlignTo;
2077FieldOffsets.push_back(Context.
toBits(FieldOffset));
2079 if(!UseExternalLayout)
2080CheckFieldPadding(Context.
toBits(FieldOffset), UnpaddedFieldOffset,
2081Context.
toBits(UnpackedFieldOffset),
2082Context.
toBits(UnpackedFieldAlign), FieldPacked,
D);
2084 if(InsertExtraPadding) {
2086 CharUnitsExtraSizeForAsan = ASanAlignment;
2087 if(FieldSize % ASanAlignment)
2090EffectiveFieldSize = FieldSize = FieldSize + ExtraSizeForAsan;
2094 if(!IsOverlappingEmptyField) {
2095 uint64_tEffectiveFieldSizeInBits = Context.
toBits(EffectiveFieldSize);
2097setDataSize(std::max(getDataSizeInBits(), EffectiveFieldSizeInBits));
2099setDataSize(FieldOffset + EffectiveFieldSize);
2101PaddedFieldSize = std::max(PaddedFieldSize, FieldOffset + FieldSize);
2102setSize(std::max(getSizeInBits(), getDataSizeInBits()));
2104setSize(std::max(getSizeInBits(),
2105(uint64_t)Context.
toBits(FieldOffset + FieldSize)));
2109UnadjustedAlignment = std::max(UnadjustedAlignment, FieldAlign);
2110UpdateAlignment(FieldAlign, UnpackedFieldAlign, PreferredAlign);
2116 if(RD->
hasAttr<PackedAttr>() || !MaxFieldAlignment.
isZero())
2117 if(FieldAlign < OriginalFieldAlign)
2118 if(
D->getType()->isRecordType()) {
2122 if(FieldOffset % OriginalFieldAlign != 0)
2128 if(Packed && !FieldPacked && PackedFieldAlign < FieldAlign)
2132voidItaniumRecordLayoutBuilder::FinishLayout(
const NamedDecl*
D) {
2134 if(Context.
getLangOpts().CPlusPlus && getSizeInBits() == 0) {
2148setSize(std::max(getSizeInBits(), (uint64_t)Context.
toBits(PaddedFieldSize)));
2152 uint64_tUnpaddedSize = getSizeInBits() - UnfilledBitsInLastUnit;
2154llvm::alignTo(getSizeInBits(), Context.
toBits(UnpackedAlignment));
2156 uint64_tRoundedSize = llvm::alignTo(
2160: PreferredAlignment));
2162 if(UseExternalLayout) {
2166 if(InferAlignment &&
External.Size < RoundedSize) {
2169InferAlignment =
false;
2176setSize(RoundedSize);
2179 if(
const RecordDecl*RD = dyn_cast<RecordDecl>(
D)) {
2181 if(getSizeInBits() > UnpaddedSize) {
2182 unsignedPadSize = getSizeInBits() - UnpaddedSize;
2183 boolInBits =
true;
2184 if(PadSize % CharBitNum == 0) {
2185PadSize = PadSize / CharBitNum;
2191<< (InBits ? 1 : 0);
2194 const auto*CXXRD = dyn_cast<CXXRecordDecl>(RD);
2202 if(Packed && UnpackedAlignment <= Alignment &&
2203UnpackedSizeInBits == getSizeInBits() && !HasPackedField &&
2204(!CXXRD || CXXRD->isPOD() ||
2212voidItaniumRecordLayoutBuilder::UpdateAlignment(
2217 if(IsMac68kAlign || (UseExternalLayout && !InferAlignment))
2220 if(NewAlignment > Alignment) {
2221assert(llvm::isPowerOf2_64(NewAlignment.
getQuantity()) &&
2222 "Alignment not a power of 2");
2223Alignment = NewAlignment;
2226 if(UnpackedNewAlignment > UnpackedAlignment) {
2227assert(llvm::isPowerOf2_64(UnpackedNewAlignment.
getQuantity()) &&
2228 "Alignment not a power of 2");
2229UnpackedAlignment = UnpackedNewAlignment;
2232 if(PreferredNewAlignment > PreferredAlignment) {
2233assert(llvm::isPowerOf2_64(PreferredNewAlignment.
getQuantity()) &&
2234 "Alignment not a power of 2");
2235PreferredAlignment = PreferredNewAlignment;
2240ItaniumRecordLayoutBuilder::updateExternalFieldOffset(
const FieldDecl*Field,
2241uint64_t ComputedOffset) {
2244 if(InferAlignment && ExternalFieldOffset < ComputedOffset) {
2249InferAlignment =
false;
2253 returnExternalFieldOffset;
2269 default: llvm_unreachable(
"Invalid tag kind for field padding diagnostic!");
2273voidItaniumRecordLayoutBuilder::CheckFieldPadding(
2274uint64_t Offset, uint64_t UnpaddedOffset, uint64_t UnpackedOffset,
2275 unsignedUnpackedAlign,
boolisPacked,
const FieldDecl*
D) {
2278 if(isa<ObjCIvarDecl>(
D))
2289 if(!IsUnion && Offset > UnpaddedOffset) {
2290 unsignedPadSize = Offset - UnpaddedOffset;
2291 boolInBits =
true;
2292 if(PadSize % CharBitNum == 0) {
2293PadSize = PadSize / CharBitNum;
2296 if(
D->getIdentifier()) {
2297 auto Diagnostic=
D->isBitField() ? diag::warn_padded_struct_bitfield
2298: diag::warn_padded_struct_field;
2303<<
D->getIdentifier();
2305 auto Diagnostic=
D->isBitField() ? diag::warn_padded_struct_anon_bitfield
2306: diag::warn_padded_struct_anon_field;
2310<< (InBits ? 1 : 0);
2313 if(isPacked && Offset != UnpackedOffset) {
2314HasPackedField =
true;
2338 boolallowInlineFunctions =
2342 if(!MD->isVirtual())
2345 if(MD->isPureVirtual())
2350 if(MD->isImplicit())
2353 if(MD->isInlineSpecified() || MD->isConstexpr())
2356 if(MD->hasInlineBody())
2360 if(!MD->isUserProvided())
2364 if(!allowInlineFunctions) {
2376 if(!MD->hasAttr<CUDADeviceAttr>())
2380 if(!MD->hasAttr<CUDAHostAttr>() && MD->hasAttr<CUDADeviceAttr>())
2388 if(MD->hasAttr<DLLImportAttr>() && !RD->
hasAttr<DLLImportAttr>() &&
2431 returnRD->
isPOD();
2443llvm_unreachable(
"bad tail-padding use kind");
2546structMicrosoftRecordLayoutBuilder {
2547 structElementInfo {
2551 typedefllvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy;
2552MicrosoftRecordLayoutBuilder(
const ASTContext&Context,
2553EmptySubobjectMap *EmptySubobjects)
2554: Context(Context), EmptySubobjects(EmptySubobjects) {}
2557MicrosoftRecordLayoutBuilder(
constMicrosoftRecordLayoutBuilder &) =
delete;
2558 voidoperator=(
constMicrosoftRecordLayoutBuilder &) =
delete;
2563 voidinitializeLayout(
const RecordDecl*RD);
2579 voidlayoutBitField(
const FieldDecl*FD);
2582 voidlayoutZeroWidthBitField(
const FieldDecl*FD);
2591ElementInfo getAdjustedElementInfo(
const FieldDecl*FD);
2593 voidplaceFieldAtOffset(
CharUnitsFieldOffset) {
2594FieldOffsets.push_back(Context.
toBits(FieldOffset));
2597 voidplaceFieldAtBitOffset(uint64_t FieldOffset) {
2598FieldOffsets.push_back(FieldOffset);
2601 voidcomputeVtorDispSet(
2602llvm::SmallPtrSetImpl<const CXXRecordDecl *> &HasVtorDispSet,
2605EmptySubobjectMap *EmptySubobjects;
2629ElementInfo PointerInfo;
2637BaseOffsetsMapTy Bases;
2643 unsignedRemainingBitsInField;
2647 boolLastFieldIsNonZeroWidthBitfield : 1;
2649 boolHasOwnVFPtr : 1;
2655 boolEndsWithZeroSizedObject : 1;
2658 boolLeadsWithZeroSizedBase : 1;
2661 boolUseExternalLayout : 1;
2669MicrosoftRecordLayoutBuilder::ElementInfo
2670MicrosoftRecordLayoutBuilder::getAdjustedElementInfo(
2675 if(!MaxFieldAlignment.
isZero())
2676Info.Alignment = std::min(Info.Alignment, MaxFieldAlignment);
2682Alignment = std::max(Alignment, Info.Alignment);
2689MicrosoftRecordLayoutBuilder::ElementInfo
2690MicrosoftRecordLayoutBuilder::getAdjustedElementInfo(
2696ElementInfo Info{TInfo.
Width, TInfo.Align};
2702FieldRequiredAlignment = std::max(
2708Info.Alignment = std::max(Info.Alignment, FieldRequiredAlignment);
2714FieldRequiredAlignment = std::max(FieldRequiredAlignment,
2718RequiredAlignment = std::max(RequiredAlignment, FieldRequiredAlignment);
2721 if(!MaxFieldAlignment.
isZero())
2722Info.Alignment = std::min(Info.Alignment, MaxFieldAlignment);
2723 if(FD->
hasAttr<PackedAttr>())
2725Info.Alignment = std::max(Info.Alignment, FieldRequiredAlignment);
2729voidMicrosoftRecordLayoutBuilder::layout(
const RecordDecl*RD) {
2732initializeLayout(RD);
2734DataSize =
Size=
Size.alignTo(Alignment);
2735RequiredAlignment = std::max(
2740voidMicrosoftRecordLayoutBuilder::cxxLayout(
const CXXRecordDecl*RD) {
2743initializeLayout(RD);
2744initializeCXXLayout(RD);
2745layoutNonVirtualBases(RD);
2749 if(HasOwnVFPtr || (HasVBPtr && !SharedVBPtrBase))
2750Alignment = std::max(Alignment, PointerInfo.Alignment);
2751 autoRoundingAlignment = Alignment;
2752 if(!MaxFieldAlignment.
isZero())
2753RoundingAlignment = std::min(RoundingAlignment, MaxFieldAlignment);
2754 if(!UseExternalLayout)
2755 Size=
Size.alignTo(RoundingAlignment);
2756NonVirtualSize =
Size;
2757RequiredAlignment = std::max(
2759layoutVirtualBases(RD);
2763voidMicrosoftRecordLayoutBuilder::initializeLayout(
const RecordDecl*RD) {
2776 if(
unsignedDefaultMaxFieldAlignment = Context.
getLangOpts().PackStruct)
2780 if(
constMaxFieldAlignmentAttr *MFAA = RD->
getAttr<MaxFieldAlignmentAttr>()){
2781 unsignedPackedAlignment = MFAA->getAlignment();
2782 if(PackedAlignment <=
2787 if(RD->
hasAttr<PackedAttr>())
2791UseExternalLayout =
false;
2793UseExternalLayout = Source->layoutRecordType(
2799MicrosoftRecordLayoutBuilder::initializeCXXLayout(
const CXXRecordDecl*RD) {
2800EndsWithZeroSizedObject =
false;
2801LeadsWithZeroSizedBase =
false;
2802HasOwnVFPtr =
false;
2804PrimaryBase =
nullptr;
2805SharedVBPtrBase =
nullptr;
2813 if(!MaxFieldAlignment.
isZero())
2814PointerInfo.Alignment = std::min(PointerInfo.Alignment, MaxFieldAlignment);
2818MicrosoftRecordLayoutBuilder::layoutNonVirtualBases(
const CXXRecordDecl*RD) {
2826 boolHasPolymorphicBaseClass =
false;
2833 if(
Base.isVirtual()) {
2838 if(!SharedVBPtrBase && BaseLayout.
hasVBPtr()) {
2839SharedVBPtrBase = BaseDecl;
2847PrimaryBase = BaseDecl;
2851layoutNonVirtualBase(RD, BaseDecl, BaseLayout, PreviousBaseLayout);
2855 if(!HasPolymorphicBaseClass)
2858HasOwnVFPtr =
true;
2859 else if(!PrimaryBase) {
2863 if(MicrosoftVTableContext::hasVtableSlot(M) &&
2864M->size_overridden_methods() == 0) {
2865HasOwnVFPtr =
true;
2873 boolCheckLeadingLayout = !PrimaryBase;
2876 if(
Base.isVirtual())
2887 if(CheckLeadingLayout) {
2888CheckLeadingLayout =
false;
2892layoutNonVirtualBase(RD, BaseDecl, BaseLayout, PreviousBaseLayout);
2898 else if(SharedVBPtrBase) {
2900VBPtrOffset = Bases[SharedVBPtrBase] + Layout.
getVBPtrOffset();
2905 if(!isa<CXXRecordDecl>(RD))
2907 if(RD->
hasAttr<EmptyBasesAttr>())
2909 if(
auto*LVA = RD->
getAttr<LayoutVersionAttr>())
2911 if(LVA->getVersion() <= LangOptions::MSVC2015)
2919voidMicrosoftRecordLayoutBuilder::layoutNonVirtualBase(
2930ElementInfo Info = getAdjustedElementInfo(BaseLayout);
2934 boolFoundBase =
false;
2935 if(UseExternalLayout) {
2936FoundBase =
External.getExternalNVBaseOffset(BaseDecl, BaseOffset);
2937 if(BaseOffset > Size) {
2943 if(MDCUsesEBO && BaseDecl->
isEmpty() &&
2948BaseOffset =
Size=
Size.alignTo(Info.Alignment);
2951Bases.insert(std::make_pair(BaseDecl, BaseOffset));
2954PreviousBaseLayout = &BaseLayout;
2957voidMicrosoftRecordLayoutBuilder::layoutFields(
const RecordDecl*RD) {
2958LastFieldIsNonZeroWidthBitfield =
false;
2963voidMicrosoftRecordLayoutBuilder::layoutField(
const FieldDecl*FD) {
2968LastFieldIsNonZeroWidthBitfield =
false;
2969ElementInfo Info = getAdjustedElementInfo(FD);
2970Alignment = std::max(Alignment, Info.Alignment);
2975FieldClass->
fields().empty();
2978 if(UseExternalLayout) {
2981}
else if(IsUnion) {
2983}
else if(EmptySubobjects) {
2984 if(!IsOverlappingEmptyField)
2985FieldOffset = DataSize.
alignTo(Info.Alignment);
2987 while(!EmptySubobjects->CanPlaceFieldAtOffset(FD, FieldOffset)) {
2989 boolHasBases = ParentClass && (!ParentClass->
bases().empty() ||
2990!ParentClass->
vbases().empty());
2995FieldOffset = DataSize.
alignTo(Info.Alignment);
2997FieldOffset += Info.Alignment;
3001FieldOffset =
Size.alignTo(Info.Alignment);
3003placeFieldAtOffset(FieldOffset);
3005 if(!IsOverlappingEmptyField)
3006DataSize = std::max(DataSize, FieldOffset + Info.Size);
3008 Size= std::max(Size, FieldOffset + Info.Size);
3011voidMicrosoftRecordLayoutBuilder::layoutBitField(
const FieldDecl*FD) {
3014layoutZeroWidthBitField(FD);
3017ElementInfo Info = getAdjustedElementInfo(FD);
3020 if(Width > Context.
toBits(Info.Size))
3021Width = Context.
toBits(Info.Size);
3025 if(!UseExternalLayout && !IsUnion && LastFieldIsNonZeroWidthBitfield &&
3026CurrentBitfieldSize == Info.Size && Width <= RemainingBitsInField) {
3027placeFieldAtBitOffset(Context.
toBits(Size) - RemainingBitsInField);
3028RemainingBitsInField -= Width;
3031LastFieldIsNonZeroWidthBitfield =
true;
3032CurrentBitfieldSize = Info.Size;
3033 if(UseExternalLayout) {
3034 autoFieldBitOffset =
External.getExternalFieldOffset(FD);
3035placeFieldAtBitOffset(FieldBitOffset);
3037llvm::alignDown(FieldBitOffset, Context.
toBits(Info.Alignment)) +
3038Context.
toBits(Info.Size));
3039 Size= std::max(Size, NewSize);
3040Alignment = std::max(Alignment, Info.Alignment);
3041}
else if(IsUnion) {
3043 Size= std::max(Size, Info.Size);
3048placeFieldAtOffset(FieldOffset);
3049 Size= FieldOffset + Info.Size;
3050Alignment = std::max(Alignment, Info.Alignment);
3051RemainingBitsInField = Context.
toBits(Info.Size) - Width;
3057MicrosoftRecordLayoutBuilder::layoutZeroWidthBitField(
const FieldDecl*FD) {
3060 if(!LastFieldIsNonZeroWidthBitfield) {
3066LastFieldIsNonZeroWidthBitfield =
false;
3067ElementInfo Info = getAdjustedElementInfo(FD);
3070 Size= std::max(Size, Info.Size);
3075placeFieldAtOffset(FieldOffset);
3077Alignment = std::max(Alignment, Info.Alignment);
3082voidMicrosoftRecordLayoutBuilder::injectVBPtr(
const CXXRecordDecl*RD) {
3083 if(!HasVBPtr || SharedVBPtrBase)
3088VBPtrOffset = VBPtrOffset.
alignTo(PointerInfo.Alignment);
3090 CharUnitsFieldStart = VBPtrOffset + PointerInfo.Size;
3093 if(UseExternalLayout) {
3096 if(Size < FieldStart)
3102 CharUnitsOffset = (FieldStart - InjectionSite)
3103.alignTo(std::max(RequiredAlignment, Alignment));
3105 for(uint64_t &FieldOffset : FieldOffsets)
3106FieldOffset += Context.
toBits(Offset);
3107 for(BaseOffsetsMapTy::value_type &
Base: Bases)
3108 if(
Base.second >= InjectionSite)
3109 Base.second += Offset;
3112voidMicrosoftRecordLayoutBuilder::injectVFPtr(
const CXXRecordDecl*RD) {
3118PointerInfo.Size.alignTo(std::max(RequiredAlignment, Alignment));
3122VBPtrOffset += Offset;
3124 if(UseExternalLayout) {
3127 if(
Size.isZero())
3136 for(uint64_t &FieldOffset : FieldOffsets)
3137FieldOffset += Context.
toBits(Offset);
3138 for(BaseOffsetsMapTy::value_type &
Base: Bases)
3139 Base.second += Offset;
3142voidMicrosoftRecordLayoutBuilder::layoutVirtualBases(
const CXXRecordDecl*RD) {
3147 CharUnitsVtorDispAlignment = VtorDispSize;
3149 if(!MaxFieldAlignment.
isZero())
3150VtorDispAlignment = std::min(VtorDispAlignment, MaxFieldAlignment);
3155 const CXXRecordDecl*BaseDecl = VBase.getType()->getAsCXXRecordDecl();
3160VtorDispAlignment = std::max(VtorDispAlignment, RequiredAlignment);
3163computeVtorDispSet(HasVtorDispSet, RD);
3167 const CXXRecordDecl*BaseDecl = VBase.getType()->getAsCXXRecordDecl();
3169 boolHasVtordisp = HasVtorDispSet.contains(BaseDecl);
3178 Size=
Size.alignTo(VtorDispAlignment) + VtorDispSize;
3179Alignment = std::max(VtorDispAlignment, Alignment);
3182ElementInfo Info = getAdjustedElementInfo(BaseLayout);
3186 if(UseExternalLayout) {
3187 if(!
External.getExternalVBaseOffset(BaseDecl, BaseOffset))
3190BaseOffset =
Size.alignTo(Info.Alignment);
3192assert(BaseOffset >= Size &&
"base offset already allocated");
3194VBases.insert(std::make_pair(BaseDecl,
3197PreviousBaseLayout = &BaseLayout;
3201voidMicrosoftRecordLayoutBuilder::finalizeLayout(
const RecordDecl*RD) {
3205 if(!RequiredAlignment.isZero()) {
3206Alignment = std::max(Alignment, RequiredAlignment);
3207 autoRoundingAlignment = Alignment;
3208 if(!MaxFieldAlignment.
isZero())
3209RoundingAlignment = std::min(RoundingAlignment, MaxFieldAlignment);
3210RoundingAlignment = std::max(RoundingAlignment, RequiredAlignment);
3211 Size=
Size.alignTo(RoundingAlignment);
3213 if(
Size.isZero()) {
3214 if(!
recordUsesEBO(RD) || !cast<CXXRecordDecl>(RD)->isEmpty()) {
3215EndsWithZeroSizedObject =
true;
3216LeadsWithZeroSizedBase =
true;
3220 if(RequiredAlignment >= MinEmptyStructSize)
3223 Size= MinEmptyStructSize;
3226 if(UseExternalLayout) {
3237BasesWithOverriddenMethods,
3239 if(BasesWithOverriddenMethods.count(RD))
3244 if(!
Base.isVirtual() &&
3246 Base.getType()->getAsCXXRecordDecl()))
3251voidMicrosoftRecordLayoutBuilder::computeVtorDispSet(
3252llvm::SmallPtrSetImpl<const CXXRecordDecl *> &HasVtordispSet,
3261HasVtordispSet.insert(BaseDecl);
3272 if(bi.second.hasVtorDisp())
3273HasVtordispSet.insert(bi.first);
3293 if(MicrosoftVTableContext::hasVtableSlot(MD) &&
3294!isa<CXXDestructorDecl>(MD) && !MD->isPureVirtual())
3296 while(!Work.empty()) {
3300 if(MethodRange.begin() == MethodRange.end())
3301BasesWithOverriddenMethods.insert(MD->
getParent());
3303Work.insert(MethodRange.begin(), MethodRange.end());
3311 if(!HasVtordispSet.count(BaseDecl) &&
3313HasVtordispSet.insert(BaseDecl);
3327 if(
D->hasExternalLexicalStorage() && !
D->getDefinition())
3332 D=
D->getDefinition();
3333assert(
D&&
"Cannot get layout of forward declarations!");
3334assert(!
D->
isInvalidDecl() &&
"Cannot get layout of invalid decl!");
3335assert(
D->isCompleteDefinition() &&
"Cannot layout type before complete!");
3341 if(Entry)
return*Entry;
3346 if(
const auto*RD = dyn_cast<CXXRecordDecl>(
D)) {
3347EmptySubobjectMap EmptySubobjects(*
this, RD);
3348MicrosoftRecordLayoutBuilder Builder(*
this, &EmptySubobjects);
3349Builder.cxxLayout(RD);
3351*
this, Builder.Size, Builder.Alignment, Builder.Alignment,
3352Builder.Alignment, Builder.RequiredAlignment, Builder.HasOwnVFPtr,
3353Builder.HasOwnVFPtr || Builder.PrimaryBase, Builder.VBPtrOffset,
3354Builder.DataSize, Builder.FieldOffsets, Builder.NonVirtualSize,
3356Builder.PrimaryBase,
false, Builder.SharedVBPtrBase,
3357Builder.EndsWithZeroSizedObject, Builder.LeadsWithZeroSizedBase,
3358Builder.Bases, Builder.VBases);
3360MicrosoftRecordLayoutBuilder Builder(*
this,
nullptr);
3361Builder.layout(
D);
3363*
this, Builder.Size, Builder.Alignment, Builder.Alignment,
3364Builder.Alignment, Builder.RequiredAlignment, Builder.Size,
3365Builder.FieldOffsets);
3368 if(
const auto*RD = dyn_cast<CXXRecordDecl>(
D)) {
3369EmptySubobjectMap EmptySubobjects(*
this, RD);
3370ItaniumRecordLayoutBuilder Builder(*
this, &EmptySubobjects);
3376 boolskipTailPadding =
3381skipTailPadding ? Builder.getSize() : Builder.getDataSize();
3383skipTailPadding ? DataSize : Builder.NonVirtualSize;
3385*
this, Builder.getSize(), Builder.Alignment,
3386Builder.PreferredAlignment, Builder.UnadjustedAlignment,
3390NonVirtualSize, Builder.NonVirtualAlignment,
3391Builder.PreferredNVAlignment,
3392EmptySubobjects.SizeOfLargestEmptySubobject, Builder.PrimaryBase,
3393Builder.PrimaryBaseIsVirtual,
nullptr,
false,
false, Builder.Bases,
3396ItaniumRecordLayoutBuilder Builder(*
this,
nullptr);
3397Builder.Layout(
D);
3400*
this, Builder.getSize(), Builder.Alignment,
3401Builder.PreferredAlignment, Builder.UnadjustedAlignment,
3403Builder.Alignment, Builder.getSize(), Builder.FieldOffsets);
3407ASTRecordLayouts[
D] = NewEntry;
3410llvm::outs() <<
"\n*** Dumping AST Record Layout\n";
3421assert(RD->
getDefinition() &&
"Cannot get key function for forward decl!");
3435KeyFunctions[RD] =
const_cast<Decl*
>(
Result);
3437 returncast_or_null<CXXMethodDecl>(
Result);
3442 "not working with method declaration from class definition");
3447 const auto&Map = KeyFunctions;
3448 autoI = Map.find(Method->
getParent());
3451 if(I == Map.end())
return;
3459KeyFunctions.erase(Method->
getParent());
3469uint64_t OffsetInBits;
3470 if(
const FieldDecl*FD = dyn_cast<FieldDecl>(VD)) {
3480 returnOffsetInBits;
3508 for(
const ObjCIvarDecl*IVD = Container->all_declared_ivar_begin();
3509IVD; IVD = IVD->getNextIvar()) {
3514assert(Index < RL->getFieldCount() &&
"Ivar is not inside record layout!");
3528 if(
D->hasExternalLexicalStorage() && !
D->getDefinition())
3530 D=
D->getDefinition();
3531assert(
D&& !
D->
isInvalidDecl() &&
D->isThisDeclarationADefinition() &&
3532 "Invalid interface decl!");
3547 if(SynthCount == 0)
3548 returngetObjCLayout(
D,
nullptr);
3551ItaniumRecordLayoutBuilder Builder(*
this,
nullptr);
3552Builder.Layout(
D);
3555*
this, Builder.getSize(), Builder.Alignment, Builder.PreferredAlignment,
3556Builder.UnadjustedAlignment,
3558Builder.Alignment, Builder.getDataSize(), Builder.FieldOffsets);
3560ObjCLayouts[Key] = NewEntry;
3566 CharUnitsOffset,
unsignedIndentLevel) {
3567OS << llvm::format(
"%10"PRId64
" | ", (int64_t)Offset.getQuantity());
3568OS.indent(IndentLevel * 2);
3572 unsigned Begin,
unsignedWidth,
3573 unsignedIndentLevel) {
3576llvm::raw_svector_ostream BufferOS(Buffer);
3577BufferOS << Offset.getQuantity() <<
':';
3581BufferOS <<
Begin<<
'-'<< (
Begin+ Width - 1);
3585OS << llvm::right_justify(Buffer, 10) <<
" | ";
3586OS.indent(IndentLevel * 2);
3591OS.indent(IndentLevel * 2);
3597 unsignedIndentLevel,
3598 const char* Description,
3600 boolIncludeVirtualBases) {
3602 autoCXXRD = dyn_cast<CXXRecordDecl>(RD);
3605OS <<
C.getTypeDeclType(
const_cast<RecordDecl*
>(RD));
3607OS <<
' '<< Description;
3608 if(CXXRD && CXXRD->isEmpty())
3621 if(CXXRD->isDynamicClass() && !PrimaryBase && !
isMsLayout(
C)) {
3623OS <<
'('<< *RD <<
" vtable pointer)\n";
3624}
else if(HasOwnVFPtr) {
3627OS <<
'('<< *RD <<
" vftable pointer)\n";
3633assert(!
Base.getType()->isDependentType() &&
3634 "Cannot layout class with dependent bases.");
3635 if(!
Base.isVirtual())
3636Bases.push_back(
Base.getType()->getAsCXXRecordDecl());
3649 Base== PrimaryBase ?
"(primary base)":
"(base)",
3657OS <<
'('<< *RD <<
" vbtable pointer)\n";
3663uint64_t LocalFieldOffsetInBits =
3666Offset +
C.toCharUnitsFromBits(LocalFieldOffsetInBits);
3669 if(
autoRT = Field->getType()->getAs<
RecordType>()) {
3671Field->getName().data(),
3677 if(Field->isBitField()) {
3678uint64_t LocalFieldByteOffsetInBits =
C.toBits(FieldOffset - Offset);
3679 unsigned Begin= LocalFieldOffsetInBits - LocalFieldByteOffsetInBits;
3680 unsignedWidth = Field->getBitWidthValue();
3685 const QualType&FieldType =
C.getLangOpts().DumpRecordLayoutsCanonical
3686? Field->getType().getCanonicalType()
3688OS << FieldType <<
' '<< *Field <<
'\n';
3692 if(CXXRD && IncludeVirtualBases) {
3697assert(
Base.isVirtual() &&
"Found non-virtual class!");
3702 if(VtorDisps.find(VBase)->second.hasVtorDisp()) {
3704OS <<
"(vtordisp for vbase "<< *VBase <<
")\n";
3709 "(primary virtual base)":
"(virtual base)",
3715 if(!PrintSizeInfo)
return;
3722 if(
C.getTargetInfo().defaultsToAIXPowerAlignment())
3730 if(
C.getTargetInfo().defaultsToAIXPowerAlignment())
3731OS <<
", preferrednvalign=" 3738 boolSimple)
const{
3755OS <<
"\nLayout: ";
3756OS <<
"<ASTRecordLayout\n";
3761 if(
Target->defaultsToAIXPowerAlignment())
3764 if(
const CXXRecordDecl*CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
3765OS <<
" BaseOffsets: [";
3767 for(
autoI : CXXRD->bases()) {
3772 Base= I.getType()->getAsCXXRecordDecl();
3773OS << Info.CXXInfo->BaseOffsets[
Base].getQuantity();
3776OS <<
" VBaseOffsets: [";
3778 for(
autoI : CXXRD->vbases()) {
3781VBase = I.getType()->getAsCXXRecordDecl();
3782OS << Info.CXXInfo->VBaseOffsets[VBase].VBaseOffset.getQuantity();
3786OS <<
" FieldOffsets: [";
3787 for(
unsignedi = 0, e = Info.
getFieldCount(); i != e; ++i) {
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)
Produce a diagnostic highlighting some portion of a literal.
static unsigned getCharWidth(tok::TokenKind kind, const TargetInfo &Target)
llvm::MachO::Target Target
static const CXXMethodDecl * computeKeyFunction(ASTContext &Context, const CXXRecordDecl *RD)
static bool mustSkipTailPadding(TargetCXXABI ABI, const CXXRecordDecl *RD)
Does the target C++ ABI require us to skip over the tail-padding of the given class (considering it a...
static bool isAIXLayout(const ASTContext &Context)
static void PrintIndentNoOffset(raw_ostream &OS, unsigned IndentLevel)
static uint64_t roundUpSizeToCharAlignment(uint64_t Size, const ASTContext &Context)
static void PrintOffset(raw_ostream &OS, CharUnits Offset, unsigned IndentLevel)
static unsigned getPaddingDiagFromTagKind(TagTypeKind Tag)
Get diagnostic select index for tag kind for field padding diagnostic message.
static void DumpRecordLayout(raw_ostream &OS, const RecordDecl *RD, const ASTContext &C, CharUnits Offset, unsigned IndentLevel, const char *Description, bool PrintSizeInfo, bool IncludeVirtualBases)
static bool isMsLayout(const ASTContext &Context)
static uint64_t getFieldOffset(const ASTContext &C, const FieldDecl *FD)
static bool RequiresVtordisp(const llvm::SmallPtrSetImpl< const CXXRecordDecl * > &BasesWithOverriddenMethods, const CXXRecordDecl *RD)
static void PrintBitFieldOffset(raw_ostream &OS, CharUnits Offset, unsigned Begin, unsigned Width, unsigned IndentLevel)
static bool recordUsesEBO(const RecordDecl *RD)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ConstantArrayType * getAsConstantArrayType(QualType T) const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
uint64_t getFieldOffset(const ValueDecl *FD) const
Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D,...
void DumpRecordLayout(const RecordDecl *RD, raw_ostream &OS, bool Simple=false) const
const CXXMethodDecl * getCurrentKeyFunction(const CXXRecordDecl *RD)
Get our current best idea for the key function of the given record decl, or nullptr if there isn't on...
const ASTRecordLayout & getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const
Get or compute information about the layout of the specified Objective-C implementation.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
const LangOptions & getLangOpts() const
const ASTRecordLayout & getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const
Get or compute information about the layout of the specified Objective-C interface.
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
unsigned CountNonClassIvars(const ObjCInterfaceDecl *OI) const
bool isNearlyEmpty(const CXXRecordDecl *RD) const
const TargetInfo * getAuxTargetInfo() const
CanQualType UnsignedLongTy
TypeInfo getTypeInfo(const Type *T) const
Get the size and alignment of the specified complete type in bits.
bool isAlignmentRequired(const Type *T) const
Determine if the alignment the type has was required using an alignment attribute.
void setNonKeyFunction(const CXXMethodDecl *method)
Observe that the given method cannot be a key function.
TypeInfoChars getTypeInfoInChars(const Type *T) const
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
uint64_t lookupFieldBitOffset(const ObjCInterfaceDecl *OID, const ObjCImplementationDecl *ID, const ObjCIvarDecl *Ivar) const
Get the offset of an ObjCIvarDecl in bits.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CanQualType UnsignedCharTy
CanQualType UnsignedIntTy
CanQualType UnsignedLongLongTy
CanQualType UnsignedShortTy
DiagnosticsEngine & getDiagnostics() const
const TargetInfo & getTargetInfo() const
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any.
uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const
Return number of constant array elements.
uint64_t getCharWidth() const
Return the size of the character type, in bits.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
bool endsWithZeroSizedObject() const
bool hasOwnVFPtr() const
hasOwnVFPtr - Does this class provide its own virtual-function table pointer, rather than inheriting ...
CharUnits getAlignment() const
getAlignment - Get the record alignment in characters.
CharUnits getPreferredAlignment() const
getPreferredFieldAlignment - Get the record preferred alignment in characters.
bool hasOwnVBPtr() const
hasOwnVBPtr - Does this class provide its own virtual-base table pointer, rather than inheriting one ...
llvm::DenseMap< const CXXRecordDecl *, VBaseInfo > VBaseOffsetsMapTy
CharUnits getSize() const
getSize - Get the record size in characters.
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
bool hasVBPtr() const
hasVBPtr - Does this class have a virtual function table pointer.
bool leadsWithZeroSizedBase() const
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
CharUnits getNonVirtualAlignment() const
getNonVirtualAlignment - Get the non-virtual alignment (in chars) of an object, which is the alignmen...
CharUnits getVBPtrOffset() const
getVBPtrOffset - Get the offset for virtual base table pointer.
CharUnits getDataSize() const
getDataSize() - Get the record data size, which is the record size without tail padding,...
CharUnits getRequiredAlignment() const
CharUnits getSizeOfLargestEmptySubobject() const
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getPreferredNVAlignment() const
getPreferredNVAlignment - Get the preferred non-virtual alignment (in chars) of an object,...
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
const VBaseOffsetsMapTy & getVBaseOffsetsMap() const
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
bool hasExtendableVFPtr() const
hasVFPtr - Does this class have a virtual function table pointer that can be extended by a derived cl...
bool isPrimaryBaseVirtual() const
isPrimaryBaseVirtual - Get whether the primary base for this record is virtual or not.
CharUnits getNonVirtualSize() const
getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...
This class is used for builtin types like 'int'.
Represents a base class of a C++ class.
A set of all the primary bases for a class.
Represents a static or instance method of a struct/union/class.
overridden_method_range overridden_methods() const
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
Represents a C++ struct/union/class.
void getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet &Bases) const
Get the indirect primary bases for this class.
bool hasUserDeclaredDestructor() const
Determine whether this class has a user-declared destructor.
method_range methods() const
CXXRecordDecl * getDefinition() const
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
base_class_range vbases()
bool isDynamicClass() const
bool isCXX11StandardLayout() const
Determine whether this class was standard-layout per C++11 [class]p7, specifically using the C++11 ru...
bool hasUserDeclaredConstructor() const
Determine whether this class has any user-declared constructors.
bool isPOD() const
Whether this class is a POD-type (C++ [class]p4)
MSVtorDispMode getMSVtorDispMode() const
Controls when vtordisps will be emitted if this record is used as a virtual base.
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
bool isTrivial() const
Determine whether this class is considered trivial.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
CharUnits - This is an opaque type for sizes expressed in character units.
bool isZero() const
isZero - Test whether the quantity equals zero.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
static CharUnits One()
One - Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
CharUnits alignTo(const CharUnits &Align) const
alignTo - Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is ...
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
Complex values, per C99 6.2.5p11.
Represents the canonical version of C arrays with a specified constant size.
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
Decl - This represents one declaration (or definition), e.g.
Decl * getMostRecentDecl()
Retrieve the most recent declaration that declares the same entity as this declaration (which may be ...
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl,...
bool isInvalidDecl() const
SourceLocation getLocation() const
A little helper class used to produce diagnostics.
A little helper class (which is basically a smart pointer that forwards info from DiagnosticsEngine a...
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Abstract interface for external sources of AST nodes.
virtual void CompleteType(TagDecl *Tag)
Gives the external AST source an opportunity to complete an incomplete type.
Represents a member of a struct/union/class.
bool isBitField() const
Determines whether this field is a bitfield.
unsigned getBitWidthValue() const
Computes the bit width of this field, if this is a bit field.
unsigned getFieldIndex() const
Returns the index of this field within its record, as appropriate for passing to ASTRecordLayout::get...
const RecordDecl * getParent() const
Returns the parent of this field declaration, which is the struct in which this field is defined.
bool isPotentiallyOverlapping() const
Determine if this field is of potentially-overlapping class type, that is, subobject with the [[no_un...
Represents a function declaration or definition.
bool isInlineSpecified() const
Determine whether the "inline" keyword was specified for this function.
Represents a field injected from an anonymous union/struct into the parent scope.
ArrayRef< NamedDecl * > chain() const
@ Ver6
Attempt to be ABI-compatible with code generated by Clang 6.0.x (SVN r321711).
@ Ver15
Attempt to be ABI-compatible with code generated by Clang 15.0.x.
This represents a decl that may have a name.
bool isExternallyVisible() const
ObjCContainerDecl - Represents a container for method declarations.
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Represents an ObjC class declaration.
ObjCIvarDecl - Represents an ObjC instance variable.
ObjCInterfaceDecl * getContainingInterface()
Return the class interface that this ivar is logically contained in; this is either the interface whe...
ObjCIvarDecl * getCanonicalDecl() override
Retrieves the canonical declaration of this field.
A (possibly-)qualified type.
Represents a struct/union/class.
bool isMsStruct(const ASTContext &C) const
Get whether or not this is an ms_struct which can be turned on with an attribute, pragma,...
field_range fields() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
Encodes a location in the source.
The basic abstraction for the target C++ ABI.
TailPaddingUseRules getTailPaddingUseRules() const
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
bool canKeyFunctionBeInline() const
Can an out-of-line inline function serve as a key function?
@ AlwaysUseTailPadding
The tail-padding of a base class is always theoretically available, even if it's POD.
@ UseTailPaddingUnlessPOD11
Only allocate objects in the tail padding of a base class if the base class is not POD according to t...
@ UseTailPaddingUnlessPOD03
Only allocate objects in the tail padding of a base class if the base class is not POD according to t...
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
bool useLeadingZeroLengthBitfield() const
Check whether zero length bitfield alignment is respected if they are leading members.
uint64_t getPointerWidth(LangAS AddrSpace) const
Return the width of pointers on this target, for the specified address space.
virtual bool hasPS4DLLImportExport() const
virtual bool defaultsToAIXPowerAlignment() const
Whether target defaults to the power alignment rules of AIX.
unsigned getCharAlign() const
unsigned getZeroLengthBitfieldBoundary() const
Get the fixed alignment value in bits for a member that follows a zero length bitfield.
bool useExplicitBitFieldAlignment() const
Check whether explicit bitfield alignment attributes should be.
uint64_t getPointerAlign(LangAS AddrSpace) const
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
unsigned getCharWidth() const
bool useZeroLengthBitfieldAlignment() const
Check whether zero length bitfields should force alignment of the next member.
bool useBitFieldTypeAlignment() const
Check whether the alignment of bit-field types is respected when laying out structures.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
const T * getAs() const
Member-template getAs<specific type>'.
const Type * getUnqualifiedDesugaredType() const
Return the specified type with any "sugar" removed from the type, removing any typedefs,...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Defines the clang::TargetInfo interface.
bool Zero(InterpState &S, CodePtr OpPC)
The JSON file list parser is used to communicate input to InstallAPI.
@ External
External linkage, which indicates that the entity can be referred to from other translation units.
@ Result
The result type of a method or function.
TagTypeKind
The kind of a tag type.
@ Interface
The "__interface" keyword.
@ Struct
The "struct" keyword.
@ Class
The "class" keyword.
const FunctionProtoType * T
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
@ None
The alignment was not explicit in code.
@ RequiredByTypedef
The alignment comes from an alignment attribute on a typedef.
@ RequiredByRecord
The alignment comes from an alignment attribute on a record type.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
bool isValid() const
Whether this pointer is non-NULL.
bool isOffset() const
Whether this pointer is currently stored as an offset.
T * get(ExternalASTSource *Source) const
Retrieve the pointer to the AST node that this lazy pointer points to.
All virtual base related information about a given record decl.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4