19 #include "llvm/ADT/SmallSet.h" 20 #include "llvm/Support/Format.h" 21 #include "llvm/Support/MathExtras.h" 23 using namespace clang;
38 struct BaseSubobjectInfo {
50 BaseSubobjectInfo *PrimaryVirtualBaseInfo;
53 const BaseSubobjectInfo *Derived;
59 struct ExternalLayout {
60 ExternalLayout() : Size(0), Align(0) {}
69 llvm::DenseMap<const FieldDecl *, uint64_t> FieldOffsets;
72 llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsets;
75 llvm::DenseMap<const CXXRecordDecl *, CharUnits> VirtualBaseOffsets;
79 uint64_t getExternalFieldOffset(
const FieldDecl *FD) {
80 assert(FieldOffsets.count(FD) &&
81 "Field does not have an external offset");
82 return FieldOffsets[FD];
86 auto Known = BaseOffsets.find(RD);
87 if (Known == BaseOffsets.end())
89 BaseOffset = Known->second;
94 auto Known = VirtualBaseOffsets.find(RD);
95 if (Known == VirtualBaseOffsets.end())
97 BaseOffset = Known->second;
104 class EmptySubobjectMap {
112 typedef llvm::TinyPtrVector<const CXXRecordDecl *> ClassVectorTy;
113 typedef llvm::DenseMap<CharUnits, ClassVectorTy> EmptyClassOffsetsMapTy;
114 EmptyClassOffsetsMapTy EmptyClassOffsets;
122 void ComputeEmptySubobjectSizes();
126 void UpdateEmptyBaseSubobjects(
const BaseSubobjectInfo *Info,
131 bool PlacingOverlappingField);
133 bool PlacingOverlappingField);
138 return Offset <= MaxEmptyClassOffset;
144 assert(FieldOffset % CharWidth == 0 &&
145 "Field offset not at char boundary!");
154 bool CanPlaceBaseSubobjectAtOffset(
const BaseSubobjectInfo *Info,
160 bool CanPlaceFieldSubobjectAtOffset(
const FieldDecl *FD,
170 : Context(Context), CharWidth(Context.
getCharWidth()), Class(Class) {
171 ComputeEmptySubobjectSizes();
178 bool CanPlaceBaseAtOffset(
const BaseSubobjectInfo *Info,
186 void EmptySubobjectMap::ComputeEmptySubobjectSizes() {
201 if (EmptySize > SizeOfLargestEmptySubobject)
202 SizeOfLargestEmptySubobject = EmptySize;
225 if (EmptySize > SizeOfLargestEmptySubobject)
226 SizeOfLargestEmptySubobject = EmptySize;
231 EmptySubobjectMap::CanPlaceSubobjectAtOffset(
const CXXRecordDecl *RD,
237 EmptyClassOffsetsMapTy::const_iterator I = EmptyClassOffsets.find(Offset);
238 if (I == EmptyClassOffsets.end())
241 const ClassVectorTy &Classes = I->second;
242 if (llvm::find(Classes, RD) == Classes.end())
249 void EmptySubobjectMap::AddSubobjectAtOffset(
const CXXRecordDecl *RD,
257 ClassVectorTy &Classes = EmptyClassOffsets[
Offset];
258 if (llvm::is_contained(Classes, RD))
261 Classes.push_back(RD);
264 if (Offset > MaxEmptyClassOffset)
265 MaxEmptyClassOffset =
Offset;
269 EmptySubobjectMap::CanPlaceBaseSubobjectAtOffset(
const BaseSubobjectInfo *Info,
273 if (!AnyEmptySubobjectsBeyondOffset(Offset))
276 if (!CanPlaceSubobjectAtOffset(Info->Class, Offset))
281 for (
const BaseSubobjectInfo *
Base : Info->Bases) {
287 if (!CanPlaceBaseSubobjectAtOffset(Base, BaseOffset))
291 if (Info->PrimaryVirtualBaseInfo) {
292 BaseSubobjectInfo *PrimaryVirtualBaseInfo = Info->PrimaryVirtualBaseInfo;
294 if (Info == PrimaryVirtualBaseInfo->Derived) {
295 if (!CanPlaceBaseSubobjectAtOffset(PrimaryVirtualBaseInfo, Offset))
301 unsigned FieldNo = 0;
303 E = Info->Class->field_end(); I != E; ++I, ++FieldNo) {
308 if (!CanPlaceFieldSubobjectAtOffset(*I, FieldOffset))
315 void EmptySubobjectMap::UpdateEmptyBaseSubobjects(
const BaseSubobjectInfo *Info,
317 bool PlacingEmptyBase) {
318 if (!PlacingEmptyBase && Offset >= SizeOfLargestEmptySubobject) {
327 AddSubobjectAtOffset(Info->Class, Offset);
331 for (
const BaseSubobjectInfo *Base : Info->Bases) {
336 UpdateEmptyBaseSubobjects(Base, BaseOffset, PlacingEmptyBase);
339 if (Info->PrimaryVirtualBaseInfo) {
340 BaseSubobjectInfo *PrimaryVirtualBaseInfo = Info->PrimaryVirtualBaseInfo;
342 if (Info == PrimaryVirtualBaseInfo->Derived)
343 UpdateEmptyBaseSubobjects(PrimaryVirtualBaseInfo, Offset,
348 unsigned FieldNo = 0;
350 E = Info->Class->field_end(); I != E; ++I, ++FieldNo) {
355 UpdateEmptyFieldSubobjects(*I, FieldOffset, PlacingEmptyBase);
359 bool EmptySubobjectMap::CanPlaceBaseAtOffset(
const BaseSubobjectInfo *Info,
363 if (SizeOfLargestEmptySubobject.isZero())
366 if (!CanPlaceBaseSubobjectAtOffset(Info, Offset))
371 UpdateEmptyBaseSubobjects(Info, Offset, Info->Class->isEmpty());
376 EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(
const CXXRecordDecl *RD,
381 if (!AnyEmptySubobjectsBeyondOffset(Offset))
384 if (!CanPlaceSubobjectAtOffset(RD, Offset))
391 if (Base.isVirtual())
394 const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
397 if (!CanPlaceFieldSubobjectAtOffset(BaseDecl, Class, BaseOffset))
404 const CXXRecordDecl *VBaseDecl = Base.getType()->getAsCXXRecordDecl();
407 if (!CanPlaceFieldSubobjectAtOffset(VBaseDecl, Class, VBaseOffset))
413 unsigned FieldNo = 0;
415 I != E; ++I, ++FieldNo) {
421 if (!CanPlaceFieldSubobjectAtOffset(*I, FieldOffset))
429 EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(
const FieldDecl *FD,
433 if (!AnyEmptySubobjectsBeyondOffset(Offset))
438 return CanPlaceFieldSubobjectAtOffset(RD, RD, Offset);
452 for (uint64_t I = 0; I != NumElements; ++I) {
455 if (!AnyEmptySubobjectsBeyondOffset(ElementOffset))
458 if (!CanPlaceFieldSubobjectAtOffset(RD, RD, ElementOffset))
461 ElementOffset += Layout.
getSize();
469 EmptySubobjectMap::CanPlaceFieldAtOffset(
const FieldDecl *FD,
471 if (!CanPlaceFieldSubobjectAtOffset(FD, Offset))
476 UpdateEmptyFieldSubobjects(FD, Offset, FD->
hasAttr<NoUniqueAddressAttr>());
480 void EmptySubobjectMap::UpdateEmptyFieldSubobjects(
482 bool PlacingOverlappingField) {
493 if (!PlacingOverlappingField && Offset >= SizeOfLargestEmptySubobject)
496 AddSubobjectAtOffset(RD, Offset);
502 if (Base.isVirtual())
505 const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
508 UpdateEmptyFieldSubobjects(BaseDecl, Class, BaseOffset,
509 PlacingOverlappingField);
515 const CXXRecordDecl *VBaseDecl = Base.getType()->getAsCXXRecordDecl();
518 UpdateEmptyFieldSubobjects(VBaseDecl, Class, VBaseOffset,
519 PlacingOverlappingField);
524 unsigned FieldNo = 0;
526 I != E; ++I, ++FieldNo) {
532 UpdateEmptyFieldSubobjects(*I, FieldOffset, PlacingOverlappingField);
536 void EmptySubobjectMap::UpdateEmptyFieldSubobjects(
540 UpdateEmptyFieldSubobjects(RD, RD, Offset, PlacingOverlappingField);
557 for (uint64_t I = 0; I != NumElements; ++I) {
563 if (!PlacingOverlappingField &&
564 ElementOffset >= SizeOfLargestEmptySubobject)
567 UpdateEmptyFieldSubobjects(RD, RD, ElementOffset,
568 PlacingOverlappingField);
569 ElementOffset += Layout.
getSize();
574 typedef llvm::SmallPtrSet<const CXXRecordDecl*, 4> ClassSetTy;
576 class ItaniumRecordLayoutBuilder {
583 EmptySubobjectMap *EmptySubobjects;
601 unsigned UseExternalLayout : 1;
605 unsigned InferAlignment : 1;
610 unsigned IsUnion : 1;
612 unsigned IsMac68kAlign : 1;
614 unsigned IsMsStruct : 1;
620 unsigned char UnfilledBitsInLastUnit;
623 unsigned char LastBitfieldTypeSize;
645 bool PrimaryBaseIsVirtual;
654 typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy;
657 BaseOffsetsMapTy Bases;
672 llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases;
675 ExternalLayout External;
677 ItaniumRecordLayoutBuilder(
const ASTContext &Context,
678 EmptySubobjectMap *EmptySubobjects)
679 : Context(Context), EmptySubobjects(EmptySubobjects), Size(0),
684 UnfilledBitsInLastUnit(0), LastBitfieldTypeSize(0),
689 PrimaryBaseIsVirtual(
false), HasOwnVFPtr(
false),
690 HasPackedField(
false), FirstNearlyEmptyVBase(nullptr) {}
697 void LayoutField(
const FieldDecl *D,
bool InsertExtraPadding);
698 void LayoutWideBitField(uint64_t FieldSize, uint64_t TypeSize,
707 llvm::SpecificBumpPtrAllocator<BaseSubobjectInfo> BaseSubobjectInfoAllocator;
709 typedef llvm::DenseMap<const CXXRecordDecl *, BaseSubobjectInfo *>
710 BaseSubobjectInfoMapTy;
718 BaseSubobjectInfoMapTy NonVirtualBaseInfo;
726 BaseSubobjectInfo *ComputeBaseSubobjectInfo(
const CXXRecordDecl *RD,
728 BaseSubobjectInfo *Derived);
735 void EnsureVTablePointerAlignment(
CharUnits UnpackedBaseAlign);
742 void LayoutNonVirtualBase(
const BaseSubobjectInfo *Base);
744 void AddPrimaryVirtualBaseOffsets(
const BaseSubobjectInfo *Info,
752 void LayoutVirtualBase(
const BaseSubobjectInfo *Base);
756 CharUnits LayoutBase(
const BaseSubobjectInfo *Base);
759 void InitializeLayout(
const Decl *D);
766 void UpdateAlignment(
CharUnits NewAlignment) {
767 UpdateAlignment(NewAlignment, NewAlignment);
775 uint64_t updateExternalFieldOffset(
const FieldDecl *Field,
776 uint64_t ComputedOffset);
778 void CheckFieldPadding(uint64_t Offset, uint64_t UnpaddedOffset,
779 uint64_t UnpackedOffset,
unsigned UnpackedAlign,
788 uint64_t getSizeInBits()
const {
return Size; }
791 void setSize(uint64_t NewSize) { Size = NewSize; }
793 CharUnits getAligment()
const {
return Alignment; }
799 uint64_t getDataSizeInBits()
const {
return DataSize; }
801 void setDataSize(
CharUnits NewSize) { DataSize = Context.
toBits(NewSize); }
802 void setDataSize(uint64_t NewSize) { DataSize = NewSize; }
804 ItaniumRecordLayoutBuilder(
const ItaniumRecordLayoutBuilder &) =
delete;
805 void operator=(
const ItaniumRecordLayoutBuilder &) =
delete;
809 void ItaniumRecordLayoutBuilder::SelectPrimaryVBase(
const CXXRecordDecl *RD) {
810 for (
const auto &I : RD->
bases()) {
811 assert(!I.getType()->isDependentType() &&
812 "Cannot layout class with dependent bases.");
814 const CXXRecordDecl *Base = I.getType()->getAsCXXRecordDecl();
820 if (!IndirectPrimaryBases.count(Base)) {
822 PrimaryBaseIsVirtual =
true;
827 if (!FirstNearlyEmptyVBase)
828 FirstNearlyEmptyVBase = Base;
831 SelectPrimaryVBase(Base);
838 void ItaniumRecordLayoutBuilder::DeterminePrimaryBase(
const CXXRecordDecl *RD) {
850 for (
const auto &I : RD->
bases()) {
855 const CXXRecordDecl *Base = I.getType()->getAsCXXRecordDecl();
860 PrimaryBaseIsVirtual =
false;
870 SelectPrimaryVBase(RD);
876 if (FirstNearlyEmptyVBase) {
877 PrimaryBase = FirstNearlyEmptyVBase;
878 PrimaryBaseIsVirtual =
true;
882 assert(!PrimaryBase &&
"Should not get here with a primary base!");
885 BaseSubobjectInfo *ItaniumRecordLayoutBuilder::ComputeBaseSubobjectInfo(
886 const CXXRecordDecl *RD,
bool IsVirtual, BaseSubobjectInfo *Derived) {
887 BaseSubobjectInfo *Info;
891 BaseSubobjectInfo *&InfoSlot = VirtualBaseInfo[RD];
893 assert(InfoSlot->Class == RD &&
"Wrong class for virtual base info!");
898 InfoSlot =
new (BaseSubobjectInfoAllocator.Allocate()) BaseSubobjectInfo;
901 Info =
new (BaseSubobjectInfoAllocator.Allocate()) BaseSubobjectInfo;
905 Info->IsVirtual = IsVirtual;
906 Info->Derived =
nullptr;
907 Info->PrimaryVirtualBaseInfo =
nullptr;
910 BaseSubobjectInfo *PrimaryVirtualBaseInfo =
nullptr;
918 assert(PrimaryVirtualBase &&
"Didn't have a primary virtual base!");
921 PrimaryVirtualBaseInfo = VirtualBaseInfo.lookup(PrimaryVirtualBase);
923 if (PrimaryVirtualBaseInfo) {
924 if (PrimaryVirtualBaseInfo->Derived) {
928 PrimaryVirtualBase =
nullptr;
931 Info->PrimaryVirtualBaseInfo = PrimaryVirtualBaseInfo;
932 PrimaryVirtualBaseInfo->Derived = Info;
939 for (
const auto &I : RD->
bases()) {
940 bool IsVirtual = I.isVirtual();
942 const CXXRecordDecl *BaseDecl = I.getType()->getAsCXXRecordDecl();
944 Info->Bases.push_back(ComputeBaseSubobjectInfo(BaseDecl, IsVirtual, Info));
947 if (PrimaryVirtualBase && !PrimaryVirtualBaseInfo) {
950 PrimaryVirtualBaseInfo = VirtualBaseInfo.lookup(PrimaryVirtualBase);
951 assert(PrimaryVirtualBaseInfo &&
952 "Did not create a primary virtual base!");
955 Info->PrimaryVirtualBaseInfo = PrimaryVirtualBaseInfo;
956 PrimaryVirtualBaseInfo->Derived = Info;
962 void ItaniumRecordLayoutBuilder::ComputeBaseSubobjectInfo(
964 for (
const auto &I : RD->
bases()) {
965 bool IsVirtual = I.isVirtual();
967 const CXXRecordDecl *BaseDecl = I.getType()->getAsCXXRecordDecl();
970 BaseSubobjectInfo *Info = ComputeBaseSubobjectInfo(BaseDecl, IsVirtual,
975 assert(VirtualBaseInfo.count(BaseDecl) &&
976 "Did not add virtual base!");
979 assert(!NonVirtualBaseInfo.count(BaseDecl) &&
980 "Non-virtual base already exists!");
981 NonVirtualBaseInfo.insert(std::make_pair(BaseDecl, Info));
986 void ItaniumRecordLayoutBuilder::EnsureVTablePointerAlignment(
991 if (!MaxFieldAlignment.
isZero()) {
992 BaseAlign =
std::min(BaseAlign, MaxFieldAlignment);
993 UnpackedBaseAlign =
std::min(UnpackedBaseAlign, MaxFieldAlignment);
997 setSize(getSize().alignTo(BaseAlign));
1000 UpdateAlignment(BaseAlign, UnpackedBaseAlign);
1003 void ItaniumRecordLayoutBuilder::LayoutNonVirtualBases(
1006 DeterminePrimaryBase(RD);
1009 ComputeBaseSubobjectInfo(RD);
1013 if (PrimaryBaseIsVirtual) {
1016 BaseSubobjectInfo *PrimaryBaseInfo = VirtualBaseInfo.lookup(PrimaryBase);
1017 PrimaryBaseInfo->Derived =
nullptr;
1020 IndirectPrimaryBases.insert(PrimaryBase);
1022 assert(!VisitedVirtualBases.count(PrimaryBase) &&
1023 "vbase already visited!");
1024 VisitedVirtualBases.insert(PrimaryBase);
1026 LayoutVirtualBase(PrimaryBaseInfo);
1028 BaseSubobjectInfo *PrimaryBaseInfo =
1029 NonVirtualBaseInfo.lookup(PrimaryBase);
1030 assert(PrimaryBaseInfo &&
1031 "Did not find base info for non-virtual primary base!");
1033 LayoutNonVirtualBase(PrimaryBaseInfo);
1039 assert(DataSize == 0 &&
"Vtable pointer must be at offset zero!");
1044 EnsureVTablePointerAlignment(PtrAlign);
1046 setSize(getSize() + PtrWidth);
1047 setDataSize(getSize());
1051 for (
const auto &I : RD->
bases()) {
1057 const CXXRecordDecl *BaseDecl = I.getType()->getAsCXXRecordDecl();
1062 if (BaseDecl == PrimaryBase && !PrimaryBaseIsVirtual)
1066 BaseSubobjectInfo *BaseInfo = NonVirtualBaseInfo.
lookup(BaseDecl);
1067 assert(BaseInfo &&
"Did not find base info for non-virtual base!");
1069 LayoutNonVirtualBase(BaseInfo);
1073 void ItaniumRecordLayoutBuilder::LayoutNonVirtualBase(
1074 const BaseSubobjectInfo *Base) {
1079 assert(!Bases.count(Base->Class) &&
"base offset already exists!");
1080 Bases.insert(std::make_pair(Base->Class, Offset));
1082 AddPrimaryVirtualBaseOffsets(Base, Offset);
1085 void ItaniumRecordLayoutBuilder::AddPrimaryVirtualBaseOffsets(
1086 const BaseSubobjectInfo *Info,
CharUnits Offset) {
1088 if (!Info->Class->getNumVBases())
1092 if (Info->PrimaryVirtualBaseInfo) {
1093 assert(Info->PrimaryVirtualBaseInfo->IsVirtual &&
1094 "Primary virtual base is not virtual!");
1095 if (Info->PrimaryVirtualBaseInfo->Derived == Info) {
1097 assert(!VBases.count(Info->PrimaryVirtualBaseInfo->Class) &&
1098 "primary vbase offset already exists!");
1099 VBases.insert(std::make_pair(Info->PrimaryVirtualBaseInfo->Class,
1103 AddPrimaryVirtualBaseOffsets(Info->PrimaryVirtualBaseInfo, Offset);
1109 for (
const BaseSubobjectInfo *Base : Info->Bases) {
1110 if (Base->IsVirtual)
1114 AddPrimaryVirtualBaseOffsets(Base, BaseOffset);
1118 void ItaniumRecordLayoutBuilder::LayoutVirtualBases(
1121 bool PrimaryBaseIsVirtual;
1123 if (MostDerivedClass == RD) {
1124 PrimaryBase = this->PrimaryBase;
1125 PrimaryBaseIsVirtual = this->PrimaryBaseIsVirtual;
1133 assert(!Base.getType()->isDependentType() &&
1134 "Cannot layout class with dependent bases.");
1136 const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
1138 if (Base.isVirtual()) {
1139 if (PrimaryBase != BaseDecl || !PrimaryBaseIsVirtual) {
1140 bool IndirectPrimaryBase = IndirectPrimaryBases.count(BaseDecl);
1143 if (!IndirectPrimaryBase) {
1145 if (!VisitedVirtualBases.insert(BaseDecl).second)
1148 const BaseSubobjectInfo *BaseInfo = VirtualBaseInfo.lookup(BaseDecl);
1149 assert(BaseInfo &&
"Did not find virtual base info!");
1150 LayoutVirtualBase(BaseInfo);
1155 if (!BaseDecl->getNumVBases()) {
1160 LayoutVirtualBases(BaseDecl, MostDerivedClass);
1164 void ItaniumRecordLayoutBuilder::LayoutVirtualBase(
1165 const BaseSubobjectInfo *Base) {
1166 assert(!Base->Derived &&
"Trying to lay out a primary virtual base!");
1172 assert(!VBases.count(Base->Class) &&
"vbase offset already exists!");
1173 VBases.insert(std::make_pair(Base->Class,
1176 AddPrimaryVirtualBaseOffsets(Base, Offset);
1180 ItaniumRecordLayoutBuilder::LayoutBase(
const BaseSubobjectInfo *Base) {
1187 bool HasExternalLayout =
false;
1188 if (UseExternalLayout) {
1190 if (Base->IsVirtual)
1191 HasExternalLayout = External.getExternalNVBaseOffset(Base->Class, Offset);
1193 HasExternalLayout = External.getExternalVBaseOffset(Base->Class, Offset);
1200 (Packed && ((Context.
getLangOpts().getClangABICompat() <=
1204 : UnpackedBaseAlign;
1207 if (Base->Class->isEmpty() &&
1211 UpdateAlignment(BaseAlign, UnpackedBaseAlign);
1217 if (!MaxFieldAlignment.
isZero()) {
1218 BaseAlign =
std::min(BaseAlign, MaxFieldAlignment);
1219 UnpackedBaseAlign =
std::min(UnpackedBaseAlign, MaxFieldAlignment);
1222 if (!HasExternalLayout) {
1224 Offset = getDataSize().
alignTo(BaseAlign);
1227 while (!EmptySubobjects->CanPlaceBaseAtOffset(Base, Offset))
1228 Offset += BaseAlign;
1230 bool Allowed = EmptySubobjects->CanPlaceBaseAtOffset(Base, Offset);
1232 assert(Allowed &&
"Base subobject externally placed at overlapping offset");
1234 if (InferAlignment && Offset < getDataSize().alignTo(BaseAlign)) {
1238 InferAlignment =
false;
1242 if (!Base->Class->isEmpty()) {
1246 setSize(
std::max(getSize(), getDataSize()));
1251 UpdateAlignment(BaseAlign, UnpackedBaseAlign);
1256 void ItaniumRecordLayoutBuilder::InitializeLayout(
const Decl *D) {
1257 if (
const RecordDecl *RD = dyn_cast<RecordDecl>(D)) {
1262 Packed = D->
hasAttr<PackedAttr>();
1265 if (
unsigned DefaultMaxFieldAlignment = Context.
getLangOpts().PackStruct) {
1273 if (D->
hasAttr<AlignMac68kAttr>()) {
1274 IsMac68kAlign =
true;
1278 if (
const MaxFieldAlignmentAttr *MFAA = D->
getAttr<MaxFieldAlignmentAttr>())
1286 if (
const RecordDecl *RD = dyn_cast<RecordDecl>(D))
1288 UseExternalLayout = Source->layoutRecordType(
1289 RD, External.Size, External.Align, External.FieldOffsets,
1290 External.BaseOffsets, External.VirtualBaseOffsets);
1293 if (UseExternalLayout) {
1294 if (External.Align > 0) {
1298 InferAlignment =
true;
1304 void ItaniumRecordLayoutBuilder::Layout(
const RecordDecl *D) {
1305 InitializeLayout(D);
1313 void ItaniumRecordLayoutBuilder::Layout(
const CXXRecordDecl *RD) {
1314 InitializeLayout(RD);
1317 LayoutNonVirtualBases(RD);
1323 NonVirtualAlignment = Alignment;
1326 LayoutVirtualBases(RD, RD);
1335 if (Base.isVirtual())
1338 const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
1340 assert(Bases.count(BaseDecl) &&
"Did not find base offset!");
1345 const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
1347 assert(VBases.count(BaseDecl) &&
"Did not find base offset!");
1361 setSize(getDataSize());
1364 InitializeLayout(D);
1368 LayoutField(IVD,
false);
1375 void ItaniumRecordLayoutBuilder::LayoutFields(
const RecordDecl *D) {
1384 InsertExtraPadding && (Next !=
End || !HasFlexibleArrayMember));
1393 return llvm::alignTo(Size, CharAlignment);
1396 void ItaniumRecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize,
1401 "Can only have wide bit-fields in C++!");
1413 for (
const QualType &QT : IntegralPODTypes) {
1416 if (Size > FieldSize)
1421 assert(!Type.
isNull() &&
"Did not find a type!");
1426 UnfilledBitsInLastUnit = 0;
1427 LastBitfieldTypeSize = 0;
1429 uint64_t FieldOffset;
1430 uint64_t UnpaddedFieldOffset = getDataSizeInBits() - UnfilledBitsInLastUnit;
1435 setDataSize(
std::max(getDataSizeInBits(), RoundedFieldSize));
1440 FieldOffset = llvm::alignTo(getDataSizeInBits(), Context.
toBits(TypeAlign));
1442 uint64_t NewSizeInBits = FieldOffset + FieldSize;
1446 UnfilledBitsInLastUnit = getDataSizeInBits() - NewSizeInBits;
1450 FieldOffsets.push_back(FieldOffset);
1452 CheckFieldPadding(FieldOffset, UnpaddedFieldOffset, FieldOffset,
1453 Context.
toBits(TypeAlign), FieldPacked, D);
1456 setSize(
std::max(getSizeInBits(), getDataSizeInBits()));
1459 UpdateAlignment(TypeAlign);
1462 void ItaniumRecordLayoutBuilder::LayoutBitField(
const FieldDecl *D) {
1463 bool FieldPacked = Packed || D->
hasAttr<PackedAttr>();
1466 uint64_t TypeSize = FieldInfo.
Width;
1467 unsigned FieldAlign = FieldInfo.
Align;
1529 FieldAlign = TypeSize;
1534 if (LastBitfieldTypeSize != TypeSize ||
1535 UnfilledBitsInLastUnit < FieldSize) {
1537 if (!LastBitfieldTypeSize && !FieldSize)
1540 UnfilledBitsInLastUnit = 0;
1541 LastBitfieldTypeSize = 0;
1547 if (FieldSize > TypeSize) {
1548 LayoutWideBitField(FieldSize, TypeSize, FieldPacked, D);
1553 uint64_t FieldOffset =
1554 IsUnion ? 0 : (getDataSizeInBits() - UnfilledBitsInLastUnit);
1559 if (FieldSize == 0 &&
1563 unsigned ZeroLengthBitfieldBoundary =
1565 FieldAlign =
std::max(FieldAlign, ZeroLengthBitfieldBoundary);
1574 unsigned UnpackedFieldAlign = FieldAlign;
1577 if (!IsMsStruct && FieldPacked && FieldSize != 0)
1582 if (ExplicitFieldAlign) {
1583 FieldAlign =
std::max(FieldAlign, ExplicitFieldAlign);
1584 UnpackedFieldAlign =
std::max(UnpackedFieldAlign, ExplicitFieldAlign);
1589 unsigned MaxFieldAlignmentInBits = Context.
toBits(MaxFieldAlignment);
1590 if (!MaxFieldAlignment.
isZero() && FieldSize) {
1591 UnpackedFieldAlign =
std::min(UnpackedFieldAlign, MaxFieldAlignmentInBits);
1593 FieldAlign = UnpackedFieldAlign;
1595 FieldAlign =
std::min(FieldAlign, MaxFieldAlignmentInBits);
1600 if (IsMsStruct && IsUnion) {
1601 FieldAlign = UnpackedFieldAlign = 1;
1607 uint64_t UnpaddedFieldOffset = FieldOffset;
1608 uint64_t UnpackedFieldOffset = FieldOffset;
1618 if (FieldSize == 0 || FieldSize > UnfilledBitsInLastUnit) {
1619 FieldOffset = llvm::alignTo(FieldOffset, FieldAlign);
1620 UnpackedFieldOffset =
1621 llvm::alignTo(UnpackedFieldOffset, UnpackedFieldAlign);
1622 UnfilledBitsInLastUnit = 0;
1627 bool AllowPadding = MaxFieldAlignment.
isZero();
1630 if (FieldSize == 0 ||
1632 (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize)) {
1633 FieldOffset = llvm::alignTo(FieldOffset, FieldAlign);
1634 }
else if (ExplicitFieldAlign &&
1635 (MaxFieldAlignmentInBits == 0 ||
1636 ExplicitFieldAlign <= MaxFieldAlignmentInBits) &&
1640 FieldOffset = llvm::alignTo(FieldOffset, ExplicitFieldAlign);
1644 if (FieldSize == 0 ||
1646 (UnpackedFieldOffset & (UnpackedFieldAlign-1)) + FieldSize > TypeSize))
1647 UnpackedFieldOffset =
1648 llvm::alignTo(UnpackedFieldOffset, UnpackedFieldAlign);
1649 else if (ExplicitFieldAlign &&
1650 (MaxFieldAlignmentInBits == 0 ||
1651 ExplicitFieldAlign <= MaxFieldAlignmentInBits) &&
1653 UnpackedFieldOffset =
1654 llvm::alignTo(UnpackedFieldOffset, ExplicitFieldAlign);
1659 if (UseExternalLayout)
1660 FieldOffset = updateExternalFieldOffset(D, FieldOffset);
1663 FieldOffsets.push_back(FieldOffset);
1672 FieldAlign = UnpackedFieldAlign = 1;
1675 if (!UseExternalLayout)
1676 CheckFieldPadding(FieldOffset, UnpaddedFieldOffset, UnpackedFieldOffset,
1677 UnpackedFieldAlign, FieldPacked, D);
1685 uint64_t RoundedFieldSize;
1695 setDataSize(
std::max(getDataSizeInBits(), RoundedFieldSize));
1699 }
else if (IsMsStruct && FieldSize) {
1702 if (!UnfilledBitsInLastUnit) {
1703 setDataSize(FieldOffset + TypeSize);
1704 UnfilledBitsInLastUnit = TypeSize;
1706 UnfilledBitsInLastUnit -= FieldSize;
1707 LastBitfieldTypeSize = TypeSize;
1713 uint64_t NewSizeInBits = FieldOffset + FieldSize;
1715 setDataSize(llvm::alignTo(NewSizeInBits, CharAlignment));
1716 UnfilledBitsInLastUnit = getDataSizeInBits() - NewSizeInBits;
1721 LastBitfieldTypeSize = 0;
1725 setSize(
std::max(getSizeInBits(), getDataSizeInBits()));
1728 UnadjustedAlignment =
1734 void ItaniumRecordLayoutBuilder::LayoutField(
const FieldDecl *D,
1735 bool InsertExtraPadding) {
1741 uint64_t UnpaddedFieldOffset = getDataSizeInBits() - UnfilledBitsInLastUnit;
1744 UnfilledBitsInLastUnit = 0;
1745 LastBitfieldTypeSize = 0;
1748 bool PotentiallyOverlapping = D->
hasAttr<NoUniqueAddressAttr>() && FieldClass;
1749 bool IsOverlappingEmptyField = PotentiallyOverlapping && FieldClass->isEmpty();
1750 bool FieldPacked = Packed || D->
hasAttr<PackedAttr>();
1752 CharUnits FieldOffset = (IsUnion || IsOverlappingEmptyField)
1772 EffectiveFieldSize = FieldSize =
1777 std::pair<CharUnits, CharUnits> FieldInfo =
1779 EffectiveFieldSize = FieldSize = FieldInfo.first;
1780 FieldAlign = FieldInfo.second;
1784 if (PotentiallyOverlapping) {
1786 EffectiveFieldSize =
1800 if (!llvm::isPowerOf2_64(TypeSize.
getQuantity())) {
1803 "Non PowerOf2 size in MSVC mode");
1825 if (TypeSize > FieldAlign &&
1827 FieldAlign = TypeSize;
1834 CharUnits UnpackedFieldAlign = FieldAlign;
1835 CharUnits UnpackedFieldOffset = FieldOffset;
1841 FieldAlign =
std::max(FieldAlign, MaxAlignmentInChars);
1842 UnpackedFieldAlign =
std::max(UnpackedFieldAlign, MaxAlignmentInChars);
1845 if (!MaxFieldAlignment.
isZero()) {
1846 FieldAlign =
std::min(FieldAlign, MaxFieldAlignment);
1847 UnpackedFieldAlign =
std::min(UnpackedFieldAlign, MaxFieldAlignment);
1851 FieldOffset = FieldOffset.alignTo(FieldAlign);
1852 UnpackedFieldOffset = UnpackedFieldOffset.
alignTo(UnpackedFieldAlign);
1854 if (UseExternalLayout) {
1856 updateExternalFieldOffset(D, Context.
toBits(FieldOffset)));
1858 if (!IsUnion && EmptySubobjects) {
1860 bool Allowed = EmptySubobjects->CanPlaceFieldAtOffset(D, FieldOffset);
1862 assert(Allowed &&
"Externally-placed field cannot be placed here");
1865 if (!IsUnion && EmptySubobjects) {
1867 while (!EmptySubobjects->CanPlaceFieldAtOffset(D, FieldOffset)) {
1872 FieldOffset = getDataSize().alignTo(FieldAlign);
1874 FieldOffset += FieldAlign;
1880 FieldOffsets.push_back(Context.
toBits(FieldOffset));
1882 if (!UseExternalLayout)
1883 CheckFieldPadding(Context.
toBits(FieldOffset), UnpaddedFieldOffset,
1884 Context.
toBits(UnpackedFieldOffset),
1885 Context.
toBits(UnpackedFieldAlign), FieldPacked, D);
1887 if (InsertExtraPadding) {
1889 CharUnits ExtraSizeForAsan = ASanAlignment;
1890 if (FieldSize % ASanAlignment)
1893 EffectiveFieldSize = FieldSize = FieldSize + ExtraSizeForAsan;
1897 if (!IsOverlappingEmptyField) {
1898 uint64_t EffectiveFieldSizeInBits = Context.
toBits(EffectiveFieldSize);
1900 setDataSize(
std::max(getDataSizeInBits(), EffectiveFieldSizeInBits));
1902 setDataSize(FieldOffset + EffectiveFieldSize);
1904 PaddedFieldSize =
std::max(PaddedFieldSize, FieldOffset + FieldSize);
1905 setSize(
std::max(getSizeInBits(), getDataSizeInBits()));
1908 (uint64_t)Context.
toBits(FieldOffset + FieldSize)));
1912 UnadjustedAlignment =
std::max(UnadjustedAlignment, FieldAlign);
1913 UpdateAlignment(FieldAlign, UnpackedFieldAlign);
1916 void ItaniumRecordLayoutBuilder::FinishLayout(
const NamedDecl *D) {
1918 if (Context.
getLangOpts().CPlusPlus && getSizeInBits() == 0) {
1924 setSize(CharUnits::One());
1927 setSize(CharUnits::One());
1932 setSize(
std::max(getSizeInBits(), (uint64_t)Context.
toBits(PaddedFieldSize)));
1936 uint64_t UnpaddedSize = getSizeInBits() - UnfilledBitsInLastUnit;
1937 uint64_t UnpackedSizeInBits =
1938 llvm::alignTo(getSizeInBits(), Context.
toBits(UnpackedAlignment));
1939 uint64_t RoundedSize =
1940 llvm::alignTo(getSizeInBits(), Context.
toBits(Alignment));
1942 if (UseExternalLayout) {
1946 if (InferAlignment && External.Size < RoundedSize) {
1948 InferAlignment =
false;
1950 setSize(External.Size);
1955 setSize(RoundedSize);
1958 if (
const RecordDecl *RD = dyn_cast<RecordDecl>(D)) {
1960 if (getSizeInBits() > UnpaddedSize) {
1961 unsigned PadSize = getSizeInBits() - UnpaddedSize;
1963 if (PadSize % CharBitNum == 0) {
1964 PadSize = PadSize / CharBitNum;
1970 << (InBits ? 1 : 0);
1976 if (Packed && UnpackedAlignment <= Alignment &&
1977 UnpackedSizeInBits == getSizeInBits() && !HasPackedField)
1983 void ItaniumRecordLayoutBuilder::UpdateAlignment(
1987 if (IsMac68kAlign || (UseExternalLayout && !InferAlignment))
1990 if (NewAlignment > Alignment) {
1991 assert(llvm::isPowerOf2_64(NewAlignment.
getQuantity()) &&
1992 "Alignment not a power of 2");
1993 Alignment = NewAlignment;
1996 if (UnpackedNewAlignment > UnpackedAlignment) {
1997 assert(llvm::isPowerOf2_64(UnpackedNewAlignment.
getQuantity()) &&
1998 "Alignment not a power of 2");
1999 UnpackedAlignment = UnpackedNewAlignment;
2004 ItaniumRecordLayoutBuilder::updateExternalFieldOffset(
const FieldDecl *Field,
2005 uint64_t ComputedOffset) {
2006 uint64_t ExternalFieldOffset = External.getExternalFieldOffset(Field);
2008 if (InferAlignment && ExternalFieldOffset < ComputedOffset) {
2012 InferAlignment =
false;
2016 return ExternalFieldOffset;
2029 default: llvm_unreachable(
"Invalid tag kind for field padding diagnostic!");
2033 void ItaniumRecordLayoutBuilder::CheckFieldPadding(
2034 uint64_t Offset, uint64_t UnpaddedOffset, uint64_t UnpackedOffset,
2035 unsigned UnpackedAlign,
bool isPacked,
const FieldDecl *D) {
2038 if (isa<ObjCIvarDecl>(D))
2049 if (!IsUnion && Offset > UnpaddedOffset) {
2050 unsigned PadSize = Offset - UnpaddedOffset;
2052 if (PadSize % CharBitNum == 0) {
2053 PadSize = PadSize / CharBitNum;
2068 << (InBits ? 1 : 0);
2070 if (isPacked && Offset != UnpackedOffset) {
2071 HasPackedField =
true;
2095 bool allowInlineFunctions =
2099 if (!MD->isVirtual())
2107 if (MD->isImplicit())
2110 if (MD->isInlineSpecified())
2113 if (MD->hasInlineBody())
2117 if (!MD->isUserProvided())
2121 if (!allowInlineFunctions) {
2133 if (!MD->hasAttr<CUDADeviceAttr>())
2137 if (!MD->hasAttr<CUDAHostAttr>() && MD->hasAttr<CUDADeviceAttr>())
2145 if (MD->hasAttr<DLLImportAttr>() && !RD->
hasAttr<DLLImportAttr>())
2199 llvm_unreachable(
"bad tail-padding use kind");
2297 struct MicrosoftRecordLayoutBuilder {
2298 struct ElementInfo {
2302 typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy;
2303 MicrosoftRecordLayoutBuilder(
const ASTContext &Context) : Context(Context) {}
2305 MicrosoftRecordLayoutBuilder(
const MicrosoftRecordLayoutBuilder &) =
delete;
2306 void operator=(
const MicrosoftRecordLayoutBuilder &) =
delete;
2327 void layoutBitField(
const FieldDecl *FD);
2330 void layoutZeroWidthBitField(
const FieldDecl *FD);
2339 ElementInfo getAdjustedElementInfo(
const FieldDecl *FD);
2341 void placeFieldAtOffset(
CharUnits FieldOffset) {
2342 FieldOffsets.push_back(Context.
toBits(FieldOffset));
2345 void placeFieldAtBitOffset(uint64_t FieldOffset) {
2346 FieldOffsets.push_back(FieldOffset);
2349 void computeVtorDispSet(
2350 llvm::SmallPtrSetImpl<const CXXRecordDecl *> &HasVtorDispSet,
2375 ElementInfo PointerInfo;
2383 BaseOffsetsMapTy Bases;
2389 unsigned RemainingBitsInField;
2393 bool LastFieldIsNonZeroWidthBitfield : 1;
2395 bool HasOwnVFPtr : 1;
2401 bool EndsWithZeroSizedObject : 1;
2404 bool LeadsWithZeroSizedBase : 1;
2407 bool UseExternalLayout : 1;
2411 ExternalLayout External;
2415 MicrosoftRecordLayoutBuilder::ElementInfo
2416 MicrosoftRecordLayoutBuilder::getAdjustedElementInfo(
2421 if (!MaxFieldAlignment.
isZero())
2422 Info.Alignment =
std::min(Info.Alignment, MaxFieldAlignment);
2428 Alignment =
std::max(Alignment, Info.Alignment);
2435 MicrosoftRecordLayoutBuilder::ElementInfo
2436 MicrosoftRecordLayoutBuilder::getAdjustedElementInfo(
2441 std::tie(Info.Size, Info.Alignment) =
2454 Info.Alignment =
std::max(Info.Alignment, FieldRequiredAlignment);
2460 FieldRequiredAlignment =
std::max(FieldRequiredAlignment,
2464 RequiredAlignment =
std::max(RequiredAlignment, FieldRequiredAlignment);
2467 if (!MaxFieldAlignment.
isZero())
2468 Info.Alignment =
std::min(Info.Alignment, MaxFieldAlignment);
2469 if (FD->
hasAttr<PackedAttr>())
2470 Info.Alignment = CharUnits::One();
2471 Info.Alignment =
std::max(Info.Alignment, FieldRequiredAlignment);
2475 void MicrosoftRecordLayoutBuilder::layout(
const RecordDecl *RD) {
2478 initializeLayout(RD);
2480 DataSize = Size = Size.alignTo(Alignment);
2486 void MicrosoftRecordLayoutBuilder::cxxLayout(
const CXXRecordDecl *RD) {
2489 initializeLayout(RD);
2490 initializeCXXLayout(RD);
2491 layoutNonVirtualBases(RD);
2495 if (HasOwnVFPtr || (HasVBPtr && !SharedVBPtrBase))
2496 Alignment =
std::max(Alignment, PointerInfo.Alignment);
2497 auto RoundingAlignment = Alignment;
2498 if (!MaxFieldAlignment.
isZero())
2499 RoundingAlignment =
std::min(RoundingAlignment, MaxFieldAlignment);
2500 if (!UseExternalLayout)
2501 Size = Size.alignTo(RoundingAlignment);
2502 NonVirtualSize = Size;
2505 layoutVirtualBases(RD);
2509 void MicrosoftRecordLayoutBuilder::initializeLayout(
const RecordDecl *RD) {
2522 if (
unsigned DefaultMaxFieldAlignment = Context.
getLangOpts().PackStruct)
2526 if (
const MaxFieldAlignmentAttr *MFAA = RD->
getAttr<MaxFieldAlignmentAttr>()){
2527 unsigned PackedAlignment = MFAA->getAlignment();
2532 if (RD->
hasAttr<PackedAttr>())
2536 UseExternalLayout =
false;
2538 UseExternalLayout = Source->layoutRecordType(
2539 RD, External.Size, External.Align, External.FieldOffsets,
2540 External.BaseOffsets, External.VirtualBaseOffsets);
2544 MicrosoftRecordLayoutBuilder::initializeCXXLayout(
const CXXRecordDecl *RD) {
2545 EndsWithZeroSizedObject =
false;
2546 LeadsWithZeroSizedBase =
false;
2547 HasOwnVFPtr =
false;
2549 PrimaryBase =
nullptr;
2550 SharedVBPtrBase =
nullptr;
2555 PointerInfo.Alignment =
2558 if (!MaxFieldAlignment.
isZero())
2559 PointerInfo.Alignment =
std::min(PointerInfo.Alignment, MaxFieldAlignment);
2563 MicrosoftRecordLayoutBuilder::layoutNonVirtualBases(
const CXXRecordDecl *RD) {
2573 const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
2576 if (Base.isVirtual()) {
2581 if (!SharedVBPtrBase && BaseLayout.
hasVBPtr()) {
2582 SharedVBPtrBase = BaseDecl;
2590 PrimaryBase = BaseDecl;
2594 layoutNonVirtualBase(RD, BaseDecl, BaseLayout, PreviousBaseLayout);
2600 !HasOwnVFPtr && i != e; ++i)
2601 HasOwnVFPtr = i->isVirtual() && i->size_overridden_methods() == 0;
2604 bool CheckLeadingLayout = !PrimaryBase;
2607 if (Base.isVirtual())
2609 const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
2618 if (CheckLeadingLayout) {
2619 CheckLeadingLayout =
false;
2623 layoutNonVirtualBase(RD, BaseDecl, BaseLayout, PreviousBaseLayout);
2629 else if (SharedVBPtrBase) {
2636 if (!isa<CXXRecordDecl>(RD))
2638 if (RD->
hasAttr<EmptyBasesAttr>())
2640 if (
auto *LVA = RD->
getAttr<LayoutVersionAttr>())
2650 void MicrosoftRecordLayoutBuilder::layoutNonVirtualBase(
2662 ElementInfo Info = getAdjustedElementInfo(BaseLayout);
2666 bool FoundBase =
false;
2667 if (UseExternalLayout) {
2668 FoundBase = External.getExternalNVBaseOffset(BaseDecl, BaseOffset);
2670 assert(BaseOffset >= Size &&
"base offset already allocated");
2676 if (MDCUsesEBO && BaseDecl->
isEmpty()) {
2681 BaseOffset = Size = Size.
alignTo(Info.Alignment);
2684 Bases.insert(std::make_pair(BaseDecl, BaseOffset));
2686 PreviousBaseLayout = &BaseLayout;
2689 void MicrosoftRecordLayoutBuilder::layoutFields(
const RecordDecl *RD) {
2690 LastFieldIsNonZeroWidthBitfield =
false;
2695 void MicrosoftRecordLayoutBuilder::layoutField(
const FieldDecl *FD) {
2700 LastFieldIsNonZeroWidthBitfield =
false;
2701 ElementInfo Info = getAdjustedElementInfo(FD);
2702 Alignment =
std::max(Alignment, Info.Alignment);
2704 if (UseExternalLayout)
2710 FieldOffset = Size.
alignTo(Info.Alignment);
2711 placeFieldAtOffset(FieldOffset);
2712 Size =
std::max(Size, FieldOffset + Info.Size);
2715 void MicrosoftRecordLayoutBuilder::layoutBitField(
const FieldDecl *FD) {
2718 layoutZeroWidthBitField(FD);
2721 ElementInfo Info = getAdjustedElementInfo(FD);
2724 if (Width > Context.
toBits(Info.Size))
2725 Width = Context.
toBits(Info.Size);
2729 if (!UseExternalLayout && !IsUnion && LastFieldIsNonZeroWidthBitfield &&
2730 CurrentBitfieldSize == Info.Size && Width <= RemainingBitsInField) {
2731 placeFieldAtBitOffset(Context.
toBits(Size) - RemainingBitsInField);
2732 RemainingBitsInField -= Width;
2735 LastFieldIsNonZeroWidthBitfield =
true;
2736 CurrentBitfieldSize = Info.Size;
2737 if (UseExternalLayout) {
2738 auto FieldBitOffset = External.getExternalFieldOffset(FD);
2739 placeFieldAtBitOffset(FieldBitOffset);
2741 llvm::alignDown(FieldBitOffset, Context.
toBits(Info.Alignment)) +
2742 Context.
toBits(Info.Size));
2744 Alignment =
std::max(Alignment, Info.Alignment);
2745 }
else if (IsUnion) {
2752 placeFieldAtOffset(FieldOffset);
2753 Size = FieldOffset + Info.Size;
2754 Alignment =
std::max(Alignment, Info.Alignment);
2755 RemainingBitsInField = Context.
toBits(Info.Size) - Width;
2760 MicrosoftRecordLayoutBuilder::layoutZeroWidthBitField(
const FieldDecl *FD) {
2763 if (!LastFieldIsNonZeroWidthBitfield) {
2769 LastFieldIsNonZeroWidthBitfield =
false;
2770 ElementInfo Info = getAdjustedElementInfo(FD);
2778 placeFieldAtOffset(FieldOffset);
2780 Alignment =
std::max(Alignment, Info.Alignment);
2784 void MicrosoftRecordLayoutBuilder::injectVBPtr(
const CXXRecordDecl *RD) {
2785 if (!HasVBPtr || SharedVBPtrBase)
2790 VBPtrOffset = VBPtrOffset.
alignTo(PointerInfo.Alignment);
2792 CharUnits FieldStart = VBPtrOffset + PointerInfo.Size;
2795 if (UseExternalLayout) {
2798 if (Size < FieldStart)
2804 CharUnits Offset = (FieldStart - InjectionSite)
2805 .alignTo(
std::max(RequiredAlignment, Alignment));
2807 for (uint64_t &FieldOffset : FieldOffsets)
2808 FieldOffset += Context.
toBits(Offset);
2809 for (BaseOffsetsMapTy::value_type &Base : Bases)
2810 if (Base.second >= InjectionSite)
2814 void MicrosoftRecordLayoutBuilder::injectVFPtr(
const CXXRecordDecl *RD) {
2826 if (UseExternalLayout) {
2830 if (FieldOffsets.empty() && Bases.empty())
2839 for (uint64_t &FieldOffset : FieldOffsets)
2840 FieldOffset += Context.
toBits(Offset);
2841 for (BaseOffsetsMapTy::value_type &Base : Bases)
2845 void MicrosoftRecordLayoutBuilder::layoutVirtualBases(
const CXXRecordDecl *RD) {
2850 CharUnits VtorDispAlignment = VtorDispSize;
2852 if (!MaxFieldAlignment.
isZero())
2853 VtorDispAlignment =
std::min(VtorDispAlignment, MaxFieldAlignment);
2858 const CXXRecordDecl *BaseDecl = VBase.getType()->getAsCXXRecordDecl();
2863 VtorDispAlignment =
std::max(VtorDispAlignment, RequiredAlignment);
2865 llvm::SmallPtrSet<const CXXRecordDecl *, 2> HasVtorDispSet;
2866 computeVtorDispSet(HasVtorDispSet, RD);
2870 const CXXRecordDecl *BaseDecl = VBase.getType()->getAsCXXRecordDecl();
2872 bool HasVtordisp = HasVtorDispSet.count(BaseDecl) > 0;
2881 Size = Size.alignTo(VtorDispAlignment) + VtorDispSize;
2882 Alignment =
std::max(VtorDispAlignment, Alignment);
2885 ElementInfo Info = getAdjustedElementInfo(BaseLayout);
2889 if (UseExternalLayout) {
2890 if (!External.getExternalVBaseOffset(BaseDecl, BaseOffset))
2893 BaseOffset = Size.
alignTo(Info.Alignment);
2895 assert(BaseOffset >= Size &&
"base offset already allocated");
2897 VBases.insert(std::make_pair(BaseDecl,
2900 PreviousBaseLayout = &BaseLayout;
2904 void MicrosoftRecordLayoutBuilder::finalizeLayout(
const RecordDecl *RD) {
2908 if (!RequiredAlignment.isZero()) {
2909 Alignment =
std::max(Alignment, RequiredAlignment);
2910 auto RoundingAlignment = Alignment;
2911 if (!MaxFieldAlignment.
isZero())
2912 RoundingAlignment =
std::min(RoundingAlignment, MaxFieldAlignment);
2913 RoundingAlignment =
std::max(RoundingAlignment, RequiredAlignment);
2914 Size = Size.alignTo(RoundingAlignment);
2916 if (Size.isZero()) {
2917 if (!
recordUsesEBO(RD) || !cast<CXXRecordDecl>(RD)->isEmpty()) {
2918 EndsWithZeroSizedObject =
true;
2919 LeadsWithZeroSizedBase =
true;
2923 if (RequiredAlignment >= MinEmptyStructSize)
2926 Size = MinEmptyStructSize;
2929 if (UseExternalLayout) {
2940 BasesWithOverriddenMethods,
2942 if (BasesWithOverriddenMethods.count(RD))
2947 if (!Base.isVirtual() &&
2949 Base.getType()->getAsCXXRecordDecl()))
2954 void MicrosoftRecordLayoutBuilder::computeVtorDispSet(
2955 llvm::SmallPtrSetImpl<const CXXRecordDecl *> &HasVtordispSet,
2961 const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
2964 HasVtordispSet.insert(BaseDecl);
2972 const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
2975 if (bi.second.hasVtorDisp())
2976 HasVtordispSet.insert(bi.first);
2992 llvm::SmallPtrSet<const CXXMethodDecl *, 8> Work;
2993 llvm::SmallPtrSet<const CXXRecordDecl *, 2> BasesWithOverriddenMethods;
2996 if (MD->isVirtual() && !isa<CXXDestructorDecl>(MD) && !MD->isPure())
2998 while (!Work.empty()) {
3002 if (MethodRange.begin() == MethodRange.end())
3003 BasesWithOverriddenMethods.insert(MD->
getParent());
3005 Work.insert(MethodRange.begin(), MethodRange.end());
3012 const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl();
3013 if (!HasVtordispSet.count(BaseDecl) &&
3015 HasVtordispSet.insert(BaseDecl);
3030 getExternalSource()->CompleteType(const_cast<RecordDecl*>(D));
3033 assert(D &&
"Cannot get layout of forward declarations!");
3034 assert(!D->
isInvalidDecl() &&
"Cannot get layout of invalid decl!");
3041 if (Entry)
return *Entry;
3046 MicrosoftRecordLayoutBuilder Builder(*
this);
3047 if (
const auto *RD = dyn_cast<CXXRecordDecl>(D)) {
3048 Builder.cxxLayout(RD);
3050 *
this, Builder.Size, Builder.Alignment, Builder.Alignment,
3051 Builder.RequiredAlignment,
3052 Builder.HasOwnVFPtr, Builder.HasOwnVFPtr || Builder.PrimaryBase,
3053 Builder.VBPtrOffset, Builder.DataSize, Builder.FieldOffsets,
3055 Builder.PrimaryBase,
false, Builder.SharedVBPtrBase,
3056 Builder.EndsWithZeroSizedObject, Builder.LeadsWithZeroSizedBase,
3057 Builder.Bases, Builder.VBases);
3061 *
this, Builder.Size, Builder.Alignment, Builder.Alignment,
3062 Builder.RequiredAlignment,
3063 Builder.Size, Builder.FieldOffsets);
3066 if (
const auto *RD = dyn_cast<CXXRecordDecl>(D)) {
3067 EmptySubobjectMap EmptySubobjects(*
this, RD);
3068 ItaniumRecordLayoutBuilder Builder(*
this, &EmptySubobjects);
3074 bool skipTailPadding =
3079 skipTailPadding ? Builder.getSize() : Builder.getDataSize();
3081 skipTailPadding ? DataSize : Builder.NonVirtualSize;
3083 *
this, Builder.getSize(), Builder.Alignment, Builder.UnadjustedAlignment,
3087 NonVirtualSize, Builder.NonVirtualAlignment,
3088 EmptySubobjects.SizeOfLargestEmptySubobject, Builder.PrimaryBase,
3089 Builder.PrimaryBaseIsVirtual,
nullptr,
false,
false, Builder.Bases,
3092 ItaniumRecordLayoutBuilder Builder(*
this,
nullptr);
3096 *
this, Builder.getSize(), Builder.Alignment, Builder.UnadjustedAlignment,
3098 Builder.Alignment, Builder.getSize(), Builder.FieldOffsets);
3102 ASTRecordLayouts[D] = NewEntry;
3104 if (getLangOpts().DumpRecordLayouts) {
3105 llvm::outs() <<
"\n*** Dumping AST Record Layout\n";
3113 if (!getTargetInfo().getCXXABI().hasKeyFunctions())
3116 assert(RD->
getDefinition() &&
"Cannot get key function for forward decl!");
3130 KeyFunctions[RD] = const_cast<Decl*>(Result);
3132 return cast_or_null<CXXMethodDecl>(
Result);
3137 "not working with method declaration from class definition");
3142 const auto &Map = KeyFunctions;
3146 if (I == Map.end())
return;
3152 if (Ptr.
get(getExternalSource()) == Method) {
3154 KeyFunctions.erase(Method->
getParent());
3164 uint64_t OffsetInBits;
3165 if (
const FieldDecl *FD = dyn_cast<FieldDecl>(VD)) {
3175 return OffsetInBits;
3191 RL = &getASTObjCImplementationLayout(ID);
3193 RL = &getASTObjCInterfaceLayout(Container);
3208 assert(Index < RL->getFieldCount() &&
"Ivar is not inside record layout!");
3223 getExternalSource()->CompleteType(const_cast<ObjCInterfaceDecl*>(D));
3235 unsigned SynthCount = CountNonClassIvars(D);
3240 if (SynthCount == 0)
3241 return getObjCLayout(D,
nullptr);
3244 ItaniumRecordLayoutBuilder Builder(*
this,
nullptr);
3250 Builder.UnadjustedAlignment,
3253 Builder.getDataSize(),
3254 Builder.FieldOffsets);
3256 ObjCLayouts[Key] = NewEntry;
3262 CharUnits Offset,
unsigned IndentLevel) {
3263 OS << llvm::format(
"%10" PRId64
" | ", (int64_t)Offset.
getQuantity());
3264 OS.indent(IndentLevel * 2);
3268 unsigned Begin,
unsigned Width,
3269 unsigned IndentLevel) {
3272 llvm::raw_svector_ostream BufferOS(Buffer);
3277 BufferOS << Begin <<
'-' << (Begin + Width - 1);
3281 OS << llvm::right_justify(Buffer, 10) <<
" | ";
3282 OS.indent(IndentLevel * 2);
3287 OS.indent(IndentLevel * 2);
3293 unsigned IndentLevel,
3294 const char* Description,
3296 bool IncludeVirtualBases) {
3303 OS <<
' ' << Description;
3304 if (CXXRD && CXXRD->isEmpty())
3317 if (CXXRD->isDynamicClass() && !PrimaryBase && !
isMsLayout(C)) {
3319 OS <<
'(' << *RD <<
" vtable pointer)\n";
3320 }
else if (HasOwnVFPtr) {
3323 OS <<
'(' << *RD <<
" vftable pointer)\n";
3329 assert(!Base.getType()->isDependentType() &&
3330 "Cannot layout class with dependent bases.");
3331 if (!Base.isVirtual())
3332 Bases.push_back(Base.getType()->getAsCXXRecordDecl());
3345 Base == PrimaryBase ?
"(primary base)" :
"(base)",
3353 OS <<
'(' << *RD <<
" vbtable pointer)\n";
3358 uint64_t FieldNo = 0;
3360 E = RD->
field_end(); I != E; ++I, ++FieldNo) {
3362 uint64_t LocalFieldOffsetInBits = Layout.
getFieldOffset(FieldNo);
3376 uint64_t LocalFieldByteOffsetInBits = C.
toBits(FieldOffset - Offset);
3377 unsigned Begin = LocalFieldOffsetInBits - LocalFieldByteOffsetInBits;
3387 if (CXXRD && IncludeVirtualBases) {
3392 assert(Base.isVirtual() &&
"Found non-virtual class!");
3393 const CXXRecordDecl *VBase = Base.getType()->getAsCXXRecordDecl();
3397 if (VtorDisps.find(VBase)->second.hasVtorDisp()) {
3399 OS <<
"(vtordisp for vbase " << *VBase <<
")\n";
3404 "(primary virtual base)" :
"(virtual base)",
3410 if (!PrintSizeInfo)
return;
3429 bool Simple)
const {
3445 OS <<
"Type: " << getTypeDeclType(RD).getAsString() <<
"\n";
3447 OS <<
"<ASTRecordLayout\n";
3448 OS <<
" Size:" << toBits(Info.
getSize()) <<
"\n";
3450 OS <<
" DataSize:" << toBits(Info.
getDataSize()) <<
"\n";
3451 OS <<
" Alignment:" << toBits(Info.
getAlignment()) <<
"\n";
3452 OS <<
" FieldOffsets: [";
3453 for (
unsigned i = 0, e = Info.
getFieldCount(); i != e; ++i) {
static uint64_t getFieldOffset(const ASTContext &C, const FieldDecl *FD)
Defines the clang::ASTContext interface.
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 ...
Represents a function declaration or definition.
Only allocate objects in the tail padding of a base class if the base class is not POD according to t...
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.
bool isPrimaryBaseVirtual() const
isPrimaryBaseVirtual - Get whether the primary base for this record is virtual or not...
A (possibly-)qualified type.
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 void DumpRecordLayout(raw_ostream &OS, const RecordDecl *RD, const ASTContext &C, CharUnits Offset, unsigned IndentLevel, const char *Description, bool PrintSizeInfo, bool IncludeVirtualBases)
Attempt to be ABI-compatible with code generated by Clang 6.0.x (SVN r321711).
The basic abstraction for the target C++ ABI.
bool isThisDeclarationADefinition() const
Determine whether this particular declaration of this class is actually also a definition.
const ASTRecordLayout & getASTRecordLayout(const RecordDecl *D) const
Get or compute information about the layout of the specified record (struct/union/class) D...
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee...
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
unsigned getNumVBases() const
Retrieves the number of virtual base classes of this class.
Decl - This represents one declaration (or definition), e.g.
bool isPOD() const
Whether this class is a POD-type (C++ [class]p4)
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...
The base class of the type hierarchy.
DiagnosticsEngine & getDiagnostics() const
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
bool isZero() const
isZero - Test whether the quantity equals zero.
const TargetInfo & getTargetInfo() const
CharUnits getAlignment() const
getAlignment - Get the record alignment in characters.
unsigned getCharWidth() const
QualType getElementType() const
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
bool hasVBPtr() const
hasVBPtr - Does this class have a virtual function table pointer.
const T * getAs() const
Member-template getAs<specific type>'.
unsigned getCharAlign() const
The "__interface" keyword.
bool hasOwnVFPtr() const
hasOwnVFPtr - Does this class provide its own virtual-function table pointer, rather than inheriting ...
bool isInvalidDecl() const
unsigned getZeroLengthBitfieldBoundary() const
Get the fixed alignment value in bits for a member that follows a zero length bitfield.
bool mayInsertExtraPadding(bool EmitRemark=false) const
Whether we are allowed to insert extra padding between fields.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Represents a struct/union/class.
uint64_t getPointerWidth(unsigned AddrSpace) const
Return the width of pointers on this target, for the specified address space.
bool isEmpty() const
Determine whether this is an empty class in the sense of (C++11 [meta.unary.prop]).
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
RecordDecl * getDefinition() const
Returns the RecordDecl that actually defines this struct/union/class.
field_range fields() const
Represents a member of a struct/union/class.
bool Zero(InterpState &S, CodePtr OpPC)
bool hasUserDeclaredDestructor() const
Determine whether this class has a user-declared destructor.
static CharUnits Zero()
Zero - Construct a CharUnits quantity of zero.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
method_iterator method_begin() const
Method begin iterator.
__DEVICE__ int max(int __a, int __b)
uint64_t lookupFieldBitOffset(const ObjCInterfaceDecl *OID, const ObjCImplementationDecl *ID, const ObjCIvarDecl *Ivar) const
Get the offset of an ObjCIvarDecl in bits.
const ASTRecordLayout & getASTObjCInterfaceLayout(const ObjCInterfaceDecl *D) const
Get or compute information about the layout of the specified Objective-C interface.
specific_decl_iterator< FieldDecl > field_iterator
bool canKeyFunctionBeInline() const
Can an out-of-line inline function serve as a key function?
uint64_t getConstantArrayElementCount(const ConstantArrayType *CA) const
Return number of constant array elements.
bool isBitField() const
Determines whether this field is a bitfield.
ObjCContainerDecl - Represents a container for method declarations.
TagKind getTagKind() const
CharUnits - This is an opaque type for sizes expressed in character units.
bool endsWithZeroSizedObject() const
ArrayRef< NamedDecl * > chain() const
field_iterator field_begin() const
unsigned getBitWidthValue(const ASTContext &Ctx) const
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
const VBaseOffsetsMapTy & getVBaseOffsetsMap() const
bool isAlignmentRequired(const Type *T) const
Determine if the alignment the type has was required using an alignment attribute.
bool useZeroLengthBitfieldAlignment() const
Check whether zero length bitfields should force alignment of the next member.
Represents an ObjC class declaration.
const Type * getUnqualifiedDesugaredType() const
Return the specified type with any "sugar" removed from the type, removing any typedefs, typeofs, etc., as well as any qualifiers.
CanQualType UnsignedCharTy
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
static CharUnits One()
One - Construct a CharUnits quantity of one.
A little helper class used to produce diagnostics.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isDynamicClass() const
bool useExplicitBitFieldAlignment() const
Check whether explicit bitfield alignment attributes should be.
static void PrintOffset(raw_ostream &OS, CharUnits Offset, unsigned IndentLevel)
TemplateSpecializationKind getTemplateSpecializationKind() const
Determine whether this particular class is a specialization or instantiation of a class template or m...
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
bool isMsStruct(const ASTContext &C) const
Get whether or not this is an ms_struct which can be turned on with an attribute, pragma...
bool isInlineSpecified() const
Determine whether the "inline" keyword was specified for this function.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isNearlyEmpty(const CXXRecordDecl *RD) const
field_iterator field_end() const
CharUnits getSizeOfLargestEmptySubobject() const
overridden_method_range overridden_methods() const
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
CXXRecordDecl * getDefinition() const
ObjCInterfaceDecl * getSuperClass() const
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
static CharUnits fromQuantity(QuantityType Quantity)
fromQuantity - Construct a CharUnits quantity from a raw integer type.
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
bool isTrivial() const
Determine whether this class is considered trivial.
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
bool hasExtendableVFPtr() const
hasVFPtr - Does this class have a virtual function table pointer that can be extended by a derived cl...
unsigned getMaxAlignment() const
getMaxAlignment - return the maximum alignment specified by attributes on this decl, 0 if there are none.
method_iterator method_end() const
Method past-the-end iterator.
CharUnits getVBPtrOffset() const
getVBPtrOffset - Get the offset for virtual base table pointer.
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
CharUnits getRequiredAlignment() const
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
The result type of a method or function.
This template specialization was implicitly instantiated from a template.
void getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet &Bases) const
Get the indirect primary bases for this class.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
decl_type * getFirstDecl()
Return the first declaration of this declaration or itself if this is the only declaration.
static bool recordUsesEBO(const RecordDecl *RD)
RecordDecl * getDecl() const
Abstract interface for external sources of AST nodes.
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
static uint64_t roundUpSizeToCharAlignment(uint64_t Size, const ASTContext &Context)
Only allocate objects in the tail padding of a base class if the base class is not POD according to t...
Encodes a location in the source.
A set of all the primary bases for a class.
static void PrintIndentNoOffset(raw_ostream &OS, unsigned IndentLevel)
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
Represents a static or instance method of a struct/union/class.
const ConstantArrayType * getAsConstantArrayType(QualType T) const
const ArrayType * getAsArrayType(QualType T) const
Type Query functions.
bool hasExternalLexicalStorage() const
Whether this DeclContext has external storage containing additional declarations that are lexically i...
This template specialization was instantiated from a template due to an explicit instantiation defini...
CharUnits getDataSize() const
getDataSize() - Get the record data size, which is the record size without tail padding, in characters.
bool useBitFieldTypeAlignment() const
Check whether the alignment of bit-field types is respected when laying out structures.
MSVtorDispAttr::Mode getMSVtorDispMode() const
Controls when vtordisps will be emitted if this record is used as a virtual base. ...
static unsigned getPaddingDiagFromTagKind(TagTypeKind Tag)
Get diagnostic select index for tag kind for field padding diagnostic message.
bool hasFlexibleArrayMember() const
bool isValid() const
Whether this pointer is non-NULL.
ASTContext & operator=(const ASTContext &)=delete
std::pair< CharUnits, CharUnits > getTypeInfoInChars(const Type *T) const
CanQualType UnsignedShortTy
ObjCIvarDecl * getNextIvar()
CharUnits getNonVirtualAlignment() const
getNonVirtualSize - Get the non-virtual alignment (in chars) of an object, which is the alignment of ...
TagTypeKind
The kind of a tag type.
const ObjCInterfaceDecl * getClassInterface() const
Dataflow Directional Tag Classes.
CharUnits getSize() const
getSize - Get the record size in characters.
Represents a field injected from an anonymous union/struct into the parent scope. ...
CanQualType UnsignedLongLongTy
ObjCInterfaceDecl * getDefinition()
Retrieve the definition of this class, or NULL if this class has been forward-declared (with @class) ...
This template specialization was instantiated from a template due to an explicit instantiation declar...
bool hasUserDeclaredConstructor() const
Determine whether this class has any user-declared constructors.
TailPaddingUseRules getTailPaddingUseRules() const
bool isCXX11StandardLayout() const
Determine whether this class was standard-layout per C++11 [class]p7, specifically using the C++11 ru...
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined...
void DumpRecordLayout(const RecordDecl *RD, raw_ostream &OS, bool Simple=false) const
const ObjCInterfaceDecl * getContainingInterface() const
Return the class interface that this ivar is logically contained in; this is either the interface whe...
TemplateSpecializationKind
Describes the kind of template specialization that a particular template specialization declaration r...
ExternalASTSource * getExternalSource() const
Retrieve a pointer to the external AST source associated with this AST context, if any...
T * get(ExternalASTSource *Source) const
Retrieve the pointer to the AST node that this lazy pointer points to.
specific_decl_iterator - Iterates over a subrange of declarations stored in a DeclContext, providing only those that are of type SpecificDecl (or a class derived from it).
All virtual base related information about a given record decl.
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
bool isIncompleteArrayType() const
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
CanQualType UnsignedLongTy
static bool RequiresVtordisp(const llvm::SmallPtrSetImpl< const CXXRecordDecl *> &BasesWithOverriddenMethods, const CXXRecordDecl *RD)
uint64_t getCharWidth() const
Return the size of the character type, in bits.
void setNonKeyFunction(const CXXMethodDecl *method)
Observe that the given method cannot be a key function.
Base for LValueReferenceType and RValueReferenceType.
Represents a base class of a C++ class.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
uint64_t getFieldOffset(const ValueDecl *FD) const
Get the offset of a FieldDecl or IndirectFieldDecl, in bits.
CharUnits toCharUnitsFromBits(int64_t BitSize) const
Convert a size in bits to a size in characters.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
int64_t toBits(CharUnits CharSize) const
Convert a size in characters to a size in bits.
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...
Represents a C++ struct/union/class.
TypeInfo getTypeInfo(const Type *T) const
Get the size and alignment of the specified complete type in bits.
ObjCIvarDecl - Represents an ObjC instance variable.
CharUnits getNonVirtualSize() const
getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...
static bool isMsLayout(const ASTContext &Context)
static unsigned getCharWidth(tok::TokenKind kind, const TargetInfo &Target)
This class is used for builtin types like 'int'.
static const CXXMethodDecl * computeKeyFunction(ASTContext &Context, const CXXRecordDecl *RD)
The tail-padding of a base class is always theoretically available, even if it's POD.
__DEVICE__ int min(int __a, int __b)
llvm::DenseMap< const CXXRecordDecl *, VBaseInfo > VBaseOffsetsMapTy
bool isOffset() const
Whether this pointer is currently stored as an offset.
uint64_t getPointerAlign(unsigned AddrSpace) const
Defines the clang::TargetInfo interface.
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
static void PrintBitFieldOffset(raw_ostream &OS, CharUnits Offset, unsigned Begin, unsigned Width, unsigned IndentLevel)
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
This represents a decl that may have a name.
ObjCIvarDecl * all_declared_ivar_begin()
all_declared_ivar_begin - return first ivar declared in this class, its extensions and its implementa...
bool hasOwnVBPtr() const
hasOwnVBPtr - Does this class provide its own virtual-base table pointer, rather than inheriting one ...
unsigned getTargetAddressSpace(QualType T) const
const LangOptions & getLangOpts() const
Represents the canonical version of C arrays with a specified constant size.
base_class_range vbases()
SourceLocation getLocation() const
bool isExternallyVisible() const
CanQualType UnsignedIntTy
bool leadsWithZeroSizedBase() const
method_range methods() const