xref: /freebsd-src/contrib/llvm-project/clang/lib/AST/RecordLayoutBuilder.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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