10b57cec5SDimitry Andric //=== RecordLayoutBuilder.cpp - Helper class for building record layouts ---==// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 90b57cec5SDimitry Andric #include "clang/AST/ASTContext.h" 100b57cec5SDimitry Andric #include "clang/AST/ASTDiagnostic.h" 110b57cec5SDimitry Andric #include "clang/AST/Attr.h" 120b57cec5SDimitry Andric #include "clang/AST/CXXInheritance.h" 130b57cec5SDimitry Andric #include "clang/AST/Decl.h" 140b57cec5SDimitry Andric #include "clang/AST/DeclCXX.h" 150b57cec5SDimitry Andric #include "clang/AST/DeclObjC.h" 160b57cec5SDimitry Andric #include "clang/AST/Expr.h" 175ffd83dbSDimitry Andric #include "clang/AST/VTableBuilder.h" 18e8d8bef9SDimitry Andric #include "clang/AST/RecordLayout.h" 190b57cec5SDimitry Andric #include "clang/Basic/TargetInfo.h" 200b57cec5SDimitry Andric #include "llvm/ADT/SmallSet.h" 210b57cec5SDimitry Andric #include "llvm/Support/Format.h" 220b57cec5SDimitry Andric #include "llvm/Support/MathExtras.h" 230b57cec5SDimitry Andric 240b57cec5SDimitry Andric using namespace clang; 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric namespace { 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric /// BaseSubobjectInfo - Represents a single base subobject in a complete class. 290b57cec5SDimitry Andric /// For a class hierarchy like 300b57cec5SDimitry Andric /// 310b57cec5SDimitry Andric /// class A { }; 320b57cec5SDimitry Andric /// class B : A { }; 330b57cec5SDimitry Andric /// class C : A, B { }; 340b57cec5SDimitry Andric /// 350b57cec5SDimitry Andric /// The BaseSubobjectInfo graph for C will have three BaseSubobjectInfo 360b57cec5SDimitry Andric /// instances, one for B and two for A. 370b57cec5SDimitry Andric /// 380b57cec5SDimitry Andric /// If a base is virtual, it will only have one BaseSubobjectInfo allocated. 390b57cec5SDimitry Andric struct BaseSubobjectInfo { 400b57cec5SDimitry Andric /// Class - The class for this base info. 410b57cec5SDimitry Andric const CXXRecordDecl *Class; 420b57cec5SDimitry Andric 430b57cec5SDimitry Andric /// IsVirtual - Whether the BaseInfo represents a virtual base or not. 440b57cec5SDimitry Andric bool IsVirtual; 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric /// Bases - Information about the base subobjects. 470b57cec5SDimitry Andric SmallVector<BaseSubobjectInfo*, 4> Bases; 480b57cec5SDimitry Andric 490b57cec5SDimitry Andric /// PrimaryVirtualBaseInfo - Holds the base info for the primary virtual base 500b57cec5SDimitry Andric /// of this base info (if one exists). 510b57cec5SDimitry Andric BaseSubobjectInfo *PrimaryVirtualBaseInfo; 520b57cec5SDimitry Andric 530b57cec5SDimitry Andric // FIXME: Document. 540b57cec5SDimitry Andric const BaseSubobjectInfo *Derived; 550b57cec5SDimitry Andric }; 560b57cec5SDimitry Andric 570b57cec5SDimitry Andric /// Externally provided layout. Typically used when the AST source, such 580b57cec5SDimitry Andric /// as DWARF, lacks all the information that was available at compile time, such 590b57cec5SDimitry Andric /// as alignment attributes on fields and pragmas in effect. 600b57cec5SDimitry Andric struct ExternalLayout { 615f757f3fSDimitry Andric ExternalLayout() = default; 620b57cec5SDimitry Andric 630b57cec5SDimitry Andric /// Overall record size in bits. 645f757f3fSDimitry Andric uint64_t Size = 0; 650b57cec5SDimitry Andric 660b57cec5SDimitry Andric /// Overall record alignment in bits. 675f757f3fSDimitry Andric uint64_t Align = 0; 680b57cec5SDimitry Andric 690b57cec5SDimitry Andric /// Record field offsets in bits. 700b57cec5SDimitry Andric llvm::DenseMap<const FieldDecl *, uint64_t> FieldOffsets; 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric /// Direct, non-virtual base offsets. 730b57cec5SDimitry Andric llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsets; 740b57cec5SDimitry Andric 750b57cec5SDimitry Andric /// Virtual base offsets. 760b57cec5SDimitry Andric llvm::DenseMap<const CXXRecordDecl *, CharUnits> VirtualBaseOffsets; 770b57cec5SDimitry Andric 780b57cec5SDimitry Andric /// Get the offset of the given field. The external source must provide 790b57cec5SDimitry Andric /// entries for all fields in the record. 800b57cec5SDimitry Andric uint64_t getExternalFieldOffset(const FieldDecl *FD) { 810b57cec5SDimitry Andric assert(FieldOffsets.count(FD) && 820b57cec5SDimitry Andric "Field does not have an external offset"); 830b57cec5SDimitry Andric return FieldOffsets[FD]; 840b57cec5SDimitry Andric } 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric bool getExternalNVBaseOffset(const CXXRecordDecl *RD, CharUnits &BaseOffset) { 870b57cec5SDimitry Andric auto Known = BaseOffsets.find(RD); 880b57cec5SDimitry Andric if (Known == BaseOffsets.end()) 890b57cec5SDimitry Andric return false; 900b57cec5SDimitry Andric BaseOffset = Known->second; 910b57cec5SDimitry Andric return true; 920b57cec5SDimitry Andric } 930b57cec5SDimitry Andric 940b57cec5SDimitry Andric bool getExternalVBaseOffset(const CXXRecordDecl *RD, CharUnits &BaseOffset) { 950b57cec5SDimitry Andric auto Known = VirtualBaseOffsets.find(RD); 960b57cec5SDimitry Andric if (Known == VirtualBaseOffsets.end()) 970b57cec5SDimitry Andric return false; 980b57cec5SDimitry Andric BaseOffset = Known->second; 990b57cec5SDimitry Andric return true; 1000b57cec5SDimitry Andric } 1010b57cec5SDimitry Andric }; 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric /// EmptySubobjectMap - Keeps track of which empty subobjects exist at different 1040b57cec5SDimitry Andric /// offsets while laying out a C++ class. 1050b57cec5SDimitry Andric class EmptySubobjectMap { 1060b57cec5SDimitry Andric const ASTContext &Context; 1070b57cec5SDimitry Andric uint64_t CharWidth; 1080b57cec5SDimitry Andric 1090b57cec5SDimitry Andric /// Class - The class whose empty entries we're keeping track of. 1100b57cec5SDimitry Andric const CXXRecordDecl *Class; 1110b57cec5SDimitry Andric 1120b57cec5SDimitry Andric /// EmptyClassOffsets - A map from offsets to empty record decls. 1130b57cec5SDimitry Andric typedef llvm::TinyPtrVector<const CXXRecordDecl *> ClassVectorTy; 1140b57cec5SDimitry Andric typedef llvm::DenseMap<CharUnits, ClassVectorTy> EmptyClassOffsetsMapTy; 1150b57cec5SDimitry Andric EmptyClassOffsetsMapTy EmptyClassOffsets; 1160b57cec5SDimitry Andric 1170b57cec5SDimitry Andric /// MaxEmptyClassOffset - The highest offset known to contain an empty 1180b57cec5SDimitry Andric /// base subobject. 1190b57cec5SDimitry Andric CharUnits MaxEmptyClassOffset; 1200b57cec5SDimitry Andric 1210b57cec5SDimitry Andric /// ComputeEmptySubobjectSizes - Compute the size of the largest base or 1220b57cec5SDimitry Andric /// member subobject that is empty. 1230b57cec5SDimitry Andric void ComputeEmptySubobjectSizes(); 1240b57cec5SDimitry Andric 1250b57cec5SDimitry Andric void AddSubobjectAtOffset(const CXXRecordDecl *RD, CharUnits Offset); 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric void UpdateEmptyBaseSubobjects(const BaseSubobjectInfo *Info, 1280b57cec5SDimitry Andric CharUnits Offset, bool PlacingEmptyBase); 1290b57cec5SDimitry Andric 1300b57cec5SDimitry Andric void UpdateEmptyFieldSubobjects(const CXXRecordDecl *RD, 1310b57cec5SDimitry Andric const CXXRecordDecl *Class, CharUnits Offset, 1320b57cec5SDimitry Andric bool PlacingOverlappingField); 1330b57cec5SDimitry Andric void UpdateEmptyFieldSubobjects(const FieldDecl *FD, CharUnits Offset, 1340b57cec5SDimitry Andric bool PlacingOverlappingField); 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric /// AnyEmptySubobjectsBeyondOffset - Returns whether there are any empty 1370b57cec5SDimitry Andric /// subobjects beyond the given offset. 1380b57cec5SDimitry Andric bool AnyEmptySubobjectsBeyondOffset(CharUnits Offset) const { 1390b57cec5SDimitry Andric return Offset <= MaxEmptyClassOffset; 1400b57cec5SDimitry Andric } 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric CharUnits 1430b57cec5SDimitry Andric getFieldOffset(const ASTRecordLayout &Layout, unsigned FieldNo) const { 1440b57cec5SDimitry Andric uint64_t FieldOffset = Layout.getFieldOffset(FieldNo); 1450b57cec5SDimitry Andric assert(FieldOffset % CharWidth == 0 && 1460b57cec5SDimitry Andric "Field offset not at char boundary!"); 1470b57cec5SDimitry Andric 1480b57cec5SDimitry Andric return Context.toCharUnitsFromBits(FieldOffset); 1490b57cec5SDimitry Andric } 1500b57cec5SDimitry Andric 1510b57cec5SDimitry Andric protected: 1520b57cec5SDimitry Andric bool CanPlaceSubobjectAtOffset(const CXXRecordDecl *RD, 1530b57cec5SDimitry Andric CharUnits Offset) const; 1540b57cec5SDimitry Andric 1550b57cec5SDimitry Andric bool CanPlaceBaseSubobjectAtOffset(const BaseSubobjectInfo *Info, 1560b57cec5SDimitry Andric CharUnits Offset); 1570b57cec5SDimitry Andric 1580b57cec5SDimitry Andric bool CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD, 1590b57cec5SDimitry Andric const CXXRecordDecl *Class, 1600b57cec5SDimitry Andric CharUnits Offset) const; 1610b57cec5SDimitry Andric bool CanPlaceFieldSubobjectAtOffset(const FieldDecl *FD, 1620b57cec5SDimitry Andric CharUnits Offset) const; 1630b57cec5SDimitry Andric 1640b57cec5SDimitry Andric public: 1650b57cec5SDimitry Andric /// This holds the size of the largest empty subobject (either a base 1660b57cec5SDimitry Andric /// or a member). Will be zero if the record being built doesn't contain 1670b57cec5SDimitry Andric /// any empty classes. 1680b57cec5SDimitry Andric CharUnits SizeOfLargestEmptySubobject; 1690b57cec5SDimitry Andric 1700b57cec5SDimitry Andric EmptySubobjectMap(const ASTContext &Context, const CXXRecordDecl *Class) 1710b57cec5SDimitry Andric : Context(Context), CharWidth(Context.getCharWidth()), Class(Class) { 1720b57cec5SDimitry Andric ComputeEmptySubobjectSizes(); 1730b57cec5SDimitry Andric } 1740b57cec5SDimitry Andric 1750b57cec5SDimitry Andric /// CanPlaceBaseAtOffset - Return whether the given base class can be placed 1760b57cec5SDimitry Andric /// at the given offset. 1770b57cec5SDimitry Andric /// Returns false if placing the record will result in two components 1780b57cec5SDimitry Andric /// (direct or indirect) of the same type having the same offset. 1790b57cec5SDimitry Andric bool CanPlaceBaseAtOffset(const BaseSubobjectInfo *Info, 1800b57cec5SDimitry Andric CharUnits Offset); 1810b57cec5SDimitry Andric 1820b57cec5SDimitry Andric /// CanPlaceFieldAtOffset - Return whether a field can be placed at the given 1830b57cec5SDimitry Andric /// offset. 1840b57cec5SDimitry Andric bool CanPlaceFieldAtOffset(const FieldDecl *FD, CharUnits Offset); 1850b57cec5SDimitry Andric }; 1860b57cec5SDimitry Andric 1870b57cec5SDimitry Andric void EmptySubobjectMap::ComputeEmptySubobjectSizes() { 1880b57cec5SDimitry Andric // Check the bases. 1890b57cec5SDimitry Andric for (const CXXBaseSpecifier &Base : Class->bases()) { 1900b57cec5SDimitry Andric const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl(); 1910b57cec5SDimitry Andric 1920b57cec5SDimitry Andric CharUnits EmptySize; 1930b57cec5SDimitry Andric const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl); 1940b57cec5SDimitry Andric if (BaseDecl->isEmpty()) { 1950b57cec5SDimitry Andric // If the class decl is empty, get its size. 1960b57cec5SDimitry Andric EmptySize = Layout.getSize(); 1970b57cec5SDimitry Andric } else { 1980b57cec5SDimitry Andric // Otherwise, we get the largest empty subobject for the decl. 1990b57cec5SDimitry Andric EmptySize = Layout.getSizeOfLargestEmptySubobject(); 2000b57cec5SDimitry Andric } 2010b57cec5SDimitry Andric 2020b57cec5SDimitry Andric if (EmptySize > SizeOfLargestEmptySubobject) 2030b57cec5SDimitry Andric SizeOfLargestEmptySubobject = EmptySize; 2040b57cec5SDimitry Andric } 2050b57cec5SDimitry Andric 2060b57cec5SDimitry Andric // Check the fields. 2070b57cec5SDimitry Andric for (const FieldDecl *FD : Class->fields()) { 2080b57cec5SDimitry Andric const RecordType *RT = 2090b57cec5SDimitry Andric Context.getBaseElementType(FD->getType())->getAs<RecordType>(); 2100b57cec5SDimitry Andric 2110b57cec5SDimitry Andric // We only care about record types. 2120b57cec5SDimitry Andric if (!RT) 2130b57cec5SDimitry Andric continue; 2140b57cec5SDimitry Andric 2150b57cec5SDimitry Andric CharUnits EmptySize; 2160b57cec5SDimitry Andric const CXXRecordDecl *MemberDecl = RT->getAsCXXRecordDecl(); 2170b57cec5SDimitry Andric const ASTRecordLayout &Layout = Context.getASTRecordLayout(MemberDecl); 2180b57cec5SDimitry Andric if (MemberDecl->isEmpty()) { 2190b57cec5SDimitry Andric // If the class decl is empty, get its size. 2200b57cec5SDimitry Andric EmptySize = Layout.getSize(); 2210b57cec5SDimitry Andric } else { 2220b57cec5SDimitry Andric // Otherwise, we get the largest empty subobject for the decl. 2230b57cec5SDimitry Andric EmptySize = Layout.getSizeOfLargestEmptySubobject(); 2240b57cec5SDimitry Andric } 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric if (EmptySize > SizeOfLargestEmptySubobject) 2270b57cec5SDimitry Andric SizeOfLargestEmptySubobject = EmptySize; 2280b57cec5SDimitry Andric } 2290b57cec5SDimitry Andric } 2300b57cec5SDimitry Andric 2310b57cec5SDimitry Andric bool 2320b57cec5SDimitry Andric EmptySubobjectMap::CanPlaceSubobjectAtOffset(const CXXRecordDecl *RD, 2330b57cec5SDimitry Andric CharUnits Offset) const { 2340b57cec5SDimitry Andric // We only need to check empty bases. 2350b57cec5SDimitry Andric if (!RD->isEmpty()) 2360b57cec5SDimitry Andric return true; 2370b57cec5SDimitry Andric 2380b57cec5SDimitry Andric EmptyClassOffsetsMapTy::const_iterator I = EmptyClassOffsets.find(Offset); 2390b57cec5SDimitry Andric if (I == EmptyClassOffsets.end()) 2400b57cec5SDimitry Andric return true; 2410b57cec5SDimitry Andric 2420b57cec5SDimitry Andric const ClassVectorTy &Classes = I->second; 243349cc55cSDimitry Andric if (!llvm::is_contained(Classes, RD)) 2440b57cec5SDimitry Andric return true; 2450b57cec5SDimitry Andric 2460b57cec5SDimitry Andric // There is already an empty class of the same type at this offset. 2470b57cec5SDimitry Andric return false; 2480b57cec5SDimitry Andric } 2490b57cec5SDimitry Andric 2500b57cec5SDimitry Andric void EmptySubobjectMap::AddSubobjectAtOffset(const CXXRecordDecl *RD, 2510b57cec5SDimitry Andric CharUnits Offset) { 2520b57cec5SDimitry Andric // We only care about empty bases. 2530b57cec5SDimitry Andric if (!RD->isEmpty()) 2540b57cec5SDimitry Andric return; 2550b57cec5SDimitry Andric 2560b57cec5SDimitry Andric // If we have empty structures inside a union, we can assign both 2570b57cec5SDimitry Andric // the same offset. Just avoid pushing them twice in the list. 2580b57cec5SDimitry Andric ClassVectorTy &Classes = EmptyClassOffsets[Offset]; 2590b57cec5SDimitry Andric if (llvm::is_contained(Classes, RD)) 2600b57cec5SDimitry Andric return; 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric Classes.push_back(RD); 2630b57cec5SDimitry Andric 2640b57cec5SDimitry Andric // Update the empty class offset. 2650b57cec5SDimitry Andric if (Offset > MaxEmptyClassOffset) 2660b57cec5SDimitry Andric MaxEmptyClassOffset = Offset; 2670b57cec5SDimitry Andric } 2680b57cec5SDimitry Andric 2690b57cec5SDimitry Andric bool 2700b57cec5SDimitry Andric EmptySubobjectMap::CanPlaceBaseSubobjectAtOffset(const BaseSubobjectInfo *Info, 2710b57cec5SDimitry Andric CharUnits Offset) { 2720b57cec5SDimitry Andric // We don't have to keep looking past the maximum offset that's known to 2730b57cec5SDimitry Andric // contain an empty class. 2740b57cec5SDimitry Andric if (!AnyEmptySubobjectsBeyondOffset(Offset)) 2750b57cec5SDimitry Andric return true; 2760b57cec5SDimitry Andric 2770b57cec5SDimitry Andric if (!CanPlaceSubobjectAtOffset(Info->Class, Offset)) 2780b57cec5SDimitry Andric return false; 2790b57cec5SDimitry Andric 2800b57cec5SDimitry Andric // Traverse all non-virtual bases. 2810b57cec5SDimitry Andric const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class); 2820b57cec5SDimitry Andric for (const BaseSubobjectInfo *Base : Info->Bases) { 2830b57cec5SDimitry Andric if (Base->IsVirtual) 2840b57cec5SDimitry Andric continue; 2850b57cec5SDimitry Andric 2860b57cec5SDimitry Andric CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class); 2870b57cec5SDimitry Andric 2880b57cec5SDimitry Andric if (!CanPlaceBaseSubobjectAtOffset(Base, BaseOffset)) 2890b57cec5SDimitry Andric return false; 2900b57cec5SDimitry Andric } 2910b57cec5SDimitry Andric 2920b57cec5SDimitry Andric if (Info->PrimaryVirtualBaseInfo) { 2930b57cec5SDimitry Andric BaseSubobjectInfo *PrimaryVirtualBaseInfo = Info->PrimaryVirtualBaseInfo; 2940b57cec5SDimitry Andric 2950b57cec5SDimitry Andric if (Info == PrimaryVirtualBaseInfo->Derived) { 2960b57cec5SDimitry Andric if (!CanPlaceBaseSubobjectAtOffset(PrimaryVirtualBaseInfo, Offset)) 2970b57cec5SDimitry Andric return false; 2980b57cec5SDimitry Andric } 2990b57cec5SDimitry Andric } 3000b57cec5SDimitry Andric 3010b57cec5SDimitry Andric // Traverse all member variables. 3020b57cec5SDimitry Andric unsigned FieldNo = 0; 3030b57cec5SDimitry Andric for (CXXRecordDecl::field_iterator I = Info->Class->field_begin(), 3040b57cec5SDimitry Andric E = Info->Class->field_end(); I != E; ++I, ++FieldNo) { 3050b57cec5SDimitry Andric if (I->isBitField()) 3060b57cec5SDimitry Andric continue; 3070b57cec5SDimitry Andric 3080b57cec5SDimitry Andric CharUnits FieldOffset = Offset + getFieldOffset(Layout, FieldNo); 3090b57cec5SDimitry Andric if (!CanPlaceFieldSubobjectAtOffset(*I, FieldOffset)) 3100b57cec5SDimitry Andric return false; 3110b57cec5SDimitry Andric } 3120b57cec5SDimitry Andric 3130b57cec5SDimitry Andric return true; 3140b57cec5SDimitry Andric } 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andric void EmptySubobjectMap::UpdateEmptyBaseSubobjects(const BaseSubobjectInfo *Info, 3170b57cec5SDimitry Andric CharUnits Offset, 3180b57cec5SDimitry Andric bool PlacingEmptyBase) { 3190b57cec5SDimitry Andric if (!PlacingEmptyBase && Offset >= SizeOfLargestEmptySubobject) { 3200b57cec5SDimitry Andric // We know that the only empty subobjects that can conflict with empty 3210b57cec5SDimitry Andric // subobject of non-empty bases, are empty bases that can be placed at 3220b57cec5SDimitry Andric // offset zero. Because of this, we only need to keep track of empty base 3230b57cec5SDimitry Andric // subobjects with offsets less than the size of the largest empty 3240b57cec5SDimitry Andric // subobject for our class. 3250b57cec5SDimitry Andric return; 3260b57cec5SDimitry Andric } 3270b57cec5SDimitry Andric 3280b57cec5SDimitry Andric AddSubobjectAtOffset(Info->Class, Offset); 3290b57cec5SDimitry Andric 3300b57cec5SDimitry Andric // Traverse all non-virtual bases. 3310b57cec5SDimitry Andric const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class); 3320b57cec5SDimitry Andric for (const BaseSubobjectInfo *Base : Info->Bases) { 3330b57cec5SDimitry Andric if (Base->IsVirtual) 3340b57cec5SDimitry Andric continue; 3350b57cec5SDimitry Andric 3360b57cec5SDimitry Andric CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class); 3370b57cec5SDimitry Andric UpdateEmptyBaseSubobjects(Base, BaseOffset, PlacingEmptyBase); 3380b57cec5SDimitry Andric } 3390b57cec5SDimitry Andric 3400b57cec5SDimitry Andric if (Info->PrimaryVirtualBaseInfo) { 3410b57cec5SDimitry Andric BaseSubobjectInfo *PrimaryVirtualBaseInfo = Info->PrimaryVirtualBaseInfo; 3420b57cec5SDimitry Andric 3430b57cec5SDimitry Andric if (Info == PrimaryVirtualBaseInfo->Derived) 3440b57cec5SDimitry Andric UpdateEmptyBaseSubobjects(PrimaryVirtualBaseInfo, Offset, 3450b57cec5SDimitry Andric PlacingEmptyBase); 3460b57cec5SDimitry Andric } 3470b57cec5SDimitry Andric 3480b57cec5SDimitry Andric // Traverse all member variables. 3490b57cec5SDimitry Andric unsigned FieldNo = 0; 3500b57cec5SDimitry Andric for (CXXRecordDecl::field_iterator I = Info->Class->field_begin(), 3510b57cec5SDimitry Andric E = Info->Class->field_end(); I != E; ++I, ++FieldNo) { 3520b57cec5SDimitry Andric if (I->isBitField()) 3530b57cec5SDimitry Andric continue; 3540b57cec5SDimitry Andric 3550b57cec5SDimitry Andric CharUnits FieldOffset = Offset + getFieldOffset(Layout, FieldNo); 3560b57cec5SDimitry Andric UpdateEmptyFieldSubobjects(*I, FieldOffset, PlacingEmptyBase); 3570b57cec5SDimitry Andric } 3580b57cec5SDimitry Andric } 3590b57cec5SDimitry Andric 3600b57cec5SDimitry Andric bool EmptySubobjectMap::CanPlaceBaseAtOffset(const BaseSubobjectInfo *Info, 3610b57cec5SDimitry Andric CharUnits Offset) { 3620b57cec5SDimitry Andric // If we know this class doesn't have any empty subobjects we don't need to 3630b57cec5SDimitry Andric // bother checking. 3640b57cec5SDimitry Andric if (SizeOfLargestEmptySubobject.isZero()) 3650b57cec5SDimitry Andric return true; 3660b57cec5SDimitry Andric 3670b57cec5SDimitry Andric if (!CanPlaceBaseSubobjectAtOffset(Info, Offset)) 3680b57cec5SDimitry Andric return false; 3690b57cec5SDimitry Andric 3700b57cec5SDimitry Andric // We are able to place the base at this offset. Make sure to update the 3710b57cec5SDimitry Andric // empty base subobject map. 3720b57cec5SDimitry Andric UpdateEmptyBaseSubobjects(Info, Offset, Info->Class->isEmpty()); 3730b57cec5SDimitry Andric return true; 3740b57cec5SDimitry Andric } 3750b57cec5SDimitry Andric 3760b57cec5SDimitry Andric bool 3770b57cec5SDimitry Andric EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD, 3780b57cec5SDimitry Andric const CXXRecordDecl *Class, 3790b57cec5SDimitry Andric CharUnits Offset) const { 3800b57cec5SDimitry Andric // We don't have to keep looking past the maximum offset that's known to 3810b57cec5SDimitry Andric // contain an empty class. 3820b57cec5SDimitry Andric if (!AnyEmptySubobjectsBeyondOffset(Offset)) 3830b57cec5SDimitry Andric return true; 3840b57cec5SDimitry Andric 3850b57cec5SDimitry Andric if (!CanPlaceSubobjectAtOffset(RD, Offset)) 3860b57cec5SDimitry Andric return false; 3870b57cec5SDimitry Andric 3880b57cec5SDimitry Andric const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 3890b57cec5SDimitry Andric 3900b57cec5SDimitry Andric // Traverse all non-virtual bases. 3910b57cec5SDimitry Andric for (const CXXBaseSpecifier &Base : RD->bases()) { 3920b57cec5SDimitry Andric if (Base.isVirtual()) 3930b57cec5SDimitry Andric continue; 3940b57cec5SDimitry Andric 3950b57cec5SDimitry Andric const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl(); 3960b57cec5SDimitry Andric 3970b57cec5SDimitry Andric CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(BaseDecl); 3980b57cec5SDimitry Andric if (!CanPlaceFieldSubobjectAtOffset(BaseDecl, Class, BaseOffset)) 3990b57cec5SDimitry Andric return false; 4000b57cec5SDimitry Andric } 4010b57cec5SDimitry Andric 4020b57cec5SDimitry Andric if (RD == Class) { 4030b57cec5SDimitry Andric // This is the most derived class, traverse virtual bases as well. 4040b57cec5SDimitry Andric for (const CXXBaseSpecifier &Base : RD->vbases()) { 4050b57cec5SDimitry Andric const CXXRecordDecl *VBaseDecl = Base.getType()->getAsCXXRecordDecl(); 4060b57cec5SDimitry Andric 4070b57cec5SDimitry Andric CharUnits VBaseOffset = Offset + Layout.getVBaseClassOffset(VBaseDecl); 4080b57cec5SDimitry Andric if (!CanPlaceFieldSubobjectAtOffset(VBaseDecl, Class, VBaseOffset)) 4090b57cec5SDimitry Andric return false; 4100b57cec5SDimitry Andric } 4110b57cec5SDimitry Andric } 4120b57cec5SDimitry Andric 4130b57cec5SDimitry Andric // Traverse all member variables. 4140b57cec5SDimitry Andric unsigned FieldNo = 0; 4150b57cec5SDimitry Andric for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); 4160b57cec5SDimitry Andric I != E; ++I, ++FieldNo) { 4170b57cec5SDimitry Andric if (I->isBitField()) 4180b57cec5SDimitry Andric continue; 4190b57cec5SDimitry Andric 4200b57cec5SDimitry Andric CharUnits FieldOffset = Offset + getFieldOffset(Layout, FieldNo); 4210b57cec5SDimitry Andric 4220b57cec5SDimitry Andric if (!CanPlaceFieldSubobjectAtOffset(*I, FieldOffset)) 4230b57cec5SDimitry Andric return false; 4240b57cec5SDimitry Andric } 4250b57cec5SDimitry Andric 4260b57cec5SDimitry Andric return true; 4270b57cec5SDimitry Andric } 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric bool 4300b57cec5SDimitry Andric EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const FieldDecl *FD, 4310b57cec5SDimitry Andric CharUnits Offset) const { 4320b57cec5SDimitry Andric // We don't have to keep looking past the maximum offset that's known to 4330b57cec5SDimitry Andric // contain an empty class. 4340b57cec5SDimitry Andric if (!AnyEmptySubobjectsBeyondOffset(Offset)) 4350b57cec5SDimitry Andric return true; 4360b57cec5SDimitry Andric 4370b57cec5SDimitry Andric QualType T = FD->getType(); 4380b57cec5SDimitry Andric if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) 4390b57cec5SDimitry Andric return CanPlaceFieldSubobjectAtOffset(RD, RD, Offset); 4400b57cec5SDimitry Andric 4410b57cec5SDimitry Andric // If we have an array type we need to look at every element. 4420b57cec5SDimitry Andric if (const ConstantArrayType *AT = Context.getAsConstantArrayType(T)) { 4430b57cec5SDimitry Andric QualType ElemTy = Context.getBaseElementType(AT); 4440b57cec5SDimitry Andric const RecordType *RT = ElemTy->getAs<RecordType>(); 4450b57cec5SDimitry Andric if (!RT) 4460b57cec5SDimitry Andric return true; 4470b57cec5SDimitry Andric 4480b57cec5SDimitry Andric const CXXRecordDecl *RD = RT->getAsCXXRecordDecl(); 4490b57cec5SDimitry Andric const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 4500b57cec5SDimitry Andric 4510b57cec5SDimitry Andric uint64_t NumElements = Context.getConstantArrayElementCount(AT); 4520b57cec5SDimitry Andric CharUnits ElementOffset = Offset; 4530b57cec5SDimitry Andric for (uint64_t I = 0; I != NumElements; ++I) { 4540b57cec5SDimitry Andric // We don't have to keep looking past the maximum offset that's known to 4550b57cec5SDimitry Andric // contain an empty class. 4560b57cec5SDimitry Andric if (!AnyEmptySubobjectsBeyondOffset(ElementOffset)) 4570b57cec5SDimitry Andric return true; 4580b57cec5SDimitry Andric 4590b57cec5SDimitry Andric if (!CanPlaceFieldSubobjectAtOffset(RD, RD, ElementOffset)) 4600b57cec5SDimitry Andric return false; 4610b57cec5SDimitry Andric 4620b57cec5SDimitry Andric ElementOffset += Layout.getSize(); 4630b57cec5SDimitry Andric } 4640b57cec5SDimitry Andric } 4650b57cec5SDimitry Andric 4660b57cec5SDimitry Andric return true; 4670b57cec5SDimitry Andric } 4680b57cec5SDimitry Andric 4690b57cec5SDimitry Andric bool 4700b57cec5SDimitry Andric EmptySubobjectMap::CanPlaceFieldAtOffset(const FieldDecl *FD, 4710b57cec5SDimitry Andric CharUnits Offset) { 4720b57cec5SDimitry Andric if (!CanPlaceFieldSubobjectAtOffset(FD, Offset)) 4730b57cec5SDimitry Andric return false; 4740b57cec5SDimitry Andric 4750b57cec5SDimitry Andric // We are able to place the member variable at this offset. 4760b57cec5SDimitry Andric // Make sure to update the empty field subobject map. 4770b57cec5SDimitry Andric UpdateEmptyFieldSubobjects(FD, Offset, FD->hasAttr<NoUniqueAddressAttr>()); 4780b57cec5SDimitry Andric return true; 4790b57cec5SDimitry Andric } 4800b57cec5SDimitry Andric 4810b57cec5SDimitry Andric void EmptySubobjectMap::UpdateEmptyFieldSubobjects( 4820b57cec5SDimitry Andric const CXXRecordDecl *RD, const CXXRecordDecl *Class, CharUnits Offset, 4830b57cec5SDimitry Andric bool PlacingOverlappingField) { 4840b57cec5SDimitry Andric // We know that the only empty subobjects that can conflict with empty 4850b57cec5SDimitry Andric // field subobjects are subobjects of empty bases and potentially-overlapping 4860b57cec5SDimitry Andric // fields that can be placed at offset zero. Because of this, we only need to 4870b57cec5SDimitry Andric // keep track of empty field subobjects with offsets less than the size of 4880b57cec5SDimitry Andric // the largest empty subobject for our class. 4890b57cec5SDimitry Andric // 4900b57cec5SDimitry Andric // (Proof: we will only consider placing a subobject at offset zero or at 4910b57cec5SDimitry Andric // >= the current dsize. The only cases where the earlier subobject can be 4920b57cec5SDimitry Andric // placed beyond the end of dsize is if it's an empty base or a 4930b57cec5SDimitry Andric // potentially-overlapping field.) 4940b57cec5SDimitry Andric if (!PlacingOverlappingField && Offset >= SizeOfLargestEmptySubobject) 4950b57cec5SDimitry Andric return; 4960b57cec5SDimitry Andric 4970b57cec5SDimitry Andric AddSubobjectAtOffset(RD, Offset); 4980b57cec5SDimitry Andric 4990b57cec5SDimitry Andric const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 5000b57cec5SDimitry Andric 5010b57cec5SDimitry Andric // Traverse all non-virtual bases. 5020b57cec5SDimitry Andric for (const CXXBaseSpecifier &Base : RD->bases()) { 5030b57cec5SDimitry Andric if (Base.isVirtual()) 5040b57cec5SDimitry Andric continue; 5050b57cec5SDimitry Andric 5060b57cec5SDimitry Andric const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl(); 5070b57cec5SDimitry Andric 5080b57cec5SDimitry Andric CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(BaseDecl); 5090b57cec5SDimitry Andric UpdateEmptyFieldSubobjects(BaseDecl, Class, BaseOffset, 5100b57cec5SDimitry Andric PlacingOverlappingField); 5110b57cec5SDimitry Andric } 5120b57cec5SDimitry Andric 5130b57cec5SDimitry Andric if (RD == Class) { 5140b57cec5SDimitry Andric // This is the most derived class, traverse virtual bases as well. 5150b57cec5SDimitry Andric for (const CXXBaseSpecifier &Base : RD->vbases()) { 5160b57cec5SDimitry Andric const CXXRecordDecl *VBaseDecl = Base.getType()->getAsCXXRecordDecl(); 5170b57cec5SDimitry Andric 5180b57cec5SDimitry Andric CharUnits VBaseOffset = Offset + Layout.getVBaseClassOffset(VBaseDecl); 5190b57cec5SDimitry Andric UpdateEmptyFieldSubobjects(VBaseDecl, Class, VBaseOffset, 5200b57cec5SDimitry Andric PlacingOverlappingField); 5210b57cec5SDimitry Andric } 5220b57cec5SDimitry Andric } 5230b57cec5SDimitry Andric 5240b57cec5SDimitry Andric // Traverse all member variables. 5250b57cec5SDimitry Andric unsigned FieldNo = 0; 5260b57cec5SDimitry Andric for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); 5270b57cec5SDimitry Andric I != E; ++I, ++FieldNo) { 5280b57cec5SDimitry Andric if (I->isBitField()) 5290b57cec5SDimitry Andric continue; 5300b57cec5SDimitry Andric 5310b57cec5SDimitry Andric CharUnits FieldOffset = Offset + getFieldOffset(Layout, FieldNo); 5320b57cec5SDimitry Andric 5330b57cec5SDimitry Andric UpdateEmptyFieldSubobjects(*I, FieldOffset, PlacingOverlappingField); 5340b57cec5SDimitry Andric } 5350b57cec5SDimitry Andric } 5360b57cec5SDimitry Andric 5370b57cec5SDimitry Andric void EmptySubobjectMap::UpdateEmptyFieldSubobjects( 5380b57cec5SDimitry Andric const FieldDecl *FD, CharUnits Offset, bool PlacingOverlappingField) { 5390b57cec5SDimitry Andric QualType T = FD->getType(); 5400b57cec5SDimitry Andric if (const CXXRecordDecl *RD = T->getAsCXXRecordDecl()) { 5410b57cec5SDimitry Andric UpdateEmptyFieldSubobjects(RD, RD, Offset, PlacingOverlappingField); 5420b57cec5SDimitry Andric return; 5430b57cec5SDimitry Andric } 5440b57cec5SDimitry Andric 5450b57cec5SDimitry Andric // If we have an array type we need to update every element. 5460b57cec5SDimitry Andric if (const ConstantArrayType *AT = Context.getAsConstantArrayType(T)) { 5470b57cec5SDimitry Andric QualType ElemTy = Context.getBaseElementType(AT); 5480b57cec5SDimitry Andric const RecordType *RT = ElemTy->getAs<RecordType>(); 5490b57cec5SDimitry Andric if (!RT) 5500b57cec5SDimitry Andric return; 5510b57cec5SDimitry Andric 5520b57cec5SDimitry Andric const CXXRecordDecl *RD = RT->getAsCXXRecordDecl(); 5530b57cec5SDimitry Andric const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 5540b57cec5SDimitry Andric 5550b57cec5SDimitry Andric uint64_t NumElements = Context.getConstantArrayElementCount(AT); 5560b57cec5SDimitry Andric CharUnits ElementOffset = Offset; 5570b57cec5SDimitry Andric 5580b57cec5SDimitry Andric for (uint64_t I = 0; I != NumElements; ++I) { 5590b57cec5SDimitry Andric // We know that the only empty subobjects that can conflict with empty 5600b57cec5SDimitry Andric // field subobjects are subobjects of empty bases that can be placed at 5610b57cec5SDimitry Andric // offset zero. Because of this, we only need to keep track of empty field 5620b57cec5SDimitry Andric // subobjects with offsets less than the size of the largest empty 5630b57cec5SDimitry Andric // subobject for our class. 5640b57cec5SDimitry Andric if (!PlacingOverlappingField && 5650b57cec5SDimitry Andric ElementOffset >= SizeOfLargestEmptySubobject) 5660b57cec5SDimitry Andric return; 5670b57cec5SDimitry Andric 5680b57cec5SDimitry Andric UpdateEmptyFieldSubobjects(RD, RD, ElementOffset, 5690b57cec5SDimitry Andric PlacingOverlappingField); 5700b57cec5SDimitry Andric ElementOffset += Layout.getSize(); 5710b57cec5SDimitry Andric } 5720b57cec5SDimitry Andric } 5730b57cec5SDimitry Andric } 5740b57cec5SDimitry Andric 5750b57cec5SDimitry Andric typedef llvm::SmallPtrSet<const CXXRecordDecl*, 4> ClassSetTy; 5760b57cec5SDimitry Andric 5770b57cec5SDimitry Andric class ItaniumRecordLayoutBuilder { 5780b57cec5SDimitry Andric protected: 5790b57cec5SDimitry Andric // FIXME: Remove this and make the appropriate fields public. 5800b57cec5SDimitry Andric friend class clang::ASTContext; 5810b57cec5SDimitry Andric 5820b57cec5SDimitry Andric const ASTContext &Context; 5830b57cec5SDimitry Andric 5840b57cec5SDimitry Andric EmptySubobjectMap *EmptySubobjects; 5850b57cec5SDimitry Andric 5860b57cec5SDimitry Andric /// Size - The current size of the record layout. 5870b57cec5SDimitry Andric uint64_t Size; 5880b57cec5SDimitry Andric 5890b57cec5SDimitry Andric /// Alignment - The current alignment of the record layout. 5900b57cec5SDimitry Andric CharUnits Alignment; 5910b57cec5SDimitry Andric 592e8d8bef9SDimitry Andric /// PreferredAlignment - The preferred alignment of the record layout. 593e8d8bef9SDimitry Andric CharUnits PreferredAlignment; 594e8d8bef9SDimitry Andric 5950b57cec5SDimitry Andric /// The alignment if attribute packed is not used. 5960b57cec5SDimitry Andric CharUnits UnpackedAlignment; 5970b57cec5SDimitry Andric 5980b57cec5SDimitry Andric /// \brief The maximum of the alignments of top-level members. 5990b57cec5SDimitry Andric CharUnits UnadjustedAlignment; 6000b57cec5SDimitry Andric 6010b57cec5SDimitry Andric SmallVector<uint64_t, 16> FieldOffsets; 6020b57cec5SDimitry Andric 6030b57cec5SDimitry Andric /// Whether the external AST source has provided a layout for this 6040b57cec5SDimitry Andric /// record. 605*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 6060b57cec5SDimitry Andric unsigned UseExternalLayout : 1; 6070b57cec5SDimitry Andric 6080b57cec5SDimitry Andric /// Whether we need to infer alignment, even when we have an 6090b57cec5SDimitry Andric /// externally-provided layout. 610*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 6110b57cec5SDimitry Andric unsigned InferAlignment : 1; 6120b57cec5SDimitry Andric 6130b57cec5SDimitry Andric /// Packed - Whether the record is packed or not. 614*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 6150b57cec5SDimitry Andric unsigned Packed : 1; 6160b57cec5SDimitry Andric 617*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 6180b57cec5SDimitry Andric unsigned IsUnion : 1; 6190b57cec5SDimitry Andric 620*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 6210b57cec5SDimitry Andric unsigned IsMac68kAlign : 1; 6220b57cec5SDimitry Andric 623*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 624e8d8bef9SDimitry Andric unsigned IsNaturalAlign : 1; 625e8d8bef9SDimitry Andric 626*0fca6ea1SDimitry Andric LLVM_PREFERRED_TYPE(bool) 6270b57cec5SDimitry Andric unsigned IsMsStruct : 1; 6280b57cec5SDimitry Andric 6290b57cec5SDimitry Andric /// UnfilledBitsInLastUnit - If the last field laid out was a bitfield, 6300b57cec5SDimitry Andric /// this contains the number of bits in the last unit that can be used for 6310b57cec5SDimitry Andric /// an adjacent bitfield if necessary. The unit in question is usually 6320b57cec5SDimitry Andric /// a byte, but larger units are used if IsMsStruct. 6330b57cec5SDimitry Andric unsigned char UnfilledBitsInLastUnit; 634e8d8bef9SDimitry Andric 635e8d8bef9SDimitry Andric /// LastBitfieldStorageUnitSize - If IsMsStruct, represents the size of the 636e8d8bef9SDimitry Andric /// storage unit of the previous field if it was a bitfield. 637e8d8bef9SDimitry Andric unsigned char LastBitfieldStorageUnitSize; 6380b57cec5SDimitry Andric 6390b57cec5SDimitry Andric /// MaxFieldAlignment - The maximum allowed field alignment. This is set by 6400b57cec5SDimitry Andric /// #pragma pack. 6410b57cec5SDimitry Andric CharUnits MaxFieldAlignment; 6420b57cec5SDimitry Andric 6430b57cec5SDimitry Andric /// DataSize - The data size of the record being laid out. 6440b57cec5SDimitry Andric uint64_t DataSize; 6450b57cec5SDimitry Andric 6460b57cec5SDimitry Andric CharUnits NonVirtualSize; 6470b57cec5SDimitry Andric CharUnits NonVirtualAlignment; 648e8d8bef9SDimitry Andric CharUnits PreferredNVAlignment; 6490b57cec5SDimitry Andric 6500b57cec5SDimitry Andric /// If we've laid out a field but not included its tail padding in Size yet, 6510b57cec5SDimitry Andric /// this is the size up to the end of that field. 6520b57cec5SDimitry Andric CharUnits PaddedFieldSize; 6530b57cec5SDimitry Andric 6540b57cec5SDimitry Andric /// PrimaryBase - the primary base class (if one exists) of the class 6550b57cec5SDimitry Andric /// we're laying out. 6560b57cec5SDimitry Andric const CXXRecordDecl *PrimaryBase; 6570b57cec5SDimitry Andric 6580b57cec5SDimitry Andric /// PrimaryBaseIsVirtual - Whether the primary base of the class we're laying 6590b57cec5SDimitry Andric /// out is virtual. 6600b57cec5SDimitry Andric bool PrimaryBaseIsVirtual; 6610b57cec5SDimitry Andric 6620b57cec5SDimitry Andric /// HasOwnVFPtr - Whether the class provides its own vtable/vftbl 6630b57cec5SDimitry Andric /// pointer, as opposed to inheriting one from a primary base class. 6640b57cec5SDimitry Andric bool HasOwnVFPtr; 6650b57cec5SDimitry Andric 6660b57cec5SDimitry Andric /// the flag of field offset changing due to packed attribute. 6670b57cec5SDimitry Andric bool HasPackedField; 6680b57cec5SDimitry Andric 669e8d8bef9SDimitry Andric /// HandledFirstNonOverlappingEmptyField - An auxiliary field used for AIX. 670e8d8bef9SDimitry Andric /// When there are OverlappingEmptyFields existing in the aggregate, the 671e8d8bef9SDimitry Andric /// flag shows if the following first non-empty or empty-but-non-overlapping 672e8d8bef9SDimitry Andric /// field has been handled, if any. 673e8d8bef9SDimitry Andric bool HandledFirstNonOverlappingEmptyField; 674e8d8bef9SDimitry Andric 6750b57cec5SDimitry Andric typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy; 6760b57cec5SDimitry Andric 6770b57cec5SDimitry Andric /// Bases - base classes and their offsets in the record. 6780b57cec5SDimitry Andric BaseOffsetsMapTy Bases; 6790b57cec5SDimitry Andric 6800b57cec5SDimitry Andric // VBases - virtual base classes and their offsets in the record. 6810b57cec5SDimitry Andric ASTRecordLayout::VBaseOffsetsMapTy VBases; 6820b57cec5SDimitry Andric 6830b57cec5SDimitry Andric /// IndirectPrimaryBases - Virtual base classes, direct or indirect, that are 6840b57cec5SDimitry Andric /// primary base classes for some other direct or indirect base class. 6850b57cec5SDimitry Andric CXXIndirectPrimaryBaseSet IndirectPrimaryBases; 6860b57cec5SDimitry Andric 6870b57cec5SDimitry Andric /// FirstNearlyEmptyVBase - The first nearly empty virtual base class in 6880b57cec5SDimitry Andric /// inheritance graph order. Used for determining the primary base class. 6890b57cec5SDimitry Andric const CXXRecordDecl *FirstNearlyEmptyVBase; 6900b57cec5SDimitry Andric 6910b57cec5SDimitry Andric /// VisitedVirtualBases - A set of all the visited virtual bases, used to 6920b57cec5SDimitry Andric /// avoid visiting virtual bases more than once. 6930b57cec5SDimitry Andric llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases; 6940b57cec5SDimitry Andric 6950b57cec5SDimitry Andric /// Valid if UseExternalLayout is true. 6960b57cec5SDimitry Andric ExternalLayout External; 6970b57cec5SDimitry Andric 6980b57cec5SDimitry Andric ItaniumRecordLayoutBuilder(const ASTContext &Context, 6990b57cec5SDimitry Andric EmptySubobjectMap *EmptySubobjects) 7000b57cec5SDimitry Andric : Context(Context), EmptySubobjects(EmptySubobjects), Size(0), 701e8d8bef9SDimitry Andric Alignment(CharUnits::One()), PreferredAlignment(CharUnits::One()), 702e8d8bef9SDimitry Andric UnpackedAlignment(CharUnits::One()), 703e8d8bef9SDimitry Andric UnadjustedAlignment(CharUnits::One()), UseExternalLayout(false), 704e8d8bef9SDimitry Andric InferAlignment(false), Packed(false), IsUnion(false), 705e8d8bef9SDimitry Andric IsMac68kAlign(false), 706e8d8bef9SDimitry Andric IsNaturalAlign(!Context.getTargetInfo().getTriple().isOSAIX()), 707e8d8bef9SDimitry Andric IsMsStruct(false), UnfilledBitsInLastUnit(0), 708e8d8bef9SDimitry Andric LastBitfieldStorageUnitSize(0), MaxFieldAlignment(CharUnits::Zero()), 709e8d8bef9SDimitry Andric DataSize(0), NonVirtualSize(CharUnits::Zero()), 7100b57cec5SDimitry Andric NonVirtualAlignment(CharUnits::One()), 711e8d8bef9SDimitry Andric PreferredNVAlignment(CharUnits::One()), 7120b57cec5SDimitry Andric PaddedFieldSize(CharUnits::Zero()), PrimaryBase(nullptr), 713e8d8bef9SDimitry Andric PrimaryBaseIsVirtual(false), HasOwnVFPtr(false), HasPackedField(false), 714e8d8bef9SDimitry Andric HandledFirstNonOverlappingEmptyField(false), 715e8d8bef9SDimitry Andric FirstNearlyEmptyVBase(nullptr) {} 7160b57cec5SDimitry Andric 7170b57cec5SDimitry Andric void Layout(const RecordDecl *D); 7180b57cec5SDimitry Andric void Layout(const CXXRecordDecl *D); 7190b57cec5SDimitry Andric void Layout(const ObjCInterfaceDecl *D); 7200b57cec5SDimitry Andric 7210b57cec5SDimitry Andric void LayoutFields(const RecordDecl *D); 7220b57cec5SDimitry Andric void LayoutField(const FieldDecl *D, bool InsertExtraPadding); 723e8d8bef9SDimitry Andric void LayoutWideBitField(uint64_t FieldSize, uint64_t StorageUnitSize, 7240b57cec5SDimitry Andric bool FieldPacked, const FieldDecl *D); 7250b57cec5SDimitry Andric void LayoutBitField(const FieldDecl *D); 7260b57cec5SDimitry Andric 7270b57cec5SDimitry Andric TargetCXXABI getCXXABI() const { 7280b57cec5SDimitry Andric return Context.getTargetInfo().getCXXABI(); 7290b57cec5SDimitry Andric } 7300b57cec5SDimitry Andric 7310b57cec5SDimitry Andric /// BaseSubobjectInfoAllocator - Allocator for BaseSubobjectInfo objects. 7320b57cec5SDimitry Andric llvm::SpecificBumpPtrAllocator<BaseSubobjectInfo> BaseSubobjectInfoAllocator; 7330b57cec5SDimitry Andric 7340b57cec5SDimitry Andric typedef llvm::DenseMap<const CXXRecordDecl *, BaseSubobjectInfo *> 7350b57cec5SDimitry Andric BaseSubobjectInfoMapTy; 7360b57cec5SDimitry Andric 7370b57cec5SDimitry Andric /// VirtualBaseInfo - Map from all the (direct or indirect) virtual bases 7380b57cec5SDimitry Andric /// of the class we're laying out to their base subobject info. 7390b57cec5SDimitry Andric BaseSubobjectInfoMapTy VirtualBaseInfo; 7400b57cec5SDimitry Andric 7410b57cec5SDimitry Andric /// NonVirtualBaseInfo - Map from all the direct non-virtual bases of the 7420b57cec5SDimitry Andric /// class we're laying out to their base subobject info. 7430b57cec5SDimitry Andric BaseSubobjectInfoMapTy NonVirtualBaseInfo; 7440b57cec5SDimitry Andric 7450b57cec5SDimitry Andric /// ComputeBaseSubobjectInfo - Compute the base subobject information for the 7460b57cec5SDimitry Andric /// bases of the given class. 7470b57cec5SDimitry Andric void ComputeBaseSubobjectInfo(const CXXRecordDecl *RD); 7480b57cec5SDimitry Andric 7490b57cec5SDimitry Andric /// ComputeBaseSubobjectInfo - Compute the base subobject information for a 7500b57cec5SDimitry Andric /// single class and all of its base classes. 7510b57cec5SDimitry Andric BaseSubobjectInfo *ComputeBaseSubobjectInfo(const CXXRecordDecl *RD, 7520b57cec5SDimitry Andric bool IsVirtual, 7530b57cec5SDimitry Andric BaseSubobjectInfo *Derived); 7540b57cec5SDimitry Andric 7550b57cec5SDimitry Andric /// DeterminePrimaryBase - Determine the primary base of the given class. 7560b57cec5SDimitry Andric void DeterminePrimaryBase(const CXXRecordDecl *RD); 7570b57cec5SDimitry Andric 7580b57cec5SDimitry Andric void SelectPrimaryVBase(const CXXRecordDecl *RD); 7590b57cec5SDimitry Andric 7600b57cec5SDimitry Andric void EnsureVTablePointerAlignment(CharUnits UnpackedBaseAlign); 7610b57cec5SDimitry Andric 7620b57cec5SDimitry Andric /// LayoutNonVirtualBases - Determines the primary base class (if any) and 7630b57cec5SDimitry Andric /// lays it out. Will then proceed to lay out all non-virtual base clasess. 7640b57cec5SDimitry Andric void LayoutNonVirtualBases(const CXXRecordDecl *RD); 7650b57cec5SDimitry Andric 7660b57cec5SDimitry Andric /// LayoutNonVirtualBase - Lays out a single non-virtual base. 7670b57cec5SDimitry Andric void LayoutNonVirtualBase(const BaseSubobjectInfo *Base); 7680b57cec5SDimitry Andric 7690b57cec5SDimitry Andric void AddPrimaryVirtualBaseOffsets(const BaseSubobjectInfo *Info, 7700b57cec5SDimitry Andric CharUnits Offset); 7710b57cec5SDimitry Andric 7720b57cec5SDimitry Andric /// LayoutVirtualBases - Lays out all the virtual bases. 7730b57cec5SDimitry Andric void LayoutVirtualBases(const CXXRecordDecl *RD, 7740b57cec5SDimitry Andric const CXXRecordDecl *MostDerivedClass); 7750b57cec5SDimitry Andric 7760b57cec5SDimitry Andric /// LayoutVirtualBase - Lays out a single virtual base. 7770b57cec5SDimitry Andric void LayoutVirtualBase(const BaseSubobjectInfo *Base); 7780b57cec5SDimitry Andric 7790b57cec5SDimitry Andric /// LayoutBase - Will lay out a base and return the offset where it was 7800b57cec5SDimitry Andric /// placed, in chars. 7810b57cec5SDimitry Andric CharUnits LayoutBase(const BaseSubobjectInfo *Base); 7820b57cec5SDimitry Andric 7830b57cec5SDimitry Andric /// InitializeLayout - Initialize record layout for the given record decl. 7840b57cec5SDimitry Andric void InitializeLayout(const Decl *D); 7850b57cec5SDimitry Andric 7860b57cec5SDimitry Andric /// FinishLayout - Finalize record layout. Adjust record size based on the 7870b57cec5SDimitry Andric /// alignment. 7880b57cec5SDimitry Andric void FinishLayout(const NamedDecl *D); 7890b57cec5SDimitry Andric 790e8d8bef9SDimitry Andric void UpdateAlignment(CharUnits NewAlignment, CharUnits UnpackedNewAlignment, 791e8d8bef9SDimitry Andric CharUnits PreferredAlignment); 792e8d8bef9SDimitry Andric void UpdateAlignment(CharUnits NewAlignment, CharUnits UnpackedNewAlignment) { 793e8d8bef9SDimitry Andric UpdateAlignment(NewAlignment, UnpackedNewAlignment, NewAlignment); 794e8d8bef9SDimitry Andric } 7950b57cec5SDimitry Andric void UpdateAlignment(CharUnits NewAlignment) { 796e8d8bef9SDimitry Andric UpdateAlignment(NewAlignment, NewAlignment, NewAlignment); 7970b57cec5SDimitry Andric } 7980b57cec5SDimitry Andric 7990b57cec5SDimitry Andric /// Retrieve the externally-supplied field offset for the given 8000b57cec5SDimitry Andric /// field. 8010b57cec5SDimitry Andric /// 8020b57cec5SDimitry Andric /// \param Field The field whose offset is being queried. 8030b57cec5SDimitry Andric /// \param ComputedOffset The offset that we've computed for this field. 8040b57cec5SDimitry Andric uint64_t updateExternalFieldOffset(const FieldDecl *Field, 8050b57cec5SDimitry Andric uint64_t ComputedOffset); 8060b57cec5SDimitry Andric 8070b57cec5SDimitry Andric void CheckFieldPadding(uint64_t Offset, uint64_t UnpaddedOffset, 8080b57cec5SDimitry Andric uint64_t UnpackedOffset, unsigned UnpackedAlign, 8090b57cec5SDimitry Andric bool isPacked, const FieldDecl *D); 8100b57cec5SDimitry Andric 8110b57cec5SDimitry Andric DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID); 8120b57cec5SDimitry Andric 8130b57cec5SDimitry Andric CharUnits getSize() const { 8140b57cec5SDimitry Andric assert(Size % Context.getCharWidth() == 0); 8150b57cec5SDimitry Andric return Context.toCharUnitsFromBits(Size); 8160b57cec5SDimitry Andric } 8170b57cec5SDimitry Andric uint64_t getSizeInBits() const { return Size; } 8180b57cec5SDimitry Andric 8190b57cec5SDimitry Andric void setSize(CharUnits NewSize) { Size = Context.toBits(NewSize); } 8200b57cec5SDimitry Andric void setSize(uint64_t NewSize) { Size = NewSize; } 8210b57cec5SDimitry Andric 8220b57cec5SDimitry Andric CharUnits getAligment() const { return Alignment; } 8230b57cec5SDimitry Andric 8240b57cec5SDimitry Andric CharUnits getDataSize() const { 8250b57cec5SDimitry Andric assert(DataSize % Context.getCharWidth() == 0); 8260b57cec5SDimitry Andric return Context.toCharUnitsFromBits(DataSize); 8270b57cec5SDimitry Andric } 8280b57cec5SDimitry Andric uint64_t getDataSizeInBits() const { return DataSize; } 8290b57cec5SDimitry Andric 8300b57cec5SDimitry Andric void setDataSize(CharUnits NewSize) { DataSize = Context.toBits(NewSize); } 8310b57cec5SDimitry Andric void setDataSize(uint64_t NewSize) { DataSize = NewSize; } 8320b57cec5SDimitry Andric 8330b57cec5SDimitry Andric ItaniumRecordLayoutBuilder(const ItaniumRecordLayoutBuilder &) = delete; 8340b57cec5SDimitry Andric void operator=(const ItaniumRecordLayoutBuilder &) = delete; 8350b57cec5SDimitry Andric }; 8360b57cec5SDimitry Andric } // end anonymous namespace 8370b57cec5SDimitry Andric 8380b57cec5SDimitry Andric void ItaniumRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD) { 8390b57cec5SDimitry Andric for (const auto &I : RD->bases()) { 8400b57cec5SDimitry Andric assert(!I.getType()->isDependentType() && 8410b57cec5SDimitry Andric "Cannot layout class with dependent bases."); 8420b57cec5SDimitry Andric 8430b57cec5SDimitry Andric const CXXRecordDecl *Base = I.getType()->getAsCXXRecordDecl(); 8440b57cec5SDimitry Andric 8450b57cec5SDimitry Andric // Check if this is a nearly empty virtual base. 8460b57cec5SDimitry Andric if (I.isVirtual() && Context.isNearlyEmpty(Base)) { 8470b57cec5SDimitry Andric // If it's not an indirect primary base, then we've found our primary 8480b57cec5SDimitry Andric // base. 8490b57cec5SDimitry Andric if (!IndirectPrimaryBases.count(Base)) { 8500b57cec5SDimitry Andric PrimaryBase = Base; 8510b57cec5SDimitry Andric PrimaryBaseIsVirtual = true; 8520b57cec5SDimitry Andric return; 8530b57cec5SDimitry Andric } 8540b57cec5SDimitry Andric 8550b57cec5SDimitry Andric // Is this the first nearly empty virtual base? 8560b57cec5SDimitry Andric if (!FirstNearlyEmptyVBase) 8570b57cec5SDimitry Andric FirstNearlyEmptyVBase = Base; 8580b57cec5SDimitry Andric } 8590b57cec5SDimitry Andric 8600b57cec5SDimitry Andric SelectPrimaryVBase(Base); 8610b57cec5SDimitry Andric if (PrimaryBase) 8620b57cec5SDimitry Andric return; 8630b57cec5SDimitry Andric } 8640b57cec5SDimitry Andric } 8650b57cec5SDimitry Andric 8660b57cec5SDimitry Andric /// DeterminePrimaryBase - Determine the primary base of the given class. 8670b57cec5SDimitry Andric void ItaniumRecordLayoutBuilder::DeterminePrimaryBase(const CXXRecordDecl *RD) { 8680b57cec5SDimitry Andric // If the class isn't dynamic, it won't have a primary base. 8690b57cec5SDimitry Andric if (!RD->isDynamicClass()) 8700b57cec5SDimitry Andric return; 8710b57cec5SDimitry Andric 8720b57cec5SDimitry Andric // Compute all the primary virtual bases for all of our direct and 8730b57cec5SDimitry Andric // indirect bases, and record all their primary virtual base classes. 8740b57cec5SDimitry Andric RD->getIndirectPrimaryBases(IndirectPrimaryBases); 8750b57cec5SDimitry Andric 8760b57cec5SDimitry Andric // If the record has a dynamic base class, attempt to choose a primary base 8770b57cec5SDimitry Andric // class. It is the first (in direct base class order) non-virtual dynamic 8780b57cec5SDimitry Andric // base class, if one exists. 8790b57cec5SDimitry Andric for (const auto &I : RD->bases()) { 8800b57cec5SDimitry Andric // Ignore virtual bases. 8810b57cec5SDimitry Andric if (I.isVirtual()) 8820b57cec5SDimitry Andric continue; 8830b57cec5SDimitry Andric 8840b57cec5SDimitry Andric const CXXRecordDecl *Base = I.getType()->getAsCXXRecordDecl(); 8850b57cec5SDimitry Andric 8860b57cec5SDimitry Andric if (Base->isDynamicClass()) { 8870b57cec5SDimitry Andric // We found it. 8880b57cec5SDimitry Andric PrimaryBase = Base; 8890b57cec5SDimitry Andric PrimaryBaseIsVirtual = false; 8900b57cec5SDimitry Andric return; 8910b57cec5SDimitry Andric } 8920b57cec5SDimitry Andric } 8930b57cec5SDimitry Andric 8940b57cec5SDimitry Andric // Under the Itanium ABI, if there is no non-virtual primary base class, 8950b57cec5SDimitry Andric // try to compute the primary virtual base. The primary virtual base is 8960b57cec5SDimitry Andric // the first nearly empty virtual base that is not an indirect primary 8970b57cec5SDimitry Andric // virtual base class, if one exists. 8980b57cec5SDimitry Andric if (RD->getNumVBases() != 0) { 8990b57cec5SDimitry Andric SelectPrimaryVBase(RD); 9000b57cec5SDimitry Andric if (PrimaryBase) 9010b57cec5SDimitry Andric return; 9020b57cec5SDimitry Andric } 9030b57cec5SDimitry Andric 9040b57cec5SDimitry Andric // Otherwise, it is the first indirect primary base class, if one exists. 9050b57cec5SDimitry Andric if (FirstNearlyEmptyVBase) { 9060b57cec5SDimitry Andric PrimaryBase = FirstNearlyEmptyVBase; 9070b57cec5SDimitry Andric PrimaryBaseIsVirtual = true; 9080b57cec5SDimitry Andric return; 9090b57cec5SDimitry Andric } 9100b57cec5SDimitry Andric 9110b57cec5SDimitry Andric assert(!PrimaryBase && "Should not get here with a primary base!"); 9120b57cec5SDimitry Andric } 9130b57cec5SDimitry Andric 9140b57cec5SDimitry Andric BaseSubobjectInfo *ItaniumRecordLayoutBuilder::ComputeBaseSubobjectInfo( 9150b57cec5SDimitry Andric const CXXRecordDecl *RD, bool IsVirtual, BaseSubobjectInfo *Derived) { 9160b57cec5SDimitry Andric BaseSubobjectInfo *Info; 9170b57cec5SDimitry Andric 9180b57cec5SDimitry Andric if (IsVirtual) { 9190b57cec5SDimitry Andric // Check if we already have info about this virtual base. 9200b57cec5SDimitry Andric BaseSubobjectInfo *&InfoSlot = VirtualBaseInfo[RD]; 9210b57cec5SDimitry Andric if (InfoSlot) { 9220b57cec5SDimitry Andric assert(InfoSlot->Class == RD && "Wrong class for virtual base info!"); 9230b57cec5SDimitry Andric return InfoSlot; 9240b57cec5SDimitry Andric } 9250b57cec5SDimitry Andric 9260b57cec5SDimitry Andric // We don't, create it. 9270b57cec5SDimitry Andric InfoSlot = new (BaseSubobjectInfoAllocator.Allocate()) BaseSubobjectInfo; 9280b57cec5SDimitry Andric Info = InfoSlot; 9290b57cec5SDimitry Andric } else { 9300b57cec5SDimitry Andric Info = new (BaseSubobjectInfoAllocator.Allocate()) BaseSubobjectInfo; 9310b57cec5SDimitry Andric } 9320b57cec5SDimitry Andric 9330b57cec5SDimitry Andric Info->Class = RD; 9340b57cec5SDimitry Andric Info->IsVirtual = IsVirtual; 9350b57cec5SDimitry Andric Info->Derived = nullptr; 9360b57cec5SDimitry Andric Info->PrimaryVirtualBaseInfo = nullptr; 9370b57cec5SDimitry Andric 9380b57cec5SDimitry Andric const CXXRecordDecl *PrimaryVirtualBase = nullptr; 9390b57cec5SDimitry Andric BaseSubobjectInfo *PrimaryVirtualBaseInfo = nullptr; 9400b57cec5SDimitry Andric 9410b57cec5SDimitry Andric // Check if this base has a primary virtual base. 9420b57cec5SDimitry Andric if (RD->getNumVBases()) { 9430b57cec5SDimitry Andric const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 9440b57cec5SDimitry Andric if (Layout.isPrimaryBaseVirtual()) { 9450b57cec5SDimitry Andric // This base does have a primary virtual base. 9460b57cec5SDimitry Andric PrimaryVirtualBase = Layout.getPrimaryBase(); 9470b57cec5SDimitry Andric assert(PrimaryVirtualBase && "Didn't have a primary virtual base!"); 9480b57cec5SDimitry Andric 9490b57cec5SDimitry Andric // Now check if we have base subobject info about this primary base. 9500b57cec5SDimitry Andric PrimaryVirtualBaseInfo = VirtualBaseInfo.lookup(PrimaryVirtualBase); 9510b57cec5SDimitry Andric 9520b57cec5SDimitry Andric if (PrimaryVirtualBaseInfo) { 9530b57cec5SDimitry Andric if (PrimaryVirtualBaseInfo->Derived) { 9540b57cec5SDimitry Andric // We did have info about this primary base, and it turns out that it 9550b57cec5SDimitry Andric // has already been claimed as a primary virtual base for another 9560b57cec5SDimitry Andric // base. 9570b57cec5SDimitry Andric PrimaryVirtualBase = nullptr; 9580b57cec5SDimitry Andric } else { 9590b57cec5SDimitry Andric // We can claim this base as our primary base. 9600b57cec5SDimitry Andric Info->PrimaryVirtualBaseInfo = PrimaryVirtualBaseInfo; 9610b57cec5SDimitry Andric PrimaryVirtualBaseInfo->Derived = Info; 9620b57cec5SDimitry Andric } 9630b57cec5SDimitry Andric } 9640b57cec5SDimitry Andric } 9650b57cec5SDimitry Andric } 9660b57cec5SDimitry Andric 9670b57cec5SDimitry Andric // Now go through all direct bases. 9680b57cec5SDimitry Andric for (const auto &I : RD->bases()) { 9690b57cec5SDimitry Andric bool IsVirtual = I.isVirtual(); 9700b57cec5SDimitry Andric 9710b57cec5SDimitry Andric const CXXRecordDecl *BaseDecl = I.getType()->getAsCXXRecordDecl(); 9720b57cec5SDimitry Andric 9730b57cec5SDimitry Andric Info->Bases.push_back(ComputeBaseSubobjectInfo(BaseDecl, IsVirtual, Info)); 9740b57cec5SDimitry Andric } 9750b57cec5SDimitry Andric 9760b57cec5SDimitry Andric if (PrimaryVirtualBase && !PrimaryVirtualBaseInfo) { 9770b57cec5SDimitry Andric // Traversing the bases must have created the base info for our primary 9780b57cec5SDimitry Andric // virtual base. 9790b57cec5SDimitry Andric PrimaryVirtualBaseInfo = VirtualBaseInfo.lookup(PrimaryVirtualBase); 9800b57cec5SDimitry Andric assert(PrimaryVirtualBaseInfo && 9810b57cec5SDimitry Andric "Did not create a primary virtual base!"); 9820b57cec5SDimitry Andric 9830b57cec5SDimitry Andric // Claim the primary virtual base as our primary virtual base. 9840b57cec5SDimitry Andric Info->PrimaryVirtualBaseInfo = PrimaryVirtualBaseInfo; 9850b57cec5SDimitry Andric PrimaryVirtualBaseInfo->Derived = Info; 9860b57cec5SDimitry Andric } 9870b57cec5SDimitry Andric 9880b57cec5SDimitry Andric return Info; 9890b57cec5SDimitry Andric } 9900b57cec5SDimitry Andric 9910b57cec5SDimitry Andric void ItaniumRecordLayoutBuilder::ComputeBaseSubobjectInfo( 9920b57cec5SDimitry Andric const CXXRecordDecl *RD) { 9930b57cec5SDimitry Andric for (const auto &I : RD->bases()) { 9940b57cec5SDimitry Andric bool IsVirtual = I.isVirtual(); 9950b57cec5SDimitry Andric 9960b57cec5SDimitry Andric const CXXRecordDecl *BaseDecl = I.getType()->getAsCXXRecordDecl(); 9970b57cec5SDimitry Andric 9980b57cec5SDimitry Andric // Compute the base subobject info for this base. 9990b57cec5SDimitry Andric BaseSubobjectInfo *Info = ComputeBaseSubobjectInfo(BaseDecl, IsVirtual, 10000b57cec5SDimitry Andric nullptr); 10010b57cec5SDimitry Andric 10020b57cec5SDimitry Andric if (IsVirtual) { 10030b57cec5SDimitry Andric // ComputeBaseInfo has already added this base for us. 10040b57cec5SDimitry Andric assert(VirtualBaseInfo.count(BaseDecl) && 10050b57cec5SDimitry Andric "Did not add virtual base!"); 10060b57cec5SDimitry Andric } else { 10070b57cec5SDimitry Andric // Add the base info to the map of non-virtual bases. 10080b57cec5SDimitry Andric assert(!NonVirtualBaseInfo.count(BaseDecl) && 10090b57cec5SDimitry Andric "Non-virtual base already exists!"); 10100b57cec5SDimitry Andric NonVirtualBaseInfo.insert(std::make_pair(BaseDecl, Info)); 10110b57cec5SDimitry Andric } 10120b57cec5SDimitry Andric } 10130b57cec5SDimitry Andric } 10140b57cec5SDimitry Andric 10150b57cec5SDimitry Andric void ItaniumRecordLayoutBuilder::EnsureVTablePointerAlignment( 10160b57cec5SDimitry Andric CharUnits UnpackedBaseAlign) { 10170b57cec5SDimitry Andric CharUnits BaseAlign = Packed ? CharUnits::One() : UnpackedBaseAlign; 10180b57cec5SDimitry Andric 10190b57cec5SDimitry Andric // The maximum field alignment overrides base align. 10200b57cec5SDimitry Andric if (!MaxFieldAlignment.isZero()) { 10210b57cec5SDimitry Andric BaseAlign = std::min(BaseAlign, MaxFieldAlignment); 10220b57cec5SDimitry Andric UnpackedBaseAlign = std::min(UnpackedBaseAlign, MaxFieldAlignment); 10230b57cec5SDimitry Andric } 10240b57cec5SDimitry Andric 10250b57cec5SDimitry Andric // Round up the current record size to pointer alignment. 10260b57cec5SDimitry Andric setSize(getSize().alignTo(BaseAlign)); 10270b57cec5SDimitry Andric 10280b57cec5SDimitry Andric // Update the alignment. 1029e8d8bef9SDimitry Andric UpdateAlignment(BaseAlign, UnpackedBaseAlign, BaseAlign); 10300b57cec5SDimitry Andric } 10310b57cec5SDimitry Andric 10320b57cec5SDimitry Andric void ItaniumRecordLayoutBuilder::LayoutNonVirtualBases( 10330b57cec5SDimitry Andric const CXXRecordDecl *RD) { 10340b57cec5SDimitry Andric // Then, determine the primary base class. 10350b57cec5SDimitry Andric DeterminePrimaryBase(RD); 10360b57cec5SDimitry Andric 10370b57cec5SDimitry Andric // Compute base subobject info. 10380b57cec5SDimitry Andric ComputeBaseSubobjectInfo(RD); 10390b57cec5SDimitry Andric 10400b57cec5SDimitry Andric // If we have a primary base class, lay it out. 10410b57cec5SDimitry Andric if (PrimaryBase) { 10420b57cec5SDimitry Andric if (PrimaryBaseIsVirtual) { 10430b57cec5SDimitry Andric // If the primary virtual base was a primary virtual base of some other 10440b57cec5SDimitry Andric // base class we'll have to steal it. 10450b57cec5SDimitry Andric BaseSubobjectInfo *PrimaryBaseInfo = VirtualBaseInfo.lookup(PrimaryBase); 10460b57cec5SDimitry Andric PrimaryBaseInfo->Derived = nullptr; 10470b57cec5SDimitry Andric 10480b57cec5SDimitry Andric // We have a virtual primary base, insert it as an indirect primary base. 10490b57cec5SDimitry Andric IndirectPrimaryBases.insert(PrimaryBase); 10500b57cec5SDimitry Andric 10510b57cec5SDimitry Andric assert(!VisitedVirtualBases.count(PrimaryBase) && 10520b57cec5SDimitry Andric "vbase already visited!"); 10530b57cec5SDimitry Andric VisitedVirtualBases.insert(PrimaryBase); 10540b57cec5SDimitry Andric 10550b57cec5SDimitry Andric LayoutVirtualBase(PrimaryBaseInfo); 10560b57cec5SDimitry Andric } else { 10570b57cec5SDimitry Andric BaseSubobjectInfo *PrimaryBaseInfo = 10580b57cec5SDimitry Andric NonVirtualBaseInfo.lookup(PrimaryBase); 10590b57cec5SDimitry Andric assert(PrimaryBaseInfo && 10600b57cec5SDimitry Andric "Did not find base info for non-virtual primary base!"); 10610b57cec5SDimitry Andric 10620b57cec5SDimitry Andric LayoutNonVirtualBase(PrimaryBaseInfo); 10630b57cec5SDimitry Andric } 10640b57cec5SDimitry Andric 10650b57cec5SDimitry Andric // If this class needs a vtable/vf-table and didn't get one from a 10660b57cec5SDimitry Andric // primary base, add it in now. 10670b57cec5SDimitry Andric } else if (RD->isDynamicClass()) { 10680b57cec5SDimitry Andric assert(DataSize == 0 && "Vtable pointer must be at offset zero!"); 1069bdd1243dSDimitry Andric CharUnits PtrWidth = Context.toCharUnitsFromBits( 1070bdd1243dSDimitry Andric Context.getTargetInfo().getPointerWidth(LangAS::Default)); 1071bdd1243dSDimitry Andric CharUnits PtrAlign = Context.toCharUnitsFromBits( 1072bdd1243dSDimitry Andric Context.getTargetInfo().getPointerAlign(LangAS::Default)); 10730b57cec5SDimitry Andric EnsureVTablePointerAlignment(PtrAlign); 10740b57cec5SDimitry Andric HasOwnVFPtr = true; 1075e8d8bef9SDimitry Andric 1076e8d8bef9SDimitry Andric assert(!IsUnion && "Unions cannot be dynamic classes."); 1077e8d8bef9SDimitry Andric HandledFirstNonOverlappingEmptyField = true; 1078e8d8bef9SDimitry Andric 10790b57cec5SDimitry Andric setSize(getSize() + PtrWidth); 10800b57cec5SDimitry Andric setDataSize(getSize()); 10810b57cec5SDimitry Andric } 10820b57cec5SDimitry Andric 10830b57cec5SDimitry Andric // Now lay out the non-virtual bases. 10840b57cec5SDimitry Andric for (const auto &I : RD->bases()) { 10850b57cec5SDimitry Andric 10860b57cec5SDimitry Andric // Ignore virtual bases. 10870b57cec5SDimitry Andric if (I.isVirtual()) 10880b57cec5SDimitry Andric continue; 10890b57cec5SDimitry Andric 10900b57cec5SDimitry Andric const CXXRecordDecl *BaseDecl = I.getType()->getAsCXXRecordDecl(); 10910b57cec5SDimitry Andric 10920b57cec5SDimitry Andric // Skip the primary base, because we've already laid it out. The 10930b57cec5SDimitry Andric // !PrimaryBaseIsVirtual check is required because we might have a 10940b57cec5SDimitry Andric // non-virtual base of the same type as a primary virtual base. 10950b57cec5SDimitry Andric if (BaseDecl == PrimaryBase && !PrimaryBaseIsVirtual) 10960b57cec5SDimitry Andric continue; 10970b57cec5SDimitry Andric 10980b57cec5SDimitry Andric // Lay out the base. 10990b57cec5SDimitry Andric BaseSubobjectInfo *BaseInfo = NonVirtualBaseInfo.lookup(BaseDecl); 11000b57cec5SDimitry Andric assert(BaseInfo && "Did not find base info for non-virtual base!"); 11010b57cec5SDimitry Andric 11020b57cec5SDimitry Andric LayoutNonVirtualBase(BaseInfo); 11030b57cec5SDimitry Andric } 11040b57cec5SDimitry Andric } 11050b57cec5SDimitry Andric 11060b57cec5SDimitry Andric void ItaniumRecordLayoutBuilder::LayoutNonVirtualBase( 11070b57cec5SDimitry Andric const BaseSubobjectInfo *Base) { 11080b57cec5SDimitry Andric // Layout the base. 11090b57cec5SDimitry Andric CharUnits Offset = LayoutBase(Base); 11100b57cec5SDimitry Andric 11110b57cec5SDimitry Andric // Add its base class offset. 11120b57cec5SDimitry Andric assert(!Bases.count(Base->Class) && "base offset already exists!"); 11130b57cec5SDimitry Andric Bases.insert(std::make_pair(Base->Class, Offset)); 11140b57cec5SDimitry Andric 11150b57cec5SDimitry Andric AddPrimaryVirtualBaseOffsets(Base, Offset); 11160b57cec5SDimitry Andric } 11170b57cec5SDimitry Andric 11180b57cec5SDimitry Andric void ItaniumRecordLayoutBuilder::AddPrimaryVirtualBaseOffsets( 11190b57cec5SDimitry Andric const BaseSubobjectInfo *Info, CharUnits Offset) { 11200b57cec5SDimitry Andric // This base isn't interesting, it has no virtual bases. 11210b57cec5SDimitry Andric if (!Info->Class->getNumVBases()) 11220b57cec5SDimitry Andric return; 11230b57cec5SDimitry Andric 11240b57cec5SDimitry Andric // First, check if we have a virtual primary base to add offsets for. 11250b57cec5SDimitry Andric if (Info->PrimaryVirtualBaseInfo) { 11260b57cec5SDimitry Andric assert(Info->PrimaryVirtualBaseInfo->IsVirtual && 11270b57cec5SDimitry Andric "Primary virtual base is not virtual!"); 11280b57cec5SDimitry Andric if (Info->PrimaryVirtualBaseInfo->Derived == Info) { 11290b57cec5SDimitry Andric // Add the offset. 11300b57cec5SDimitry Andric assert(!VBases.count(Info->PrimaryVirtualBaseInfo->Class) && 11310b57cec5SDimitry Andric "primary vbase offset already exists!"); 11320b57cec5SDimitry Andric VBases.insert(std::make_pair(Info->PrimaryVirtualBaseInfo->Class, 11330b57cec5SDimitry Andric ASTRecordLayout::VBaseInfo(Offset, false))); 11340b57cec5SDimitry Andric 11350b57cec5SDimitry Andric // Traverse the primary virtual base. 11360b57cec5SDimitry Andric AddPrimaryVirtualBaseOffsets(Info->PrimaryVirtualBaseInfo, Offset); 11370b57cec5SDimitry Andric } 11380b57cec5SDimitry Andric } 11390b57cec5SDimitry Andric 11400b57cec5SDimitry Andric // Now go through all direct non-virtual bases. 11410b57cec5SDimitry Andric const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class); 11420b57cec5SDimitry Andric for (const BaseSubobjectInfo *Base : Info->Bases) { 11430b57cec5SDimitry Andric if (Base->IsVirtual) 11440b57cec5SDimitry Andric continue; 11450b57cec5SDimitry Andric 11460b57cec5SDimitry Andric CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class); 11470b57cec5SDimitry Andric AddPrimaryVirtualBaseOffsets(Base, BaseOffset); 11480b57cec5SDimitry Andric } 11490b57cec5SDimitry Andric } 11500b57cec5SDimitry Andric 11510b57cec5SDimitry Andric void ItaniumRecordLayoutBuilder::LayoutVirtualBases( 11520b57cec5SDimitry Andric const CXXRecordDecl *RD, const CXXRecordDecl *MostDerivedClass) { 11530b57cec5SDimitry Andric const CXXRecordDecl *PrimaryBase; 11540b57cec5SDimitry Andric bool PrimaryBaseIsVirtual; 11550b57cec5SDimitry Andric 11560b57cec5SDimitry Andric if (MostDerivedClass == RD) { 11570b57cec5SDimitry Andric PrimaryBase = this->PrimaryBase; 11580b57cec5SDimitry Andric PrimaryBaseIsVirtual = this->PrimaryBaseIsVirtual; 11590b57cec5SDimitry Andric } else { 11600b57cec5SDimitry Andric const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 11610b57cec5SDimitry Andric PrimaryBase = Layout.getPrimaryBase(); 11620b57cec5SDimitry Andric PrimaryBaseIsVirtual = Layout.isPrimaryBaseVirtual(); 11630b57cec5SDimitry Andric } 11640b57cec5SDimitry Andric 11650b57cec5SDimitry Andric for (const CXXBaseSpecifier &Base : RD->bases()) { 11660b57cec5SDimitry Andric assert(!Base.getType()->isDependentType() && 11670b57cec5SDimitry Andric "Cannot layout class with dependent bases."); 11680b57cec5SDimitry Andric 11690b57cec5SDimitry Andric const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl(); 11700b57cec5SDimitry Andric 11710b57cec5SDimitry Andric if (Base.isVirtual()) { 11720b57cec5SDimitry Andric if (PrimaryBase != BaseDecl || !PrimaryBaseIsVirtual) { 11730b57cec5SDimitry Andric bool IndirectPrimaryBase = IndirectPrimaryBases.count(BaseDecl); 11740b57cec5SDimitry Andric 11750b57cec5SDimitry Andric // Only lay out the virtual base if it's not an indirect primary base. 11760b57cec5SDimitry Andric if (!IndirectPrimaryBase) { 11770b57cec5SDimitry Andric // Only visit virtual bases once. 11780b57cec5SDimitry Andric if (!VisitedVirtualBases.insert(BaseDecl).second) 11790b57cec5SDimitry Andric continue; 11800b57cec5SDimitry Andric 11810b57cec5SDimitry Andric const BaseSubobjectInfo *BaseInfo = VirtualBaseInfo.lookup(BaseDecl); 11820b57cec5SDimitry Andric assert(BaseInfo && "Did not find virtual base info!"); 11830b57cec5SDimitry Andric LayoutVirtualBase(BaseInfo); 11840b57cec5SDimitry Andric } 11850b57cec5SDimitry Andric } 11860b57cec5SDimitry Andric } 11870b57cec5SDimitry Andric 11880b57cec5SDimitry Andric if (!BaseDecl->getNumVBases()) { 11890b57cec5SDimitry Andric // This base isn't interesting since it doesn't have any virtual bases. 11900b57cec5SDimitry Andric continue; 11910b57cec5SDimitry Andric } 11920b57cec5SDimitry Andric 11930b57cec5SDimitry Andric LayoutVirtualBases(BaseDecl, MostDerivedClass); 11940b57cec5SDimitry Andric } 11950b57cec5SDimitry Andric } 11960b57cec5SDimitry Andric 11970b57cec5SDimitry Andric void ItaniumRecordLayoutBuilder::LayoutVirtualBase( 11980b57cec5SDimitry Andric const BaseSubobjectInfo *Base) { 11990b57cec5SDimitry Andric assert(!Base->Derived && "Trying to lay out a primary virtual base!"); 12000b57cec5SDimitry Andric 12010b57cec5SDimitry Andric // Layout the base. 12020b57cec5SDimitry Andric CharUnits Offset = LayoutBase(Base); 12030b57cec5SDimitry Andric 12040b57cec5SDimitry Andric // Add its base class offset. 12050b57cec5SDimitry Andric assert(!VBases.count(Base->Class) && "vbase offset already exists!"); 12060b57cec5SDimitry Andric VBases.insert(std::make_pair(Base->Class, 12070b57cec5SDimitry Andric ASTRecordLayout::VBaseInfo(Offset, false))); 12080b57cec5SDimitry Andric 12090b57cec5SDimitry Andric AddPrimaryVirtualBaseOffsets(Base, Offset); 12100b57cec5SDimitry Andric } 12110b57cec5SDimitry Andric 12120b57cec5SDimitry Andric CharUnits 12130b57cec5SDimitry Andric ItaniumRecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) { 1214e8d8bef9SDimitry Andric assert(!IsUnion && "Unions cannot have base classes."); 1215e8d8bef9SDimitry Andric 12160b57cec5SDimitry Andric const ASTRecordLayout &Layout = Context.getASTRecordLayout(Base->Class); 12170b57cec5SDimitry Andric CharUnits Offset; 12180b57cec5SDimitry Andric 12190b57cec5SDimitry Andric // Query the external layout to see if it provides an offset. 12200b57cec5SDimitry Andric bool HasExternalLayout = false; 12210b57cec5SDimitry Andric if (UseExternalLayout) { 12220b57cec5SDimitry Andric if (Base->IsVirtual) 12230b57cec5SDimitry Andric HasExternalLayout = External.getExternalVBaseOffset(Base->Class, Offset); 12245ffd83dbSDimitry Andric else 12255ffd83dbSDimitry Andric HasExternalLayout = External.getExternalNVBaseOffset(Base->Class, Offset); 12260b57cec5SDimitry Andric } 12270b57cec5SDimitry Andric 1228e8d8bef9SDimitry Andric auto getBaseOrPreferredBaseAlignFromUnpacked = [&](CharUnits UnpackedAlign) { 12290b57cec5SDimitry Andric // Clang <= 6 incorrectly applied the 'packed' attribute to base classes. 12300b57cec5SDimitry Andric // Per GCC's documentation, it only applies to non-static data members. 1231e8d8bef9SDimitry Andric return (Packed && ((Context.getLangOpts().getClangABICompat() <= 12320b57cec5SDimitry Andric LangOptions::ClangABI::Ver6) || 123381ad6265SDimitry Andric Context.getTargetInfo().getTriple().isPS() || 1234e8d8bef9SDimitry Andric Context.getTargetInfo().getTriple().isOSAIX())) 12350b57cec5SDimitry Andric ? CharUnits::One() 1236e8d8bef9SDimitry Andric : UnpackedAlign; 1237e8d8bef9SDimitry Andric }; 12380b57cec5SDimitry Andric 1239e8d8bef9SDimitry Andric CharUnits UnpackedBaseAlign = Layout.getNonVirtualAlignment(); 1240e8d8bef9SDimitry Andric CharUnits UnpackedPreferredBaseAlign = Layout.getPreferredNVAlignment(); 1241e8d8bef9SDimitry Andric CharUnits BaseAlign = 1242e8d8bef9SDimitry Andric getBaseOrPreferredBaseAlignFromUnpacked(UnpackedBaseAlign); 1243e8d8bef9SDimitry Andric CharUnits PreferredBaseAlign = 1244e8d8bef9SDimitry Andric getBaseOrPreferredBaseAlignFromUnpacked(UnpackedPreferredBaseAlign); 1245e8d8bef9SDimitry Andric 1246e8d8bef9SDimitry Andric const bool DefaultsToAIXPowerAlignment = 1247e8d8bef9SDimitry Andric Context.getTargetInfo().defaultsToAIXPowerAlignment(); 1248e8d8bef9SDimitry Andric if (DefaultsToAIXPowerAlignment) { 1249e8d8bef9SDimitry Andric // AIX `power` alignment does not apply the preferred alignment for 1250e8d8bef9SDimitry Andric // non-union classes if the source of the alignment (the current base in 1251e8d8bef9SDimitry Andric // this context) follows introduction of the first subobject with 1252e8d8bef9SDimitry Andric // exclusively allocated space or zero-extent array. 1253e8d8bef9SDimitry Andric if (!Base->Class->isEmpty() && !HandledFirstNonOverlappingEmptyField) { 1254e8d8bef9SDimitry Andric // By handling a base class that is not empty, we're handling the 1255e8d8bef9SDimitry Andric // "first (inherited) member". 1256e8d8bef9SDimitry Andric HandledFirstNonOverlappingEmptyField = true; 1257e8d8bef9SDimitry Andric } else if (!IsNaturalAlign) { 1258e8d8bef9SDimitry Andric UnpackedPreferredBaseAlign = UnpackedBaseAlign; 1259e8d8bef9SDimitry Andric PreferredBaseAlign = BaseAlign; 1260e8d8bef9SDimitry Andric } 1261e8d8bef9SDimitry Andric } 1262e8d8bef9SDimitry Andric 1263e8d8bef9SDimitry Andric CharUnits UnpackedAlignTo = !DefaultsToAIXPowerAlignment 1264e8d8bef9SDimitry Andric ? UnpackedBaseAlign 1265e8d8bef9SDimitry Andric : UnpackedPreferredBaseAlign; 12660b57cec5SDimitry Andric // If we have an empty base class, try to place it at offset 0. 12670b57cec5SDimitry Andric if (Base->Class->isEmpty() && 12680b57cec5SDimitry Andric (!HasExternalLayout || Offset == CharUnits::Zero()) && 12690b57cec5SDimitry Andric EmptySubobjects->CanPlaceBaseAtOffset(Base, CharUnits::Zero())) { 12700b57cec5SDimitry Andric setSize(std::max(getSize(), Layout.getSize())); 127181ad6265SDimitry Andric // On PS4/PS5, don't update the alignment, to preserve compatibility. 127281ad6265SDimitry Andric if (!Context.getTargetInfo().getTriple().isPS()) 1273e8d8bef9SDimitry Andric UpdateAlignment(BaseAlign, UnpackedAlignTo, PreferredBaseAlign); 12740b57cec5SDimitry Andric 12750b57cec5SDimitry Andric return CharUnits::Zero(); 12760b57cec5SDimitry Andric } 12770b57cec5SDimitry Andric 1278e8d8bef9SDimitry Andric // The maximum field alignment overrides the base align/(AIX-only) preferred 1279e8d8bef9SDimitry Andric // base align. 12800b57cec5SDimitry Andric if (!MaxFieldAlignment.isZero()) { 12810b57cec5SDimitry Andric BaseAlign = std::min(BaseAlign, MaxFieldAlignment); 1282e8d8bef9SDimitry Andric PreferredBaseAlign = std::min(PreferredBaseAlign, MaxFieldAlignment); 1283e8d8bef9SDimitry Andric UnpackedAlignTo = std::min(UnpackedAlignTo, MaxFieldAlignment); 12840b57cec5SDimitry Andric } 12850b57cec5SDimitry Andric 1286e8d8bef9SDimitry Andric CharUnits AlignTo = 1287e8d8bef9SDimitry Andric !DefaultsToAIXPowerAlignment ? BaseAlign : PreferredBaseAlign; 12880b57cec5SDimitry Andric if (!HasExternalLayout) { 12890b57cec5SDimitry Andric // Round up the current record size to the base's alignment boundary. 1290e8d8bef9SDimitry Andric Offset = getDataSize().alignTo(AlignTo); 12910b57cec5SDimitry Andric 12920b57cec5SDimitry Andric // Try to place the base. 12930b57cec5SDimitry Andric while (!EmptySubobjects->CanPlaceBaseAtOffset(Base, Offset)) 1294e8d8bef9SDimitry Andric Offset += AlignTo; 12950b57cec5SDimitry Andric } else { 12960b57cec5SDimitry Andric bool Allowed = EmptySubobjects->CanPlaceBaseAtOffset(Base, Offset); 12970b57cec5SDimitry Andric (void)Allowed; 12980b57cec5SDimitry Andric assert(Allowed && "Base subobject externally placed at overlapping offset"); 12990b57cec5SDimitry Andric 1300e8d8bef9SDimitry Andric if (InferAlignment && Offset < getDataSize().alignTo(AlignTo)) { 13010b57cec5SDimitry Andric // The externally-supplied base offset is before the base offset we 13020b57cec5SDimitry Andric // computed. Assume that the structure is packed. 13030b57cec5SDimitry Andric Alignment = CharUnits::One(); 13040b57cec5SDimitry Andric InferAlignment = false; 13050b57cec5SDimitry Andric } 13060b57cec5SDimitry Andric } 13070b57cec5SDimitry Andric 13080b57cec5SDimitry Andric if (!Base->Class->isEmpty()) { 13090b57cec5SDimitry Andric // Update the data size. 13100b57cec5SDimitry Andric setDataSize(Offset + Layout.getNonVirtualSize()); 13110b57cec5SDimitry Andric 13120b57cec5SDimitry Andric setSize(std::max(getSize(), getDataSize())); 13130b57cec5SDimitry Andric } else 13140b57cec5SDimitry Andric setSize(std::max(getSize(), Offset + Layout.getSize())); 13150b57cec5SDimitry Andric 13160b57cec5SDimitry Andric // Remember max struct/class alignment. 1317e8d8bef9SDimitry Andric UpdateAlignment(BaseAlign, UnpackedAlignTo, PreferredBaseAlign); 13180b57cec5SDimitry Andric 13190b57cec5SDimitry Andric return Offset; 13200b57cec5SDimitry Andric } 13210b57cec5SDimitry Andric 13220b57cec5SDimitry Andric void ItaniumRecordLayoutBuilder::InitializeLayout(const Decl *D) { 13230b57cec5SDimitry Andric if (const RecordDecl *RD = dyn_cast<RecordDecl>(D)) { 13240b57cec5SDimitry Andric IsUnion = RD->isUnion(); 13250b57cec5SDimitry Andric IsMsStruct = RD->isMsStruct(Context); 13260b57cec5SDimitry Andric } 13270b57cec5SDimitry Andric 13280b57cec5SDimitry Andric Packed = D->hasAttr<PackedAttr>(); 13290b57cec5SDimitry Andric 13300b57cec5SDimitry Andric // Honor the default struct packing maximum alignment flag. 13310b57cec5SDimitry Andric if (unsigned DefaultMaxFieldAlignment = Context.getLangOpts().PackStruct) { 13320b57cec5SDimitry Andric MaxFieldAlignment = CharUnits::fromQuantity(DefaultMaxFieldAlignment); 13330b57cec5SDimitry Andric } 13340b57cec5SDimitry Andric 13350b57cec5SDimitry Andric // mac68k alignment supersedes maximum field alignment and attribute aligned, 13360b57cec5SDimitry Andric // and forces all structures to have 2-byte alignment. The IBM docs on it 13370b57cec5SDimitry Andric // allude to additional (more complicated) semantics, especially with regard 13380b57cec5SDimitry Andric // to bit-fields, but gcc appears not to follow that. 13390b57cec5SDimitry Andric if (D->hasAttr<AlignMac68kAttr>()) { 1340e8d8bef9SDimitry Andric assert( 1341e8d8bef9SDimitry Andric !D->hasAttr<AlignNaturalAttr>() && 1342e8d8bef9SDimitry Andric "Having both mac68k and natural alignment on a decl is not allowed."); 13430b57cec5SDimitry Andric IsMac68kAlign = true; 13440b57cec5SDimitry Andric MaxFieldAlignment = CharUnits::fromQuantity(2); 13450b57cec5SDimitry Andric Alignment = CharUnits::fromQuantity(2); 1346e8d8bef9SDimitry Andric PreferredAlignment = CharUnits::fromQuantity(2); 13470b57cec5SDimitry Andric } else { 1348e8d8bef9SDimitry Andric if (D->hasAttr<AlignNaturalAttr>()) 1349e8d8bef9SDimitry Andric IsNaturalAlign = true; 1350e8d8bef9SDimitry Andric 13510b57cec5SDimitry Andric if (const MaxFieldAlignmentAttr *MFAA = D->getAttr<MaxFieldAlignmentAttr>()) 13520b57cec5SDimitry Andric MaxFieldAlignment = Context.toCharUnitsFromBits(MFAA->getAlignment()); 13530b57cec5SDimitry Andric 13540b57cec5SDimitry Andric if (unsigned MaxAlign = D->getMaxAlignment()) 13550b57cec5SDimitry Andric UpdateAlignment(Context.toCharUnitsFromBits(MaxAlign)); 13560b57cec5SDimitry Andric } 13570b57cec5SDimitry Andric 1358e8d8bef9SDimitry Andric HandledFirstNonOverlappingEmptyField = 1359e8d8bef9SDimitry Andric !Context.getTargetInfo().defaultsToAIXPowerAlignment() || IsNaturalAlign; 1360e8d8bef9SDimitry Andric 13610b57cec5SDimitry Andric // If there is an external AST source, ask it for the various offsets. 13620b57cec5SDimitry Andric if (const RecordDecl *RD = dyn_cast<RecordDecl>(D)) 13630b57cec5SDimitry Andric if (ExternalASTSource *Source = Context.getExternalSource()) { 13640b57cec5SDimitry Andric UseExternalLayout = Source->layoutRecordType( 13650b57cec5SDimitry Andric RD, External.Size, External.Align, External.FieldOffsets, 13660b57cec5SDimitry Andric External.BaseOffsets, External.VirtualBaseOffsets); 13670b57cec5SDimitry Andric 13680b57cec5SDimitry Andric // Update based on external alignment. 13690b57cec5SDimitry Andric if (UseExternalLayout) { 13700b57cec5SDimitry Andric if (External.Align > 0) { 13710b57cec5SDimitry Andric Alignment = Context.toCharUnitsFromBits(External.Align); 1372e8d8bef9SDimitry Andric PreferredAlignment = Context.toCharUnitsFromBits(External.Align); 13730b57cec5SDimitry Andric } else { 13740b57cec5SDimitry Andric // The external source didn't have alignment information; infer it. 13750b57cec5SDimitry Andric InferAlignment = true; 13760b57cec5SDimitry Andric } 13770b57cec5SDimitry Andric } 13780b57cec5SDimitry Andric } 13790b57cec5SDimitry Andric } 13800b57cec5SDimitry Andric 13810b57cec5SDimitry Andric void ItaniumRecordLayoutBuilder::Layout(const RecordDecl *D) { 13820b57cec5SDimitry Andric InitializeLayout(D); 13830b57cec5SDimitry Andric LayoutFields(D); 13840b57cec5SDimitry Andric 13850b57cec5SDimitry Andric // Finally, round the size of the total struct up to the alignment of the 13860b57cec5SDimitry Andric // struct itself. 13870b57cec5SDimitry Andric FinishLayout(D); 13880b57cec5SDimitry Andric } 13890b57cec5SDimitry Andric 13900b57cec5SDimitry Andric void ItaniumRecordLayoutBuilder::Layout(const CXXRecordDecl *RD) { 13910b57cec5SDimitry Andric InitializeLayout(RD); 13920b57cec5SDimitry Andric 13930b57cec5SDimitry Andric // Lay out the vtable and the non-virtual bases. 13940b57cec5SDimitry Andric LayoutNonVirtualBases(RD); 13950b57cec5SDimitry Andric 13960b57cec5SDimitry Andric LayoutFields(RD); 13970b57cec5SDimitry Andric 13980b57cec5SDimitry Andric NonVirtualSize = Context.toCharUnitsFromBits( 13990b57cec5SDimitry Andric llvm::alignTo(getSizeInBits(), Context.getTargetInfo().getCharAlign())); 14000b57cec5SDimitry Andric NonVirtualAlignment = Alignment; 1401e8d8bef9SDimitry Andric PreferredNVAlignment = PreferredAlignment; 14020b57cec5SDimitry Andric 14030b57cec5SDimitry Andric // Lay out the virtual bases and add the primary virtual base offsets. 14040b57cec5SDimitry Andric LayoutVirtualBases(RD, RD); 14050b57cec5SDimitry Andric 14060b57cec5SDimitry Andric // Finally, round the size of the total struct up to the alignment 14070b57cec5SDimitry Andric // of the struct itself. 14080b57cec5SDimitry Andric FinishLayout(RD); 14090b57cec5SDimitry Andric 14100b57cec5SDimitry Andric #ifndef NDEBUG 14110b57cec5SDimitry Andric // Check that we have base offsets for all bases. 14120b57cec5SDimitry Andric for (const CXXBaseSpecifier &Base : RD->bases()) { 14130b57cec5SDimitry Andric if (Base.isVirtual()) 14140b57cec5SDimitry Andric continue; 14150b57cec5SDimitry Andric 14160b57cec5SDimitry Andric const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl(); 14170b57cec5SDimitry Andric 14180b57cec5SDimitry Andric assert(Bases.count(BaseDecl) && "Did not find base offset!"); 14190b57cec5SDimitry Andric } 14200b57cec5SDimitry Andric 14210b57cec5SDimitry Andric // And all virtual bases. 14220b57cec5SDimitry Andric for (const CXXBaseSpecifier &Base : RD->vbases()) { 14230b57cec5SDimitry Andric const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl(); 14240b57cec5SDimitry Andric 14250b57cec5SDimitry Andric assert(VBases.count(BaseDecl) && "Did not find base offset!"); 14260b57cec5SDimitry Andric } 14270b57cec5SDimitry Andric #endif 14280b57cec5SDimitry Andric } 14290b57cec5SDimitry Andric 14300b57cec5SDimitry Andric void ItaniumRecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D) { 14310b57cec5SDimitry Andric if (ObjCInterfaceDecl *SD = D->getSuperClass()) { 14320b57cec5SDimitry Andric const ASTRecordLayout &SL = Context.getASTObjCInterfaceLayout(SD); 14330b57cec5SDimitry Andric 14340b57cec5SDimitry Andric UpdateAlignment(SL.getAlignment()); 14350b57cec5SDimitry Andric 14360b57cec5SDimitry Andric // We start laying out ivars not at the end of the superclass 14370b57cec5SDimitry Andric // structure, but at the next byte following the last field. 14380b57cec5SDimitry Andric setDataSize(SL.getDataSize()); 14390b57cec5SDimitry Andric setSize(getDataSize()); 14400b57cec5SDimitry Andric } 14410b57cec5SDimitry Andric 14420b57cec5SDimitry Andric InitializeLayout(D); 14430b57cec5SDimitry Andric // Layout each ivar sequentially. 14440b57cec5SDimitry Andric for (const ObjCIvarDecl *IVD = D->all_declared_ivar_begin(); IVD; 14450b57cec5SDimitry Andric IVD = IVD->getNextIvar()) 14460b57cec5SDimitry Andric LayoutField(IVD, false); 14470b57cec5SDimitry Andric 14480b57cec5SDimitry Andric // Finally, round the size of the total struct up to the alignment of the 14490b57cec5SDimitry Andric // struct itself. 14500b57cec5SDimitry Andric FinishLayout(D); 14510b57cec5SDimitry Andric } 14520b57cec5SDimitry Andric 14530b57cec5SDimitry Andric void ItaniumRecordLayoutBuilder::LayoutFields(const RecordDecl *D) { 14540b57cec5SDimitry Andric // Layout each field, for now, just sequentially, respecting alignment. In 14550b57cec5SDimitry Andric // the future, this will need to be tweakable by targets. 14560b57cec5SDimitry Andric bool InsertExtraPadding = D->mayInsertExtraPadding(/*EmitRemark=*/true); 14570b57cec5SDimitry Andric bool HasFlexibleArrayMember = D->hasFlexibleArrayMember(); 14580b57cec5SDimitry Andric for (auto I = D->field_begin(), End = D->field_end(); I != End; ++I) { 14590b57cec5SDimitry Andric auto Next(I); 14600b57cec5SDimitry Andric ++Next; 14610b57cec5SDimitry Andric LayoutField(*I, 14620b57cec5SDimitry Andric InsertExtraPadding && (Next != End || !HasFlexibleArrayMember)); 14630b57cec5SDimitry Andric } 14640b57cec5SDimitry Andric } 14650b57cec5SDimitry Andric 14660b57cec5SDimitry Andric // Rounds the specified size to have it a multiple of the char size. 14670b57cec5SDimitry Andric static uint64_t 14680b57cec5SDimitry Andric roundUpSizeToCharAlignment(uint64_t Size, 14690b57cec5SDimitry Andric const ASTContext &Context) { 14700b57cec5SDimitry Andric uint64_t CharAlignment = Context.getTargetInfo().getCharAlign(); 14710b57cec5SDimitry Andric return llvm::alignTo(Size, CharAlignment); 14720b57cec5SDimitry Andric } 14730b57cec5SDimitry Andric 14740b57cec5SDimitry Andric void ItaniumRecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize, 1475e8d8bef9SDimitry Andric uint64_t StorageUnitSize, 14760b57cec5SDimitry Andric bool FieldPacked, 14770b57cec5SDimitry Andric const FieldDecl *D) { 14780b57cec5SDimitry Andric assert(Context.getLangOpts().CPlusPlus && 14790b57cec5SDimitry Andric "Can only have wide bit-fields in C++!"); 14800b57cec5SDimitry Andric 14810b57cec5SDimitry Andric // Itanium C++ ABI 2.4: 14820b57cec5SDimitry Andric // If sizeof(T)*8 < n, let T' be the largest integral POD type with 14830b57cec5SDimitry Andric // sizeof(T')*8 <= n. 14840b57cec5SDimitry Andric 14850b57cec5SDimitry Andric QualType IntegralPODTypes[] = { 14860b57cec5SDimitry Andric Context.UnsignedCharTy, Context.UnsignedShortTy, Context.UnsignedIntTy, 14870b57cec5SDimitry Andric Context.UnsignedLongTy, Context.UnsignedLongLongTy 14880b57cec5SDimitry Andric }; 14890b57cec5SDimitry Andric 14900b57cec5SDimitry Andric QualType Type; 14910b57cec5SDimitry Andric for (const QualType &QT : IntegralPODTypes) { 14920b57cec5SDimitry Andric uint64_t Size = Context.getTypeSize(QT); 14930b57cec5SDimitry Andric 14940b57cec5SDimitry Andric if (Size > FieldSize) 14950b57cec5SDimitry Andric break; 14960b57cec5SDimitry Andric 14970b57cec5SDimitry Andric Type = QT; 14980b57cec5SDimitry Andric } 14990b57cec5SDimitry Andric assert(!Type.isNull() && "Did not find a type!"); 15000b57cec5SDimitry Andric 15010b57cec5SDimitry Andric CharUnits TypeAlign = Context.getTypeAlignInChars(Type); 15020b57cec5SDimitry Andric 15030b57cec5SDimitry Andric // We're not going to use any of the unfilled bits in the last byte. 15040b57cec5SDimitry Andric UnfilledBitsInLastUnit = 0; 1505e8d8bef9SDimitry Andric LastBitfieldStorageUnitSize = 0; 15060b57cec5SDimitry Andric 15070b57cec5SDimitry Andric uint64_t FieldOffset; 15080b57cec5SDimitry Andric uint64_t UnpaddedFieldOffset = getDataSizeInBits() - UnfilledBitsInLastUnit; 15090b57cec5SDimitry Andric 15100b57cec5SDimitry Andric if (IsUnion) { 15110b57cec5SDimitry Andric uint64_t RoundedFieldSize = roundUpSizeToCharAlignment(FieldSize, 15120b57cec5SDimitry Andric Context); 15130b57cec5SDimitry Andric setDataSize(std::max(getDataSizeInBits(), RoundedFieldSize)); 15140b57cec5SDimitry Andric FieldOffset = 0; 15150b57cec5SDimitry Andric } else { 15160b57cec5SDimitry Andric // The bitfield is allocated starting at the next offset aligned 15170b57cec5SDimitry Andric // appropriately for T', with length n bits. 15180b57cec5SDimitry Andric FieldOffset = llvm::alignTo(getDataSizeInBits(), Context.toBits(TypeAlign)); 15190b57cec5SDimitry Andric 15200b57cec5SDimitry Andric uint64_t NewSizeInBits = FieldOffset + FieldSize; 15210b57cec5SDimitry Andric 15220b57cec5SDimitry Andric setDataSize( 15230b57cec5SDimitry Andric llvm::alignTo(NewSizeInBits, Context.getTargetInfo().getCharAlign())); 15240b57cec5SDimitry Andric UnfilledBitsInLastUnit = getDataSizeInBits() - NewSizeInBits; 15250b57cec5SDimitry Andric } 15260b57cec5SDimitry Andric 15270b57cec5SDimitry Andric // Place this field at the current location. 15280b57cec5SDimitry Andric FieldOffsets.push_back(FieldOffset); 15290b57cec5SDimitry Andric 15300b57cec5SDimitry Andric CheckFieldPadding(FieldOffset, UnpaddedFieldOffset, FieldOffset, 15310b57cec5SDimitry Andric Context.toBits(TypeAlign), FieldPacked, D); 15320b57cec5SDimitry Andric 15330b57cec5SDimitry Andric // Update the size. 15340b57cec5SDimitry Andric setSize(std::max(getSizeInBits(), getDataSizeInBits())); 15350b57cec5SDimitry Andric 15360b57cec5SDimitry Andric // Remember max struct/class alignment. 15370b57cec5SDimitry Andric UpdateAlignment(TypeAlign); 15380b57cec5SDimitry Andric } 15390b57cec5SDimitry Andric 1540fe6060f1SDimitry Andric static bool isAIXLayout(const ASTContext &Context) { 1541fe6060f1SDimitry Andric return Context.getTargetInfo().getTriple().getOS() == llvm::Triple::AIX; 1542fe6060f1SDimitry Andric } 1543fe6060f1SDimitry Andric 15440b57cec5SDimitry Andric void ItaniumRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { 15450b57cec5SDimitry Andric bool FieldPacked = Packed || D->hasAttr<PackedAttr>(); 15460b57cec5SDimitry Andric uint64_t FieldSize = D->getBitWidthValue(Context); 15470b57cec5SDimitry Andric TypeInfo FieldInfo = Context.getTypeInfo(D->getType()); 1548e8d8bef9SDimitry Andric uint64_t StorageUnitSize = FieldInfo.Width; 15490b57cec5SDimitry Andric unsigned FieldAlign = FieldInfo.Align; 1550349cc55cSDimitry Andric bool AlignIsRequired = FieldInfo.isAlignRequired(); 15510b57cec5SDimitry Andric 15520b57cec5SDimitry Andric // UnfilledBitsInLastUnit is the difference between the end of the 15530b57cec5SDimitry Andric // last allocated bitfield (i.e. the first bit offset available for 15540b57cec5SDimitry Andric // bitfields) and the end of the current data size in bits (i.e. the 15550b57cec5SDimitry Andric // first bit offset available for non-bitfields). The current data 15560b57cec5SDimitry Andric // size in bits is always a multiple of the char size; additionally, 15570b57cec5SDimitry Andric // for ms_struct records it's also a multiple of the 1558e8d8bef9SDimitry Andric // LastBitfieldStorageUnitSize (if set). 15590b57cec5SDimitry Andric 15600b57cec5SDimitry Andric // The struct-layout algorithm is dictated by the platform ABI, 15610b57cec5SDimitry Andric // which in principle could use almost any rules it likes. In 15620b57cec5SDimitry Andric // practice, UNIXy targets tend to inherit the algorithm described 15630b57cec5SDimitry Andric // in the System V generic ABI. The basic bitfield layout rule in 15640b57cec5SDimitry Andric // System V is to place bitfields at the next available bit offset 15650b57cec5SDimitry Andric // where the entire bitfield would fit in an aligned storage unit of 15660b57cec5SDimitry Andric // the declared type; it's okay if an earlier or later non-bitfield 15670b57cec5SDimitry Andric // is allocated in the same storage unit. However, some targets 15680b57cec5SDimitry Andric // (those that !useBitFieldTypeAlignment(), e.g. ARM APCS) don't 15690b57cec5SDimitry Andric // require this storage unit to be aligned, and therefore always put 15700b57cec5SDimitry Andric // the bitfield at the next available bit offset. 15710b57cec5SDimitry Andric 15720b57cec5SDimitry Andric // ms_struct basically requests a complete replacement of the 15730b57cec5SDimitry Andric // platform ABI's struct-layout algorithm, with the high-level goal 15740b57cec5SDimitry Andric // of duplicating MSVC's layout. For non-bitfields, this follows 15750b57cec5SDimitry Andric // the standard algorithm. The basic bitfield layout rule is to 15760b57cec5SDimitry Andric // allocate an entire unit of the bitfield's declared type 15770b57cec5SDimitry Andric // (e.g. 'unsigned long'), then parcel it up among successive 15780b57cec5SDimitry Andric // bitfields whose declared types have the same size, making a new 15790b57cec5SDimitry Andric // unit as soon as the last can no longer store the whole value. 15800b57cec5SDimitry Andric // Since it completely replaces the platform ABI's algorithm, 15810b57cec5SDimitry Andric // settings like !useBitFieldTypeAlignment() do not apply. 15820b57cec5SDimitry Andric 15830b57cec5SDimitry Andric // A zero-width bitfield forces the use of a new storage unit for 15840b57cec5SDimitry Andric // later bitfields. In general, this occurs by rounding up the 15850b57cec5SDimitry Andric // current size of the struct as if the algorithm were about to 15860b57cec5SDimitry Andric // place a non-bitfield of the field's formal type. Usually this 15870b57cec5SDimitry Andric // does not change the alignment of the struct itself, but it does 15880b57cec5SDimitry Andric // on some targets (those that useZeroLengthBitfieldAlignment(), 15890b57cec5SDimitry Andric // e.g. ARM). In ms_struct layout, zero-width bitfields are 15900b57cec5SDimitry Andric // ignored unless they follow a non-zero-width bitfield. 15910b57cec5SDimitry Andric 15920b57cec5SDimitry Andric // A field alignment restriction (e.g. from #pragma pack) or 15930b57cec5SDimitry Andric // specification (e.g. from __attribute__((aligned))) changes the 15940b57cec5SDimitry Andric // formal alignment of the field. For System V, this alters the 15950b57cec5SDimitry Andric // required alignment of the notional storage unit that must contain 15960b57cec5SDimitry Andric // the bitfield. For ms_struct, this only affects the placement of 15970b57cec5SDimitry Andric // new storage units. In both cases, the effect of #pragma pack is 15980b57cec5SDimitry Andric // ignored on zero-width bitfields. 15990b57cec5SDimitry Andric 16000b57cec5SDimitry Andric // On System V, a packed field (e.g. from #pragma pack or 16010b57cec5SDimitry Andric // __attribute__((packed))) always uses the next available bit 16020b57cec5SDimitry Andric // offset. 16030b57cec5SDimitry Andric 16040b57cec5SDimitry Andric // In an ms_struct struct, the alignment of a fundamental type is 16050b57cec5SDimitry Andric // always equal to its size. This is necessary in order to mimic 16060b57cec5SDimitry Andric // the i386 alignment rules on targets which might not fully align 16070b57cec5SDimitry Andric // all types (e.g. Darwin PPC32, where alignof(long long) == 4). 16080b57cec5SDimitry Andric 16090b57cec5SDimitry Andric // First, some simple bookkeeping to perform for ms_struct structs. 16100b57cec5SDimitry Andric if (IsMsStruct) { 16110b57cec5SDimitry Andric // The field alignment for integer types is always the size. 1612e8d8bef9SDimitry Andric FieldAlign = StorageUnitSize; 16130b57cec5SDimitry Andric 16140b57cec5SDimitry Andric // If the previous field was not a bitfield, or was a bitfield 16150b57cec5SDimitry Andric // with a different storage unit size, or if this field doesn't fit into 16160b57cec5SDimitry Andric // the current storage unit, we're done with that storage unit. 1617e8d8bef9SDimitry Andric if (LastBitfieldStorageUnitSize != StorageUnitSize || 16180b57cec5SDimitry Andric UnfilledBitsInLastUnit < FieldSize) { 16190b57cec5SDimitry Andric // Also, ignore zero-length bitfields after non-bitfields. 1620e8d8bef9SDimitry Andric if (!LastBitfieldStorageUnitSize && !FieldSize) 16210b57cec5SDimitry Andric FieldAlign = 1; 16220b57cec5SDimitry Andric 16230b57cec5SDimitry Andric UnfilledBitsInLastUnit = 0; 1624e8d8bef9SDimitry Andric LastBitfieldStorageUnitSize = 0; 16250b57cec5SDimitry Andric } 16260b57cec5SDimitry Andric } 16270b57cec5SDimitry Andric 1628fe6060f1SDimitry Andric if (isAIXLayout(Context)) { 1629fe6060f1SDimitry Andric if (StorageUnitSize < Context.getTypeSize(Context.UnsignedIntTy)) { 1630fe6060f1SDimitry Andric // On AIX, [bool, char, short] bitfields have the same alignment 1631fe6060f1SDimitry Andric // as [unsigned]. 1632fe6060f1SDimitry Andric StorageUnitSize = Context.getTypeSize(Context.UnsignedIntTy); 1633fe6060f1SDimitry Andric } else if (StorageUnitSize > Context.getTypeSize(Context.UnsignedIntTy) && 1634fe6060f1SDimitry Andric Context.getTargetInfo().getTriple().isArch32Bit() && 1635fe6060f1SDimitry Andric FieldSize <= 32) { 1636fe6060f1SDimitry Andric // Under 32-bit compile mode, the bitcontainer is 32 bits if a single 1637fe6060f1SDimitry Andric // long long bitfield has length no greater than 32 bits. 1638fe6060f1SDimitry Andric StorageUnitSize = 32; 1639fe6060f1SDimitry Andric 1640fe6060f1SDimitry Andric if (!AlignIsRequired) 1641fe6060f1SDimitry Andric FieldAlign = 32; 1642fe6060f1SDimitry Andric } 1643fe6060f1SDimitry Andric 1644fe6060f1SDimitry Andric if (FieldAlign < StorageUnitSize) { 1645fe6060f1SDimitry Andric // The bitfield alignment should always be greater than or equal to 1646fe6060f1SDimitry Andric // bitcontainer size. 1647fe6060f1SDimitry Andric FieldAlign = StorageUnitSize; 1648fe6060f1SDimitry Andric } 1649fe6060f1SDimitry Andric } 1650fe6060f1SDimitry Andric 16510b57cec5SDimitry Andric // If the field is wider than its declared type, it follows 1652fe6060f1SDimitry Andric // different rules in all cases, except on AIX. 1653fe6060f1SDimitry Andric // On AIX, wide bitfield follows the same rules as normal bitfield. 1654fe6060f1SDimitry Andric if (FieldSize > StorageUnitSize && !isAIXLayout(Context)) { 1655e8d8bef9SDimitry Andric LayoutWideBitField(FieldSize, StorageUnitSize, FieldPacked, D); 16560b57cec5SDimitry Andric return; 16570b57cec5SDimitry Andric } 16580b57cec5SDimitry Andric 16590b57cec5SDimitry Andric // Compute the next available bit offset. 16600b57cec5SDimitry Andric uint64_t FieldOffset = 16610b57cec5SDimitry Andric IsUnion ? 0 : (getDataSizeInBits() - UnfilledBitsInLastUnit); 16620b57cec5SDimitry Andric 16630b57cec5SDimitry Andric // Handle targets that don't honor bitfield type alignment. 16640b57cec5SDimitry Andric if (!IsMsStruct && !Context.getTargetInfo().useBitFieldTypeAlignment()) { 16650b57cec5SDimitry Andric // Some such targets do honor it on zero-width bitfields. 16660b57cec5SDimitry Andric if (FieldSize == 0 && 16670b57cec5SDimitry Andric Context.getTargetInfo().useZeroLengthBitfieldAlignment()) { 1668fe6060f1SDimitry Andric // Some targets don't honor leading zero-width bitfield. 1669fe6060f1SDimitry Andric if (!IsUnion && FieldOffset == 0 && 1670fe6060f1SDimitry Andric !Context.getTargetInfo().useLeadingZeroLengthBitfield()) 1671fe6060f1SDimitry Andric FieldAlign = 1; 1672fe6060f1SDimitry Andric else { 16730b57cec5SDimitry Andric // The alignment to round up to is the max of the field's natural 16740b57cec5SDimitry Andric // alignment and a target-specific fixed value (sometimes zero). 16750b57cec5SDimitry Andric unsigned ZeroLengthBitfieldBoundary = 16760b57cec5SDimitry Andric Context.getTargetInfo().getZeroLengthBitfieldBoundary(); 16770b57cec5SDimitry Andric FieldAlign = std::max(FieldAlign, ZeroLengthBitfieldBoundary); 1678fe6060f1SDimitry Andric } 16790b57cec5SDimitry Andric // If that doesn't apply, just ignore the field alignment. 16800b57cec5SDimitry Andric } else { 16810b57cec5SDimitry Andric FieldAlign = 1; 16820b57cec5SDimitry Andric } 16830b57cec5SDimitry Andric } 16840b57cec5SDimitry Andric 16850b57cec5SDimitry Andric // Remember the alignment we would have used if the field were not packed. 16860b57cec5SDimitry Andric unsigned UnpackedFieldAlign = FieldAlign; 16870b57cec5SDimitry Andric 16880b57cec5SDimitry Andric // Ignore the field alignment if the field is packed unless it has zero-size. 16890b57cec5SDimitry Andric if (!IsMsStruct && FieldPacked && FieldSize != 0) 16900b57cec5SDimitry Andric FieldAlign = 1; 16910b57cec5SDimitry Andric 16920b57cec5SDimitry Andric // But, if there's an 'aligned' attribute on the field, honor that. 16930b57cec5SDimitry Andric unsigned ExplicitFieldAlign = D->getMaxAlignment(); 16940b57cec5SDimitry Andric if (ExplicitFieldAlign) { 16950b57cec5SDimitry Andric FieldAlign = std::max(FieldAlign, ExplicitFieldAlign); 16960b57cec5SDimitry Andric UnpackedFieldAlign = std::max(UnpackedFieldAlign, ExplicitFieldAlign); 16970b57cec5SDimitry Andric } 16980b57cec5SDimitry Andric 16990b57cec5SDimitry Andric // But, if there's a #pragma pack in play, that takes precedent over 17000b57cec5SDimitry Andric // even the 'aligned' attribute, for non-zero-width bitfields. 17010b57cec5SDimitry Andric unsigned MaxFieldAlignmentInBits = Context.toBits(MaxFieldAlignment); 17020b57cec5SDimitry Andric if (!MaxFieldAlignment.isZero() && FieldSize) { 17030b57cec5SDimitry Andric UnpackedFieldAlign = std::min(UnpackedFieldAlign, MaxFieldAlignmentInBits); 17040b57cec5SDimitry Andric if (FieldPacked) 17050b57cec5SDimitry Andric FieldAlign = UnpackedFieldAlign; 17060b57cec5SDimitry Andric else 17070b57cec5SDimitry Andric FieldAlign = std::min(FieldAlign, MaxFieldAlignmentInBits); 17080b57cec5SDimitry Andric } 17090b57cec5SDimitry Andric 17100b57cec5SDimitry Andric // But, ms_struct just ignores all of that in unions, even explicit 17110b57cec5SDimitry Andric // alignment attributes. 17120b57cec5SDimitry Andric if (IsMsStruct && IsUnion) { 17130b57cec5SDimitry Andric FieldAlign = UnpackedFieldAlign = 1; 17140b57cec5SDimitry Andric } 17150b57cec5SDimitry Andric 17160b57cec5SDimitry Andric // For purposes of diagnostics, we're going to simultaneously 17170b57cec5SDimitry Andric // compute the field offsets that we would have used if we weren't 17180b57cec5SDimitry Andric // adding any alignment padding or if the field weren't packed. 17190b57cec5SDimitry Andric uint64_t UnpaddedFieldOffset = FieldOffset; 17200b57cec5SDimitry Andric uint64_t UnpackedFieldOffset = FieldOffset; 17210b57cec5SDimitry Andric 17220b57cec5SDimitry Andric // Check if we need to add padding to fit the bitfield within an 17230b57cec5SDimitry Andric // allocation unit with the right size and alignment. The rules are 17240b57cec5SDimitry Andric // somewhat different here for ms_struct structs. 17250b57cec5SDimitry Andric if (IsMsStruct) { 17260b57cec5SDimitry Andric // If it's not a zero-width bitfield, and we can fit the bitfield 17270b57cec5SDimitry Andric // into the active storage unit (and we haven't already decided to 17280b57cec5SDimitry Andric // start a new storage unit), just do so, regardless of any other 17290b57cec5SDimitry Andric // other consideration. Otherwise, round up to the right alignment. 17300b57cec5SDimitry Andric if (FieldSize == 0 || FieldSize > UnfilledBitsInLastUnit) { 17310b57cec5SDimitry Andric FieldOffset = llvm::alignTo(FieldOffset, FieldAlign); 17320b57cec5SDimitry Andric UnpackedFieldOffset = 17330b57cec5SDimitry Andric llvm::alignTo(UnpackedFieldOffset, UnpackedFieldAlign); 17340b57cec5SDimitry Andric UnfilledBitsInLastUnit = 0; 17350b57cec5SDimitry Andric } 17360b57cec5SDimitry Andric 17370b57cec5SDimitry Andric } else { 17380b57cec5SDimitry Andric // #pragma pack, with any value, suppresses the insertion of padding. 17390b57cec5SDimitry Andric bool AllowPadding = MaxFieldAlignment.isZero(); 17400b57cec5SDimitry Andric 17410b57cec5SDimitry Andric // Compute the real offset. 17420b57cec5SDimitry Andric if (FieldSize == 0 || 17430b57cec5SDimitry Andric (AllowPadding && 1744e8d8bef9SDimitry Andric (FieldOffset & (FieldAlign - 1)) + FieldSize > StorageUnitSize)) { 17450b57cec5SDimitry Andric FieldOffset = llvm::alignTo(FieldOffset, FieldAlign); 17460b57cec5SDimitry Andric } else if (ExplicitFieldAlign && 17470b57cec5SDimitry Andric (MaxFieldAlignmentInBits == 0 || 17480b57cec5SDimitry Andric ExplicitFieldAlign <= MaxFieldAlignmentInBits) && 17490b57cec5SDimitry Andric Context.getTargetInfo().useExplicitBitFieldAlignment()) { 17500b57cec5SDimitry Andric // TODO: figure it out what needs to be done on targets that don't honor 17510b57cec5SDimitry Andric // bit-field type alignment like ARM APCS ABI. 17520b57cec5SDimitry Andric FieldOffset = llvm::alignTo(FieldOffset, ExplicitFieldAlign); 17530b57cec5SDimitry Andric } 17540b57cec5SDimitry Andric 17550b57cec5SDimitry Andric // Repeat the computation for diagnostic purposes. 17560b57cec5SDimitry Andric if (FieldSize == 0 || 17570b57cec5SDimitry Andric (AllowPadding && 1758e8d8bef9SDimitry Andric (UnpackedFieldOffset & (UnpackedFieldAlign - 1)) + FieldSize > 1759e8d8bef9SDimitry Andric StorageUnitSize)) 17600b57cec5SDimitry Andric UnpackedFieldOffset = 17610b57cec5SDimitry Andric llvm::alignTo(UnpackedFieldOffset, UnpackedFieldAlign); 17620b57cec5SDimitry Andric else if (ExplicitFieldAlign && 17630b57cec5SDimitry Andric (MaxFieldAlignmentInBits == 0 || 17640b57cec5SDimitry Andric ExplicitFieldAlign <= MaxFieldAlignmentInBits) && 17650b57cec5SDimitry Andric Context.getTargetInfo().useExplicitBitFieldAlignment()) 17660b57cec5SDimitry Andric UnpackedFieldOffset = 17670b57cec5SDimitry Andric llvm::alignTo(UnpackedFieldOffset, ExplicitFieldAlign); 17680b57cec5SDimitry Andric } 17690b57cec5SDimitry Andric 17700b57cec5SDimitry Andric // If we're using external layout, give the external layout a chance 17710b57cec5SDimitry Andric // to override this information. 17720b57cec5SDimitry Andric if (UseExternalLayout) 17730b57cec5SDimitry Andric FieldOffset = updateExternalFieldOffset(D, FieldOffset); 17740b57cec5SDimitry Andric 17750b57cec5SDimitry Andric // Okay, place the bitfield at the calculated offset. 17760b57cec5SDimitry Andric FieldOffsets.push_back(FieldOffset); 17770b57cec5SDimitry Andric 17780b57cec5SDimitry Andric // Bookkeeping: 17790b57cec5SDimitry Andric 17800b57cec5SDimitry Andric // Anonymous members don't affect the overall record alignment, 17810b57cec5SDimitry Andric // except on targets where they do. 17820b57cec5SDimitry Andric if (!IsMsStruct && 17830b57cec5SDimitry Andric !Context.getTargetInfo().useZeroLengthBitfieldAlignment() && 17840b57cec5SDimitry Andric !D->getIdentifier()) 17850b57cec5SDimitry Andric FieldAlign = UnpackedFieldAlign = 1; 17860b57cec5SDimitry Andric 1787349cc55cSDimitry Andric // On AIX, zero-width bitfields pad out to the natural alignment boundary, 1788349cc55cSDimitry Andric // but do not increase the alignment greater than the MaxFieldAlignment, or 1 1789349cc55cSDimitry Andric // if packed. 1790349cc55cSDimitry Andric if (isAIXLayout(Context) && !FieldSize) { 1791349cc55cSDimitry Andric if (FieldPacked) 1792349cc55cSDimitry Andric FieldAlign = 1; 1793349cc55cSDimitry Andric if (!MaxFieldAlignment.isZero()) { 1794349cc55cSDimitry Andric UnpackedFieldAlign = 1795349cc55cSDimitry Andric std::min(UnpackedFieldAlign, MaxFieldAlignmentInBits); 1796fe6060f1SDimitry Andric FieldAlign = std::min(FieldAlign, MaxFieldAlignmentInBits); 1797349cc55cSDimitry Andric } 1798349cc55cSDimitry Andric } 1799fe6060f1SDimitry Andric 18000b57cec5SDimitry Andric // Diagnose differences in layout due to padding or packing. 18010b57cec5SDimitry Andric if (!UseExternalLayout) 18020b57cec5SDimitry Andric CheckFieldPadding(FieldOffset, UnpaddedFieldOffset, UnpackedFieldOffset, 18030b57cec5SDimitry Andric UnpackedFieldAlign, FieldPacked, D); 18040b57cec5SDimitry Andric 18050b57cec5SDimitry Andric // Update DataSize to include the last byte containing (part of) the bitfield. 18060b57cec5SDimitry Andric 18070b57cec5SDimitry Andric // For unions, this is just a max operation, as usual. 18080b57cec5SDimitry Andric if (IsUnion) { 18090b57cec5SDimitry Andric // For ms_struct, allocate the entire storage unit --- unless this 18100b57cec5SDimitry Andric // is a zero-width bitfield, in which case just use a size of 1. 18110b57cec5SDimitry Andric uint64_t RoundedFieldSize; 18120b57cec5SDimitry Andric if (IsMsStruct) { 1813e8d8bef9SDimitry Andric RoundedFieldSize = (FieldSize ? StorageUnitSize 1814e8d8bef9SDimitry Andric : Context.getTargetInfo().getCharWidth()); 18150b57cec5SDimitry Andric 18160b57cec5SDimitry Andric // Otherwise, allocate just the number of bytes required to store 18170b57cec5SDimitry Andric // the bitfield. 18180b57cec5SDimitry Andric } else { 18190b57cec5SDimitry Andric RoundedFieldSize = roundUpSizeToCharAlignment(FieldSize, Context); 18200b57cec5SDimitry Andric } 18210b57cec5SDimitry Andric setDataSize(std::max(getDataSizeInBits(), RoundedFieldSize)); 18220b57cec5SDimitry Andric 18230b57cec5SDimitry Andric // For non-zero-width bitfields in ms_struct structs, allocate a new 18240b57cec5SDimitry Andric // storage unit if necessary. 18250b57cec5SDimitry Andric } else if (IsMsStruct && FieldSize) { 18260b57cec5SDimitry Andric // We should have cleared UnfilledBitsInLastUnit in every case 18270b57cec5SDimitry Andric // where we changed storage units. 18280b57cec5SDimitry Andric if (!UnfilledBitsInLastUnit) { 1829e8d8bef9SDimitry Andric setDataSize(FieldOffset + StorageUnitSize); 1830e8d8bef9SDimitry Andric UnfilledBitsInLastUnit = StorageUnitSize; 18310b57cec5SDimitry Andric } 18320b57cec5SDimitry Andric UnfilledBitsInLastUnit -= FieldSize; 1833e8d8bef9SDimitry Andric LastBitfieldStorageUnitSize = StorageUnitSize; 18340b57cec5SDimitry Andric 18350b57cec5SDimitry Andric // Otherwise, bump the data size up to include the bitfield, 18360b57cec5SDimitry Andric // including padding up to char alignment, and then remember how 18370b57cec5SDimitry Andric // bits we didn't use. 18380b57cec5SDimitry Andric } else { 18390b57cec5SDimitry Andric uint64_t NewSizeInBits = FieldOffset + FieldSize; 18400b57cec5SDimitry Andric uint64_t CharAlignment = Context.getTargetInfo().getCharAlign(); 18410b57cec5SDimitry Andric setDataSize(llvm::alignTo(NewSizeInBits, CharAlignment)); 18420b57cec5SDimitry Andric UnfilledBitsInLastUnit = getDataSizeInBits() - NewSizeInBits; 18430b57cec5SDimitry Andric 18440b57cec5SDimitry Andric // The only time we can get here for an ms_struct is if this is a 18450b57cec5SDimitry Andric // zero-width bitfield, which doesn't count as anything for the 18460b57cec5SDimitry Andric // purposes of unfilled bits. 1847e8d8bef9SDimitry Andric LastBitfieldStorageUnitSize = 0; 18480b57cec5SDimitry Andric } 18490b57cec5SDimitry Andric 18500b57cec5SDimitry Andric // Update the size. 18510b57cec5SDimitry Andric setSize(std::max(getSizeInBits(), getDataSizeInBits())); 18520b57cec5SDimitry Andric 18530b57cec5SDimitry Andric // Remember max struct/class alignment. 18540b57cec5SDimitry Andric UnadjustedAlignment = 18550b57cec5SDimitry Andric std::max(UnadjustedAlignment, Context.toCharUnitsFromBits(FieldAlign)); 18560b57cec5SDimitry Andric UpdateAlignment(Context.toCharUnitsFromBits(FieldAlign), 18570b57cec5SDimitry Andric Context.toCharUnitsFromBits(UnpackedFieldAlign)); 18580b57cec5SDimitry Andric } 18590b57cec5SDimitry Andric 18600b57cec5SDimitry Andric void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D, 18610b57cec5SDimitry Andric bool InsertExtraPadding) { 1862e8d8bef9SDimitry Andric auto *FieldClass = D->getType()->getAsCXXRecordDecl(); 1863e8d8bef9SDimitry Andric bool IsOverlappingEmptyField = 186406c3fb27SDimitry Andric D->isPotentiallyOverlapping() && FieldClass->isEmpty(); 1865e8d8bef9SDimitry Andric 1866e8d8bef9SDimitry Andric CharUnits FieldOffset = 1867e8d8bef9SDimitry Andric (IsUnion || IsOverlappingEmptyField) ? CharUnits::Zero() : getDataSize(); 1868e8d8bef9SDimitry Andric 1869e8d8bef9SDimitry Andric const bool DefaultsToAIXPowerAlignment = 1870e8d8bef9SDimitry Andric Context.getTargetInfo().defaultsToAIXPowerAlignment(); 1871e8d8bef9SDimitry Andric bool FoundFirstNonOverlappingEmptyFieldForAIX = false; 1872e8d8bef9SDimitry Andric if (DefaultsToAIXPowerAlignment && !HandledFirstNonOverlappingEmptyField) { 1873e8d8bef9SDimitry Andric assert(FieldOffset == CharUnits::Zero() && 1874e8d8bef9SDimitry Andric "The first non-overlapping empty field should have been handled."); 1875e8d8bef9SDimitry Andric 1876e8d8bef9SDimitry Andric if (!IsOverlappingEmptyField) { 1877e8d8bef9SDimitry Andric FoundFirstNonOverlappingEmptyFieldForAIX = true; 1878e8d8bef9SDimitry Andric 1879e8d8bef9SDimitry Andric // We're going to handle the "first member" based on 1880e8d8bef9SDimitry Andric // `FoundFirstNonOverlappingEmptyFieldForAIX` during the current 1881e8d8bef9SDimitry Andric // invocation of this function; record it as handled for future 1882e8d8bef9SDimitry Andric // invocations (except for unions, because the current field does not 1883e8d8bef9SDimitry Andric // represent all "firsts"). 1884e8d8bef9SDimitry Andric HandledFirstNonOverlappingEmptyField = !IsUnion; 1885e8d8bef9SDimitry Andric } 1886e8d8bef9SDimitry Andric } 1887e8d8bef9SDimitry Andric 18880b57cec5SDimitry Andric if (D->isBitField()) { 18890b57cec5SDimitry Andric LayoutBitField(D); 18900b57cec5SDimitry Andric return; 18910b57cec5SDimitry Andric } 18920b57cec5SDimitry Andric 18930b57cec5SDimitry Andric uint64_t UnpaddedFieldOffset = getDataSizeInBits() - UnfilledBitsInLastUnit; 18940b57cec5SDimitry Andric // Reset the unfilled bits. 18950b57cec5SDimitry Andric UnfilledBitsInLastUnit = 0; 1896e8d8bef9SDimitry Andric LastBitfieldStorageUnitSize = 0; 18970b57cec5SDimitry Andric 1898bdd1243dSDimitry Andric llvm::Triple Target = Context.getTargetInfo().getTriple(); 18990b57cec5SDimitry Andric 1900349cc55cSDimitry Andric AlignRequirementKind AlignRequirement = AlignRequirementKind::None; 19010b57cec5SDimitry Andric CharUnits FieldSize; 19020b57cec5SDimitry Andric CharUnits FieldAlign; 19030b57cec5SDimitry Andric // The amount of this class's dsize occupied by the field. 19040b57cec5SDimitry Andric // This is equal to FieldSize unless we're permitted to pack 19050b57cec5SDimitry Andric // into the field's tail padding. 19060b57cec5SDimitry Andric CharUnits EffectiveFieldSize; 19070b57cec5SDimitry Andric 1908e8d8bef9SDimitry Andric auto setDeclInfo = [&](bool IsIncompleteArrayType) { 1909e8d8bef9SDimitry Andric auto TI = Context.getTypeInfoInChars(D->getType()); 1910e8d8bef9SDimitry Andric FieldAlign = TI.Align; 1911e8d8bef9SDimitry Andric // Flexible array members don't have any size, but they have to be 1912e8d8bef9SDimitry Andric // aligned appropriately for their element type. 1913e8d8bef9SDimitry Andric EffectiveFieldSize = FieldSize = 1914e8d8bef9SDimitry Andric IsIncompleteArrayType ? CharUnits::Zero() : TI.Width; 1915349cc55cSDimitry Andric AlignRequirement = TI.AlignRequirement; 1916e8d8bef9SDimitry Andric }; 1917e8d8bef9SDimitry Andric 19180b57cec5SDimitry Andric if (D->getType()->isIncompleteArrayType()) { 1919e8d8bef9SDimitry Andric setDeclInfo(true /* IsIncompleteArrayType */); 19200b57cec5SDimitry Andric } else { 1921e8d8bef9SDimitry Andric setDeclInfo(false /* IsIncompleteArrayType */); 19220b57cec5SDimitry Andric 19230b57cec5SDimitry Andric // A potentially-overlapping field occupies its dsize or nvsize, whichever 19240b57cec5SDimitry Andric // is larger. 192506c3fb27SDimitry Andric if (D->isPotentiallyOverlapping()) { 19260b57cec5SDimitry Andric const ASTRecordLayout &Layout = Context.getASTRecordLayout(FieldClass); 19270b57cec5SDimitry Andric EffectiveFieldSize = 19280b57cec5SDimitry Andric std::max(Layout.getNonVirtualSize(), Layout.getDataSize()); 19290b57cec5SDimitry Andric } 19300b57cec5SDimitry Andric 19310b57cec5SDimitry Andric if (IsMsStruct) { 19320b57cec5SDimitry Andric // If MS bitfield layout is required, figure out what type is being 19330b57cec5SDimitry Andric // laid out and align the field to the width of that type. 19340b57cec5SDimitry Andric 19350b57cec5SDimitry Andric // Resolve all typedefs down to their base type and round up the field 19360b57cec5SDimitry Andric // alignment if necessary. 19370b57cec5SDimitry Andric QualType T = Context.getBaseElementType(D->getType()); 19380b57cec5SDimitry Andric if (const BuiltinType *BTy = T->getAs<BuiltinType>()) { 19390b57cec5SDimitry Andric CharUnits TypeSize = Context.getTypeSizeInChars(BTy); 19400b57cec5SDimitry Andric 19410b57cec5SDimitry Andric if (!llvm::isPowerOf2_64(TypeSize.getQuantity())) { 19420b57cec5SDimitry Andric assert( 19430b57cec5SDimitry Andric !Context.getTargetInfo().getTriple().isWindowsMSVCEnvironment() && 19440b57cec5SDimitry Andric "Non PowerOf2 size in MSVC mode"); 19450b57cec5SDimitry Andric // Base types with sizes that aren't a power of two don't work 19460b57cec5SDimitry Andric // with the layout rules for MS structs. This isn't an issue in 19470b57cec5SDimitry Andric // MSVC itself since there are no such base data types there. 19480b57cec5SDimitry Andric // On e.g. x86_32 mingw and linux, long double is 12 bytes though. 19490b57cec5SDimitry Andric // Any structs involving that data type obviously can't be ABI 19500b57cec5SDimitry Andric // compatible with MSVC regardless of how it is laid out. 19510b57cec5SDimitry Andric 19520b57cec5SDimitry Andric // Since ms_struct can be mass enabled (via a pragma or via the 19530b57cec5SDimitry Andric // -mms-bitfields command line parameter), this can trigger for 19540b57cec5SDimitry Andric // structs that don't actually need MSVC compatibility, so we 19550b57cec5SDimitry Andric // need to be able to sidestep the ms_struct layout for these types. 19560b57cec5SDimitry Andric 19570b57cec5SDimitry Andric // Since the combination of -mms-bitfields together with structs 19580b57cec5SDimitry Andric // like max_align_t (which contains a long double) for mingw is 1959349cc55cSDimitry Andric // quite common (and GCC handles it silently), just handle it 19600b57cec5SDimitry Andric // silently there. For other targets that have ms_struct enabled 19610b57cec5SDimitry Andric // (most probably via a pragma or attribute), trigger a diagnostic 19620b57cec5SDimitry Andric // that defaults to an error. 19630b57cec5SDimitry Andric if (!Context.getTargetInfo().getTriple().isWindowsGNUEnvironment()) 19640b57cec5SDimitry Andric Diag(D->getLocation(), diag::warn_npot_ms_struct); 19650b57cec5SDimitry Andric } 19660b57cec5SDimitry Andric if (TypeSize > FieldAlign && 19670b57cec5SDimitry Andric llvm::isPowerOf2_64(TypeSize.getQuantity())) 19680b57cec5SDimitry Andric FieldAlign = TypeSize; 19690b57cec5SDimitry Andric } 19700b57cec5SDimitry Andric } 19710b57cec5SDimitry Andric } 19720b57cec5SDimitry Andric 1973bdd1243dSDimitry Andric bool FieldPacked = (Packed && (!FieldClass || FieldClass->isPOD() || 1974bdd1243dSDimitry Andric FieldClass->hasAttr<PackedAttr>() || 1975bdd1243dSDimitry Andric Context.getLangOpts().getClangABICompat() <= 1976bdd1243dSDimitry Andric LangOptions::ClangABI::Ver15 || 1977bdd1243dSDimitry Andric Target.isPS() || Target.isOSDarwin() || 1978bdd1243dSDimitry Andric Target.isOSAIX())) || 1979bdd1243dSDimitry Andric D->hasAttr<PackedAttr>(); 1980bdd1243dSDimitry Andric 1981349cc55cSDimitry Andric // When used as part of a typedef, or together with a 'packed' attribute, the 1982349cc55cSDimitry Andric // 'aligned' attribute can be used to decrease alignment. In that case, it 1983349cc55cSDimitry Andric // overrides any computed alignment we have, and there is no need to upgrade 1984349cc55cSDimitry Andric // the alignment. 1985349cc55cSDimitry Andric auto alignedAttrCanDecreaseAIXAlignment = [AlignRequirement, FieldPacked] { 1986349cc55cSDimitry Andric // Enum alignment sources can be safely ignored here, because this only 1987349cc55cSDimitry Andric // helps decide whether we need the AIX alignment upgrade, which only 1988349cc55cSDimitry Andric // applies to floating-point types. 1989349cc55cSDimitry Andric return AlignRequirement == AlignRequirementKind::RequiredByTypedef || 1990349cc55cSDimitry Andric (AlignRequirement == AlignRequirementKind::RequiredByRecord && 1991349cc55cSDimitry Andric FieldPacked); 1992349cc55cSDimitry Andric }; 1993349cc55cSDimitry Andric 1994e8d8bef9SDimitry Andric // The AIX `power` alignment rules apply the natural alignment of the 1995e8d8bef9SDimitry Andric // "first member" if it is of a floating-point data type (or is an aggregate 1996e8d8bef9SDimitry Andric // whose recursively "first" member or element is such a type). The alignment 1997e8d8bef9SDimitry Andric // associated with these types for subsequent members use an alignment value 1998e8d8bef9SDimitry Andric // where the floating-point data type is considered to have 4-byte alignment. 1999e8d8bef9SDimitry Andric // 2000e8d8bef9SDimitry Andric // For the purposes of the foregoing: vtable pointers, non-empty base classes, 2001e8d8bef9SDimitry Andric // and zero-width bit-fields count as prior members; members of empty class 2002e8d8bef9SDimitry Andric // types marked `no_unique_address` are not considered to be prior members. 2003e8d8bef9SDimitry Andric CharUnits PreferredAlign = FieldAlign; 2004349cc55cSDimitry Andric if (DefaultsToAIXPowerAlignment && !alignedAttrCanDecreaseAIXAlignment() && 2005e8d8bef9SDimitry Andric (FoundFirstNonOverlappingEmptyFieldForAIX || IsNaturalAlign)) { 2006e8d8bef9SDimitry Andric auto performBuiltinTypeAlignmentUpgrade = [&](const BuiltinType *BTy) { 2007e8d8bef9SDimitry Andric if (BTy->getKind() == BuiltinType::Double || 2008e8d8bef9SDimitry Andric BTy->getKind() == BuiltinType::LongDouble) { 2009e8d8bef9SDimitry Andric assert(PreferredAlign == CharUnits::fromQuantity(4) && 2010e8d8bef9SDimitry Andric "No need to upgrade the alignment value."); 2011e8d8bef9SDimitry Andric PreferredAlign = CharUnits::fromQuantity(8); 2012e8d8bef9SDimitry Andric } 2013e8d8bef9SDimitry Andric }; 2014e8d8bef9SDimitry Andric 2015349cc55cSDimitry Andric const Type *BaseTy = D->getType()->getBaseElementTypeUnsafe(); 2016349cc55cSDimitry Andric if (const ComplexType *CTy = BaseTy->getAs<ComplexType>()) { 2017349cc55cSDimitry Andric performBuiltinTypeAlignmentUpgrade( 2018349cc55cSDimitry Andric CTy->getElementType()->castAs<BuiltinType>()); 2019349cc55cSDimitry Andric } else if (const BuiltinType *BTy = BaseTy->getAs<BuiltinType>()) { 2020e8d8bef9SDimitry Andric performBuiltinTypeAlignmentUpgrade(BTy); 2021349cc55cSDimitry Andric } else if (const RecordType *RT = BaseTy->getAs<RecordType>()) { 2022e8d8bef9SDimitry Andric const RecordDecl *RD = RT->getDecl(); 2023e8d8bef9SDimitry Andric assert(RD && "Expected non-null RecordDecl."); 2024e8d8bef9SDimitry Andric const ASTRecordLayout &FieldRecord = Context.getASTRecordLayout(RD); 2025e8d8bef9SDimitry Andric PreferredAlign = FieldRecord.getPreferredAlignment(); 2026e8d8bef9SDimitry Andric } 2027e8d8bef9SDimitry Andric } 2028e8d8bef9SDimitry Andric 20290b57cec5SDimitry Andric // The align if the field is not packed. This is to check if the attribute 20300b57cec5SDimitry Andric // was unnecessary (-Wpacked). 2031bdd1243dSDimitry Andric CharUnits UnpackedFieldAlign = FieldAlign; 2032bdd1243dSDimitry Andric CharUnits PackedFieldAlign = CharUnits::One(); 20330b57cec5SDimitry Andric CharUnits UnpackedFieldOffset = FieldOffset; 203404eeddc0SDimitry Andric CharUnits OriginalFieldAlign = UnpackedFieldAlign; 20350b57cec5SDimitry Andric 20360b57cec5SDimitry Andric CharUnits MaxAlignmentInChars = 20370b57cec5SDimitry Andric Context.toCharUnitsFromBits(D->getMaxAlignment()); 2038bdd1243dSDimitry Andric PackedFieldAlign = std::max(PackedFieldAlign, MaxAlignmentInChars); 2039e8d8bef9SDimitry Andric PreferredAlign = std::max(PreferredAlign, MaxAlignmentInChars); 20400b57cec5SDimitry Andric UnpackedFieldAlign = std::max(UnpackedFieldAlign, MaxAlignmentInChars); 20410b57cec5SDimitry Andric 20420b57cec5SDimitry Andric // The maximum field alignment overrides the aligned attribute. 20430b57cec5SDimitry Andric if (!MaxFieldAlignment.isZero()) { 2044bdd1243dSDimitry Andric PackedFieldAlign = std::min(PackedFieldAlign, MaxFieldAlignment); 2045e8d8bef9SDimitry Andric PreferredAlign = std::min(PreferredAlign, MaxFieldAlignment); 20460b57cec5SDimitry Andric UnpackedFieldAlign = std::min(UnpackedFieldAlign, MaxFieldAlignment); 20470b57cec5SDimitry Andric } 20480b57cec5SDimitry Andric 2049bdd1243dSDimitry Andric 2050bdd1243dSDimitry Andric if (!FieldPacked) 2051bdd1243dSDimitry Andric FieldAlign = UnpackedFieldAlign; 2052bdd1243dSDimitry Andric if (DefaultsToAIXPowerAlignment) 2053bdd1243dSDimitry Andric UnpackedFieldAlign = PreferredAlign; 2054bdd1243dSDimitry Andric if (FieldPacked) { 2055bdd1243dSDimitry Andric PreferredAlign = PackedFieldAlign; 2056bdd1243dSDimitry Andric FieldAlign = PackedFieldAlign; 2057bdd1243dSDimitry Andric } 2058bdd1243dSDimitry Andric 2059e8d8bef9SDimitry Andric CharUnits AlignTo = 2060e8d8bef9SDimitry Andric !DefaultsToAIXPowerAlignment ? FieldAlign : PreferredAlign; 20610b57cec5SDimitry Andric // Round up the current record size to the field's alignment boundary. 2062e8d8bef9SDimitry Andric FieldOffset = FieldOffset.alignTo(AlignTo); 20630b57cec5SDimitry Andric UnpackedFieldOffset = UnpackedFieldOffset.alignTo(UnpackedFieldAlign); 20640b57cec5SDimitry Andric 20650b57cec5SDimitry Andric if (UseExternalLayout) { 20660b57cec5SDimitry Andric FieldOffset = Context.toCharUnitsFromBits( 20670b57cec5SDimitry Andric updateExternalFieldOffset(D, Context.toBits(FieldOffset))); 20680b57cec5SDimitry Andric 20690b57cec5SDimitry Andric if (!IsUnion && EmptySubobjects) { 20700b57cec5SDimitry Andric // Record the fact that we're placing a field at this offset. 20710b57cec5SDimitry Andric bool Allowed = EmptySubobjects->CanPlaceFieldAtOffset(D, FieldOffset); 20720b57cec5SDimitry Andric (void)Allowed; 20730b57cec5SDimitry Andric assert(Allowed && "Externally-placed field cannot be placed here"); 20740b57cec5SDimitry Andric } 20750b57cec5SDimitry Andric } else { 20760b57cec5SDimitry Andric if (!IsUnion && EmptySubobjects) { 20770b57cec5SDimitry Andric // Check if we can place the field at this offset. 20780b57cec5SDimitry Andric while (!EmptySubobjects->CanPlaceFieldAtOffset(D, FieldOffset)) { 20790b57cec5SDimitry Andric // We couldn't place the field at the offset. Try again at a new offset. 20800b57cec5SDimitry Andric // We try offset 0 (for an empty field) and then dsize(C) onwards. 20810b57cec5SDimitry Andric if (FieldOffset == CharUnits::Zero() && 20820b57cec5SDimitry Andric getDataSize() != CharUnits::Zero()) 2083e8d8bef9SDimitry Andric FieldOffset = getDataSize().alignTo(AlignTo); 20840b57cec5SDimitry Andric else 2085e8d8bef9SDimitry Andric FieldOffset += AlignTo; 20860b57cec5SDimitry Andric } 20870b57cec5SDimitry Andric } 20880b57cec5SDimitry Andric } 20890b57cec5SDimitry Andric 20900b57cec5SDimitry Andric // Place this field at the current location. 20910b57cec5SDimitry Andric FieldOffsets.push_back(Context.toBits(FieldOffset)); 20920b57cec5SDimitry Andric 20930b57cec5SDimitry Andric if (!UseExternalLayout) 20940b57cec5SDimitry Andric CheckFieldPadding(Context.toBits(FieldOffset), UnpaddedFieldOffset, 20950b57cec5SDimitry Andric Context.toBits(UnpackedFieldOffset), 20960b57cec5SDimitry Andric Context.toBits(UnpackedFieldAlign), FieldPacked, D); 20970b57cec5SDimitry Andric 20980b57cec5SDimitry Andric if (InsertExtraPadding) { 20990b57cec5SDimitry Andric CharUnits ASanAlignment = CharUnits::fromQuantity(8); 21000b57cec5SDimitry Andric CharUnits ExtraSizeForAsan = ASanAlignment; 21010b57cec5SDimitry Andric if (FieldSize % ASanAlignment) 21020b57cec5SDimitry Andric ExtraSizeForAsan += 21030b57cec5SDimitry Andric ASanAlignment - CharUnits::fromQuantity(FieldSize % ASanAlignment); 21040b57cec5SDimitry Andric EffectiveFieldSize = FieldSize = FieldSize + ExtraSizeForAsan; 21050b57cec5SDimitry Andric } 21060b57cec5SDimitry Andric 21070b57cec5SDimitry Andric // Reserve space for this field. 21080b57cec5SDimitry Andric if (!IsOverlappingEmptyField) { 21090b57cec5SDimitry Andric uint64_t EffectiveFieldSizeInBits = Context.toBits(EffectiveFieldSize); 21100b57cec5SDimitry Andric if (IsUnion) 21110b57cec5SDimitry Andric setDataSize(std::max(getDataSizeInBits(), EffectiveFieldSizeInBits)); 21120b57cec5SDimitry Andric else 21130b57cec5SDimitry Andric setDataSize(FieldOffset + EffectiveFieldSize); 21140b57cec5SDimitry Andric 21150b57cec5SDimitry Andric PaddedFieldSize = std::max(PaddedFieldSize, FieldOffset + FieldSize); 21160b57cec5SDimitry Andric setSize(std::max(getSizeInBits(), getDataSizeInBits())); 21170b57cec5SDimitry Andric } else { 21180b57cec5SDimitry Andric setSize(std::max(getSizeInBits(), 21190b57cec5SDimitry Andric (uint64_t)Context.toBits(FieldOffset + FieldSize))); 21200b57cec5SDimitry Andric } 21210b57cec5SDimitry Andric 2122e8d8bef9SDimitry Andric // Remember max struct/class ABI-specified alignment. 21230b57cec5SDimitry Andric UnadjustedAlignment = std::max(UnadjustedAlignment, FieldAlign); 2124e8d8bef9SDimitry Andric UpdateAlignment(FieldAlign, UnpackedFieldAlign, PreferredAlign); 212504eeddc0SDimitry Andric 212604eeddc0SDimitry Andric // For checking the alignment of inner fields against 212704eeddc0SDimitry Andric // the alignment of its parent record. 212804eeddc0SDimitry Andric if (const RecordDecl *RD = D->getParent()) { 212904eeddc0SDimitry Andric // Check if packed attribute or pragma pack is present. 213004eeddc0SDimitry Andric if (RD->hasAttr<PackedAttr>() || !MaxFieldAlignment.isZero()) 213104eeddc0SDimitry Andric if (FieldAlign < OriginalFieldAlign) 213204eeddc0SDimitry Andric if (D->getType()->isRecordType()) { 213304eeddc0SDimitry Andric // If the offset is a multiple of the alignment of 213404eeddc0SDimitry Andric // the type, raise the warning. 213504eeddc0SDimitry Andric // TODO: Takes no account the alignment of the outer struct 213604eeddc0SDimitry Andric if (FieldOffset % OriginalFieldAlign != 0) 213704eeddc0SDimitry Andric Diag(D->getLocation(), diag::warn_unaligned_access) 213804eeddc0SDimitry Andric << Context.getTypeDeclType(RD) << D->getName() << D->getType(); 213904eeddc0SDimitry Andric } 214004eeddc0SDimitry Andric } 2141bdd1243dSDimitry Andric 2142bdd1243dSDimitry Andric if (Packed && !FieldPacked && PackedFieldAlign < FieldAlign) 2143bdd1243dSDimitry Andric Diag(D->getLocation(), diag::warn_unpacked_field) << D; 21440b57cec5SDimitry Andric } 21450b57cec5SDimitry Andric 21460b57cec5SDimitry Andric void ItaniumRecordLayoutBuilder::FinishLayout(const NamedDecl *D) { 21470b57cec5SDimitry Andric // In C++, records cannot be of size 0. 21480b57cec5SDimitry Andric if (Context.getLangOpts().CPlusPlus && getSizeInBits() == 0) { 21490b57cec5SDimitry Andric if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) { 21500b57cec5SDimitry Andric // Compatibility with gcc requires a class (pod or non-pod) 21510b57cec5SDimitry Andric // which is not empty but of size 0; such as having fields of 21520b57cec5SDimitry Andric // array of zero-length, remains of Size 0 21530b57cec5SDimitry Andric if (RD->isEmpty()) 21540b57cec5SDimitry Andric setSize(CharUnits::One()); 21550b57cec5SDimitry Andric } 21560b57cec5SDimitry Andric else 21570b57cec5SDimitry Andric setSize(CharUnits::One()); 21580b57cec5SDimitry Andric } 21590b57cec5SDimitry Andric 21600b57cec5SDimitry Andric // If we have any remaining field tail padding, include that in the overall 21610b57cec5SDimitry Andric // size. 21620b57cec5SDimitry Andric setSize(std::max(getSizeInBits(), (uint64_t)Context.toBits(PaddedFieldSize))); 21630b57cec5SDimitry Andric 21640b57cec5SDimitry Andric // Finally, round the size of the record up to the alignment of the 21650b57cec5SDimitry Andric // record itself. 21660b57cec5SDimitry Andric uint64_t UnpaddedSize = getSizeInBits() - UnfilledBitsInLastUnit; 21670b57cec5SDimitry Andric uint64_t UnpackedSizeInBits = 21680b57cec5SDimitry Andric llvm::alignTo(getSizeInBits(), Context.toBits(UnpackedAlignment)); 2169e8d8bef9SDimitry Andric 2170e8d8bef9SDimitry Andric uint64_t RoundedSize = llvm::alignTo( 2171e8d8bef9SDimitry Andric getSizeInBits(), 2172e8d8bef9SDimitry Andric Context.toBits(!Context.getTargetInfo().defaultsToAIXPowerAlignment() 2173e8d8bef9SDimitry Andric ? Alignment 2174e8d8bef9SDimitry Andric : PreferredAlignment)); 21750b57cec5SDimitry Andric 21760b57cec5SDimitry Andric if (UseExternalLayout) { 21770b57cec5SDimitry Andric // If we're inferring alignment, and the external size is smaller than 21780b57cec5SDimitry Andric // our size after we've rounded up to alignment, conservatively set the 21790b57cec5SDimitry Andric // alignment to 1. 21800b57cec5SDimitry Andric if (InferAlignment && External.Size < RoundedSize) { 21810b57cec5SDimitry Andric Alignment = CharUnits::One(); 2182e8d8bef9SDimitry Andric PreferredAlignment = CharUnits::One(); 21830b57cec5SDimitry Andric InferAlignment = false; 21840b57cec5SDimitry Andric } 21850b57cec5SDimitry Andric setSize(External.Size); 21860b57cec5SDimitry Andric return; 21870b57cec5SDimitry Andric } 21880b57cec5SDimitry Andric 21890b57cec5SDimitry Andric // Set the size to the final size. 21900b57cec5SDimitry Andric setSize(RoundedSize); 21910b57cec5SDimitry Andric 21920b57cec5SDimitry Andric unsigned CharBitNum = Context.getTargetInfo().getCharWidth(); 21930b57cec5SDimitry Andric if (const RecordDecl *RD = dyn_cast<RecordDecl>(D)) { 21940b57cec5SDimitry Andric // Warn if padding was introduced to the struct/class/union. 21950b57cec5SDimitry Andric if (getSizeInBits() > UnpaddedSize) { 21960b57cec5SDimitry Andric unsigned PadSize = getSizeInBits() - UnpaddedSize; 21970b57cec5SDimitry Andric bool InBits = true; 21980b57cec5SDimitry Andric if (PadSize % CharBitNum == 0) { 21990b57cec5SDimitry Andric PadSize = PadSize / CharBitNum; 22000b57cec5SDimitry Andric InBits = false; 22010b57cec5SDimitry Andric } 22020b57cec5SDimitry Andric Diag(RD->getLocation(), diag::warn_padded_struct_size) 22030b57cec5SDimitry Andric << Context.getTypeDeclType(RD) 22040b57cec5SDimitry Andric << PadSize 22050b57cec5SDimitry Andric << (InBits ? 1 : 0); // (byte|bit) 22060b57cec5SDimitry Andric } 22070b57cec5SDimitry Andric 220806c3fb27SDimitry Andric const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD); 220906c3fb27SDimitry Andric 22100b57cec5SDimitry Andric // Warn if we packed it unnecessarily, when the unpacked alignment is not 22110b57cec5SDimitry Andric // greater than the one after packing, the size in bits doesn't change and 22120b57cec5SDimitry Andric // the offset of each field is identical. 221306c3fb27SDimitry Andric // Unless the type is non-POD (for Clang ABI > 15), where the packed 221406c3fb27SDimitry Andric // attribute on such a type does allow the type to be packed into other 221506c3fb27SDimitry Andric // structures that use the packed attribute. 22160b57cec5SDimitry Andric if (Packed && UnpackedAlignment <= Alignment && 221706c3fb27SDimitry Andric UnpackedSizeInBits == getSizeInBits() && !HasPackedField && 221806c3fb27SDimitry Andric (!CXXRD || CXXRD->isPOD() || 221906c3fb27SDimitry Andric Context.getLangOpts().getClangABICompat() <= 222006c3fb27SDimitry Andric LangOptions::ClangABI::Ver15)) 22210b57cec5SDimitry Andric Diag(D->getLocation(), diag::warn_unnecessary_packed) 22220b57cec5SDimitry Andric << Context.getTypeDeclType(RD); 22230b57cec5SDimitry Andric } 22240b57cec5SDimitry Andric } 22250b57cec5SDimitry Andric 22260b57cec5SDimitry Andric void ItaniumRecordLayoutBuilder::UpdateAlignment( 2227e8d8bef9SDimitry Andric CharUnits NewAlignment, CharUnits UnpackedNewAlignment, 2228e8d8bef9SDimitry Andric CharUnits PreferredNewAlignment) { 22290b57cec5SDimitry Andric // The alignment is not modified when using 'mac68k' alignment or when 22300b57cec5SDimitry Andric // we have an externally-supplied layout that also provides overall alignment. 22310b57cec5SDimitry Andric if (IsMac68kAlign || (UseExternalLayout && !InferAlignment)) 22320b57cec5SDimitry Andric return; 22330b57cec5SDimitry Andric 22340b57cec5SDimitry Andric if (NewAlignment > Alignment) { 22350b57cec5SDimitry Andric assert(llvm::isPowerOf2_64(NewAlignment.getQuantity()) && 22360b57cec5SDimitry Andric "Alignment not a power of 2"); 22370b57cec5SDimitry Andric Alignment = NewAlignment; 22380b57cec5SDimitry Andric } 22390b57cec5SDimitry Andric 22400b57cec5SDimitry Andric if (UnpackedNewAlignment > UnpackedAlignment) { 22410b57cec5SDimitry Andric assert(llvm::isPowerOf2_64(UnpackedNewAlignment.getQuantity()) && 22420b57cec5SDimitry Andric "Alignment not a power of 2"); 22430b57cec5SDimitry Andric UnpackedAlignment = UnpackedNewAlignment; 22440b57cec5SDimitry Andric } 2245e8d8bef9SDimitry Andric 2246e8d8bef9SDimitry Andric if (PreferredNewAlignment > PreferredAlignment) { 2247e8d8bef9SDimitry Andric assert(llvm::isPowerOf2_64(PreferredNewAlignment.getQuantity()) && 2248e8d8bef9SDimitry Andric "Alignment not a power of 2"); 2249e8d8bef9SDimitry Andric PreferredAlignment = PreferredNewAlignment; 2250e8d8bef9SDimitry Andric } 22510b57cec5SDimitry Andric } 22520b57cec5SDimitry Andric 22530b57cec5SDimitry Andric uint64_t 22540b57cec5SDimitry Andric ItaniumRecordLayoutBuilder::updateExternalFieldOffset(const FieldDecl *Field, 22550b57cec5SDimitry Andric uint64_t ComputedOffset) { 22560b57cec5SDimitry Andric uint64_t ExternalFieldOffset = External.getExternalFieldOffset(Field); 22570b57cec5SDimitry Andric 22580b57cec5SDimitry Andric if (InferAlignment && ExternalFieldOffset < ComputedOffset) { 22590b57cec5SDimitry Andric // The externally-supplied field offset is before the field offset we 22600b57cec5SDimitry Andric // computed. Assume that the structure is packed. 22610b57cec5SDimitry Andric Alignment = CharUnits::One(); 2262e8d8bef9SDimitry Andric PreferredAlignment = CharUnits::One(); 22630b57cec5SDimitry Andric InferAlignment = false; 22640b57cec5SDimitry Andric } 22650b57cec5SDimitry Andric 22660b57cec5SDimitry Andric // Use the externally-supplied field offset. 22670b57cec5SDimitry Andric return ExternalFieldOffset; 22680b57cec5SDimitry Andric } 22690b57cec5SDimitry Andric 22700b57cec5SDimitry Andric /// Get diagnostic %select index for tag kind for 22710b57cec5SDimitry Andric /// field padding diagnostic message. 22720b57cec5SDimitry Andric /// WARNING: Indexes apply to particular diagnostics only! 22730b57cec5SDimitry Andric /// 22740b57cec5SDimitry Andric /// \returns diagnostic %select index. 22750b57cec5SDimitry Andric static unsigned getPaddingDiagFromTagKind(TagTypeKind Tag) { 22760b57cec5SDimitry Andric switch (Tag) { 22775f757f3fSDimitry Andric case TagTypeKind::Struct: 22785f757f3fSDimitry Andric return 0; 22795f757f3fSDimitry Andric case TagTypeKind::Interface: 22805f757f3fSDimitry Andric return 1; 22815f757f3fSDimitry Andric case TagTypeKind::Class: 22825f757f3fSDimitry Andric return 2; 22830b57cec5SDimitry Andric default: llvm_unreachable("Invalid tag kind for field padding diagnostic!"); 22840b57cec5SDimitry Andric } 22850b57cec5SDimitry Andric } 22860b57cec5SDimitry Andric 22870b57cec5SDimitry Andric void ItaniumRecordLayoutBuilder::CheckFieldPadding( 22880b57cec5SDimitry Andric uint64_t Offset, uint64_t UnpaddedOffset, uint64_t UnpackedOffset, 22890b57cec5SDimitry Andric unsigned UnpackedAlign, bool isPacked, const FieldDecl *D) { 22900b57cec5SDimitry Andric // We let objc ivars without warning, objc interfaces generally are not used 22910b57cec5SDimitry Andric // for padding tricks. 22920b57cec5SDimitry Andric if (isa<ObjCIvarDecl>(D)) 22930b57cec5SDimitry Andric return; 22940b57cec5SDimitry Andric 22950b57cec5SDimitry Andric // Don't warn about structs created without a SourceLocation. This can 22960b57cec5SDimitry Andric // be done by clients of the AST, such as codegen. 22970b57cec5SDimitry Andric if (D->getLocation().isInvalid()) 22980b57cec5SDimitry Andric return; 22990b57cec5SDimitry Andric 23000b57cec5SDimitry Andric unsigned CharBitNum = Context.getTargetInfo().getCharWidth(); 23010b57cec5SDimitry Andric 23020b57cec5SDimitry Andric // Warn if padding was introduced to the struct/class. 23030b57cec5SDimitry Andric if (!IsUnion && Offset > UnpaddedOffset) { 23040b57cec5SDimitry Andric unsigned PadSize = Offset - UnpaddedOffset; 23050b57cec5SDimitry Andric bool InBits = true; 23060b57cec5SDimitry Andric if (PadSize % CharBitNum == 0) { 23070b57cec5SDimitry Andric PadSize = PadSize / CharBitNum; 23080b57cec5SDimitry Andric InBits = false; 23090b57cec5SDimitry Andric } 23105f757f3fSDimitry Andric if (D->getIdentifier()) { 23115f757f3fSDimitry Andric auto Diagnostic = D->isBitField() ? diag::warn_padded_struct_bitfield 23125f757f3fSDimitry Andric : diag::warn_padded_struct_field; 23135f757f3fSDimitry Andric Diag(D->getLocation(), Diagnostic) 23140b57cec5SDimitry Andric << getPaddingDiagFromTagKind(D->getParent()->getTagKind()) 23155f757f3fSDimitry Andric << Context.getTypeDeclType(D->getParent()) << PadSize 23160b57cec5SDimitry Andric << (InBits ? 1 : 0) // (byte|bit) 23170b57cec5SDimitry Andric << D->getIdentifier(); 23185f757f3fSDimitry Andric } else { 23195f757f3fSDimitry Andric auto Diagnostic = D->isBitField() ? diag::warn_padded_struct_anon_bitfield 23205f757f3fSDimitry Andric : diag::warn_padded_struct_anon_field; 23215f757f3fSDimitry Andric Diag(D->getLocation(), Diagnostic) 23220b57cec5SDimitry Andric << getPaddingDiagFromTagKind(D->getParent()->getTagKind()) 23235f757f3fSDimitry Andric << Context.getTypeDeclType(D->getParent()) << PadSize 23240b57cec5SDimitry Andric << (InBits ? 1 : 0); // (byte|bit) 23250b57cec5SDimitry Andric } 23265f757f3fSDimitry Andric } 23270b57cec5SDimitry Andric if (isPacked && Offset != UnpackedOffset) { 23280b57cec5SDimitry Andric HasPackedField = true; 23290b57cec5SDimitry Andric } 23300b57cec5SDimitry Andric } 23310b57cec5SDimitry Andric 23320b57cec5SDimitry Andric static const CXXMethodDecl *computeKeyFunction(ASTContext &Context, 23330b57cec5SDimitry Andric const CXXRecordDecl *RD) { 23340b57cec5SDimitry Andric // If a class isn't polymorphic it doesn't have a key function. 23350b57cec5SDimitry Andric if (!RD->isPolymorphic()) 23360b57cec5SDimitry Andric return nullptr; 23370b57cec5SDimitry Andric 23380b57cec5SDimitry Andric // A class that is not externally visible doesn't have a key function. (Or 23390b57cec5SDimitry Andric // at least, there's no point to assigning a key function to such a class; 23400b57cec5SDimitry Andric // this doesn't affect the ABI.) 23410b57cec5SDimitry Andric if (!RD->isExternallyVisible()) 23420b57cec5SDimitry Andric return nullptr; 23430b57cec5SDimitry Andric 23440b57cec5SDimitry Andric // Template instantiations don't have key functions per Itanium C++ ABI 5.2.6. 23450b57cec5SDimitry Andric // Same behavior as GCC. 23460b57cec5SDimitry Andric TemplateSpecializationKind TSK = RD->getTemplateSpecializationKind(); 23470b57cec5SDimitry Andric if (TSK == TSK_ImplicitInstantiation || 23480b57cec5SDimitry Andric TSK == TSK_ExplicitInstantiationDeclaration || 23490b57cec5SDimitry Andric TSK == TSK_ExplicitInstantiationDefinition) 23500b57cec5SDimitry Andric return nullptr; 23510b57cec5SDimitry Andric 23520b57cec5SDimitry Andric bool allowInlineFunctions = 23530b57cec5SDimitry Andric Context.getTargetInfo().getCXXABI().canKeyFunctionBeInline(); 23540b57cec5SDimitry Andric 23550b57cec5SDimitry Andric for (const CXXMethodDecl *MD : RD->methods()) { 23560b57cec5SDimitry Andric if (!MD->isVirtual()) 23570b57cec5SDimitry Andric continue; 23580b57cec5SDimitry Andric 23597a6dacacSDimitry Andric if (MD->isPureVirtual()) 23600b57cec5SDimitry Andric continue; 23610b57cec5SDimitry Andric 23620b57cec5SDimitry Andric // Ignore implicit member functions, they are always marked as inline, but 23630b57cec5SDimitry Andric // they don't have a body until they're defined. 23640b57cec5SDimitry Andric if (MD->isImplicit()) 23650b57cec5SDimitry Andric continue; 23660b57cec5SDimitry Andric 23675ffd83dbSDimitry Andric if (MD->isInlineSpecified() || MD->isConstexpr()) 23680b57cec5SDimitry Andric continue; 23690b57cec5SDimitry Andric 23700b57cec5SDimitry Andric if (MD->hasInlineBody()) 23710b57cec5SDimitry Andric continue; 23720b57cec5SDimitry Andric 23730b57cec5SDimitry Andric // Ignore inline deleted or defaulted functions. 23740b57cec5SDimitry Andric if (!MD->isUserProvided()) 23750b57cec5SDimitry Andric continue; 23760b57cec5SDimitry Andric 23770b57cec5SDimitry Andric // In certain ABIs, ignore functions with out-of-line inline definitions. 23780b57cec5SDimitry Andric if (!allowInlineFunctions) { 23790b57cec5SDimitry Andric const FunctionDecl *Def; 23800b57cec5SDimitry Andric if (MD->hasBody(Def) && Def->isInlineSpecified()) 23810b57cec5SDimitry Andric continue; 23820b57cec5SDimitry Andric } 23830b57cec5SDimitry Andric 23840b57cec5SDimitry Andric if (Context.getLangOpts().CUDA) { 23850b57cec5SDimitry Andric // While compiler may see key method in this TU, during CUDA 23860b57cec5SDimitry Andric // compilation we should ignore methods that are not accessible 23870b57cec5SDimitry Andric // on this side of compilation. 23880b57cec5SDimitry Andric if (Context.getLangOpts().CUDAIsDevice) { 23890b57cec5SDimitry Andric // In device mode ignore methods without __device__ attribute. 23900b57cec5SDimitry Andric if (!MD->hasAttr<CUDADeviceAttr>()) 23910b57cec5SDimitry Andric continue; 23920b57cec5SDimitry Andric } else { 23930b57cec5SDimitry Andric // In host mode ignore __device__-only methods. 23940b57cec5SDimitry Andric if (!MD->hasAttr<CUDAHostAttr>() && MD->hasAttr<CUDADeviceAttr>()) 23950b57cec5SDimitry Andric continue; 23960b57cec5SDimitry Andric } 23970b57cec5SDimitry Andric } 23980b57cec5SDimitry Andric 23990b57cec5SDimitry Andric // If the key function is dllimport but the class isn't, then the class has 24000b57cec5SDimitry Andric // no key function. The DLL that exports the key function won't export the 24010b57cec5SDimitry Andric // vtable in this case. 2402fe6060f1SDimitry Andric if (MD->hasAttr<DLLImportAttr>() && !RD->hasAttr<DLLImportAttr>() && 2403fe6060f1SDimitry Andric !Context.getTargetInfo().hasPS4DLLImportExport()) 24040b57cec5SDimitry Andric return nullptr; 24050b57cec5SDimitry Andric 24060b57cec5SDimitry Andric // We found it. 24070b57cec5SDimitry Andric return MD; 24080b57cec5SDimitry Andric } 24090b57cec5SDimitry Andric 24100b57cec5SDimitry Andric return nullptr; 24110b57cec5SDimitry Andric } 24120b57cec5SDimitry Andric 24130b57cec5SDimitry Andric DiagnosticBuilder ItaniumRecordLayoutBuilder::Diag(SourceLocation Loc, 24140b57cec5SDimitry Andric unsigned DiagID) { 24150b57cec5SDimitry Andric return Context.getDiagnostics().Report(Loc, DiagID); 24160b57cec5SDimitry Andric } 24170b57cec5SDimitry Andric 24180b57cec5SDimitry Andric /// Does the target C++ ABI require us to skip over the tail-padding 24190b57cec5SDimitry Andric /// of the given class (considering it as a base class) when allocating 24200b57cec5SDimitry Andric /// objects? 24210b57cec5SDimitry Andric static bool mustSkipTailPadding(TargetCXXABI ABI, const CXXRecordDecl *RD) { 24220b57cec5SDimitry Andric switch (ABI.getTailPaddingUseRules()) { 24230b57cec5SDimitry Andric case TargetCXXABI::AlwaysUseTailPadding: 24240b57cec5SDimitry Andric return false; 24250b57cec5SDimitry Andric 24260b57cec5SDimitry Andric case TargetCXXABI::UseTailPaddingUnlessPOD03: 24270b57cec5SDimitry Andric // FIXME: To the extent that this is meant to cover the Itanium ABI 24280b57cec5SDimitry Andric // rules, we should implement the restrictions about over-sized 24290b57cec5SDimitry Andric // bitfields: 24300b57cec5SDimitry Andric // 24310b57cec5SDimitry Andric // http://itanium-cxx-abi.github.io/cxx-abi/abi.html#POD : 24320b57cec5SDimitry Andric // In general, a type is considered a POD for the purposes of 24330b57cec5SDimitry Andric // layout if it is a POD type (in the sense of ISO C++ 24340b57cec5SDimitry Andric // [basic.types]). However, a POD-struct or POD-union (in the 24350b57cec5SDimitry Andric // sense of ISO C++ [class]) with a bitfield member whose 24360b57cec5SDimitry Andric // declared width is wider than the declared type of the 24370b57cec5SDimitry Andric // bitfield is not a POD for the purpose of layout. Similarly, 24380b57cec5SDimitry Andric // an array type is not a POD for the purpose of layout if the 24390b57cec5SDimitry Andric // element type of the array is not a POD for the purpose of 24400b57cec5SDimitry Andric // layout. 24410b57cec5SDimitry Andric // 24420b57cec5SDimitry Andric // Where references to the ISO C++ are made in this paragraph, 24430b57cec5SDimitry Andric // the Technical Corrigendum 1 version of the standard is 24440b57cec5SDimitry Andric // intended. 24450b57cec5SDimitry Andric return RD->isPOD(); 24460b57cec5SDimitry Andric 24470b57cec5SDimitry Andric case TargetCXXABI::UseTailPaddingUnlessPOD11: 24480b57cec5SDimitry Andric // This is equivalent to RD->getTypeForDecl().isCXX11PODType(), 24490b57cec5SDimitry Andric // but with a lot of abstraction penalty stripped off. This does 24500b57cec5SDimitry Andric // assume that these properties are set correctly even in C++98 24510b57cec5SDimitry Andric // mode; fortunately, that is true because we want to assign 24520b57cec5SDimitry Andric // consistently semantics to the type-traits intrinsics (or at 24530b57cec5SDimitry Andric // least as many of them as possible). 24540b57cec5SDimitry Andric return RD->isTrivial() && RD->isCXX11StandardLayout(); 24550b57cec5SDimitry Andric } 24560b57cec5SDimitry Andric 24570b57cec5SDimitry Andric llvm_unreachable("bad tail-padding use kind"); 24580b57cec5SDimitry Andric } 24590b57cec5SDimitry Andric 24600b57cec5SDimitry Andric static bool isMsLayout(const ASTContext &Context) { 2461*0fca6ea1SDimitry Andric // Check if it's CUDA device compilation; ensure layout consistency with host. 2462*0fca6ea1SDimitry Andric if (Context.getLangOpts().CUDA && Context.getLangOpts().CUDAIsDevice && 2463*0fca6ea1SDimitry Andric Context.getAuxTargetInfo()) 2464*0fca6ea1SDimitry Andric return Context.getAuxTargetInfo()->getCXXABI().isMicrosoft(); 2465*0fca6ea1SDimitry Andric 24660b57cec5SDimitry Andric return Context.getTargetInfo().getCXXABI().isMicrosoft(); 24670b57cec5SDimitry Andric } 24680b57cec5SDimitry Andric 24690b57cec5SDimitry Andric // This section contains an implementation of struct layout that is, up to the 24700b57cec5SDimitry Andric // included tests, compatible with cl.exe (2013). The layout produced is 24710b57cec5SDimitry Andric // significantly different than those produced by the Itanium ABI. Here we note 24720b57cec5SDimitry Andric // the most important differences. 24730b57cec5SDimitry Andric // 24740b57cec5SDimitry Andric // * The alignment of bitfields in unions is ignored when computing the 24750b57cec5SDimitry Andric // alignment of the union. 24760b57cec5SDimitry Andric // * The existence of zero-width bitfield that occurs after anything other than 24770b57cec5SDimitry Andric // a non-zero length bitfield is ignored. 24780b57cec5SDimitry Andric // * There is no explicit primary base for the purposes of layout. All bases 24790b57cec5SDimitry Andric // with vfptrs are laid out first, followed by all bases without vfptrs. 24800b57cec5SDimitry Andric // * The Itanium equivalent vtable pointers are split into a vfptr (virtual 24810b57cec5SDimitry Andric // function pointer) and a vbptr (virtual base pointer). They can each be 24820b57cec5SDimitry Andric // shared with a, non-virtual bases. These bases need not be the same. vfptrs 24830b57cec5SDimitry Andric // always occur at offset 0. vbptrs can occur at an arbitrary offset and are 24840b57cec5SDimitry Andric // placed after the lexicographically last non-virtual base. This placement 24850b57cec5SDimitry Andric // is always before fields but can be in the middle of the non-virtual bases 24860b57cec5SDimitry Andric // due to the two-pass layout scheme for non-virtual-bases. 24870b57cec5SDimitry Andric // * Virtual bases sometimes require a 'vtordisp' field that is laid out before 24880b57cec5SDimitry Andric // the virtual base and is used in conjunction with virtual overrides during 24890b57cec5SDimitry Andric // construction and destruction. This is always a 4 byte value and is used as 24900b57cec5SDimitry Andric // an alternative to constructor vtables. 24910b57cec5SDimitry Andric // * vtordisps are allocated in a block of memory with size and alignment equal 24920b57cec5SDimitry Andric // to the alignment of the completed structure (before applying __declspec( 24930b57cec5SDimitry Andric // align())). The vtordisp always occur at the end of the allocation block, 24940b57cec5SDimitry Andric // immediately prior to the virtual base. 24950b57cec5SDimitry Andric // * vfptrs are injected after all bases and fields have been laid out. In 24960b57cec5SDimitry Andric // order to guarantee proper alignment of all fields, the vfptr injection 24970b57cec5SDimitry Andric // pushes all bases and fields back by the alignment imposed by those bases 24980b57cec5SDimitry Andric // and fields. This can potentially add a significant amount of padding. 24990b57cec5SDimitry Andric // vfptrs are always injected at offset 0. 25000b57cec5SDimitry Andric // * vbptrs are injected after all bases and fields have been laid out. In 25010b57cec5SDimitry Andric // order to guarantee proper alignment of all fields, the vfptr injection 25020b57cec5SDimitry Andric // pushes all bases and fields back by the alignment imposed by those bases 25030b57cec5SDimitry Andric // and fields. This can potentially add a significant amount of padding. 25040b57cec5SDimitry Andric // vbptrs are injected immediately after the last non-virtual base as 25050b57cec5SDimitry Andric // lexicographically ordered in the code. If this site isn't pointer aligned 25060b57cec5SDimitry Andric // the vbptr is placed at the next properly aligned location. Enough padding 25070b57cec5SDimitry Andric // is added to guarantee a fit. 25080b57cec5SDimitry Andric // * The last zero sized non-virtual base can be placed at the end of the 25090b57cec5SDimitry Andric // struct (potentially aliasing another object), or may alias with the first 25100b57cec5SDimitry Andric // field, even if they are of the same type. 25110b57cec5SDimitry Andric // * The last zero size virtual base may be placed at the end of the struct 25120b57cec5SDimitry Andric // potentially aliasing another object. 25130b57cec5SDimitry Andric // * The ABI attempts to avoid aliasing of zero sized bases by adding padding 25140b57cec5SDimitry Andric // between bases or vbases with specific properties. The criteria for 25150b57cec5SDimitry Andric // additional padding between two bases is that the first base is zero sized 25160b57cec5SDimitry Andric // or ends with a zero sized subobject and the second base is zero sized or 25170b57cec5SDimitry Andric // trails with a zero sized base or field (sharing of vfptrs can reorder the 25180b57cec5SDimitry Andric // layout of the so the leading base is not always the first one declared). 25190b57cec5SDimitry Andric // This rule does take into account fields that are not records, so padding 25200b57cec5SDimitry Andric // will occur even if the last field is, e.g. an int. The padding added for 25210b57cec5SDimitry Andric // bases is 1 byte. The padding added between vbases depends on the alignment 25220b57cec5SDimitry Andric // of the object but is at least 4 bytes (in both 32 and 64 bit modes). 25230b57cec5SDimitry Andric // * There is no concept of non-virtual alignment, non-virtual alignment and 25240b57cec5SDimitry Andric // alignment are always identical. 25250b57cec5SDimitry Andric // * There is a distinction between alignment and required alignment. 25260b57cec5SDimitry Andric // __declspec(align) changes the required alignment of a struct. This 25270b57cec5SDimitry Andric // alignment is _always_ obeyed, even in the presence of #pragma pack. A 25280b57cec5SDimitry Andric // record inherits required alignment from all of its fields and bases. 25290b57cec5SDimitry Andric // * __declspec(align) on bitfields has the effect of changing the bitfield's 25300b57cec5SDimitry Andric // alignment instead of its required alignment. This is the only known way 25310b57cec5SDimitry Andric // to make the alignment of a struct bigger than 8. Interestingly enough 25320b57cec5SDimitry Andric // this alignment is also immune to the effects of #pragma pack and can be 25330b57cec5SDimitry Andric // used to create structures with large alignment under #pragma pack. 25340b57cec5SDimitry Andric // However, because it does not impact required alignment, such a structure, 25350b57cec5SDimitry Andric // when used as a field or base, will not be aligned if #pragma pack is 25360b57cec5SDimitry Andric // still active at the time of use. 25370b57cec5SDimitry Andric // 25380b57cec5SDimitry Andric // Known incompatibilities: 25390b57cec5SDimitry Andric // * all: #pragma pack between fields in a record 25400b57cec5SDimitry Andric // * 2010 and back: If the last field in a record is a bitfield, every object 25410b57cec5SDimitry Andric // laid out after the record will have extra padding inserted before it. The 25420b57cec5SDimitry Andric // extra padding will have size equal to the size of the storage class of the 25430b57cec5SDimitry Andric // bitfield. 0 sized bitfields don't exhibit this behavior and the extra 25440b57cec5SDimitry Andric // padding can be avoided by adding a 0 sized bitfield after the non-zero- 25450b57cec5SDimitry Andric // sized bitfield. 25460b57cec5SDimitry Andric // * 2012 and back: In 64-bit mode, if the alignment of a record is 16 or 25470b57cec5SDimitry Andric // greater due to __declspec(align()) then a second layout phase occurs after 25480b57cec5SDimitry Andric // The locations of the vf and vb pointers are known. This layout phase 25490b57cec5SDimitry Andric // suffers from the "last field is a bitfield" bug in 2010 and results in 25500b57cec5SDimitry Andric // _every_ field getting padding put in front of it, potentially including the 25510b57cec5SDimitry Andric // vfptr, leaving the vfprt at a non-zero location which results in a fault if 25520b57cec5SDimitry Andric // anything tries to read the vftbl. The second layout phase also treats 25530b57cec5SDimitry Andric // bitfields as separate entities and gives them each storage rather than 25540b57cec5SDimitry Andric // packing them. Additionally, because this phase appears to perform a 25550b57cec5SDimitry Andric // (an unstable) sort on the members before laying them out and because merged 25560b57cec5SDimitry Andric // bitfields have the same address, the bitfields end up in whatever order 25570b57cec5SDimitry Andric // the sort left them in, a behavior we could never hope to replicate. 25580b57cec5SDimitry Andric 25590b57cec5SDimitry Andric namespace { 25600b57cec5SDimitry Andric struct MicrosoftRecordLayoutBuilder { 25610b57cec5SDimitry Andric struct ElementInfo { 25620b57cec5SDimitry Andric CharUnits Size; 25630b57cec5SDimitry Andric CharUnits Alignment; 25640b57cec5SDimitry Andric }; 25650b57cec5SDimitry Andric typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy; 25665f757f3fSDimitry Andric MicrosoftRecordLayoutBuilder(const ASTContext &Context, 25675f757f3fSDimitry Andric EmptySubobjectMap *EmptySubobjects) 25685f757f3fSDimitry Andric : Context(Context), EmptySubobjects(EmptySubobjects) {} 25695f757f3fSDimitry Andric 25700b57cec5SDimitry Andric private: 25710b57cec5SDimitry Andric MicrosoftRecordLayoutBuilder(const MicrosoftRecordLayoutBuilder &) = delete; 25720b57cec5SDimitry Andric void operator=(const MicrosoftRecordLayoutBuilder &) = delete; 25730b57cec5SDimitry Andric public: 25740b57cec5SDimitry Andric void layout(const RecordDecl *RD); 25750b57cec5SDimitry Andric void cxxLayout(const CXXRecordDecl *RD); 25760b57cec5SDimitry Andric /// Initializes size and alignment and honors some flags. 25770b57cec5SDimitry Andric void initializeLayout(const RecordDecl *RD); 25780b57cec5SDimitry Andric /// Initialized C++ layout, compute alignment and virtual alignment and 25790b57cec5SDimitry Andric /// existence of vfptrs and vbptrs. Alignment is needed before the vfptr is 25800b57cec5SDimitry Andric /// laid out. 25810b57cec5SDimitry Andric void initializeCXXLayout(const CXXRecordDecl *RD); 25820b57cec5SDimitry Andric void layoutNonVirtualBases(const CXXRecordDecl *RD); 25830b57cec5SDimitry Andric void layoutNonVirtualBase(const CXXRecordDecl *RD, 25840b57cec5SDimitry Andric const CXXRecordDecl *BaseDecl, 25850b57cec5SDimitry Andric const ASTRecordLayout &BaseLayout, 25860b57cec5SDimitry Andric const ASTRecordLayout *&PreviousBaseLayout); 25870b57cec5SDimitry Andric void injectVFPtr(const CXXRecordDecl *RD); 25880b57cec5SDimitry Andric void injectVBPtr(const CXXRecordDecl *RD); 25890b57cec5SDimitry Andric /// Lays out the fields of the record. Also rounds size up to 25900b57cec5SDimitry Andric /// alignment. 25910b57cec5SDimitry Andric void layoutFields(const RecordDecl *RD); 25920b57cec5SDimitry Andric void layoutField(const FieldDecl *FD); 25930b57cec5SDimitry Andric void layoutBitField(const FieldDecl *FD); 25940b57cec5SDimitry Andric /// Lays out a single zero-width bit-field in the record and handles 25950b57cec5SDimitry Andric /// special cases associated with zero-width bit-fields. 25960b57cec5SDimitry Andric void layoutZeroWidthBitField(const FieldDecl *FD); 25970b57cec5SDimitry Andric void layoutVirtualBases(const CXXRecordDecl *RD); 25980b57cec5SDimitry Andric void finalizeLayout(const RecordDecl *RD); 25990b57cec5SDimitry Andric /// Gets the size and alignment of a base taking pragma pack and 26000b57cec5SDimitry Andric /// __declspec(align) into account. 26010b57cec5SDimitry Andric ElementInfo getAdjustedElementInfo(const ASTRecordLayout &Layout); 26020b57cec5SDimitry Andric /// Gets the size and alignment of a field taking pragma pack and 26030b57cec5SDimitry Andric /// __declspec(align) into account. It also updates RequiredAlignment as a 26040b57cec5SDimitry Andric /// side effect because it is most convenient to do so here. 26050b57cec5SDimitry Andric ElementInfo getAdjustedElementInfo(const FieldDecl *FD); 26060b57cec5SDimitry Andric /// Places a field at an offset in CharUnits. 26070b57cec5SDimitry Andric void placeFieldAtOffset(CharUnits FieldOffset) { 26080b57cec5SDimitry Andric FieldOffsets.push_back(Context.toBits(FieldOffset)); 26090b57cec5SDimitry Andric } 26100b57cec5SDimitry Andric /// Places a bitfield at a bit offset. 26110b57cec5SDimitry Andric void placeFieldAtBitOffset(uint64_t FieldOffset) { 26120b57cec5SDimitry Andric FieldOffsets.push_back(FieldOffset); 26130b57cec5SDimitry Andric } 26140b57cec5SDimitry Andric /// Compute the set of virtual bases for which vtordisps are required. 26150b57cec5SDimitry Andric void computeVtorDispSet( 26160b57cec5SDimitry Andric llvm::SmallPtrSetImpl<const CXXRecordDecl *> &HasVtorDispSet, 26170b57cec5SDimitry Andric const CXXRecordDecl *RD) const; 26180b57cec5SDimitry Andric const ASTContext &Context; 26195f757f3fSDimitry Andric EmptySubobjectMap *EmptySubobjects; 26205f757f3fSDimitry Andric 26210b57cec5SDimitry Andric /// The size of the record being laid out. 26220b57cec5SDimitry Andric CharUnits Size; 26230b57cec5SDimitry Andric /// The non-virtual size of the record layout. 26240b57cec5SDimitry Andric CharUnits NonVirtualSize; 26250b57cec5SDimitry Andric /// The data size of the record layout. 26260b57cec5SDimitry Andric CharUnits DataSize; 26270b57cec5SDimitry Andric /// The current alignment of the record layout. 26280b57cec5SDimitry Andric CharUnits Alignment; 26290b57cec5SDimitry Andric /// The maximum allowed field alignment. This is set by #pragma pack. 26300b57cec5SDimitry Andric CharUnits MaxFieldAlignment; 26310b57cec5SDimitry Andric /// The alignment that this record must obey. This is imposed by 26320b57cec5SDimitry Andric /// __declspec(align()) on the record itself or one of its fields or bases. 26330b57cec5SDimitry Andric CharUnits RequiredAlignment; 26340b57cec5SDimitry Andric /// The size of the allocation of the currently active bitfield. 26350b57cec5SDimitry Andric /// This value isn't meaningful unless LastFieldIsNonZeroWidthBitfield 26360b57cec5SDimitry Andric /// is true. 26370b57cec5SDimitry Andric CharUnits CurrentBitfieldSize; 26380b57cec5SDimitry Andric /// Offset to the virtual base table pointer (if one exists). 26390b57cec5SDimitry Andric CharUnits VBPtrOffset; 26400b57cec5SDimitry Andric /// Minimum record size possible. 26410b57cec5SDimitry Andric CharUnits MinEmptyStructSize; 26420b57cec5SDimitry Andric /// The size and alignment info of a pointer. 26430b57cec5SDimitry Andric ElementInfo PointerInfo; 26440b57cec5SDimitry Andric /// The primary base class (if one exists). 26450b57cec5SDimitry Andric const CXXRecordDecl *PrimaryBase; 26460b57cec5SDimitry Andric /// The class we share our vb-pointer with. 26470b57cec5SDimitry Andric const CXXRecordDecl *SharedVBPtrBase; 26480b57cec5SDimitry Andric /// The collection of field offsets. 26490b57cec5SDimitry Andric SmallVector<uint64_t, 16> FieldOffsets; 26500b57cec5SDimitry Andric /// Base classes and their offsets in the record. 26510b57cec5SDimitry Andric BaseOffsetsMapTy Bases; 26520b57cec5SDimitry Andric /// virtual base classes and their offsets in the record. 26530b57cec5SDimitry Andric ASTRecordLayout::VBaseOffsetsMapTy VBases; 26540b57cec5SDimitry Andric /// The number of remaining bits in our last bitfield allocation. 26550b57cec5SDimitry Andric /// This value isn't meaningful unless LastFieldIsNonZeroWidthBitfield is 26560b57cec5SDimitry Andric /// true. 26570b57cec5SDimitry Andric unsigned RemainingBitsInField; 26580b57cec5SDimitry Andric bool IsUnion : 1; 26590b57cec5SDimitry Andric /// True if the last field laid out was a bitfield and was not 0 26600b57cec5SDimitry Andric /// width. 26610b57cec5SDimitry Andric bool LastFieldIsNonZeroWidthBitfield : 1; 26620b57cec5SDimitry Andric /// True if the class has its own vftable pointer. 26630b57cec5SDimitry Andric bool HasOwnVFPtr : 1; 26640b57cec5SDimitry Andric /// True if the class has a vbtable pointer. 26650b57cec5SDimitry Andric bool HasVBPtr : 1; 26660b57cec5SDimitry Andric /// True if the last sub-object within the type is zero sized or the 26670b57cec5SDimitry Andric /// object itself is zero sized. This *does not* count members that are not 26680b57cec5SDimitry Andric /// records. Only used for MS-ABI. 26690b57cec5SDimitry Andric bool EndsWithZeroSizedObject : 1; 26700b57cec5SDimitry Andric /// True if this class is zero sized or first base is zero sized or 26710b57cec5SDimitry Andric /// has this property. Only used for MS-ABI. 26720b57cec5SDimitry Andric bool LeadsWithZeroSizedBase : 1; 26730b57cec5SDimitry Andric 26740b57cec5SDimitry Andric /// True if the external AST source provided a layout for this record. 26750b57cec5SDimitry Andric bool UseExternalLayout : 1; 26760b57cec5SDimitry Andric 26770b57cec5SDimitry Andric /// The layout provided by the external AST source. Only active if 26780b57cec5SDimitry Andric /// UseExternalLayout is true. 26790b57cec5SDimitry Andric ExternalLayout External; 26800b57cec5SDimitry Andric }; 26810b57cec5SDimitry Andric } // namespace 26820b57cec5SDimitry Andric 26830b57cec5SDimitry Andric MicrosoftRecordLayoutBuilder::ElementInfo 26840b57cec5SDimitry Andric MicrosoftRecordLayoutBuilder::getAdjustedElementInfo( 26850b57cec5SDimitry Andric const ASTRecordLayout &Layout) { 26860b57cec5SDimitry Andric ElementInfo Info; 26870b57cec5SDimitry Andric Info.Alignment = Layout.getAlignment(); 26880b57cec5SDimitry Andric // Respect pragma pack. 26890b57cec5SDimitry Andric if (!MaxFieldAlignment.isZero()) 26900b57cec5SDimitry Andric Info.Alignment = std::min(Info.Alignment, MaxFieldAlignment); 26910b57cec5SDimitry Andric // Track zero-sized subobjects here where it's already available. 26920b57cec5SDimitry Andric EndsWithZeroSizedObject = Layout.endsWithZeroSizedObject(); 26930b57cec5SDimitry Andric // Respect required alignment, this is necessary because we may have adjusted 2694349cc55cSDimitry Andric // the alignment in the case of pragma pack. Note that the required alignment 26950b57cec5SDimitry Andric // doesn't actually apply to the struct alignment at this point. 26960b57cec5SDimitry Andric Alignment = std::max(Alignment, Info.Alignment); 26970b57cec5SDimitry Andric RequiredAlignment = std::max(RequiredAlignment, Layout.getRequiredAlignment()); 26980b57cec5SDimitry Andric Info.Alignment = std::max(Info.Alignment, Layout.getRequiredAlignment()); 26990b57cec5SDimitry Andric Info.Size = Layout.getNonVirtualSize(); 27000b57cec5SDimitry Andric return Info; 27010b57cec5SDimitry Andric } 27020b57cec5SDimitry Andric 27030b57cec5SDimitry Andric MicrosoftRecordLayoutBuilder::ElementInfo 27040b57cec5SDimitry Andric MicrosoftRecordLayoutBuilder::getAdjustedElementInfo( 27050b57cec5SDimitry Andric const FieldDecl *FD) { 27060b57cec5SDimitry Andric // Get the alignment of the field type's natural alignment, ignore any 27070b57cec5SDimitry Andric // alignment attributes. 2708e8d8bef9SDimitry Andric auto TInfo = 27090b57cec5SDimitry Andric Context.getTypeInfoInChars(FD->getType()->getUnqualifiedDesugaredType()); 2710e8d8bef9SDimitry Andric ElementInfo Info{TInfo.Width, TInfo.Align}; 27110b57cec5SDimitry Andric // Respect align attributes on the field. 27120b57cec5SDimitry Andric CharUnits FieldRequiredAlignment = 27130b57cec5SDimitry Andric Context.toCharUnitsFromBits(FD->getMaxAlignment()); 27140b57cec5SDimitry Andric // Respect align attributes on the type. 27150b57cec5SDimitry Andric if (Context.isAlignmentRequired(FD->getType())) 27160b57cec5SDimitry Andric FieldRequiredAlignment = std::max( 27170b57cec5SDimitry Andric Context.getTypeAlignInChars(FD->getType()), FieldRequiredAlignment); 27180b57cec5SDimitry Andric // Respect attributes applied to subobjects of the field. 27190b57cec5SDimitry Andric if (FD->isBitField()) 27200b57cec5SDimitry Andric // For some reason __declspec align impacts alignment rather than required 27210b57cec5SDimitry Andric // alignment when it is applied to bitfields. 27220b57cec5SDimitry Andric Info.Alignment = std::max(Info.Alignment, FieldRequiredAlignment); 27230b57cec5SDimitry Andric else { 27240b57cec5SDimitry Andric if (auto RT = 27250b57cec5SDimitry Andric FD->getType()->getBaseElementTypeUnsafe()->getAs<RecordType>()) { 27260b57cec5SDimitry Andric auto const &Layout = Context.getASTRecordLayout(RT->getDecl()); 27270b57cec5SDimitry Andric EndsWithZeroSizedObject = Layout.endsWithZeroSizedObject(); 27280b57cec5SDimitry Andric FieldRequiredAlignment = std::max(FieldRequiredAlignment, 27290b57cec5SDimitry Andric Layout.getRequiredAlignment()); 27300b57cec5SDimitry Andric } 27310b57cec5SDimitry Andric // Capture required alignment as a side-effect. 27320b57cec5SDimitry Andric RequiredAlignment = std::max(RequiredAlignment, FieldRequiredAlignment); 27330b57cec5SDimitry Andric } 27340b57cec5SDimitry Andric // Respect pragma pack, attribute pack and declspec align 27350b57cec5SDimitry Andric if (!MaxFieldAlignment.isZero()) 27360b57cec5SDimitry Andric Info.Alignment = std::min(Info.Alignment, MaxFieldAlignment); 27370b57cec5SDimitry Andric if (FD->hasAttr<PackedAttr>()) 27380b57cec5SDimitry Andric Info.Alignment = CharUnits::One(); 27390b57cec5SDimitry Andric Info.Alignment = std::max(Info.Alignment, FieldRequiredAlignment); 27400b57cec5SDimitry Andric return Info; 27410b57cec5SDimitry Andric } 27420b57cec5SDimitry Andric 27430b57cec5SDimitry Andric void MicrosoftRecordLayoutBuilder::layout(const RecordDecl *RD) { 27440b57cec5SDimitry Andric // For C record layout, zero-sized records always have size 4. 27450b57cec5SDimitry Andric MinEmptyStructSize = CharUnits::fromQuantity(4); 27460b57cec5SDimitry Andric initializeLayout(RD); 27470b57cec5SDimitry Andric layoutFields(RD); 27480b57cec5SDimitry Andric DataSize = Size = Size.alignTo(Alignment); 27490b57cec5SDimitry Andric RequiredAlignment = std::max( 27500b57cec5SDimitry Andric RequiredAlignment, Context.toCharUnitsFromBits(RD->getMaxAlignment())); 27510b57cec5SDimitry Andric finalizeLayout(RD); 27520b57cec5SDimitry Andric } 27530b57cec5SDimitry Andric 27540b57cec5SDimitry Andric void MicrosoftRecordLayoutBuilder::cxxLayout(const CXXRecordDecl *RD) { 27550b57cec5SDimitry Andric // The C++ standard says that empty structs have size 1. 27560b57cec5SDimitry Andric MinEmptyStructSize = CharUnits::One(); 27570b57cec5SDimitry Andric initializeLayout(RD); 27580b57cec5SDimitry Andric initializeCXXLayout(RD); 27590b57cec5SDimitry Andric layoutNonVirtualBases(RD); 27600b57cec5SDimitry Andric layoutFields(RD); 27610b57cec5SDimitry Andric injectVBPtr(RD); 27620b57cec5SDimitry Andric injectVFPtr(RD); 27630b57cec5SDimitry Andric if (HasOwnVFPtr || (HasVBPtr && !SharedVBPtrBase)) 27640b57cec5SDimitry Andric Alignment = std::max(Alignment, PointerInfo.Alignment); 27650b57cec5SDimitry Andric auto RoundingAlignment = Alignment; 27660b57cec5SDimitry Andric if (!MaxFieldAlignment.isZero()) 27670b57cec5SDimitry Andric RoundingAlignment = std::min(RoundingAlignment, MaxFieldAlignment); 27680b57cec5SDimitry Andric if (!UseExternalLayout) 27690b57cec5SDimitry Andric Size = Size.alignTo(RoundingAlignment); 27700b57cec5SDimitry Andric NonVirtualSize = Size; 27710b57cec5SDimitry Andric RequiredAlignment = std::max( 27720b57cec5SDimitry Andric RequiredAlignment, Context.toCharUnitsFromBits(RD->getMaxAlignment())); 27730b57cec5SDimitry Andric layoutVirtualBases(RD); 27740b57cec5SDimitry Andric finalizeLayout(RD); 27750b57cec5SDimitry Andric } 27760b57cec5SDimitry Andric 27770b57cec5SDimitry Andric void MicrosoftRecordLayoutBuilder::initializeLayout(const RecordDecl *RD) { 27780b57cec5SDimitry Andric IsUnion = RD->isUnion(); 27790b57cec5SDimitry Andric Size = CharUnits::Zero(); 27800b57cec5SDimitry Andric Alignment = CharUnits::One(); 27810b57cec5SDimitry Andric // In 64-bit mode we always perform an alignment step after laying out vbases. 27820b57cec5SDimitry Andric // In 32-bit mode we do not. The check to see if we need to perform alignment 27830b57cec5SDimitry Andric // checks the RequiredAlignment field and performs alignment if it isn't 0. 27840b57cec5SDimitry Andric RequiredAlignment = Context.getTargetInfo().getTriple().isArch64Bit() 27850b57cec5SDimitry Andric ? CharUnits::One() 27860b57cec5SDimitry Andric : CharUnits::Zero(); 27870b57cec5SDimitry Andric // Compute the maximum field alignment. 27880b57cec5SDimitry Andric MaxFieldAlignment = CharUnits::Zero(); 27890b57cec5SDimitry Andric // Honor the default struct packing maximum alignment flag. 27900b57cec5SDimitry Andric if (unsigned DefaultMaxFieldAlignment = Context.getLangOpts().PackStruct) 27910b57cec5SDimitry Andric MaxFieldAlignment = CharUnits::fromQuantity(DefaultMaxFieldAlignment); 27920b57cec5SDimitry Andric // Honor the packing attribute. The MS-ABI ignores pragma pack if its larger 27930b57cec5SDimitry Andric // than the pointer size. 27940b57cec5SDimitry Andric if (const MaxFieldAlignmentAttr *MFAA = RD->getAttr<MaxFieldAlignmentAttr>()){ 27950b57cec5SDimitry Andric unsigned PackedAlignment = MFAA->getAlignment(); 2796bdd1243dSDimitry Andric if (PackedAlignment <= 2797bdd1243dSDimitry Andric Context.getTargetInfo().getPointerWidth(LangAS::Default)) 27980b57cec5SDimitry Andric MaxFieldAlignment = Context.toCharUnitsFromBits(PackedAlignment); 27990b57cec5SDimitry Andric } 28000b57cec5SDimitry Andric // Packed attribute forces max field alignment to be 1. 28010b57cec5SDimitry Andric if (RD->hasAttr<PackedAttr>()) 28020b57cec5SDimitry Andric MaxFieldAlignment = CharUnits::One(); 28030b57cec5SDimitry Andric 28040b57cec5SDimitry Andric // Try to respect the external layout if present. 28050b57cec5SDimitry Andric UseExternalLayout = false; 28060b57cec5SDimitry Andric if (ExternalASTSource *Source = Context.getExternalSource()) 28070b57cec5SDimitry Andric UseExternalLayout = Source->layoutRecordType( 28080b57cec5SDimitry Andric RD, External.Size, External.Align, External.FieldOffsets, 28090b57cec5SDimitry Andric External.BaseOffsets, External.VirtualBaseOffsets); 28100b57cec5SDimitry Andric } 28110b57cec5SDimitry Andric 28120b57cec5SDimitry Andric void 28130b57cec5SDimitry Andric MicrosoftRecordLayoutBuilder::initializeCXXLayout(const CXXRecordDecl *RD) { 28140b57cec5SDimitry Andric EndsWithZeroSizedObject = false; 28150b57cec5SDimitry Andric LeadsWithZeroSizedBase = false; 28160b57cec5SDimitry Andric HasOwnVFPtr = false; 28170b57cec5SDimitry Andric HasVBPtr = false; 28180b57cec5SDimitry Andric PrimaryBase = nullptr; 28190b57cec5SDimitry Andric SharedVBPtrBase = nullptr; 28200b57cec5SDimitry Andric // Calculate pointer size and alignment. These are used for vfptr and vbprt 28210b57cec5SDimitry Andric // injection. 2822bdd1243dSDimitry Andric PointerInfo.Size = Context.toCharUnitsFromBits( 2823bdd1243dSDimitry Andric Context.getTargetInfo().getPointerWidth(LangAS::Default)); 2824bdd1243dSDimitry Andric PointerInfo.Alignment = Context.toCharUnitsFromBits( 2825bdd1243dSDimitry Andric Context.getTargetInfo().getPointerAlign(LangAS::Default)); 28260b57cec5SDimitry Andric // Respect pragma pack. 28270b57cec5SDimitry Andric if (!MaxFieldAlignment.isZero()) 28280b57cec5SDimitry Andric PointerInfo.Alignment = std::min(PointerInfo.Alignment, MaxFieldAlignment); 28290b57cec5SDimitry Andric } 28300b57cec5SDimitry Andric 28310b57cec5SDimitry Andric void 28320b57cec5SDimitry Andric MicrosoftRecordLayoutBuilder::layoutNonVirtualBases(const CXXRecordDecl *RD) { 28330b57cec5SDimitry Andric // The MS-ABI lays out all bases that contain leading vfptrs before it lays 28340b57cec5SDimitry Andric // out any bases that do not contain vfptrs. We implement this as two passes 28350b57cec5SDimitry Andric // over the bases. This approach guarantees that the primary base is laid out 28360b57cec5SDimitry Andric // first. We use these passes to calculate some additional aggregated 28370b57cec5SDimitry Andric // information about the bases, such as required alignment and the presence of 28380b57cec5SDimitry Andric // zero sized members. 28390b57cec5SDimitry Andric const ASTRecordLayout *PreviousBaseLayout = nullptr; 28405ffd83dbSDimitry Andric bool HasPolymorphicBaseClass = false; 28410b57cec5SDimitry Andric // Iterate through the bases and lay out the non-virtual ones. 28420b57cec5SDimitry Andric for (const CXXBaseSpecifier &Base : RD->bases()) { 28430b57cec5SDimitry Andric const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl(); 28445ffd83dbSDimitry Andric HasPolymorphicBaseClass |= BaseDecl->isPolymorphic(); 28450b57cec5SDimitry Andric const ASTRecordLayout &BaseLayout = Context.getASTRecordLayout(BaseDecl); 28460b57cec5SDimitry Andric // Mark and skip virtual bases. 28470b57cec5SDimitry Andric if (Base.isVirtual()) { 28480b57cec5SDimitry Andric HasVBPtr = true; 28490b57cec5SDimitry Andric continue; 28500b57cec5SDimitry Andric } 28510b57cec5SDimitry Andric // Check for a base to share a VBPtr with. 28520b57cec5SDimitry Andric if (!SharedVBPtrBase && BaseLayout.hasVBPtr()) { 28530b57cec5SDimitry Andric SharedVBPtrBase = BaseDecl; 28540b57cec5SDimitry Andric HasVBPtr = true; 28550b57cec5SDimitry Andric } 28560b57cec5SDimitry Andric // Only lay out bases with extendable VFPtrs on the first pass. 28570b57cec5SDimitry Andric if (!BaseLayout.hasExtendableVFPtr()) 28580b57cec5SDimitry Andric continue; 28590b57cec5SDimitry Andric // If we don't have a primary base, this one qualifies. 28600b57cec5SDimitry Andric if (!PrimaryBase) { 28610b57cec5SDimitry Andric PrimaryBase = BaseDecl; 28620b57cec5SDimitry Andric LeadsWithZeroSizedBase = BaseLayout.leadsWithZeroSizedBase(); 28630b57cec5SDimitry Andric } 28640b57cec5SDimitry Andric // Lay out the base. 28650b57cec5SDimitry Andric layoutNonVirtualBase(RD, BaseDecl, BaseLayout, PreviousBaseLayout); 28660b57cec5SDimitry Andric } 28670b57cec5SDimitry Andric // Figure out if we need a fresh VFPtr for this class. 28685ffd83dbSDimitry Andric if (RD->isPolymorphic()) { 28695ffd83dbSDimitry Andric if (!HasPolymorphicBaseClass) 28705ffd83dbSDimitry Andric // This class introduces polymorphism, so we need a vftable to store the 28715ffd83dbSDimitry Andric // RTTI information. 28725ffd83dbSDimitry Andric HasOwnVFPtr = true; 28735ffd83dbSDimitry Andric else if (!PrimaryBase) { 28745ffd83dbSDimitry Andric // We have a polymorphic base class but can't extend its vftable. Add a 28755ffd83dbSDimitry Andric // new vfptr if we would use any vftable slots. 28765ffd83dbSDimitry Andric for (CXXMethodDecl *M : RD->methods()) { 28775ffd83dbSDimitry Andric if (MicrosoftVTableContext::hasVtableSlot(M) && 28785ffd83dbSDimitry Andric M->size_overridden_methods() == 0) { 28795ffd83dbSDimitry Andric HasOwnVFPtr = true; 28805ffd83dbSDimitry Andric break; 28815ffd83dbSDimitry Andric } 28825ffd83dbSDimitry Andric } 28835ffd83dbSDimitry Andric } 28845ffd83dbSDimitry Andric } 28850b57cec5SDimitry Andric // If we don't have a primary base then we have a leading object that could 28860b57cec5SDimitry Andric // itself lead with a zero-sized object, something we track. 28870b57cec5SDimitry Andric bool CheckLeadingLayout = !PrimaryBase; 28880b57cec5SDimitry Andric // Iterate through the bases and lay out the non-virtual ones. 28890b57cec5SDimitry Andric for (const CXXBaseSpecifier &Base : RD->bases()) { 28900b57cec5SDimitry Andric if (Base.isVirtual()) 28910b57cec5SDimitry Andric continue; 28920b57cec5SDimitry Andric const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl(); 28930b57cec5SDimitry Andric const ASTRecordLayout &BaseLayout = Context.getASTRecordLayout(BaseDecl); 28940b57cec5SDimitry Andric // Only lay out bases without extendable VFPtrs on the second pass. 28950b57cec5SDimitry Andric if (BaseLayout.hasExtendableVFPtr()) { 28960b57cec5SDimitry Andric VBPtrOffset = Bases[BaseDecl] + BaseLayout.getNonVirtualSize(); 28970b57cec5SDimitry Andric continue; 28980b57cec5SDimitry Andric } 28990b57cec5SDimitry Andric // If this is the first layout, check to see if it leads with a zero sized 29000b57cec5SDimitry Andric // object. If it does, so do we. 29010b57cec5SDimitry Andric if (CheckLeadingLayout) { 29020b57cec5SDimitry Andric CheckLeadingLayout = false; 29030b57cec5SDimitry Andric LeadsWithZeroSizedBase = BaseLayout.leadsWithZeroSizedBase(); 29040b57cec5SDimitry Andric } 29050b57cec5SDimitry Andric // Lay out the base. 29060b57cec5SDimitry Andric layoutNonVirtualBase(RD, BaseDecl, BaseLayout, PreviousBaseLayout); 29070b57cec5SDimitry Andric VBPtrOffset = Bases[BaseDecl] + BaseLayout.getNonVirtualSize(); 29080b57cec5SDimitry Andric } 29090b57cec5SDimitry Andric // Set our VBPtroffset if we know it at this point. 29100b57cec5SDimitry Andric if (!HasVBPtr) 29110b57cec5SDimitry Andric VBPtrOffset = CharUnits::fromQuantity(-1); 29120b57cec5SDimitry Andric else if (SharedVBPtrBase) { 29130b57cec5SDimitry Andric const ASTRecordLayout &Layout = Context.getASTRecordLayout(SharedVBPtrBase); 29140b57cec5SDimitry Andric VBPtrOffset = Bases[SharedVBPtrBase] + Layout.getVBPtrOffset(); 29150b57cec5SDimitry Andric } 29160b57cec5SDimitry Andric } 29170b57cec5SDimitry Andric 29180b57cec5SDimitry Andric static bool recordUsesEBO(const RecordDecl *RD) { 29190b57cec5SDimitry Andric if (!isa<CXXRecordDecl>(RD)) 29200b57cec5SDimitry Andric return false; 29210b57cec5SDimitry Andric if (RD->hasAttr<EmptyBasesAttr>()) 29220b57cec5SDimitry Andric return true; 29230b57cec5SDimitry Andric if (auto *LVA = RD->getAttr<LayoutVersionAttr>()) 29240b57cec5SDimitry Andric // TODO: Double check with the next version of MSVC. 29250b57cec5SDimitry Andric if (LVA->getVersion() <= LangOptions::MSVC2015) 29260b57cec5SDimitry Andric return false; 29270b57cec5SDimitry Andric // TODO: Some later version of MSVC will change the default behavior of the 29280b57cec5SDimitry Andric // compiler to enable EBO by default. When this happens, we will need an 29290b57cec5SDimitry Andric // additional isCompatibleWithMSVC check. 29300b57cec5SDimitry Andric return false; 29310b57cec5SDimitry Andric } 29320b57cec5SDimitry Andric 29330b57cec5SDimitry Andric void MicrosoftRecordLayoutBuilder::layoutNonVirtualBase( 29345f757f3fSDimitry Andric const CXXRecordDecl *RD, const CXXRecordDecl *BaseDecl, 29350b57cec5SDimitry Andric const ASTRecordLayout &BaseLayout, 29360b57cec5SDimitry Andric const ASTRecordLayout *&PreviousBaseLayout) { 29370b57cec5SDimitry Andric // Insert padding between two bases if the left first one is zero sized or 29380b57cec5SDimitry Andric // contains a zero sized subobject and the right is zero sized or one leads 29390b57cec5SDimitry Andric // with a zero sized base. 29400b57cec5SDimitry Andric bool MDCUsesEBO = recordUsesEBO(RD); 29410b57cec5SDimitry Andric if (PreviousBaseLayout && PreviousBaseLayout->endsWithZeroSizedObject() && 29420b57cec5SDimitry Andric BaseLayout.leadsWithZeroSizedBase() && !MDCUsesEBO) 29430b57cec5SDimitry Andric Size++; 29440b57cec5SDimitry Andric ElementInfo Info = getAdjustedElementInfo(BaseLayout); 29450b57cec5SDimitry Andric CharUnits BaseOffset; 29460b57cec5SDimitry Andric 29470b57cec5SDimitry Andric // Respect the external AST source base offset, if present. 29480b57cec5SDimitry Andric bool FoundBase = false; 29490b57cec5SDimitry Andric if (UseExternalLayout) { 29500b57cec5SDimitry Andric FoundBase = External.getExternalNVBaseOffset(BaseDecl, BaseOffset); 295106c3fb27SDimitry Andric if (BaseOffset > Size) { 29520b57cec5SDimitry Andric Size = BaseOffset; 29530b57cec5SDimitry Andric } 29540b57cec5SDimitry Andric } 29550b57cec5SDimitry Andric 29560b57cec5SDimitry Andric if (!FoundBase) { 29575f757f3fSDimitry Andric if (MDCUsesEBO && BaseDecl->isEmpty() && 29585f757f3fSDimitry Andric (BaseLayout.getNonVirtualSize() == CharUnits::Zero())) { 29590b57cec5SDimitry Andric BaseOffset = CharUnits::Zero(); 29600b57cec5SDimitry Andric } else { 29610b57cec5SDimitry Andric // Otherwise, lay the base out at the end of the MDC. 29620b57cec5SDimitry Andric BaseOffset = Size = Size.alignTo(Info.Alignment); 29630b57cec5SDimitry Andric } 29640b57cec5SDimitry Andric } 29650b57cec5SDimitry Andric Bases.insert(std::make_pair(BaseDecl, BaseOffset)); 29660b57cec5SDimitry Andric Size += BaseLayout.getNonVirtualSize(); 29675f757f3fSDimitry Andric DataSize = Size; 29680b57cec5SDimitry Andric PreviousBaseLayout = &BaseLayout; 29690b57cec5SDimitry Andric } 29700b57cec5SDimitry Andric 29710b57cec5SDimitry Andric void MicrosoftRecordLayoutBuilder::layoutFields(const RecordDecl *RD) { 29720b57cec5SDimitry Andric LastFieldIsNonZeroWidthBitfield = false; 29730b57cec5SDimitry Andric for (const FieldDecl *Field : RD->fields()) 29740b57cec5SDimitry Andric layoutField(Field); 29750b57cec5SDimitry Andric } 29760b57cec5SDimitry Andric 29770b57cec5SDimitry Andric void MicrosoftRecordLayoutBuilder::layoutField(const FieldDecl *FD) { 29780b57cec5SDimitry Andric if (FD->isBitField()) { 29790b57cec5SDimitry Andric layoutBitField(FD); 29800b57cec5SDimitry Andric return; 29810b57cec5SDimitry Andric } 29820b57cec5SDimitry Andric LastFieldIsNonZeroWidthBitfield = false; 29830b57cec5SDimitry Andric ElementInfo Info = getAdjustedElementInfo(FD); 29840b57cec5SDimitry Andric Alignment = std::max(Alignment, Info.Alignment); 29855f757f3fSDimitry Andric 29865f757f3fSDimitry Andric const CXXRecordDecl *FieldClass = FD->getType()->getAsCXXRecordDecl(); 29875f757f3fSDimitry Andric bool IsOverlappingEmptyField = FD->isPotentiallyOverlapping() && 29885f757f3fSDimitry Andric FieldClass->isEmpty() && 29895f757f3fSDimitry Andric FieldClass->fields().empty(); 29905f757f3fSDimitry Andric CharUnits FieldOffset = CharUnits::Zero(); 29915f757f3fSDimitry Andric 29925f757f3fSDimitry Andric if (UseExternalLayout) { 29930b57cec5SDimitry Andric FieldOffset = 29940b57cec5SDimitry Andric Context.toCharUnitsFromBits(External.getExternalFieldOffset(FD)); 29955f757f3fSDimitry Andric } else if (IsUnion) { 29960b57cec5SDimitry Andric FieldOffset = CharUnits::Zero(); 29975f757f3fSDimitry Andric } else if (EmptySubobjects) { 29985f757f3fSDimitry Andric if (!IsOverlappingEmptyField) 29995f757f3fSDimitry Andric FieldOffset = DataSize.alignTo(Info.Alignment); 30005f757f3fSDimitry Andric 30015f757f3fSDimitry Andric while (!EmptySubobjects->CanPlaceFieldAtOffset(FD, FieldOffset)) { 30025f757f3fSDimitry Andric const CXXRecordDecl *ParentClass = cast<CXXRecordDecl>(FD->getParent()); 30035f757f3fSDimitry Andric bool HasBases = ParentClass && (!ParentClass->bases().empty() || 30045f757f3fSDimitry Andric !ParentClass->vbases().empty()); 30055f757f3fSDimitry Andric if (FieldOffset == CharUnits::Zero() && DataSize != CharUnits::Zero() && 30065f757f3fSDimitry Andric HasBases) { 30075f757f3fSDimitry Andric // MSVC appears to only do this when there are base classes; 30085f757f3fSDimitry Andric // otherwise it overlaps no_unique_address fields in non-zero offsets. 30095f757f3fSDimitry Andric FieldOffset = DataSize.alignTo(Info.Alignment); 30105f757f3fSDimitry Andric } else { 30115f757f3fSDimitry Andric FieldOffset += Info.Alignment; 30125f757f3fSDimitry Andric } 30135f757f3fSDimitry Andric } 30145f757f3fSDimitry Andric } else { 30150b57cec5SDimitry Andric FieldOffset = Size.alignTo(Info.Alignment); 30165f757f3fSDimitry Andric } 30170b57cec5SDimitry Andric placeFieldAtOffset(FieldOffset); 30185f757f3fSDimitry Andric 30195f757f3fSDimitry Andric if (!IsOverlappingEmptyField) 30205f757f3fSDimitry Andric DataSize = std::max(DataSize, FieldOffset + Info.Size); 30215f757f3fSDimitry Andric 30220b57cec5SDimitry Andric Size = std::max(Size, FieldOffset + Info.Size); 30230b57cec5SDimitry Andric } 30240b57cec5SDimitry Andric 30250b57cec5SDimitry Andric void MicrosoftRecordLayoutBuilder::layoutBitField(const FieldDecl *FD) { 30260b57cec5SDimitry Andric unsigned Width = FD->getBitWidthValue(Context); 30270b57cec5SDimitry Andric if (Width == 0) { 30280b57cec5SDimitry Andric layoutZeroWidthBitField(FD); 30290b57cec5SDimitry Andric return; 30300b57cec5SDimitry Andric } 30310b57cec5SDimitry Andric ElementInfo Info = getAdjustedElementInfo(FD); 30320b57cec5SDimitry Andric // Clamp the bitfield to a containable size for the sake of being able 30330b57cec5SDimitry Andric // to lay them out. Sema will throw an error. 30340b57cec5SDimitry Andric if (Width > Context.toBits(Info.Size)) 30350b57cec5SDimitry Andric Width = Context.toBits(Info.Size); 30360b57cec5SDimitry Andric // Check to see if this bitfield fits into an existing allocation. Note: 30370b57cec5SDimitry Andric // MSVC refuses to pack bitfields of formal types with different sizes 30380b57cec5SDimitry Andric // into the same allocation. 30390b57cec5SDimitry Andric if (!UseExternalLayout && !IsUnion && LastFieldIsNonZeroWidthBitfield && 30400b57cec5SDimitry Andric CurrentBitfieldSize == Info.Size && Width <= RemainingBitsInField) { 30410b57cec5SDimitry Andric placeFieldAtBitOffset(Context.toBits(Size) - RemainingBitsInField); 30420b57cec5SDimitry Andric RemainingBitsInField -= Width; 30430b57cec5SDimitry Andric return; 30440b57cec5SDimitry Andric } 30450b57cec5SDimitry Andric LastFieldIsNonZeroWidthBitfield = true; 30460b57cec5SDimitry Andric CurrentBitfieldSize = Info.Size; 30470b57cec5SDimitry Andric if (UseExternalLayout) { 30480b57cec5SDimitry Andric auto FieldBitOffset = External.getExternalFieldOffset(FD); 30490b57cec5SDimitry Andric placeFieldAtBitOffset(FieldBitOffset); 30500b57cec5SDimitry Andric auto NewSize = Context.toCharUnitsFromBits( 30510b57cec5SDimitry Andric llvm::alignDown(FieldBitOffset, Context.toBits(Info.Alignment)) + 30520b57cec5SDimitry Andric Context.toBits(Info.Size)); 30530b57cec5SDimitry Andric Size = std::max(Size, NewSize); 30540b57cec5SDimitry Andric Alignment = std::max(Alignment, Info.Alignment); 30550b57cec5SDimitry Andric } else if (IsUnion) { 30560b57cec5SDimitry Andric placeFieldAtOffset(CharUnits::Zero()); 30570b57cec5SDimitry Andric Size = std::max(Size, Info.Size); 30580b57cec5SDimitry Andric // TODO: Add a Sema warning that MS ignores bitfield alignment in unions. 30590b57cec5SDimitry Andric } else { 30600b57cec5SDimitry Andric // Allocate a new block of memory and place the bitfield in it. 30610b57cec5SDimitry Andric CharUnits FieldOffset = Size.alignTo(Info.Alignment); 30620b57cec5SDimitry Andric placeFieldAtOffset(FieldOffset); 30630b57cec5SDimitry Andric Size = FieldOffset + Info.Size; 30640b57cec5SDimitry Andric Alignment = std::max(Alignment, Info.Alignment); 30650b57cec5SDimitry Andric RemainingBitsInField = Context.toBits(Info.Size) - Width; 30660b57cec5SDimitry Andric } 30675f757f3fSDimitry Andric DataSize = Size; 30680b57cec5SDimitry Andric } 30690b57cec5SDimitry Andric 30700b57cec5SDimitry Andric void 30710b57cec5SDimitry Andric MicrosoftRecordLayoutBuilder::layoutZeroWidthBitField(const FieldDecl *FD) { 30720b57cec5SDimitry Andric // Zero-width bitfields are ignored unless they follow a non-zero-width 30730b57cec5SDimitry Andric // bitfield. 30740b57cec5SDimitry Andric if (!LastFieldIsNonZeroWidthBitfield) { 30750b57cec5SDimitry Andric placeFieldAtOffset(IsUnion ? CharUnits::Zero() : Size); 30760b57cec5SDimitry Andric // TODO: Add a Sema warning that MS ignores alignment for zero 30770b57cec5SDimitry Andric // sized bitfields that occur after zero-size bitfields or non-bitfields. 30780b57cec5SDimitry Andric return; 30790b57cec5SDimitry Andric } 30800b57cec5SDimitry Andric LastFieldIsNonZeroWidthBitfield = false; 30810b57cec5SDimitry Andric ElementInfo Info = getAdjustedElementInfo(FD); 30820b57cec5SDimitry Andric if (IsUnion) { 30830b57cec5SDimitry Andric placeFieldAtOffset(CharUnits::Zero()); 30840b57cec5SDimitry Andric Size = std::max(Size, Info.Size); 30850b57cec5SDimitry Andric // TODO: Add a Sema warning that MS ignores bitfield alignment in unions. 30860b57cec5SDimitry Andric } else { 30870b57cec5SDimitry Andric // Round up the current record size to the field's alignment boundary. 30880b57cec5SDimitry Andric CharUnits FieldOffset = Size.alignTo(Info.Alignment); 30890b57cec5SDimitry Andric placeFieldAtOffset(FieldOffset); 30900b57cec5SDimitry Andric Size = FieldOffset; 30910b57cec5SDimitry Andric Alignment = std::max(Alignment, Info.Alignment); 30920b57cec5SDimitry Andric } 30935f757f3fSDimitry Andric DataSize = Size; 30940b57cec5SDimitry Andric } 30950b57cec5SDimitry Andric 30960b57cec5SDimitry Andric void MicrosoftRecordLayoutBuilder::injectVBPtr(const CXXRecordDecl *RD) { 30970b57cec5SDimitry Andric if (!HasVBPtr || SharedVBPtrBase) 30980b57cec5SDimitry Andric return; 30990b57cec5SDimitry Andric // Inject the VBPointer at the injection site. 31000b57cec5SDimitry Andric CharUnits InjectionSite = VBPtrOffset; 31010b57cec5SDimitry Andric // But before we do, make sure it's properly aligned. 31020b57cec5SDimitry Andric VBPtrOffset = VBPtrOffset.alignTo(PointerInfo.Alignment); 31030b57cec5SDimitry Andric // Determine where the first field should be laid out after the vbptr. 31040b57cec5SDimitry Andric CharUnits FieldStart = VBPtrOffset + PointerInfo.Size; 31050b57cec5SDimitry Andric // Shift everything after the vbptr down, unless we're using an external 31060b57cec5SDimitry Andric // layout. 31070b57cec5SDimitry Andric if (UseExternalLayout) { 31080b57cec5SDimitry Andric // It is possible that there were no fields or bases located after vbptr, 31090b57cec5SDimitry Andric // so the size was not adjusted before. 31100b57cec5SDimitry Andric if (Size < FieldStart) 31110b57cec5SDimitry Andric Size = FieldStart; 31120b57cec5SDimitry Andric return; 31130b57cec5SDimitry Andric } 31140b57cec5SDimitry Andric // Make sure that the amount we push the fields back by is a multiple of the 31150b57cec5SDimitry Andric // alignment. 31160b57cec5SDimitry Andric CharUnits Offset = (FieldStart - InjectionSite) 31170b57cec5SDimitry Andric .alignTo(std::max(RequiredAlignment, Alignment)); 31180b57cec5SDimitry Andric Size += Offset; 31190b57cec5SDimitry Andric for (uint64_t &FieldOffset : FieldOffsets) 31200b57cec5SDimitry Andric FieldOffset += Context.toBits(Offset); 31210b57cec5SDimitry Andric for (BaseOffsetsMapTy::value_type &Base : Bases) 31220b57cec5SDimitry Andric if (Base.second >= InjectionSite) 31230b57cec5SDimitry Andric Base.second += Offset; 31240b57cec5SDimitry Andric } 31250b57cec5SDimitry Andric 31260b57cec5SDimitry Andric void MicrosoftRecordLayoutBuilder::injectVFPtr(const CXXRecordDecl *RD) { 31270b57cec5SDimitry Andric if (!HasOwnVFPtr) 31280b57cec5SDimitry Andric return; 31290b57cec5SDimitry Andric // Make sure that the amount we push the struct back by is a multiple of the 31300b57cec5SDimitry Andric // alignment. 31310b57cec5SDimitry Andric CharUnits Offset = 31320b57cec5SDimitry Andric PointerInfo.Size.alignTo(std::max(RequiredAlignment, Alignment)); 31330b57cec5SDimitry Andric // Push back the vbptr, but increase the size of the object and push back 31340b57cec5SDimitry Andric // regular fields by the offset only if not using external record layout. 31350b57cec5SDimitry Andric if (HasVBPtr) 31360b57cec5SDimitry Andric VBPtrOffset += Offset; 31370b57cec5SDimitry Andric 31380b57cec5SDimitry Andric if (UseExternalLayout) { 3139bdd1243dSDimitry Andric // The class may have size 0 and a vfptr (e.g. it's an interface class). The 3140bdd1243dSDimitry Andric // size was not correctly set before in this case. 3141bdd1243dSDimitry Andric if (Size.isZero()) 31420b57cec5SDimitry Andric Size += Offset; 31430b57cec5SDimitry Andric return; 31440b57cec5SDimitry Andric } 31450b57cec5SDimitry Andric 31460b57cec5SDimitry Andric Size += Offset; 31470b57cec5SDimitry Andric 31480b57cec5SDimitry Andric // If we're using an external layout, the fields offsets have already 31490b57cec5SDimitry Andric // accounted for this adjustment. 31500b57cec5SDimitry Andric for (uint64_t &FieldOffset : FieldOffsets) 31510b57cec5SDimitry Andric FieldOffset += Context.toBits(Offset); 31520b57cec5SDimitry Andric for (BaseOffsetsMapTy::value_type &Base : Bases) 31530b57cec5SDimitry Andric Base.second += Offset; 31540b57cec5SDimitry Andric } 31550b57cec5SDimitry Andric 31560b57cec5SDimitry Andric void MicrosoftRecordLayoutBuilder::layoutVirtualBases(const CXXRecordDecl *RD) { 31570b57cec5SDimitry Andric if (!HasVBPtr) 31580b57cec5SDimitry Andric return; 31590b57cec5SDimitry Andric // Vtordisps are always 4 bytes (even in 64-bit mode) 31600b57cec5SDimitry Andric CharUnits VtorDispSize = CharUnits::fromQuantity(4); 31610b57cec5SDimitry Andric CharUnits VtorDispAlignment = VtorDispSize; 31620b57cec5SDimitry Andric // vtordisps respect pragma pack. 31630b57cec5SDimitry Andric if (!MaxFieldAlignment.isZero()) 31640b57cec5SDimitry Andric VtorDispAlignment = std::min(VtorDispAlignment, MaxFieldAlignment); 31650b57cec5SDimitry Andric // The alignment of the vtordisp is at least the required alignment of the 31660b57cec5SDimitry Andric // entire record. This requirement may be present to support vtordisp 31670b57cec5SDimitry Andric // injection. 31680b57cec5SDimitry Andric for (const CXXBaseSpecifier &VBase : RD->vbases()) { 31690b57cec5SDimitry Andric const CXXRecordDecl *BaseDecl = VBase.getType()->getAsCXXRecordDecl(); 31700b57cec5SDimitry Andric const ASTRecordLayout &BaseLayout = Context.getASTRecordLayout(BaseDecl); 31710b57cec5SDimitry Andric RequiredAlignment = 31720b57cec5SDimitry Andric std::max(RequiredAlignment, BaseLayout.getRequiredAlignment()); 31730b57cec5SDimitry Andric } 31740b57cec5SDimitry Andric VtorDispAlignment = std::max(VtorDispAlignment, RequiredAlignment); 31750b57cec5SDimitry Andric // Compute the vtordisp set. 31760b57cec5SDimitry Andric llvm::SmallPtrSet<const CXXRecordDecl *, 2> HasVtorDispSet; 31770b57cec5SDimitry Andric computeVtorDispSet(HasVtorDispSet, RD); 31780b57cec5SDimitry Andric // Iterate through the virtual bases and lay them out. 31790b57cec5SDimitry Andric const ASTRecordLayout *PreviousBaseLayout = nullptr; 31800b57cec5SDimitry Andric for (const CXXBaseSpecifier &VBase : RD->vbases()) { 31810b57cec5SDimitry Andric const CXXRecordDecl *BaseDecl = VBase.getType()->getAsCXXRecordDecl(); 31820b57cec5SDimitry Andric const ASTRecordLayout &BaseLayout = Context.getASTRecordLayout(BaseDecl); 3183349cc55cSDimitry Andric bool HasVtordisp = HasVtorDispSet.contains(BaseDecl); 31840b57cec5SDimitry Andric // Insert padding between two bases if the left first one is zero sized or 31850b57cec5SDimitry Andric // contains a zero sized subobject and the right is zero sized or one leads 31860b57cec5SDimitry Andric // with a zero sized base. The padding between virtual bases is 4 31870b57cec5SDimitry Andric // bytes (in both 32 and 64 bits modes) and always involves rounding up to 31880b57cec5SDimitry Andric // the required alignment, we don't know why. 31890b57cec5SDimitry Andric if ((PreviousBaseLayout && PreviousBaseLayout->endsWithZeroSizedObject() && 31900b57cec5SDimitry Andric BaseLayout.leadsWithZeroSizedBase() && !recordUsesEBO(RD)) || 31910b57cec5SDimitry Andric HasVtordisp) { 31920b57cec5SDimitry Andric Size = Size.alignTo(VtorDispAlignment) + VtorDispSize; 31930b57cec5SDimitry Andric Alignment = std::max(VtorDispAlignment, Alignment); 31940b57cec5SDimitry Andric } 31950b57cec5SDimitry Andric // Insert the virtual base. 31960b57cec5SDimitry Andric ElementInfo Info = getAdjustedElementInfo(BaseLayout); 31970b57cec5SDimitry Andric CharUnits BaseOffset; 31980b57cec5SDimitry Andric 31990b57cec5SDimitry Andric // Respect the external AST source base offset, if present. 32000b57cec5SDimitry Andric if (UseExternalLayout) { 32010b57cec5SDimitry Andric if (!External.getExternalVBaseOffset(BaseDecl, BaseOffset)) 32020b57cec5SDimitry Andric BaseOffset = Size; 32030b57cec5SDimitry Andric } else 32040b57cec5SDimitry Andric BaseOffset = Size.alignTo(Info.Alignment); 32050b57cec5SDimitry Andric 32060b57cec5SDimitry Andric assert(BaseOffset >= Size && "base offset already allocated"); 32070b57cec5SDimitry Andric 32080b57cec5SDimitry Andric VBases.insert(std::make_pair(BaseDecl, 32090b57cec5SDimitry Andric ASTRecordLayout::VBaseInfo(BaseOffset, HasVtordisp))); 32100b57cec5SDimitry Andric Size = BaseOffset + BaseLayout.getNonVirtualSize(); 32110b57cec5SDimitry Andric PreviousBaseLayout = &BaseLayout; 32120b57cec5SDimitry Andric } 32130b57cec5SDimitry Andric } 32140b57cec5SDimitry Andric 32150b57cec5SDimitry Andric void MicrosoftRecordLayoutBuilder::finalizeLayout(const RecordDecl *RD) { 32160b57cec5SDimitry Andric // Respect required alignment. Note that in 32-bit mode Required alignment 32170b57cec5SDimitry Andric // may be 0 and cause size not to be updated. 32180b57cec5SDimitry Andric DataSize = Size; 32190b57cec5SDimitry Andric if (!RequiredAlignment.isZero()) { 32200b57cec5SDimitry Andric Alignment = std::max(Alignment, RequiredAlignment); 32210b57cec5SDimitry Andric auto RoundingAlignment = Alignment; 32220b57cec5SDimitry Andric if (!MaxFieldAlignment.isZero()) 32230b57cec5SDimitry Andric RoundingAlignment = std::min(RoundingAlignment, MaxFieldAlignment); 32240b57cec5SDimitry Andric RoundingAlignment = std::max(RoundingAlignment, RequiredAlignment); 32250b57cec5SDimitry Andric Size = Size.alignTo(RoundingAlignment); 32260b57cec5SDimitry Andric } 32270b57cec5SDimitry Andric if (Size.isZero()) { 32280b57cec5SDimitry Andric if (!recordUsesEBO(RD) || !cast<CXXRecordDecl>(RD)->isEmpty()) { 32290b57cec5SDimitry Andric EndsWithZeroSizedObject = true; 32300b57cec5SDimitry Andric LeadsWithZeroSizedBase = true; 32310b57cec5SDimitry Andric } 32320b57cec5SDimitry Andric // Zero-sized structures have size equal to their alignment if a 32330b57cec5SDimitry Andric // __declspec(align) came into play. 32340b57cec5SDimitry Andric if (RequiredAlignment >= MinEmptyStructSize) 32350b57cec5SDimitry Andric Size = Alignment; 32360b57cec5SDimitry Andric else 32370b57cec5SDimitry Andric Size = MinEmptyStructSize; 32380b57cec5SDimitry Andric } 32390b57cec5SDimitry Andric 32400b57cec5SDimitry Andric if (UseExternalLayout) { 32410b57cec5SDimitry Andric Size = Context.toCharUnitsFromBits(External.Size); 32420b57cec5SDimitry Andric if (External.Align) 32430b57cec5SDimitry Andric Alignment = Context.toCharUnitsFromBits(External.Align); 32440b57cec5SDimitry Andric } 32450b57cec5SDimitry Andric } 32460b57cec5SDimitry Andric 32470b57cec5SDimitry Andric // Recursively walks the non-virtual bases of a class and determines if any of 32480b57cec5SDimitry Andric // them are in the bases with overridden methods set. 32490b57cec5SDimitry Andric static bool 32500b57cec5SDimitry Andric RequiresVtordisp(const llvm::SmallPtrSetImpl<const CXXRecordDecl *> & 32510b57cec5SDimitry Andric BasesWithOverriddenMethods, 32520b57cec5SDimitry Andric const CXXRecordDecl *RD) { 32530b57cec5SDimitry Andric if (BasesWithOverriddenMethods.count(RD)) 32540b57cec5SDimitry Andric return true; 32550b57cec5SDimitry Andric // If any of a virtual bases non-virtual bases (recursively) requires a 32560b57cec5SDimitry Andric // vtordisp than so does this virtual base. 32570b57cec5SDimitry Andric for (const CXXBaseSpecifier &Base : RD->bases()) 32580b57cec5SDimitry Andric if (!Base.isVirtual() && 32590b57cec5SDimitry Andric RequiresVtordisp(BasesWithOverriddenMethods, 32600b57cec5SDimitry Andric Base.getType()->getAsCXXRecordDecl())) 32610b57cec5SDimitry Andric return true; 32620b57cec5SDimitry Andric return false; 32630b57cec5SDimitry Andric } 32640b57cec5SDimitry Andric 32650b57cec5SDimitry Andric void MicrosoftRecordLayoutBuilder::computeVtorDispSet( 32660b57cec5SDimitry Andric llvm::SmallPtrSetImpl<const CXXRecordDecl *> &HasVtordispSet, 32670b57cec5SDimitry Andric const CXXRecordDecl *RD) const { 32680b57cec5SDimitry Andric // /vd2 or #pragma vtordisp(2): Always use vtordisps for virtual bases with 32690b57cec5SDimitry Andric // vftables. 3270480093f4SDimitry Andric if (RD->getMSVtorDispMode() == MSVtorDispMode::ForVFTable) { 32710b57cec5SDimitry Andric for (const CXXBaseSpecifier &Base : RD->vbases()) { 32720b57cec5SDimitry Andric const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl(); 32730b57cec5SDimitry Andric const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl); 32740b57cec5SDimitry Andric if (Layout.hasExtendableVFPtr()) 32750b57cec5SDimitry Andric HasVtordispSet.insert(BaseDecl); 32760b57cec5SDimitry Andric } 32770b57cec5SDimitry Andric return; 32780b57cec5SDimitry Andric } 32790b57cec5SDimitry Andric 32800b57cec5SDimitry Andric // If any of our bases need a vtordisp for this type, so do we. Check our 32810b57cec5SDimitry Andric // direct bases for vtordisp requirements. 32820b57cec5SDimitry Andric for (const CXXBaseSpecifier &Base : RD->bases()) { 32830b57cec5SDimitry Andric const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl(); 32840b57cec5SDimitry Andric const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl); 32850b57cec5SDimitry Andric for (const auto &bi : Layout.getVBaseOffsetsMap()) 32860b57cec5SDimitry Andric if (bi.second.hasVtorDisp()) 32870b57cec5SDimitry Andric HasVtordispSet.insert(bi.first); 32880b57cec5SDimitry Andric } 32890b57cec5SDimitry Andric // We don't introduce any additional vtordisps if either: 32900b57cec5SDimitry Andric // * A user declared constructor or destructor aren't declared. 32910b57cec5SDimitry Andric // * #pragma vtordisp(0) or the /vd0 flag are in use. 32920b57cec5SDimitry Andric if ((!RD->hasUserDeclaredConstructor() && !RD->hasUserDeclaredDestructor()) || 3293480093f4SDimitry Andric RD->getMSVtorDispMode() == MSVtorDispMode::Never) 32940b57cec5SDimitry Andric return; 32950b57cec5SDimitry Andric // /vd1 or #pragma vtordisp(1): Try to guess based on whether we think it's 32960b57cec5SDimitry Andric // possible for a partially constructed object with virtual base overrides to 32970b57cec5SDimitry Andric // escape a non-trivial constructor. 3298480093f4SDimitry Andric assert(RD->getMSVtorDispMode() == MSVtorDispMode::ForVBaseOverride); 32990b57cec5SDimitry Andric // Compute a set of base classes which define methods we override. A virtual 33000b57cec5SDimitry Andric // base in this set will require a vtordisp. A virtual base that transitively 33010b57cec5SDimitry Andric // contains one of these bases as a non-virtual base will also require a 33020b57cec5SDimitry Andric // vtordisp. 33030b57cec5SDimitry Andric llvm::SmallPtrSet<const CXXMethodDecl *, 8> Work; 33040b57cec5SDimitry Andric llvm::SmallPtrSet<const CXXRecordDecl *, 2> BasesWithOverriddenMethods; 33050b57cec5SDimitry Andric // Seed the working set with our non-destructor, non-pure virtual methods. 33060b57cec5SDimitry Andric for (const CXXMethodDecl *MD : RD->methods()) 33075ffd83dbSDimitry Andric if (MicrosoftVTableContext::hasVtableSlot(MD) && 33087a6dacacSDimitry Andric !isa<CXXDestructorDecl>(MD) && !MD->isPureVirtual()) 33090b57cec5SDimitry Andric Work.insert(MD); 33100b57cec5SDimitry Andric while (!Work.empty()) { 33110b57cec5SDimitry Andric const CXXMethodDecl *MD = *Work.begin(); 33120b57cec5SDimitry Andric auto MethodRange = MD->overridden_methods(); 33130b57cec5SDimitry Andric // If a virtual method has no-overrides it lives in its parent's vtable. 33140b57cec5SDimitry Andric if (MethodRange.begin() == MethodRange.end()) 33150b57cec5SDimitry Andric BasesWithOverriddenMethods.insert(MD->getParent()); 33160b57cec5SDimitry Andric else 33170b57cec5SDimitry Andric Work.insert(MethodRange.begin(), MethodRange.end()); 33180b57cec5SDimitry Andric // We've finished processing this element, remove it from the working set. 33190b57cec5SDimitry Andric Work.erase(MD); 33200b57cec5SDimitry Andric } 33210b57cec5SDimitry Andric // For each of our virtual bases, check if it is in the set of overridden 33220b57cec5SDimitry Andric // bases or if it transitively contains a non-virtual base that is. 33230b57cec5SDimitry Andric for (const CXXBaseSpecifier &Base : RD->vbases()) { 33240b57cec5SDimitry Andric const CXXRecordDecl *BaseDecl = Base.getType()->getAsCXXRecordDecl(); 33250b57cec5SDimitry Andric if (!HasVtordispSet.count(BaseDecl) && 33260b57cec5SDimitry Andric RequiresVtordisp(BasesWithOverriddenMethods, BaseDecl)) 33270b57cec5SDimitry Andric HasVtordispSet.insert(BaseDecl); 33280b57cec5SDimitry Andric } 33290b57cec5SDimitry Andric } 33300b57cec5SDimitry Andric 33310b57cec5SDimitry Andric /// getASTRecordLayout - Get or compute information about the layout of the 33320b57cec5SDimitry Andric /// specified record (struct/union/class), which indicates its size and field 33330b57cec5SDimitry Andric /// position information. 33340b57cec5SDimitry Andric const ASTRecordLayout & 33350b57cec5SDimitry Andric ASTContext::getASTRecordLayout(const RecordDecl *D) const { 33360b57cec5SDimitry Andric // These asserts test different things. A record has a definition 33370b57cec5SDimitry Andric // as soon as we begin to parse the definition. That definition is 33380b57cec5SDimitry Andric // not a complete definition (which is what isDefinition() tests) 33390b57cec5SDimitry Andric // until we *finish* parsing the definition. 33400b57cec5SDimitry Andric 33410b57cec5SDimitry Andric if (D->hasExternalLexicalStorage() && !D->getDefinition()) 33420b57cec5SDimitry Andric getExternalSource()->CompleteType(const_cast<RecordDecl*>(D)); 3343bdd1243dSDimitry Andric // Complete the redecl chain (if necessary). 3344bdd1243dSDimitry Andric (void)D->getMostRecentDecl(); 33450b57cec5SDimitry Andric 33460b57cec5SDimitry Andric D = D->getDefinition(); 33470b57cec5SDimitry Andric assert(D && "Cannot get layout of forward declarations!"); 33480b57cec5SDimitry Andric assert(!D->isInvalidDecl() && "Cannot get layout of invalid decl!"); 33490b57cec5SDimitry Andric assert(D->isCompleteDefinition() && "Cannot layout type before complete!"); 33500b57cec5SDimitry Andric 33510b57cec5SDimitry Andric // Look up this layout, if already laid out, return what we have. 33520b57cec5SDimitry Andric // Note that we can't save a reference to the entry because this function 33530b57cec5SDimitry Andric // is recursive. 33540b57cec5SDimitry Andric const ASTRecordLayout *Entry = ASTRecordLayouts[D]; 33550b57cec5SDimitry Andric if (Entry) return *Entry; 33560b57cec5SDimitry Andric 33570b57cec5SDimitry Andric const ASTRecordLayout *NewEntry = nullptr; 33580b57cec5SDimitry Andric 33590b57cec5SDimitry Andric if (isMsLayout(*this)) { 33600b57cec5SDimitry Andric if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) { 33615f757f3fSDimitry Andric EmptySubobjectMap EmptySubobjects(*this, RD); 33625f757f3fSDimitry Andric MicrosoftRecordLayoutBuilder Builder(*this, &EmptySubobjects); 33630b57cec5SDimitry Andric Builder.cxxLayout(RD); 33640b57cec5SDimitry Andric NewEntry = new (*this) ASTRecordLayout( 33650b57cec5SDimitry Andric *this, Builder.Size, Builder.Alignment, Builder.Alignment, 3366e8d8bef9SDimitry Andric Builder.Alignment, Builder.RequiredAlignment, Builder.HasOwnVFPtr, 3367e8d8bef9SDimitry Andric Builder.HasOwnVFPtr || Builder.PrimaryBase, Builder.VBPtrOffset, 3368e8d8bef9SDimitry Andric Builder.DataSize, Builder.FieldOffsets, Builder.NonVirtualSize, 3369e8d8bef9SDimitry Andric Builder.Alignment, Builder.Alignment, CharUnits::Zero(), 33700b57cec5SDimitry Andric Builder.PrimaryBase, false, Builder.SharedVBPtrBase, 33710b57cec5SDimitry Andric Builder.EndsWithZeroSizedObject, Builder.LeadsWithZeroSizedBase, 33720b57cec5SDimitry Andric Builder.Bases, Builder.VBases); 33730b57cec5SDimitry Andric } else { 33745f757f3fSDimitry Andric MicrosoftRecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/nullptr); 33750b57cec5SDimitry Andric Builder.layout(D); 33760b57cec5SDimitry Andric NewEntry = new (*this) ASTRecordLayout( 33770b57cec5SDimitry Andric *this, Builder.Size, Builder.Alignment, Builder.Alignment, 3378e8d8bef9SDimitry Andric Builder.Alignment, Builder.RequiredAlignment, Builder.Size, 3379e8d8bef9SDimitry Andric Builder.FieldOffsets); 33800b57cec5SDimitry Andric } 33810b57cec5SDimitry Andric } else { 33820b57cec5SDimitry Andric if (const auto *RD = dyn_cast<CXXRecordDecl>(D)) { 33830b57cec5SDimitry Andric EmptySubobjectMap EmptySubobjects(*this, RD); 33840b57cec5SDimitry Andric ItaniumRecordLayoutBuilder Builder(*this, &EmptySubobjects); 33850b57cec5SDimitry Andric Builder.Layout(RD); 33860b57cec5SDimitry Andric 33870b57cec5SDimitry Andric // In certain situations, we are allowed to lay out objects in the 33880b57cec5SDimitry Andric // tail-padding of base classes. This is ABI-dependent. 33890b57cec5SDimitry Andric // FIXME: this should be stored in the record layout. 33900b57cec5SDimitry Andric bool skipTailPadding = 33910b57cec5SDimitry Andric mustSkipTailPadding(getTargetInfo().getCXXABI(), RD); 33920b57cec5SDimitry Andric 33930b57cec5SDimitry Andric // FIXME: This should be done in FinalizeLayout. 33940b57cec5SDimitry Andric CharUnits DataSize = 33950b57cec5SDimitry Andric skipTailPadding ? Builder.getSize() : Builder.getDataSize(); 33960b57cec5SDimitry Andric CharUnits NonVirtualSize = 33970b57cec5SDimitry Andric skipTailPadding ? DataSize : Builder.NonVirtualSize; 33980b57cec5SDimitry Andric NewEntry = new (*this) ASTRecordLayout( 3399e8d8bef9SDimitry Andric *this, Builder.getSize(), Builder.Alignment, 3400e8d8bef9SDimitry Andric Builder.PreferredAlignment, Builder.UnadjustedAlignment, 34010b57cec5SDimitry Andric /*RequiredAlignment : used by MS-ABI)*/ 34020b57cec5SDimitry Andric Builder.Alignment, Builder.HasOwnVFPtr, RD->isDynamicClass(), 34030b57cec5SDimitry Andric CharUnits::fromQuantity(-1), DataSize, Builder.FieldOffsets, 34040b57cec5SDimitry Andric NonVirtualSize, Builder.NonVirtualAlignment, 3405e8d8bef9SDimitry Andric Builder.PreferredNVAlignment, 34060b57cec5SDimitry Andric EmptySubobjects.SizeOfLargestEmptySubobject, Builder.PrimaryBase, 34070b57cec5SDimitry Andric Builder.PrimaryBaseIsVirtual, nullptr, false, false, Builder.Bases, 34080b57cec5SDimitry Andric Builder.VBases); 34090b57cec5SDimitry Andric } else { 34100b57cec5SDimitry Andric ItaniumRecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/nullptr); 34110b57cec5SDimitry Andric Builder.Layout(D); 34120b57cec5SDimitry Andric 34130b57cec5SDimitry Andric NewEntry = new (*this) ASTRecordLayout( 3414e8d8bef9SDimitry Andric *this, Builder.getSize(), Builder.Alignment, 3415e8d8bef9SDimitry Andric Builder.PreferredAlignment, Builder.UnadjustedAlignment, 34160b57cec5SDimitry Andric /*RequiredAlignment : used by MS-ABI)*/ 34170b57cec5SDimitry Andric Builder.Alignment, Builder.getSize(), Builder.FieldOffsets); 34180b57cec5SDimitry Andric } 34190b57cec5SDimitry Andric } 34200b57cec5SDimitry Andric 34210b57cec5SDimitry Andric ASTRecordLayouts[D] = NewEntry; 34220b57cec5SDimitry Andric 34230b57cec5SDimitry Andric if (getLangOpts().DumpRecordLayouts) { 34240b57cec5SDimitry Andric llvm::outs() << "\n*** Dumping AST Record Layout\n"; 34250b57cec5SDimitry Andric DumpRecordLayout(D, llvm::outs(), getLangOpts().DumpRecordLayoutsSimple); 34260b57cec5SDimitry Andric } 34270b57cec5SDimitry Andric 34280b57cec5SDimitry Andric return *NewEntry; 34290b57cec5SDimitry Andric } 34300b57cec5SDimitry Andric 34310b57cec5SDimitry Andric const CXXMethodDecl *ASTContext::getCurrentKeyFunction(const CXXRecordDecl *RD) { 34320b57cec5SDimitry Andric if (!getTargetInfo().getCXXABI().hasKeyFunctions()) 34330b57cec5SDimitry Andric return nullptr; 34340b57cec5SDimitry Andric 34350b57cec5SDimitry Andric assert(RD->getDefinition() && "Cannot get key function for forward decl!"); 34360b57cec5SDimitry Andric RD = RD->getDefinition(); 34370b57cec5SDimitry Andric 34380b57cec5SDimitry Andric // Beware: 34390b57cec5SDimitry Andric // 1) computing the key function might trigger deserialization, which might 34400b57cec5SDimitry Andric // invalidate iterators into KeyFunctions 34410b57cec5SDimitry Andric // 2) 'get' on the LazyDeclPtr might also trigger deserialization and 34420b57cec5SDimitry Andric // invalidate the LazyDeclPtr within the map itself 34430b57cec5SDimitry Andric LazyDeclPtr Entry = KeyFunctions[RD]; 34440b57cec5SDimitry Andric const Decl *Result = 34450b57cec5SDimitry Andric Entry ? Entry.get(getExternalSource()) : computeKeyFunction(*this, RD); 34460b57cec5SDimitry Andric 34470b57cec5SDimitry Andric // Store it back if it changed. 34480b57cec5SDimitry Andric if (Entry.isOffset() || Entry.isValid() != bool(Result)) 34490b57cec5SDimitry Andric KeyFunctions[RD] = const_cast<Decl*>(Result); 34500b57cec5SDimitry Andric 34510b57cec5SDimitry Andric return cast_or_null<CXXMethodDecl>(Result); 34520b57cec5SDimitry Andric } 34530b57cec5SDimitry Andric 34540b57cec5SDimitry Andric void ASTContext::setNonKeyFunction(const CXXMethodDecl *Method) { 34550b57cec5SDimitry Andric assert(Method == Method->getFirstDecl() && 34560b57cec5SDimitry Andric "not working with method declaration from class definition"); 34570b57cec5SDimitry Andric 34580b57cec5SDimitry Andric // Look up the cache entry. Since we're working with the first 34590b57cec5SDimitry Andric // declaration, its parent must be the class definition, which is 34600b57cec5SDimitry Andric // the correct key for the KeyFunctions hash. 34610b57cec5SDimitry Andric const auto &Map = KeyFunctions; 34620b57cec5SDimitry Andric auto I = Map.find(Method->getParent()); 34630b57cec5SDimitry Andric 34640b57cec5SDimitry Andric // If it's not cached, there's nothing to do. 34650b57cec5SDimitry Andric if (I == Map.end()) return; 34660b57cec5SDimitry Andric 34670b57cec5SDimitry Andric // If it is cached, check whether it's the target method, and if so, 34680b57cec5SDimitry Andric // remove it from the cache. Note, the call to 'get' might invalidate 34690b57cec5SDimitry Andric // the iterator and the LazyDeclPtr object within the map. 34700b57cec5SDimitry Andric LazyDeclPtr Ptr = I->second; 34710b57cec5SDimitry Andric if (Ptr.get(getExternalSource()) == Method) { 34720b57cec5SDimitry Andric // FIXME: remember that we did this for module / chained PCH state? 34730b57cec5SDimitry Andric KeyFunctions.erase(Method->getParent()); 34740b57cec5SDimitry Andric } 34750b57cec5SDimitry Andric } 34760b57cec5SDimitry Andric 34770b57cec5SDimitry Andric static uint64_t getFieldOffset(const ASTContext &C, const FieldDecl *FD) { 34780b57cec5SDimitry Andric const ASTRecordLayout &Layout = C.getASTRecordLayout(FD->getParent()); 34790b57cec5SDimitry Andric return Layout.getFieldOffset(FD->getFieldIndex()); 34800b57cec5SDimitry Andric } 34810b57cec5SDimitry Andric 34820b57cec5SDimitry Andric uint64_t ASTContext::getFieldOffset(const ValueDecl *VD) const { 34830b57cec5SDimitry Andric uint64_t OffsetInBits; 34840b57cec5SDimitry Andric if (const FieldDecl *FD = dyn_cast<FieldDecl>(VD)) { 34850b57cec5SDimitry Andric OffsetInBits = ::getFieldOffset(*this, FD); 34860b57cec5SDimitry Andric } else { 34870b57cec5SDimitry Andric const IndirectFieldDecl *IFD = cast<IndirectFieldDecl>(VD); 34880b57cec5SDimitry Andric 34890b57cec5SDimitry Andric OffsetInBits = 0; 34900b57cec5SDimitry Andric for (const NamedDecl *ND : IFD->chain()) 34910b57cec5SDimitry Andric OffsetInBits += ::getFieldOffset(*this, cast<FieldDecl>(ND)); 34920b57cec5SDimitry Andric } 34930b57cec5SDimitry Andric 34940b57cec5SDimitry Andric return OffsetInBits; 34950b57cec5SDimitry Andric } 34960b57cec5SDimitry Andric 34970b57cec5SDimitry Andric uint64_t ASTContext::lookupFieldBitOffset(const ObjCInterfaceDecl *OID, 34980b57cec5SDimitry Andric const ObjCImplementationDecl *ID, 34990b57cec5SDimitry Andric const ObjCIvarDecl *Ivar) const { 3500349cc55cSDimitry Andric Ivar = Ivar->getCanonicalDecl(); 35010b57cec5SDimitry Andric const ObjCInterfaceDecl *Container = Ivar->getContainingInterface(); 35020b57cec5SDimitry Andric 35030b57cec5SDimitry Andric // FIXME: We should eliminate the need to have ObjCImplementationDecl passed 35040b57cec5SDimitry Andric // in here; it should never be necessary because that should be the lexical 35050b57cec5SDimitry Andric // decl context for the ivar. 35060b57cec5SDimitry Andric 35070b57cec5SDimitry Andric // If we know have an implementation (and the ivar is in it) then 35080b57cec5SDimitry Andric // look up in the implementation layout. 35090b57cec5SDimitry Andric const ASTRecordLayout *RL; 35100b57cec5SDimitry Andric if (ID && declaresSameEntity(ID->getClassInterface(), Container)) 35110b57cec5SDimitry Andric RL = &getASTObjCImplementationLayout(ID); 35120b57cec5SDimitry Andric else 35130b57cec5SDimitry Andric RL = &getASTObjCInterfaceLayout(Container); 35140b57cec5SDimitry Andric 35150b57cec5SDimitry Andric // Compute field index. 35160b57cec5SDimitry Andric // 35170b57cec5SDimitry Andric // FIXME: The index here is closely tied to how ASTContext::getObjCLayout is 35180b57cec5SDimitry Andric // implemented. This should be fixed to get the information from the layout 35190b57cec5SDimitry Andric // directly. 35200b57cec5SDimitry Andric unsigned Index = 0; 35210b57cec5SDimitry Andric 35220b57cec5SDimitry Andric for (const ObjCIvarDecl *IVD = Container->all_declared_ivar_begin(); 35230b57cec5SDimitry Andric IVD; IVD = IVD->getNextIvar()) { 35240b57cec5SDimitry Andric if (Ivar == IVD) 35250b57cec5SDimitry Andric break; 35260b57cec5SDimitry Andric ++Index; 35270b57cec5SDimitry Andric } 35280b57cec5SDimitry Andric assert(Index < RL->getFieldCount() && "Ivar is not inside record layout!"); 35290b57cec5SDimitry Andric 35300b57cec5SDimitry Andric return RL->getFieldOffset(Index); 35310b57cec5SDimitry Andric } 35320b57cec5SDimitry Andric 35330b57cec5SDimitry Andric /// getObjCLayout - Get or compute information about the layout of the 35340b57cec5SDimitry Andric /// given interface. 35350b57cec5SDimitry Andric /// 35360b57cec5SDimitry Andric /// \param Impl - If given, also include the layout of the interface's 35370b57cec5SDimitry Andric /// implementation. This may differ by including synthesized ivars. 35380b57cec5SDimitry Andric const ASTRecordLayout & 35390b57cec5SDimitry Andric ASTContext::getObjCLayout(const ObjCInterfaceDecl *D, 35400b57cec5SDimitry Andric const ObjCImplementationDecl *Impl) const { 35410b57cec5SDimitry Andric // Retrieve the definition 35420b57cec5SDimitry Andric if (D->hasExternalLexicalStorage() && !D->getDefinition()) 35430b57cec5SDimitry Andric getExternalSource()->CompleteType(const_cast<ObjCInterfaceDecl*>(D)); 35440b57cec5SDimitry Andric D = D->getDefinition(); 35455ffd83dbSDimitry Andric assert(D && !D->isInvalidDecl() && D->isThisDeclarationADefinition() && 35465ffd83dbSDimitry Andric "Invalid interface decl!"); 35470b57cec5SDimitry Andric 35480b57cec5SDimitry Andric // Look up this layout, if already laid out, return what we have. 35490b57cec5SDimitry Andric const ObjCContainerDecl *Key = 35500b57cec5SDimitry Andric Impl ? (const ObjCContainerDecl*) Impl : (const ObjCContainerDecl*) D; 35510b57cec5SDimitry Andric if (const ASTRecordLayout *Entry = ObjCLayouts[Key]) 35520b57cec5SDimitry Andric return *Entry; 35530b57cec5SDimitry Andric 35540b57cec5SDimitry Andric // Add in synthesized ivar count if laying out an implementation. 35550b57cec5SDimitry Andric if (Impl) { 35560b57cec5SDimitry Andric unsigned SynthCount = CountNonClassIvars(D); 35570b57cec5SDimitry Andric // If there aren't any synthesized ivars then reuse the interface 35580b57cec5SDimitry Andric // entry. Note we can't cache this because we simply free all 35590b57cec5SDimitry Andric // entries later; however we shouldn't look up implementations 35600b57cec5SDimitry Andric // frequently. 35610b57cec5SDimitry Andric if (SynthCount == 0) 35620b57cec5SDimitry Andric return getObjCLayout(D, nullptr); 35630b57cec5SDimitry Andric } 35640b57cec5SDimitry Andric 35650b57cec5SDimitry Andric ItaniumRecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/nullptr); 35660b57cec5SDimitry Andric Builder.Layout(D); 35670b57cec5SDimitry Andric 3568e8d8bef9SDimitry Andric const ASTRecordLayout *NewEntry = new (*this) ASTRecordLayout( 3569e8d8bef9SDimitry Andric *this, Builder.getSize(), Builder.Alignment, Builder.PreferredAlignment, 35700b57cec5SDimitry Andric Builder.UnadjustedAlignment, 35710b57cec5SDimitry Andric /*RequiredAlignment : used by MS-ABI)*/ 3572e8d8bef9SDimitry Andric Builder.Alignment, Builder.getDataSize(), Builder.FieldOffsets); 35730b57cec5SDimitry Andric 35740b57cec5SDimitry Andric ObjCLayouts[Key] = NewEntry; 35750b57cec5SDimitry Andric 35760b57cec5SDimitry Andric return *NewEntry; 35770b57cec5SDimitry Andric } 35780b57cec5SDimitry Andric 35790b57cec5SDimitry Andric static void PrintOffset(raw_ostream &OS, 35800b57cec5SDimitry Andric CharUnits Offset, unsigned IndentLevel) { 35810b57cec5SDimitry Andric OS << llvm::format("%10" PRId64 " | ", (int64_t)Offset.getQuantity()); 35820b57cec5SDimitry Andric OS.indent(IndentLevel * 2); 35830b57cec5SDimitry Andric } 35840b57cec5SDimitry Andric 35850b57cec5SDimitry Andric static void PrintBitFieldOffset(raw_ostream &OS, CharUnits Offset, 35860b57cec5SDimitry Andric unsigned Begin, unsigned Width, 35870b57cec5SDimitry Andric unsigned IndentLevel) { 35880b57cec5SDimitry Andric llvm::SmallString<10> Buffer; 35890b57cec5SDimitry Andric { 35900b57cec5SDimitry Andric llvm::raw_svector_ostream BufferOS(Buffer); 35910b57cec5SDimitry Andric BufferOS << Offset.getQuantity() << ':'; 35920b57cec5SDimitry Andric if (Width == 0) { 35930b57cec5SDimitry Andric BufferOS << '-'; 35940b57cec5SDimitry Andric } else { 35950b57cec5SDimitry Andric BufferOS << Begin << '-' << (Begin + Width - 1); 35960b57cec5SDimitry Andric } 35970b57cec5SDimitry Andric } 35980b57cec5SDimitry Andric 35990b57cec5SDimitry Andric OS << llvm::right_justify(Buffer, 10) << " | "; 36000b57cec5SDimitry Andric OS.indent(IndentLevel * 2); 36010b57cec5SDimitry Andric } 36020b57cec5SDimitry Andric 36030b57cec5SDimitry Andric static void PrintIndentNoOffset(raw_ostream &OS, unsigned IndentLevel) { 36040b57cec5SDimitry Andric OS << " | "; 36050b57cec5SDimitry Andric OS.indent(IndentLevel * 2); 36060b57cec5SDimitry Andric } 36070b57cec5SDimitry Andric 36080b57cec5SDimitry Andric static void DumpRecordLayout(raw_ostream &OS, const RecordDecl *RD, 36090b57cec5SDimitry Andric const ASTContext &C, 36100b57cec5SDimitry Andric CharUnits Offset, 36110b57cec5SDimitry Andric unsigned IndentLevel, 36120b57cec5SDimitry Andric const char* Description, 36130b57cec5SDimitry Andric bool PrintSizeInfo, 36140b57cec5SDimitry Andric bool IncludeVirtualBases) { 36150b57cec5SDimitry Andric const ASTRecordLayout &Layout = C.getASTRecordLayout(RD); 36160b57cec5SDimitry Andric auto CXXRD = dyn_cast<CXXRecordDecl>(RD); 36170b57cec5SDimitry Andric 36180b57cec5SDimitry Andric PrintOffset(OS, Offset, IndentLevel); 361981ad6265SDimitry Andric OS << C.getTypeDeclType(const_cast<RecordDecl *>(RD)); 36200b57cec5SDimitry Andric if (Description) 36210b57cec5SDimitry Andric OS << ' ' << Description; 36220b57cec5SDimitry Andric if (CXXRD && CXXRD->isEmpty()) 36230b57cec5SDimitry Andric OS << " (empty)"; 36240b57cec5SDimitry Andric OS << '\n'; 36250b57cec5SDimitry Andric 36260b57cec5SDimitry Andric IndentLevel++; 36270b57cec5SDimitry Andric 36280b57cec5SDimitry Andric // Dump bases. 36290b57cec5SDimitry Andric if (CXXRD) { 36300b57cec5SDimitry Andric const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 36310b57cec5SDimitry Andric bool HasOwnVFPtr = Layout.hasOwnVFPtr(); 36320b57cec5SDimitry Andric bool HasOwnVBPtr = Layout.hasOwnVBPtr(); 36330b57cec5SDimitry Andric 36340b57cec5SDimitry Andric // Vtable pointer. 36350b57cec5SDimitry Andric if (CXXRD->isDynamicClass() && !PrimaryBase && !isMsLayout(C)) { 36360b57cec5SDimitry Andric PrintOffset(OS, Offset, IndentLevel); 36370b57cec5SDimitry Andric OS << '(' << *RD << " vtable pointer)\n"; 36380b57cec5SDimitry Andric } else if (HasOwnVFPtr) { 36390b57cec5SDimitry Andric PrintOffset(OS, Offset, IndentLevel); 36400b57cec5SDimitry Andric // vfptr (for Microsoft C++ ABI) 36410b57cec5SDimitry Andric OS << '(' << *RD << " vftable pointer)\n"; 36420b57cec5SDimitry Andric } 36430b57cec5SDimitry Andric 36440b57cec5SDimitry Andric // Collect nvbases. 36450b57cec5SDimitry Andric SmallVector<const CXXRecordDecl *, 4> Bases; 36460b57cec5SDimitry Andric for (const CXXBaseSpecifier &Base : CXXRD->bases()) { 36470b57cec5SDimitry Andric assert(!Base.getType()->isDependentType() && 36480b57cec5SDimitry Andric "Cannot layout class with dependent bases."); 36490b57cec5SDimitry Andric if (!Base.isVirtual()) 36500b57cec5SDimitry Andric Bases.push_back(Base.getType()->getAsCXXRecordDecl()); 36510b57cec5SDimitry Andric } 36520b57cec5SDimitry Andric 36530b57cec5SDimitry Andric // Sort nvbases by offset. 36540b57cec5SDimitry Andric llvm::stable_sort( 36550b57cec5SDimitry Andric Bases, [&](const CXXRecordDecl *L, const CXXRecordDecl *R) { 36560b57cec5SDimitry Andric return Layout.getBaseClassOffset(L) < Layout.getBaseClassOffset(R); 36570b57cec5SDimitry Andric }); 36580b57cec5SDimitry Andric 36590b57cec5SDimitry Andric // Dump (non-virtual) bases 36600b57cec5SDimitry Andric for (const CXXRecordDecl *Base : Bases) { 36610b57cec5SDimitry Andric CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(Base); 36620b57cec5SDimitry Andric DumpRecordLayout(OS, Base, C, BaseOffset, IndentLevel, 36630b57cec5SDimitry Andric Base == PrimaryBase ? "(primary base)" : "(base)", 36640b57cec5SDimitry Andric /*PrintSizeInfo=*/false, 36650b57cec5SDimitry Andric /*IncludeVirtualBases=*/false); 36660b57cec5SDimitry Andric } 36670b57cec5SDimitry Andric 36680b57cec5SDimitry Andric // vbptr (for Microsoft C++ ABI) 36690b57cec5SDimitry Andric if (HasOwnVBPtr) { 36700b57cec5SDimitry Andric PrintOffset(OS, Offset + Layout.getVBPtrOffset(), IndentLevel); 36710b57cec5SDimitry Andric OS << '(' << *RD << " vbtable pointer)\n"; 36720b57cec5SDimitry Andric } 36730b57cec5SDimitry Andric } 36740b57cec5SDimitry Andric 36750b57cec5SDimitry Andric // Dump fields. 36760b57cec5SDimitry Andric uint64_t FieldNo = 0; 36770b57cec5SDimitry Andric for (RecordDecl::field_iterator I = RD->field_begin(), 36780b57cec5SDimitry Andric E = RD->field_end(); I != E; ++I, ++FieldNo) { 36790b57cec5SDimitry Andric const FieldDecl &Field = **I; 36800b57cec5SDimitry Andric uint64_t LocalFieldOffsetInBits = Layout.getFieldOffset(FieldNo); 36810b57cec5SDimitry Andric CharUnits FieldOffset = 36820b57cec5SDimitry Andric Offset + C.toCharUnitsFromBits(LocalFieldOffsetInBits); 36830b57cec5SDimitry Andric 36840b57cec5SDimitry Andric // Recursively dump fields of record type. 36850b57cec5SDimitry Andric if (auto RT = Field.getType()->getAs<RecordType>()) { 36860b57cec5SDimitry Andric DumpRecordLayout(OS, RT->getDecl(), C, FieldOffset, IndentLevel, 36870b57cec5SDimitry Andric Field.getName().data(), 36880b57cec5SDimitry Andric /*PrintSizeInfo=*/false, 36890b57cec5SDimitry Andric /*IncludeVirtualBases=*/true); 36900b57cec5SDimitry Andric continue; 36910b57cec5SDimitry Andric } 36920b57cec5SDimitry Andric 36930b57cec5SDimitry Andric if (Field.isBitField()) { 36940b57cec5SDimitry Andric uint64_t LocalFieldByteOffsetInBits = C.toBits(FieldOffset - Offset); 36950b57cec5SDimitry Andric unsigned Begin = LocalFieldOffsetInBits - LocalFieldByteOffsetInBits; 36960b57cec5SDimitry Andric unsigned Width = Field.getBitWidthValue(C); 36970b57cec5SDimitry Andric PrintBitFieldOffset(OS, FieldOffset, Begin, Width, IndentLevel); 36980b57cec5SDimitry Andric } else { 36990b57cec5SDimitry Andric PrintOffset(OS, FieldOffset, IndentLevel); 37000b57cec5SDimitry Andric } 3701fe6060f1SDimitry Andric const QualType &FieldType = C.getLangOpts().DumpRecordLayoutsCanonical 3702fe6060f1SDimitry Andric ? Field.getType().getCanonicalType() 3703fe6060f1SDimitry Andric : Field.getType(); 370481ad6265SDimitry Andric OS << FieldType << ' ' << Field << '\n'; 37050b57cec5SDimitry Andric } 37060b57cec5SDimitry Andric 37070b57cec5SDimitry Andric // Dump virtual bases. 37080b57cec5SDimitry Andric if (CXXRD && IncludeVirtualBases) { 37090b57cec5SDimitry Andric const ASTRecordLayout::VBaseOffsetsMapTy &VtorDisps = 37100b57cec5SDimitry Andric Layout.getVBaseOffsetsMap(); 37110b57cec5SDimitry Andric 37120b57cec5SDimitry Andric for (const CXXBaseSpecifier &Base : CXXRD->vbases()) { 37130b57cec5SDimitry Andric assert(Base.isVirtual() && "Found non-virtual class!"); 37140b57cec5SDimitry Andric const CXXRecordDecl *VBase = Base.getType()->getAsCXXRecordDecl(); 37150b57cec5SDimitry Andric 37160b57cec5SDimitry Andric CharUnits VBaseOffset = Offset + Layout.getVBaseClassOffset(VBase); 37170b57cec5SDimitry Andric 37180b57cec5SDimitry Andric if (VtorDisps.find(VBase)->second.hasVtorDisp()) { 37190b57cec5SDimitry Andric PrintOffset(OS, VBaseOffset - CharUnits::fromQuantity(4), IndentLevel); 37200b57cec5SDimitry Andric OS << "(vtordisp for vbase " << *VBase << ")\n"; 37210b57cec5SDimitry Andric } 37220b57cec5SDimitry Andric 37230b57cec5SDimitry Andric DumpRecordLayout(OS, VBase, C, VBaseOffset, IndentLevel, 37240b57cec5SDimitry Andric VBase == Layout.getPrimaryBase() ? 37250b57cec5SDimitry Andric "(primary virtual base)" : "(virtual base)", 37260b57cec5SDimitry Andric /*PrintSizeInfo=*/false, 37270b57cec5SDimitry Andric /*IncludeVirtualBases=*/false); 37280b57cec5SDimitry Andric } 37290b57cec5SDimitry Andric } 37300b57cec5SDimitry Andric 37310b57cec5SDimitry Andric if (!PrintSizeInfo) return; 37320b57cec5SDimitry Andric 37330b57cec5SDimitry Andric PrintIndentNoOffset(OS, IndentLevel - 1); 37340b57cec5SDimitry Andric OS << "[sizeof=" << Layout.getSize().getQuantity(); 37350b57cec5SDimitry Andric if (CXXRD && !isMsLayout(C)) 37360b57cec5SDimitry Andric OS << ", dsize=" << Layout.getDataSize().getQuantity(); 37370b57cec5SDimitry Andric OS << ", align=" << Layout.getAlignment().getQuantity(); 3738e8d8bef9SDimitry Andric if (C.getTargetInfo().defaultsToAIXPowerAlignment()) 3739e8d8bef9SDimitry Andric OS << ", preferredalign=" << Layout.getPreferredAlignment().getQuantity(); 37400b57cec5SDimitry Andric 37410b57cec5SDimitry Andric if (CXXRD) { 37420b57cec5SDimitry Andric OS << ",\n"; 37430b57cec5SDimitry Andric PrintIndentNoOffset(OS, IndentLevel - 1); 37440b57cec5SDimitry Andric OS << " nvsize=" << Layout.getNonVirtualSize().getQuantity(); 37450b57cec5SDimitry Andric OS << ", nvalign=" << Layout.getNonVirtualAlignment().getQuantity(); 3746e8d8bef9SDimitry Andric if (C.getTargetInfo().defaultsToAIXPowerAlignment()) 3747e8d8bef9SDimitry Andric OS << ", preferrednvalign=" 3748e8d8bef9SDimitry Andric << Layout.getPreferredNVAlignment().getQuantity(); 37490b57cec5SDimitry Andric } 37500b57cec5SDimitry Andric OS << "]\n"; 37510b57cec5SDimitry Andric } 37520b57cec5SDimitry Andric 3753e8d8bef9SDimitry Andric void ASTContext::DumpRecordLayout(const RecordDecl *RD, raw_ostream &OS, 37540b57cec5SDimitry Andric bool Simple) const { 37550b57cec5SDimitry Andric if (!Simple) { 37560b57cec5SDimitry Andric ::DumpRecordLayout(OS, RD, *this, CharUnits(), 0, nullptr, 37570b57cec5SDimitry Andric /*PrintSizeInfo*/ true, 37580b57cec5SDimitry Andric /*IncludeVirtualBases=*/true); 37590b57cec5SDimitry Andric return; 37600b57cec5SDimitry Andric } 37610b57cec5SDimitry Andric 37620b57cec5SDimitry Andric // The "simple" format is designed to be parsed by the 37630b57cec5SDimitry Andric // layout-override testing code. There shouldn't be any external 37640b57cec5SDimitry Andric // uses of this format --- when LLDB overrides a layout, it sets up 37650b57cec5SDimitry Andric // the data structures directly --- so feel free to adjust this as 37660b57cec5SDimitry Andric // you like as long as you also update the rudimentary parser for it 37670b57cec5SDimitry Andric // in libFrontend. 37680b57cec5SDimitry Andric 37690b57cec5SDimitry Andric const ASTRecordLayout &Info = getASTRecordLayout(RD); 377081ad6265SDimitry Andric OS << "Type: " << getTypeDeclType(RD) << "\n"; 37710b57cec5SDimitry Andric OS << "\nLayout: "; 37720b57cec5SDimitry Andric OS << "<ASTRecordLayout\n"; 37730b57cec5SDimitry Andric OS << " Size:" << toBits(Info.getSize()) << "\n"; 37740b57cec5SDimitry Andric if (!isMsLayout(*this)) 37750b57cec5SDimitry Andric OS << " DataSize:" << toBits(Info.getDataSize()) << "\n"; 37760b57cec5SDimitry Andric OS << " Alignment:" << toBits(Info.getAlignment()) << "\n"; 3777e8d8bef9SDimitry Andric if (Target->defaultsToAIXPowerAlignment()) 3778e8d8bef9SDimitry Andric OS << " PreferredAlignment:" << toBits(Info.getPreferredAlignment()) 3779e8d8bef9SDimitry Andric << "\n"; 378006c3fb27SDimitry Andric if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) { 378106c3fb27SDimitry Andric OS << " BaseOffsets: ["; 378206c3fb27SDimitry Andric const CXXRecordDecl *Base = nullptr; 378306c3fb27SDimitry Andric for (auto I : CXXRD->bases()) { 378406c3fb27SDimitry Andric if (I.isVirtual()) 378506c3fb27SDimitry Andric continue; 378606c3fb27SDimitry Andric if (Base) 378706c3fb27SDimitry Andric OS << ", "; 378806c3fb27SDimitry Andric Base = I.getType()->getAsCXXRecordDecl(); 378906c3fb27SDimitry Andric OS << Info.CXXInfo->BaseOffsets[Base].getQuantity(); 379006c3fb27SDimitry Andric } 379106c3fb27SDimitry Andric OS << "]>\n"; 379206c3fb27SDimitry Andric OS << " VBaseOffsets: ["; 379306c3fb27SDimitry Andric const CXXRecordDecl *VBase = nullptr; 379406c3fb27SDimitry Andric for (auto I : CXXRD->vbases()) { 379506c3fb27SDimitry Andric if (VBase) 379606c3fb27SDimitry Andric OS << ", "; 379706c3fb27SDimitry Andric VBase = I.getType()->getAsCXXRecordDecl(); 379806c3fb27SDimitry Andric OS << Info.CXXInfo->VBaseOffsets[VBase].VBaseOffset.getQuantity(); 379906c3fb27SDimitry Andric } 380006c3fb27SDimitry Andric OS << "]>\n"; 380106c3fb27SDimitry Andric } 38020b57cec5SDimitry Andric OS << " FieldOffsets: ["; 38030b57cec5SDimitry Andric for (unsigned i = 0, e = Info.getFieldCount(); i != e; ++i) { 3804e8d8bef9SDimitry Andric if (i) 3805e8d8bef9SDimitry Andric OS << ", "; 38060b57cec5SDimitry Andric OS << Info.getFieldOffset(i); 38070b57cec5SDimitry Andric } 38080b57cec5SDimitry Andric OS << "]>\n"; 38090b57cec5SDimitry Andric } 3810