RecordLayoutBuilder.cpp revision 812a3456b63708a5972f712e9e4b54d3cc436378
19392fa63e45716e32061d05673fa28909f325b02Anders Carlsson//=== RecordLayoutBuilder.cpp - Helper class for building record layouts ---==// 2bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson// 3bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson// The LLVM Compiler Infrastructure 4bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson// 5bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson// This file is distributed under the University of Illinois Open Source 6bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson// License. See LICENSE.TXT for details. 7bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson// 8bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson//===----------------------------------------------------------------------===// 9bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 10bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson#include "clang/AST/Attr.h" 11bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson#include "clang/AST/Decl.h" 1274cbe226207fd101623638dadfa7fbada04ff2a6Anders Carlsson#include "clang/AST/DeclCXX.h" 1393fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson#include "clang/AST/DeclObjC.h" 14bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson#include "clang/AST/Expr.h" 159392fa63e45716e32061d05673fa28909f325b02Anders Carlsson#include "clang/AST/RecordLayout.h" 16bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson#include "clang/Basic/TargetInfo.h" 17bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar#include "llvm/Support/Format.h" 18bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar#include "llvm/ADT/SmallSet.h" 19bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar#include "llvm/Support/MathExtras.h" 209392fa63e45716e32061d05673fa28909f325b02Anders Carlsson#include <map> 21bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 22bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlssonusing namespace clang; 23bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 247e220286410422ed1dc0409a9cb9708fe50e3df0Benjamin Kramernamespace { 256a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson 266a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson/// EmptySubobjectMap - Keeps track of which empty subobjects exist at different 276a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson/// offsets while laying out a C++ class. 286a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlssonclass EmptySubobjectMap { 296a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson ASTContext &Context; 300aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 316a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson /// Class - The class whose empty entries we're keeping track of. 326a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson const CXXRecordDecl *Class; 330aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 3458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson /// EmptyClassOffsets - A map from offsets to empty record decls. 3558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson typedef llvm::SmallVector<const CXXRecordDecl *, 1> ClassVectorTy; 3658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson typedef llvm::DenseMap<uint64_t, ClassVectorTy> EmptyClassOffsetsMapTy; 3758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson EmptyClassOffsetsMapTy EmptyClassOffsets; 3858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 390aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// ComputeEmptySubobjectSizes - Compute the size of the largest base or 400c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson /// member subobject that is empty. 410c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson void ComputeEmptySubobjectSizes(); 420aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 4358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson struct BaseInfo { 4458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson const CXXRecordDecl *Class; 4558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson bool IsVirtual; 4658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 4758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson const CXXRecordDecl *PrimaryVirtualBase; 4858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 4958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson llvm::SmallVector<BaseInfo*, 4> Bases; 5058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson const BaseInfo *Derived; 5158b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson }; 5258b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 5358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson llvm::DenseMap<const CXXRecordDecl *, BaseInfo *> VirtualBaseInfo; 5458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson llvm::DenseMap<const CXXRecordDecl *, BaseInfo *> NonVirtualBaseInfo; 5558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 5658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson BaseInfo *ComputeBaseInfo(const CXXRecordDecl *RD, bool IsVirtual, 5758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson const BaseInfo *Derived); 5858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson void ComputeBaseInfo(); 5958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 60812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson bool CanPlaceSubobjectAtOffset(const CXXRecordDecl *RD, uint64_t Offset); 61812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson void AddSubobjectAtOffset(const CXXRecordDecl *RD, uint64_t Offset); 62812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 6358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson bool CanPlaceBaseSubobjectAtOffset(const BaseInfo *Info, uint64_t Offset); 6458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson void UpdateEmptyBaseSubobjects(const BaseInfo *Info, uint64_t Offset); 6558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 66812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson bool CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD, 67812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *Class, 68812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t Offset); 69812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson bool CanPlaceFieldSubobjectAtOffset(const FieldDecl *FD, 70812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t Offset); 71812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 72812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson void UpdateEmptyFieldSubobjects(const CXXRecordDecl *RD, 73812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *Class, 74812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t Offset); 75812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson void UpdateEmptyFieldSubobjects(const FieldDecl *FD, uint64_t Offset); 76812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 776a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlssonpublic: 780c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson /// This holds the size of the largest empty subobject (either a base 790aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// or a member). Will be zero if the record being built doesn't contain 800c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson /// any empty classes. 810c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson uint64_t SizeOfLargestEmptySubobject; 820aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 836a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson EmptySubobjectMap(ASTContext &Context, const CXXRecordDecl *Class) 84261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson : Context(Context), Class(Class), SizeOfLargestEmptySubobject(0) { 85261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson ComputeEmptySubobjectSizes(); 8658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 8758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson ComputeBaseInfo(); 88261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson } 89261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson 90261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson /// CanPlaceBaseAtOffset - Return whether the given base class can be placed 91261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson /// at the given offset. 920aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// Returns false if placing the record will result in two components 93261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson /// (direct or indirect) of the same type having the same offset. 94261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson bool CanPlaceBaseAtOffset(const CXXRecordDecl *RD, bool BaseIsVirtual, 95261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson uint64_t Offset); 96812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 97812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson /// CanPlaceFieldAtOffset - Return whether a field can be placed at the given 98812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson /// offset. 99812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson bool CanPlaceFieldAtOffset(const FieldDecl *FD, uint64_t Offset); 1006a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson}; 1010c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson 1020c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlssonvoid EmptySubobjectMap::ComputeEmptySubobjectSizes() { 1030c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // Check the bases. 1040c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(), 1050c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson E = Class->bases_end(); I != E; ++I) { 1060c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson const CXXRecordDecl *BaseDecl = 1070c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1080c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson 1090c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson uint64_t EmptySize = 0; 1100c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl); 1110c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson if (BaseDecl->isEmpty()) { 1120c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // If the class decl is empty, get its size. 1130c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson EmptySize = Layout.getSize(); 1140c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson } else { 1150c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // Otherwise, we get the largest empty subobject for the decl. 1160c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson EmptySize = Layout.getSizeOfLargestEmptySubobject(); 1170c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson } 1180aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1190aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar SizeOfLargestEmptySubobject = std::max(SizeOfLargestEmptySubobject, 1200c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson EmptySize); 1210c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson } 1220aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1230c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // Check the fields. 1240c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson for (CXXRecordDecl::field_iterator I = Class->field_begin(), 1250c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson E = Class->field_end(); I != E; ++I) { 1260c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson const FieldDecl *FD = *I; 1270aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1280aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar const RecordType *RT = 1290c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson Context.getBaseElementType(FD->getType())->getAs<RecordType>(); 1300aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1310c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // We only care about record types. 1320c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson if (!RT) 1330c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson continue; 1340c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson 1350c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson uint64_t EmptySize = 0; 1360c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson const CXXRecordDecl *MemberDecl = cast<CXXRecordDecl>(RT->getDecl()); 1370c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(MemberDecl); 1380c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson if (MemberDecl->isEmpty()) { 1390c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // If the class decl is empty, get its size. 1400c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson EmptySize = Layout.getSize(); 1410c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson } else { 1420c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // Otherwise, we get the largest empty subobject for the decl. 1430c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson EmptySize = Layout.getSizeOfLargestEmptySubobject(); 1440c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson } 1450aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1460aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar SizeOfLargestEmptySubobject = std::max(SizeOfLargestEmptySubobject, 1470c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson EmptySize); 1480c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson } 1490c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson} 1500c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson 15158b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders CarlssonEmptySubobjectMap::BaseInfo * 15258b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders CarlssonEmptySubobjectMap::ComputeBaseInfo(const CXXRecordDecl *RD, bool IsVirtual, 15358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson const BaseInfo *Derived) { 15458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson BaseInfo *Info; 15558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 15658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (IsVirtual) { 15758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson BaseInfo *&InfoSlot = VirtualBaseInfo[RD]; 15858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (InfoSlot) { 15958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson assert(InfoSlot->Class == RD && "Wrong class for virtual base info!"); 16058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson return InfoSlot; 16158b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } 16258b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 16358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson InfoSlot = new (Context) BaseInfo; 16458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson Info = InfoSlot; 16558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } else { 16658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson Info = new (Context) BaseInfo; 16758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } 16858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 16958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson Info->Class = RD; 17058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson Info->IsVirtual = IsVirtual; 17158b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson Info->Derived = Derived; 17258b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson Info->PrimaryVirtualBase = 0; 17358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 17458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (RD->getNumVBases()) { 17558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson // Check if this class has a primary virtual base. 17658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 17758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (Layout.getPrimaryBaseWasVirtual()) { 17858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson Info->PrimaryVirtualBase = Layout.getPrimaryBase(); 17958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson assert(Info->PrimaryVirtualBase && 18058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson "Didn't have a primary virtual base!"); 18158b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } 18258b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } 18358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 18458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 18558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson E = RD->bases_end(); I != E; ++I) { 18658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson bool IsVirtual = I->isVirtual(); 18758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 18858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson const CXXRecordDecl *BaseDecl = 18958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 19058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 19158b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson Info->Bases.push_back(ComputeBaseInfo(BaseDecl, IsVirtual, Info)); 19258b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } 19358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 19458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson return Info; 19558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson} 19658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 19758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlssonvoid EmptySubobjectMap::ComputeBaseInfo() { 19858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(), 19958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson E = Class->bases_end(); I != E; ++I) { 20058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson bool IsVirtual = I->isVirtual(); 20158b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 20258b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson const CXXRecordDecl *BaseDecl = 20358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 20458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 20558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson BaseInfo *Info = ComputeBaseInfo(BaseDecl, IsVirtual, /*Derived=*/0); 20658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (IsVirtual) { 20758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson // ComputeBaseInfo has already added this base for us. 20858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson continue; 20958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } 21058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 21158b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson // Add the base info to the map of non-virtual bases. 21258b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson assert(!NonVirtualBaseInfo.count(BaseDecl) && 21358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson "Non-virtual base already exists!"); 21458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson NonVirtualBaseInfo.insert(std::make_pair(BaseDecl, Info)); 21558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } 21658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson} 21758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 2180aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbarbool 219812a3456b63708a5972f712e9e4b54d3cc436378Anders CarlssonEmptySubobjectMap::CanPlaceSubobjectAtOffset(const CXXRecordDecl *RD, 220812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t Offset) { 221812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // We only need to check empty bases. 222812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!RD->isEmpty()) 223812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 224812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 225812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson EmptyClassOffsetsMapTy::const_iterator I = EmptyClassOffsets.find(Offset); 226812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (I == EmptyClassOffsets.end()) 227812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 228812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 229812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const ClassVectorTy& Classes = I->second; 230812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (std::find(Classes.begin(), Classes.end(), RD) == Classes.end()) 231812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 232812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 233812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // There is already an empty class of the same type at this offset. 234812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 235812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 236812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 237812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlssonvoid EmptySubobjectMap::AddSubobjectAtOffset(const CXXRecordDecl *RD, 238812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t Offset) { 239812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // We only care about empty bases. 240812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!RD->isEmpty()) 241812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return; 242812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 243812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson ClassVectorTy& Classes = EmptyClassOffsets[Offset]; 244812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson assert(std::find(Classes.begin(), Classes.end(), RD) == Classes.end() && 245812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson "Duplicate empty class detected!"); 246812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 247812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson Classes.push_back(RD); 248812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 249812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 250812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlssonbool 25158b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders CarlssonEmptySubobjectMap::CanPlaceBaseSubobjectAtOffset(const BaseInfo *Info, 25258b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson uint64_t Offset) { 253812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!CanPlaceSubobjectAtOffset(Info->Class, Offset)) 254812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 255812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 25658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson // Traverse all non-virtual bases. 25758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson for (unsigned I = 0, E = Info->Bases.size(); I != E; ++I) { 25858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson BaseInfo* Base = Info->Bases[I]; 25958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (Base->IsVirtual) 26058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson continue; 26158b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 26258b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class); 26358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class); 26458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 26558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (!CanPlaceBaseSubobjectAtOffset(Base, BaseOffset)) 26658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson return false; 26758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } 26858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 26958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (Info->PrimaryVirtualBase) { 27058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson BaseInfo *PrimaryVirtualBaseInfo = 27158b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson VirtualBaseInfo.lookup(Info->PrimaryVirtualBase); 27258b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson assert(PrimaryVirtualBaseInfo && "Didn't find base info!"); 27358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 27458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (Info == PrimaryVirtualBaseInfo->Derived) { 27558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (!CanPlaceBaseSubobjectAtOffset(PrimaryVirtualBaseInfo, Offset)) 27658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson return false; 27758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } 27858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } 27958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 280812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class); 281812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 282812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Traverse all member variables. 283812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson unsigned FieldNo = 0; 284812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (CXXRecordDecl::field_iterator I = Info->Class->field_begin(), 285812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson E = Info->Class->field_end(); I != E; ++I, ++FieldNo) { 286812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const FieldDecl *FD = *I; 287812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 288812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t FieldOffset = Offset + Layout.getFieldOffset(FieldNo); 289812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 290812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!CanPlaceFieldSubobjectAtOffset(FD, FieldOffset)) 291812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 292812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 293812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 29458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson return true; 29558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson} 29658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 29758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlssonvoid EmptySubobjectMap::UpdateEmptyBaseSubobjects(const BaseInfo *Info, 29858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson uint64_t Offset) { 299812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson AddSubobjectAtOffset(Info->Class, Offset); 30058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 30158b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson // Traverse all non-virtual bases. 30258b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson for (unsigned I = 0, E = Info->Bases.size(); I != E; ++I) { 30358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson BaseInfo* Base = Info->Bases[I]; 30458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (Base->IsVirtual) 30558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson continue; 30658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 30758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class); 30858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class); 30958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 31058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson UpdateEmptyBaseSubobjects(Base, BaseOffset); 31158b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } 31258b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 31358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (Info->PrimaryVirtualBase) { 31458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson BaseInfo *PrimaryVirtualBaseInfo = 31558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson VirtualBaseInfo.lookup(Info->PrimaryVirtualBase); 31658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson assert(PrimaryVirtualBaseInfo && "Didn't find base info!"); 31758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 31858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (Info == PrimaryVirtualBaseInfo->Derived) 31958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson UpdateEmptyBaseSubobjects(PrimaryVirtualBaseInfo, Offset); 32058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } 321812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 322812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class); 323812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 324812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Traverse all member variables. 325812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson unsigned FieldNo = 0; 326812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (CXXRecordDecl::field_iterator I = Info->Class->field_begin(), 327812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson E = Info->Class->field_end(); I != E; ++I, ++FieldNo) { 328812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const FieldDecl *FD = *I; 329812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 330812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t FieldOffset = Offset + Layout.getFieldOffset(FieldNo); 331812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 332812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson UpdateEmptyFieldSubobjects(FD, FieldOffset); 333812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 33458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson} 33558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 33658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlssonbool EmptySubobjectMap::CanPlaceBaseAtOffset(const CXXRecordDecl *RD, 33758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson bool BaseIsVirtual, 33858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson uint64_t Offset) { 339261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson // If we know this class doesn't have any empty subobjects we don't need to 340261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson // bother checking. 341261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson if (!SizeOfLargestEmptySubobject) 342261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson return true; 343261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson 34458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson BaseInfo *Info; 34558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 34658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (BaseIsVirtual) 34758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson Info = VirtualBaseInfo.lookup(RD); 34858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson else 34958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson Info = NonVirtualBaseInfo.lookup(RD); 35058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 35158b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (!CanPlaceBaseSubobjectAtOffset(Info, Offset)) 35258b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson return false; 353812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 354812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // We are able to place the base at this offset. Make sure to update the 355812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // empty base subobject map. 35658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson UpdateEmptyBaseSubobjects(Info, Offset); 357261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson return true; 358261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson} 359261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson 360812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlssonbool 361812a3456b63708a5972f712e9e4b54d3cc436378Anders CarlssonEmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD, 362812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *Class, 363812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t Offset) { 364812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!CanPlaceSubobjectAtOffset(RD, Offset)) 365812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 366812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 367812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 368812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 369812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Traverse all non-virtual bases. 370812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 371812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson E = RD->bases_end(); I != E; ++I) { 372812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (I->isVirtual()) 373812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson continue; 374812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 375812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *BaseDecl = 376812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 377812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 378812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(BaseDecl); 379812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!CanPlaceFieldSubobjectAtOffset(BaseDecl, Class, BaseOffset)) 380812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 381812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 382812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 383812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Traverse all member variables. 384812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson unsigned FieldNo = 0; 385812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); 386812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson I != E; ++I, ++FieldNo) { 387812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const FieldDecl *FD = *I; 388812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 389812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t FieldOffset = Offset + Layout.getFieldOffset(FieldNo); 390812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 391812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!CanPlaceFieldSubobjectAtOffset(FD, FieldOffset)) 392812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 393812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 394812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 395812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 396812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 397812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 398812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlssonbool EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const FieldDecl *FD, 399812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t Offset) { 400812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson QualType T = FD->getType(); 401812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (const RecordType *RT = T->getAs<RecordType>()) { 402812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 403812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return CanPlaceFieldSubobjectAtOffset(RD, RD, Offset); 404812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 405812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 406812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // If we have an array type we need to look at every element. 407812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (const ConstantArrayType *AT = Context.getAsConstantArrayType(T)) { 408812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson QualType ElemTy = Context.getBaseElementType(AT); 409812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const RecordType *RT = ElemTy->getAs<RecordType>(); 410812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!RT) 411812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 412812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 413812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 414812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 415812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 416812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t NumElements = Context.getConstantArrayElementCount(AT); 417812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t ElementOffset = Offset; 418812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (uint64_t I = 0; I != NumElements; ++I) { 419812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!CanPlaceFieldSubobjectAtOffset(RD, RD, ElementOffset)) 420812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 421812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 422812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson ElementOffset += Layout.getSize(); 423812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 424812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 425812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 426812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 427812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 428812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 429812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlssonbool 430812a3456b63708a5972f712e9e4b54d3cc436378Anders CarlssonEmptySubobjectMap::CanPlaceFieldAtOffset(const FieldDecl *FD, uint64_t Offset) { 431812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!CanPlaceFieldSubobjectAtOffset(FD, Offset)) 432812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 433812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 434812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // We are able to place the member variable at this offset. 435812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Make sure to update the empty base subobject map. 436812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson UpdateEmptyFieldSubobjects(FD, Offset); 437812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 438812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 439812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 440812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlssonvoid EmptySubobjectMap::UpdateEmptyFieldSubobjects(const CXXRecordDecl *RD, 441812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *Class, 442812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t Offset) { 443812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson AddSubobjectAtOffset(RD, Offset); 444812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 445812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 446812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 447812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Traverse all non-virtual bases. 448812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 449812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson E = RD->bases_end(); I != E; ++I) { 450812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (I->isVirtual()) 451812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson continue; 452812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 453812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *BaseDecl = 454812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 455812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 456812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(BaseDecl); 457812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson UpdateEmptyFieldSubobjects(BaseDecl, Class, BaseOffset); 458812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 459812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 460812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Traverse all member variables. 461812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson unsigned FieldNo = 0; 462812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); 463812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson I != E; ++I, ++FieldNo) { 464812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const FieldDecl *FD = *I; 465812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 466812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t FieldOffset = Offset + Layout.getFieldOffset(FieldNo); 467812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 468812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson UpdateEmptyFieldSubobjects(FD, FieldOffset); 469812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 470812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 471812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 472812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlssonvoid EmptySubobjectMap::UpdateEmptyFieldSubobjects(const FieldDecl *FD, 473812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t Offset) { 474812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson QualType T = FD->getType(); 475812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (const RecordType *RT = T->getAs<RecordType>()) { 476812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 477812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson UpdateEmptyFieldSubobjects(RD, RD, Offset); 478812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return; 479812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 480812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 481812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // If we have an array type we need to update every element. 482812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (const ConstantArrayType *AT = Context.getAsConstantArrayType(T)) { 483812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson QualType ElemTy = Context.getBaseElementType(AT); 484812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const RecordType *RT = ElemTy->getAs<RecordType>(); 485812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!RT) 486812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return; 487812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 488812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 489812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 490812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 491812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t NumElements = Context.getConstantArrayElementCount(AT); 492812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t ElementOffset = Offset; 493812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 494812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (uint64_t I = 0; I != NumElements; ++I) { 495812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson UpdateEmptyFieldSubobjects(RD, RD, ElementOffset); 496812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson ElementOffset += Layout.getSize(); 497812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 498812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 499812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 500812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 5017d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonclass RecordLayoutBuilder { 5029392fa63e45716e32061d05673fa28909f325b02Anders Carlsson // FIXME: Remove this and make the appropriate fields public. 5039392fa63e45716e32061d05673fa28909f325b02Anders Carlsson friend class clang::ASTContext; 5040aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5059392fa63e45716e32061d05673fa28909f325b02Anders Carlsson ASTContext &Context; 5069392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 5076a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson EmptySubobjectMap *EmptySubobjects; 5080aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5099392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// Size - The current size of the record layout. 5109392fa63e45716e32061d05673fa28909f325b02Anders Carlsson uint64_t Size; 5110aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5129392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// Alignment - The current alignment of the record layout. 5139392fa63e45716e32061d05673fa28909f325b02Anders Carlsson unsigned Alignment; 5140aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5159392fa63e45716e32061d05673fa28909f325b02Anders Carlsson llvm::SmallVector<uint64_t, 16> FieldOffsets; 5169392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 5179392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// Packed - Whether the record is packed or not. 518c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar unsigned Packed : 1; 519c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar 520c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar unsigned IsUnion : 1; 521c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar 522c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar unsigned IsMac68kAlign : 1; 5239392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 5249392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// UnfilledBitsInLastByte - If the last field laid out was a bitfield, 5259392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// this contains the number of bits in the last byte that can be used for 5269392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// an adjacent bitfield if necessary. 5279392fa63e45716e32061d05673fa28909f325b02Anders Carlsson unsigned char UnfilledBitsInLastByte; 5280aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5299392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// MaxFieldAlignment - The maximum allowed field alignment. This is set by 5300aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// #pragma pack. 5319392fa63e45716e32061d05673fa28909f325b02Anders Carlsson unsigned MaxFieldAlignment; 5320aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5339392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// DataSize - The data size of the record being laid out. 5349392fa63e45716e32061d05673fa28909f325b02Anders Carlsson uint64_t DataSize; 5350aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5369392fa63e45716e32061d05673fa28909f325b02Anders Carlsson uint64_t NonVirtualSize; 5379392fa63e45716e32061d05673fa28909f325b02Anders Carlsson unsigned NonVirtualAlignment; 5380aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5399392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// PrimaryBase - the primary base class (if one exists) of the class 5409392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// we're laying out. 5419392fa63e45716e32061d05673fa28909f325b02Anders Carlsson const CXXRecordDecl *PrimaryBase; 5420aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5439392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// PrimaryBaseIsVirtual - Whether the primary base of the class we're laying 5449392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// out is virtual. 5459392fa63e45716e32061d05673fa28909f325b02Anders Carlsson bool PrimaryBaseIsVirtual; 5469392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 5479392fa63e45716e32061d05673fa28909f325b02Anders Carlsson typedef llvm::DenseMap<const CXXRecordDecl *, uint64_t> BaseOffsetsMapTy; 5480aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5499392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// Bases - base classes and their offsets in the record. 5509392fa63e45716e32061d05673fa28909f325b02Anders Carlsson BaseOffsetsMapTy Bases; 5510aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5529392fa63e45716e32061d05673fa28909f325b02Anders Carlsson // VBases - virtual base classes and their offsets in the record. 5539392fa63e45716e32061d05673fa28909f325b02Anders Carlsson BaseOffsetsMapTy VBases; 5549392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 5559392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// IndirectPrimaryBases - Virtual base classes, direct or indirect, that are 5569392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// primary base classes for some other direct or indirect base class. 5579392fa63e45716e32061d05673fa28909f325b02Anders Carlsson llvm::SmallSet<const CXXRecordDecl*, 32> IndirectPrimaryBases; 5580aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5599392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// FirstNearlyEmptyVBase - The first nearly empty virtual base class in 5609392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// inheritance graph order. Used for determining the primary base class. 5619392fa63e45716e32061d05673fa28909f325b02Anders Carlsson const CXXRecordDecl *FirstNearlyEmptyVBase; 5629392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 5639392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// VisitedVirtualBases - A set of all the visited virtual bases, used to 5649392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// avoid visiting virtual bases more than once. 5659392fa63e45716e32061d05673fa28909f325b02Anders Carlsson llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases; 5660aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5679392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// EmptyClassOffsets - A map from offsets to empty record decls. 5689392fa63e45716e32061d05673fa28909f325b02Anders Carlsson typedef std::multimap<uint64_t, const CXXRecordDecl *> EmptyClassOffsetsTy; 5699392fa63e45716e32061d05673fa28909f325b02Anders Carlsson EmptyClassOffsetsTy EmptyClassOffsets; 5700aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 571261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson RecordLayoutBuilder(ASTContext &Context, EmptySubobjectMap *EmptySubobjects) 572261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson : Context(Context), EmptySubobjects(EmptySubobjects), Size(0), Alignment(8), 573c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar Packed(false), IsUnion(false), IsMac68kAlign(false), 574c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar UnfilledBitsInLastByte(0), MaxFieldAlignment(0), DataSize(0), 575c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar NonVirtualSize(0), NonVirtualAlignment(8), PrimaryBase(0), 576c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar PrimaryBaseIsVirtual(false), FirstNearlyEmptyVBase(0) { } 5770aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5789392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void Layout(const RecordDecl *D); 579c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson void Layout(const CXXRecordDecl *D); 5809392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void Layout(const ObjCInterfaceDecl *D); 5819392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 5829392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void LayoutFields(const RecordDecl *D); 5839392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void LayoutField(const FieldDecl *D); 5849392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void LayoutWideBitField(uint64_t FieldSize, uint64_t TypeSize); 5859392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void LayoutBitField(const FieldDecl *D); 5869392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 5870aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// ComputeEmptySubobjectSizes - Compute the size of the largest base or 5889392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// member subobject that is empty. 5899392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void ComputeEmptySubobjectSizes(const CXXRecordDecl *RD); 5909392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 5919392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// DeterminePrimaryBase - Determine the primary base of the given class. 5929392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void DeterminePrimaryBase(const CXXRecordDecl *RD); 5939392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 5949392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void SelectPrimaryVBase(const CXXRecordDecl *RD); 5950aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5960aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// IdentifyPrimaryBases - Identify all virtual base classes, direct or 5970aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// indirect, that are primary base classes for some other direct or indirect 5989392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// base class. 5999392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void IdentifyPrimaryBases(const CXXRecordDecl *RD); 6000aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 6019392fa63e45716e32061d05673fa28909f325b02Anders Carlsson bool IsNearlyEmpty(const CXXRecordDecl *RD) const; 6020aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 6030aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// LayoutNonVirtualBases - Determines the primary base class (if any) and 6049392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// lays it out. Will then proceed to lay out all non-virtual base clasess. 6059392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void LayoutNonVirtualBases(const CXXRecordDecl *RD); 6069392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6079392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// LayoutNonVirtualBase - Lays out a single non-virtual base. 608261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson void LayoutNonVirtualBase(const CXXRecordDecl *Base); 6099392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6109392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void AddPrimaryVirtualBaseOffsets(const CXXRecordDecl *RD, uint64_t Offset, 6119392fa63e45716e32061d05673fa28909f325b02Anders Carlsson const CXXRecordDecl *MostDerivedClass); 6129392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6139392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// LayoutVirtualBases - Lays out all the virtual bases. 6149392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void LayoutVirtualBases(const CXXRecordDecl *RD, 6159392fa63e45716e32061d05673fa28909f325b02Anders Carlsson const CXXRecordDecl *MostDerivedClass); 6169392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6179392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// LayoutVirtualBase - Lays out a single virtual base. 618261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson void LayoutVirtualBase(const CXXRecordDecl *Base); 6199392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6200aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// LayoutBase - Will lay out a base and return the offset where it was 6219392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// placed, in bits. 622261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson uint64_t LayoutBase(const CXXRecordDecl *Base, bool BaseIsVirtual); 6239392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6249392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// canPlaceRecordAtOffset - Return whether a record (either a base class 6250aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// or a field) can be placed at the given offset. 6260aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// Returns false if placing the record will result in two components 6279392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// (direct or indirect) of the same type having the same offset. 6289392fa63e45716e32061d05673fa28909f325b02Anders Carlsson bool canPlaceRecordAtOffset(const CXXRecordDecl *RD, uint64_t Offset, 6299392fa63e45716e32061d05673fa28909f325b02Anders Carlsson bool CheckVBases) const; 6309392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6319392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// canPlaceFieldAtOffset - Return whether a field can be placed at the given 6329392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// offset. 6339392fa63e45716e32061d05673fa28909f325b02Anders Carlsson bool canPlaceFieldAtOffset(const FieldDecl *FD, uint64_t Offset) const; 6349392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6359392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// UpdateEmptyClassOffsets - Called after a record (either a base class 6369392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// or a field) has been placed at the given offset. Will update the 6379392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// EmptyClassOffsets map if the class is empty or has any empty bases or 6389392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// fields. 6399392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void UpdateEmptyClassOffsets(const CXXRecordDecl *RD, uint64_t Offset, 6409392fa63e45716e32061d05673fa28909f325b02Anders Carlsson bool UpdateVBases); 6419392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6420aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// UpdateEmptyClassOffsets - Called after a field has been placed at the 6439392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// given offset. 6449392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void UpdateEmptyClassOffsets(const FieldDecl *FD, uint64_t Offset); 6450aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 646c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson /// InitializeLayout - Initialize record layout for the given record decl. 647c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar void InitializeLayout(const Decl *D); 648c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 6499392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// FinishLayout - Finalize record layout. Adjust record size based on the 6509392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// alignment. 6519392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void FinishLayout(); 6529392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6539392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void UpdateAlignment(unsigned NewAlignment); 6549392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6557d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlsson RecordLayoutBuilder(const RecordLayoutBuilder&); // DO NOT IMPLEMENT 6567d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlsson void operator=(const RecordLayoutBuilder&); // DO NOT IMPLEMENT 6579392fa63e45716e32061d05673fa28909f325b02Anders Carlssonpublic: 6589392fa63e45716e32061d05673fa28909f325b02Anders Carlsson static const CXXMethodDecl *ComputeKeyFunction(const CXXRecordDecl *RD); 6599392fa63e45716e32061d05673fa28909f325b02Anders Carlsson}; 6607e220286410422ed1dc0409a9cb9708fe50e3df0Benjamin Kramer} // end anonymous namespace 6619392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6626f376336138ea719e3c4757ae046a5768043b276Mike Stump/// IsNearlyEmpty - Indicates when a class has a vtable pointer, but 6636f376336138ea719e3c4757ae046a5768043b276Mike Stump/// no other data. 6647d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonbool RecordLayoutBuilder::IsNearlyEmpty(const CXXRecordDecl *RD) const { 6656f376336138ea719e3c4757ae046a5768043b276Mike Stump // FIXME: Audit the corners 6666f376336138ea719e3c4757ae046a5768043b276Mike Stump if (!RD->isDynamicClass()) 6676f376336138ea719e3c4757ae046a5768043b276Mike Stump return false; 6680f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson const ASTRecordLayout &BaseInfo = Context.getASTRecordLayout(RD); 6690f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson if (BaseInfo.getNonVirtualSize() == Context.Target.getPointerWidth(0)) 6706f376336138ea719e3c4757ae046a5768043b276Mike Stump return true; 6716f376336138ea719e3c4757ae046a5768043b276Mike Stump return false; 6726f376336138ea719e3c4757ae046a5768043b276Mike Stump} 6736f376336138ea719e3c4757ae046a5768043b276Mike Stump 6747d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonvoid RecordLayoutBuilder::IdentifyPrimaryBases(const CXXRecordDecl *RD) { 675bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar const ASTRecordLayout::PrimaryBaseInfo &BaseInfo = 6760f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson Context.getASTRecordLayout(RD).getPrimaryBaseInfo(); 677bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 6783f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson // If the record has a primary base class that is virtual, add it to the set 6793f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson // of primary bases. 680261fba6cf57a09a1f1d0c4a4c4856aaa62753242Anders Carlsson if (BaseInfo.isVirtual()) 681261fba6cf57a09a1f1d0c4a4c4856aaa62753242Anders Carlsson IndirectPrimaryBases.insert(BaseInfo.getBase()); 682bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 6833f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson // Now traverse all bases and find primary bases for them. 6846f376336138ea719e3c4757ae046a5768043b276Mike Stump for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), 685bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar e = RD->bases_end(); i != e; ++i) { 6869994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl assert(!i->getType()->isDependentType() && 6879994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl "Cannot layout class with dependent bases."); 6881eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const CXXRecordDecl *Base = 68949520944c688a9d5fc78d0c2af544b825873477bMike Stump cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 690bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 69149520944c688a9d5fc78d0c2af544b825873477bMike Stump // Only bases with virtual bases participate in computing the 69249520944c688a9d5fc78d0c2af544b825873477bMike Stump // indirect primary virtual base classes. 6934ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump if (Base->getNumVBases()) 6943f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson IdentifyPrimaryBases(Base); 6956f376336138ea719e3c4757ae046a5768043b276Mike Stump } 6966f376336138ea719e3c4757ae046a5768043b276Mike Stump} 6976f376336138ea719e3c4757ae046a5768043b276Mike Stump 6983f066522342538509cf0aa4f381503b43fbdb68bAnders Carlssonvoid 6997d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders CarlssonRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD) { 700584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 701bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->bases_end(); I != E; ++I) { 702584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson assert(!I->getType()->isDependentType() && 7039994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl "Cannot layout class with dependent bases."); 704bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 7051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const CXXRecordDecl *Base = 706584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 707200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 708584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson // Check if this is a nearly empty virtual base. 709584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson if (I->isVirtual() && IsNearlyEmpty(Base)) { 710584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson // If it's not an indirect primary base, then we've found our primary 711584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson // base. 7123f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson if (!IndirectPrimaryBases.count(Base)) { 71328fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBase = Base; 71428fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBaseIsVirtual = true; 715d76264e0b20470267249660ab947197cf6d6e31fMike Stump return; 716d76264e0b20470267249660ab947197cf6d6e31fMike Stump } 717bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 718584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson // Is this the first nearly empty virtual base? 719584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson if (!FirstNearlyEmptyVBase) 720584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson FirstNearlyEmptyVBase = Base; 721d76264e0b20470267249660ab947197cf6d6e31fMike Stump } 722bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 723200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson SelectPrimaryVBase(Base); 72428fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson if (PrimaryBase) 72594ba380b820cde3fb9d97d5f07ac709ebbb6ac1eZhongxing Xu return; 726d76264e0b20470267249660ab947197cf6d6e31fMike Stump } 727d76264e0b20470267249660ab947197cf6d6e31fMike Stump} 728d76264e0b20470267249660ab947197cf6d6e31fMike Stump 729200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson/// DeterminePrimaryBase - Determine the primary base of the given class. 7307d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonvoid RecordLayoutBuilder::DeterminePrimaryBase(const CXXRecordDecl *RD) { 731200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // If the class isn't dynamic, it won't have a primary base. 732200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson if (!RD->isDynamicClass()) 733200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson return; 734bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 7353f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson // Compute all the primary virtual bases for all of our direct and 7360880e75541899bc1cdd73c50eb549110b5916c59Mike Stump // indirect bases, and record all their primary virtual base classes. 7370880e75541899bc1cdd73c50eb549110b5916c59Mike Stump for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), 738bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar e = RD->bases_end(); i != e; ++i) { 7399994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl assert(!i->getType()->isDependentType() && 740200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson "Cannot lay out class with dependent bases."); 7411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const CXXRecordDecl *Base = 7420880e75541899bc1cdd73c50eb549110b5916c59Mike Stump cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 7433f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson IdentifyPrimaryBases(Base); 7440880e75541899bc1cdd73c50eb549110b5916c59Mike Stump } 7450880e75541899bc1cdd73c50eb549110b5916c59Mike Stump 746bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar // If the record has a dynamic base class, attempt to choose a primary base 747bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar // class. It is the first (in direct base class order) non-virtual dynamic 7483f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson // base class, if one exists. 7496f376336138ea719e3c4757ae046a5768043b276Mike Stump for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), 750bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar e = RD->bases_end(); i != e; ++i) { 751ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson // Ignore virtual bases. 752ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson if (i->isVirtual()) 753ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson continue; 754bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 755ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson const CXXRecordDecl *Base = 756ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 757ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson 758ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson if (Base->isDynamicClass()) { 759ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson // We found it. 76028fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBase = Base; 76128fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBaseIsVirtual = false; 762ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson return; 7636f376336138ea719e3c4757ae046a5768043b276Mike Stump } 7646f376336138ea719e3c4757ae046a5768043b276Mike Stump } 7656f376336138ea719e3c4757ae046a5768043b276Mike Stump 7666f376336138ea719e3c4757ae046a5768043b276Mike Stump // Otherwise, it is the first nearly empty virtual base that is not an 76749520944c688a9d5fc78d0c2af544b825873477bMike Stump // indirect primary virtual base class, if one exists. 768200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson if (RD->getNumVBases() != 0) { 769200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson SelectPrimaryVBase(RD); 77028fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson if (PrimaryBase) 771200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson return; 772200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson } 7736f376336138ea719e3c4757ae046a5768043b276Mike Stump 774200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Otherwise, it is the first nearly empty virtual base that is not an 775200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // indirect primary virtual base class, if one exists. 776200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson if (FirstNearlyEmptyVBase) { 77728fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBase = FirstNearlyEmptyVBase; 77828fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBaseIsVirtual = true; 7796f376336138ea719e3c4757ae046a5768043b276Mike Stump return; 780200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson } 781bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 782200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Otherwise there is no primary base class. 78328fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson assert(!PrimaryBase && "Should not get here with a primary base!"); 784200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 785200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Allocate the virtual table pointer at offset zero. 786200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson assert(DataSize == 0 && "Vtable pointer must be at offset zero!"); 787bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 788200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Update the size. 7890f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson Size += Context.Target.getPointerWidth(0); 790200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson DataSize = Size; 791200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 792200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Update the alignment. 7930f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson UpdateAlignment(Context.Target.getPointerAlign(0)); 7946f376336138ea719e3c4757ae046a5768043b276Mike Stump} 7956f376336138ea719e3c4757ae046a5768043b276Mike Stump 796e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlssonvoid 7977d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders CarlssonRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) { 798200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // First, determine the primary base class. 799200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson DeterminePrimaryBase(RD); 800bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 801200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // If we have a primary base class, lay it out. 80228fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson if (PrimaryBase) { 80328fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson if (PrimaryBaseIsVirtual) { 804200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // We have a virtual primary base, insert it as an indirect primary base. 80528fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson IndirectPrimaryBases.insert(PrimaryBase); 80637147ea14f39a8522e32e3ba4d043a2a33fff90cAnders Carlsson 8070aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar assert(!VisitedVirtualBases.count(PrimaryBase) && 80828fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson "vbase already visited!"); 80928fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson VisitedVirtualBases.insert(PrimaryBase); 8100aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 81128fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson LayoutVirtualBase(PrimaryBase); 812200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson } else 81328fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson LayoutNonVirtualBase(PrimaryBase); 814200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson } 815bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 816200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Now lay out the non-virtual bases. 817200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 818bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->bases_end(); I != E; ++I) { 819200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 820200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Ignore virtual bases. 821200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson if (I->isVirtual()) 822200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson continue; 823200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 824200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson const CXXRecordDecl *Base = 825200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 826200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 827200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Skip the primary base. 828aa230b7bd2054e70e9500aff584845cb1cc34ca7Anders Carlsson if (Base == PrimaryBase && !PrimaryBaseIsVirtual) 829200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson continue; 830200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 831200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Lay out the base. 832200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson LayoutNonVirtualBase(Base); 833e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson } 834e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson} 835e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 836261febd091cd05325ae202b7d388a2d266bbf126Anders Carlssonvoid RecordLayoutBuilder::LayoutNonVirtualBase(const CXXRecordDecl *Base) { 837e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson // Layout the base. 838261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson uint64_t Offset = LayoutBase(Base, /*BaseIsVirtual=*/false); 839bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 840e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson // Add its base class offset. 841261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson if (!Bases.insert(std::make_pair(Base, Offset)).second) 842147b5ddc6c8618a9d70a83f90de409e444ae705bAnders Carlsson assert(false && "Added same base offset more than once!"); 843e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson} 844968db3364611a475909b5e76969d2f5472e65597Mike Stump 845bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbarvoid 8460aa7edbc1f579787c4f69144fd1b04e777d89391Daniel DunbarRecordLayoutBuilder::AddPrimaryVirtualBaseOffsets(const CXXRecordDecl *RD, 84797913576dbe624971bf18726899983d211d742c0Anders Carlsson uint64_t Offset, 84897913576dbe624971bf18726899983d211d742c0Anders Carlsson const CXXRecordDecl *MostDerivedClass) { 84997913576dbe624971bf18726899983d211d742c0Anders Carlsson // We already have the offset for the primary base of the most derived class. 85097913576dbe624971bf18726899983d211d742c0Anders Carlsson if (RD != MostDerivedClass) { 8510f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 85297913576dbe624971bf18726899983d211d742c0Anders Carlsson const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 85397913576dbe624971bf18726899983d211d742c0Anders Carlsson 85497913576dbe624971bf18726899983d211d742c0Anders Carlsson // If this is a primary virtual base and we haven't seen it before, add it. 85597913576dbe624971bf18726899983d211d742c0Anders Carlsson if (PrimaryBase && Layout.getPrimaryBaseWasVirtual() && 85697913576dbe624971bf18726899983d211d742c0Anders Carlsson !VBases.count(PrimaryBase)) 85797913576dbe624971bf18726899983d211d742c0Anders Carlsson VBases.insert(std::make_pair(PrimaryBase, Offset)); 85897913576dbe624971bf18726899983d211d742c0Anders Carlsson } 85997913576dbe624971bf18726899983d211d742c0Anders Carlsson 86097913576dbe624971bf18726899983d211d742c0Anders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 86197913576dbe624971bf18726899983d211d742c0Anders Carlsson E = RD->bases_end(); I != E; ++I) { 86297913576dbe624971bf18726899983d211d742c0Anders Carlsson assert(!I->getType()->isDependentType() && 86397913576dbe624971bf18726899983d211d742c0Anders Carlsson "Cannot layout class with dependent bases."); 8640aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 86597913576dbe624971bf18726899983d211d742c0Anders Carlsson const CXXRecordDecl *BaseDecl = 86697913576dbe624971bf18726899983d211d742c0Anders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 86797913576dbe624971bf18726899983d211d742c0Anders Carlsson 86897913576dbe624971bf18726899983d211d742c0Anders Carlsson if (!BaseDecl->getNumVBases()) { 86997913576dbe624971bf18726899983d211d742c0Anders Carlsson // This base isn't interesting since it doesn't have any virtual bases. 87097913576dbe624971bf18726899983d211d742c0Anders Carlsson continue; 87197913576dbe624971bf18726899983d211d742c0Anders Carlsson } 8720aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 87397913576dbe624971bf18726899983d211d742c0Anders Carlsson // Compute the offset of this base. 87497913576dbe624971bf18726899983d211d742c0Anders Carlsson uint64_t BaseOffset; 8750aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 87697913576dbe624971bf18726899983d211d742c0Anders Carlsson if (I->isVirtual()) { 87797913576dbe624971bf18726899983d211d742c0Anders Carlsson // If we don't know this vbase yet, don't visit it. It will be visited 87897913576dbe624971bf18726899983d211d742c0Anders Carlsson // later. 87997913576dbe624971bf18726899983d211d742c0Anders Carlsson if (!VBases.count(BaseDecl)) { 88097913576dbe624971bf18726899983d211d742c0Anders Carlsson continue; 88197913576dbe624971bf18726899983d211d742c0Anders Carlsson } 8820aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 88397913576dbe624971bf18726899983d211d742c0Anders Carlsson // Check if we've already visited this base. 88497913576dbe624971bf18726899983d211d742c0Anders Carlsson if (!VisitedVirtualBases.insert(BaseDecl)) 88597913576dbe624971bf18726899983d211d742c0Anders Carlsson continue; 88697913576dbe624971bf18726899983d211d742c0Anders Carlsson 88797913576dbe624971bf18726899983d211d742c0Anders Carlsson // We want the vbase offset from the class we're currently laying out. 88897913576dbe624971bf18726899983d211d742c0Anders Carlsson BaseOffset = VBases[BaseDecl]; 88997913576dbe624971bf18726899983d211d742c0Anders Carlsson } else if (RD == MostDerivedClass) { 89097913576dbe624971bf18726899983d211d742c0Anders Carlsson // We want the base offset from the class we're currently laying out. 89197913576dbe624971bf18726899983d211d742c0Anders Carlsson assert(Bases.count(BaseDecl) && "Did not find base!"); 89297913576dbe624971bf18726899983d211d742c0Anders Carlsson BaseOffset = Bases[BaseDecl]; 89397913576dbe624971bf18726899983d211d742c0Anders Carlsson } else { 8940f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 89597913576dbe624971bf18726899983d211d742c0Anders Carlsson BaseOffset = Offset + Layout.getBaseClassOffset(BaseDecl); 89697913576dbe624971bf18726899983d211d742c0Anders Carlsson } 89797913576dbe624971bf18726899983d211d742c0Anders Carlsson 89897913576dbe624971bf18726899983d211d742c0Anders Carlsson AddPrimaryVirtualBaseOffsets(BaseDecl, BaseOffset, MostDerivedClass); 89997913576dbe624971bf18726899983d211d742c0Anders Carlsson } 90097913576dbe624971bf18726899983d211d742c0Anders Carlsson} 90197913576dbe624971bf18726899983d211d742c0Anders Carlsson 90297913576dbe624971bf18726899983d211d742c0Anders Carlssonvoid 9037d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders CarlssonRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD, 90497913576dbe624971bf18726899983d211d742c0Anders Carlsson const CXXRecordDecl *MostDerivedClass) { 90588f4296e85d49e4ea63cda729cd5f696824c67ceAnders Carlsson const CXXRecordDecl *PrimaryBase; 906bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson bool PrimaryBaseIsVirtual; 90737147ea14f39a8522e32e3ba4d043a2a33fff90cAnders Carlsson 908bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson if (MostDerivedClass == RD) { 90928fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBase = this->PrimaryBase; 91028fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBaseIsVirtual = this->PrimaryBaseIsVirtual; 911bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson } else { 9120f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 91388f4296e85d49e4ea63cda729cd5f696824c67ceAnders Carlsson PrimaryBase = Layout.getPrimaryBase(); 914bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson PrimaryBaseIsVirtual = Layout.getPrimaryBaseWasVirtual(); 915bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson } 916bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson 917622e2477d0698d734671523389277e10d8566e26Anders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 918622e2477d0698d734671523389277e10d8566e26Anders Carlsson E = RD->bases_end(); I != E; ++I) { 919622e2477d0698d734671523389277e10d8566e26Anders Carlsson assert(!I->getType()->isDependentType() && 9209994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl "Cannot layout class with dependent bases."); 921bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 9221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const CXXRecordDecl *Base = 923622e2477d0698d734671523389277e10d8566e26Anders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 924622e2477d0698d734671523389277e10d8566e26Anders Carlsson 925622e2477d0698d734671523389277e10d8566e26Anders Carlsson if (I->isVirtual()) { 926bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson if (PrimaryBase != Base || !PrimaryBaseIsVirtual) { 927bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson bool IndirectPrimaryBase = IndirectPrimaryBases.count(Base); 928bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson 929bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson // Only lay out the virtual base if it's not an indirect primary base. 930bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson if (!IndirectPrimaryBase) { 931bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson // Only visit virtual bases once. 932bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson if (!VisitedVirtualBases.insert(Base)) 933bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson continue; 9340aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 93537147ea14f39a8522e32e3ba4d043a2a33fff90cAnders Carlsson LayoutVirtualBase(Base); 936147b5ddc6c8618a9d70a83f90de409e444ae705bAnders Carlsson } 937968db3364611a475909b5e76969d2f5472e65597Mike Stump } 938fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump } 939bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 940622e2477d0698d734671523389277e10d8566e26Anders Carlsson if (!Base->getNumVBases()) { 941622e2477d0698d734671523389277e10d8566e26Anders Carlsson // This base isn't interesting since it doesn't have any virtual bases. 942622e2477d0698d734671523389277e10d8566e26Anders Carlsson continue; 943622e2477d0698d734671523389277e10d8566e26Anders Carlsson } 944622e2477d0698d734671523389277e10d8566e26Anders Carlsson 94597913576dbe624971bf18726899983d211d742c0Anders Carlsson LayoutVirtualBases(Base, MostDerivedClass); 946eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump } 947eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump} 948eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump 949261febd091cd05325ae202b7d388a2d266bbf126Anders Carlssonvoid RecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *Base) { 950e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson // Layout the base. 951261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson uint64_t Offset = LayoutBase(Base, /*BaseIsVirtual=*/true); 952e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson 953e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson // Add its base class offset. 954261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson if (!VBases.insert(std::make_pair(Base, Offset)).second) 955147b5ddc6c8618a9d70a83f90de409e444ae705bAnders Carlsson assert(false && "Added same vbase offset more than once!"); 956e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson} 957e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 958261febd091cd05325ae202b7d388a2d266bbf126Anders Carlssonuint64_t RecordLayoutBuilder::LayoutBase(const CXXRecordDecl *Base, 959261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson bool BaseIsVirtual) { 960261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(Base); 961e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 962e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // If we have an empty base class, try to place it at offset 0. 9630aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar if (Base->isEmpty() && 964261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson EmptySubobjects->CanPlaceBaseAtOffset(Base, BaseIsVirtual, 0) && 965261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson canPlaceRecordAtOffset(Base, 0, /*CheckVBases=*/false)) { 966e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // We were able to place the class at offset 0. 967261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson UpdateEmptyClassOffsets(Base, 0, /*UpdateVBases=*/false); 968e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 969c3fddeb4384de2238ec03c77be6bee606725609eAnders Carlsson Size = std::max(Size, Layout.getSize()); 970e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 971e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson return 0; 972e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson } 973bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 974c3fddeb4384de2238ec03c77be6bee606725609eAnders Carlsson unsigned BaseAlign = Layout.getNonVirtualAlign(); 975bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 976e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // Round up the current record size to the base's alignment boundary. 977e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson uint64_t Offset = llvm::RoundUpToAlignment(DataSize, BaseAlign); 978bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 979e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // Try to place the base. 980e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson while (true) { 981261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson if (EmptySubobjects->CanPlaceBaseAtOffset(Base, BaseIsVirtual, Offset) && 982261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson canPlaceRecordAtOffset(Base, Offset, /*CheckVBases=*/false)) 983e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson break; 984bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 985e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson Offset += BaseAlign; 986e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson } 987e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 988261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson if (!Base->isEmpty()) { 989e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // Update the data size. 990c3fddeb4384de2238ec03c77be6bee606725609eAnders Carlsson DataSize = Offset + Layout.getNonVirtualSize(); 991e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 992e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson Size = std::max(Size, DataSize); 993e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson } else 994c3fddeb4384de2238ec03c77be6bee606725609eAnders Carlsson Size = std::max(Size, Offset + Layout.getSize()); 995e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 996e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // Remember max struct/class alignment. 997e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson UpdateAlignment(BaseAlign); 998e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 999261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson UpdateEmptyClassOffsets(Base, Offset, /*UpdateVBases=*/false); 1000e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson return Offset; 1001e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson} 1002e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 10030aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbarbool 10047d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders CarlssonRecordLayoutBuilder::canPlaceRecordAtOffset(const CXXRecordDecl *RD, 10050aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar uint64_t Offset, 10063159ffeb233021bb38d7c75f214998de741d5663Anders Carlsson bool CheckVBases) const { 10071345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson // Look for an empty class with the same type at the same offset. 1008bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar for (EmptyClassOffsetsTy::const_iterator I = 1009bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar EmptyClassOffsets.lower_bound(Offset), 1010bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = EmptyClassOffsets.upper_bound(Offset); I != E; ++I) { 1011bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 10121345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson if (I->second == RD) 10131345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson return false; 10141345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson } 1015bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1016ddae877b5d1657398f6a8f528dbd3f20dc19607fAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 1017ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson 1018ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson // Check bases. 1019ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1020bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->bases_end(); I != E; ++I) { 10219994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl assert(!I->getType()->isDependentType() && 10229994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl "Cannot layout class with dependent bases."); 1023ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson if (I->isVirtual()) 1024ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson continue; 1025bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1026ddae877b5d1657398f6a8f528dbd3f20dc19607fAnders Carlsson const CXXRecordDecl *BaseDecl = 1027ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1028ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson 1029ddae877b5d1657398f6a8f528dbd3f20dc19607fAnders Carlsson uint64_t BaseOffset = Layout.getBaseClassOffset(BaseDecl); 1030bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 10313159ffeb233021bb38d7c75f214998de741d5663Anders Carlsson if (!canPlaceRecordAtOffset(BaseDecl, Offset + BaseOffset, 10323159ffeb233021bb38d7c75f214998de741d5663Anders Carlsson /*CheckVBases=*/false)) 1033ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson return false; 1034ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson } 1035bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 10361eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson // Check fields. 10371eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson unsigned FieldNo = 0; 1038bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); 10391eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson I != E; ++I, ++FieldNo) { 10401eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson const FieldDecl *FD = *I; 1041bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1042ddae877b5d1657398f6a8f528dbd3f20dc19607fAnders Carlsson uint64_t FieldOffset = Layout.getFieldOffset(FieldNo); 1043bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 10441eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson if (!canPlaceFieldAtOffset(FD, Offset + FieldOffset)) 10451eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson return false; 10461eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson } 10471eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson 10483159ffeb233021bb38d7c75f214998de741d5663Anders Carlsson if (CheckVBases) { 10493159ffeb233021bb38d7c75f214998de741d5663Anders Carlsson // FIXME: virtual bases. 10503159ffeb233021bb38d7c75f214998de741d5663Anders Carlsson } 10513159ffeb233021bb38d7c75f214998de741d5663Anders Carlsson 10529606149722bedfc48fc56cafc58de1139aef481dAnders Carlsson return true; 10539606149722bedfc48fc56cafc58de1139aef481dAnders Carlsson} 10549606149722bedfc48fc56cafc58de1139aef481dAnders Carlsson 10557d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonbool RecordLayoutBuilder::canPlaceFieldAtOffset(const FieldDecl *FD, 10566026504302763f74102592602b392cecd5ced3aeAnders Carlsson uint64_t Offset) const { 1057fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson QualType T = FD->getType(); 1058fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson if (const RecordType *RT = T->getAs<RecordType>()) { 10596026504302763f74102592602b392cecd5ced3aeAnders Carlsson if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) 10603159ffeb233021bb38d7c75f214998de741d5663Anders Carlsson return canPlaceRecordAtOffset(RD, Offset, /*CheckVBases=*/true); 10616026504302763f74102592602b392cecd5ced3aeAnders Carlsson } 1062bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 10630f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson if (const ConstantArrayType *AT = Context.getAsConstantArrayType(T)) { 10640f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson QualType ElemTy = Context.getBaseElementType(AT); 1065fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson const RecordType *RT = ElemTy->getAs<RecordType>(); 1066fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson if (!RT) 1067fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson return true; 1068fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()); 1069fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson if (!RD) 1070fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson return true; 1071bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1072c3fddeb4384de2238ec03c77be6bee606725609eAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 1073fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson 10740f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson uint64_t NumElements = Context.getConstantArrayElementCount(AT); 1075968db3364611a475909b5e76969d2f5472e65597Mike Stump uint64_t ElementOffset = Offset; 1076fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson for (uint64_t I = 0; I != NumElements; ++I) { 10773159ffeb233021bb38d7c75f214998de741d5663Anders Carlsson if (!canPlaceRecordAtOffset(RD, ElementOffset, /*CheckVBases=*/true)) 1078fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson return false; 1079bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1080c3fddeb4384de2238ec03c77be6bee606725609eAnders Carlsson ElementOffset += Layout.getSize(); 1081fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson } 1082fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson } 1083bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 10846026504302763f74102592602b392cecd5ced3aeAnders Carlsson return true; 10856026504302763f74102592602b392cecd5ced3aeAnders Carlsson} 10866026504302763f74102592602b392cecd5ced3aeAnders Carlsson 10877d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonvoid RecordLayoutBuilder::UpdateEmptyClassOffsets(const CXXRecordDecl *RD, 1088ecafebe28f379bf45eaca4bf8469e2586eba9902Anders Carlsson uint64_t Offset, 1089ecafebe28f379bf45eaca4bf8469e2586eba9902Anders Carlsson bool UpdateVBases) { 10901345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson if (RD->isEmpty()) 10911345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson EmptyClassOffsets.insert(std::make_pair(Offset, RD)); 1092bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1093c3fddeb4384de2238ec03c77be6bee606725609eAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 1094ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson 1095ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson // Update bases. 1096ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1097bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->bases_end(); I != E; ++I) { 10989994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl assert(!I->getType()->isDependentType() && 10999994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl "Cannot layout class with dependent bases."); 1100ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson if (I->isVirtual()) 1101ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson continue; 1102bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1103ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson const CXXRecordDecl *Base = 1104ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1105bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1106c3fddeb4384de2238ec03c77be6bee606725609eAnders Carlsson uint64_t BaseClassOffset = Layout.getBaseClassOffset(Base); 1107ecafebe28f379bf45eaca4bf8469e2586eba9902Anders Carlsson UpdateEmptyClassOffsets(Base, Offset + BaseClassOffset, 1108ecafebe28f379bf45eaca4bf8469e2586eba9902Anders Carlsson /*UpdateVBases=*/false); 1109ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson } 1110bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 11111eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson // Update fields. 11121eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson unsigned FieldNo = 0; 1113bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); 11141eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson I != E; ++I, ++FieldNo) { 11151eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson const FieldDecl *FD = *I; 1116bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1117c3fddeb4384de2238ec03c77be6bee606725609eAnders Carlsson uint64_t FieldOffset = Layout.getFieldOffset(FieldNo); 11181eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson UpdateEmptyClassOffsets(FD, Offset + FieldOffset); 11191eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson } 1120bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1121bfcdc40cbc213d91d91513ba8e1fbde65734ddf4Anders Carlsson const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 11220aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1123ecafebe28f379bf45eaca4bf8469e2586eba9902Anders Carlsson if (UpdateVBases) { 1124ecafebe28f379bf45eaca4bf8469e2586eba9902Anders Carlsson // FIXME: Update virtual bases. 1125bfcdc40cbc213d91d91513ba8e1fbde65734ddf4Anders Carlsson } else if (PrimaryBase && Layout.getPrimaryBaseWasVirtual()) { 1126bfcdc40cbc213d91d91513ba8e1fbde65734ddf4Anders Carlsson // We always want to update the offsets of a primary virtual base. 1127bfcdc40cbc213d91d91513ba8e1fbde65734ddf4Anders Carlsson assert(Layout.getVBaseClassOffset(PrimaryBase) == 0 && 1128bfcdc40cbc213d91d91513ba8e1fbde65734ddf4Anders Carlsson "primary base class offset must always be 0!"); 1129bfcdc40cbc213d91d91513ba8e1fbde65734ddf4Anders Carlsson UpdateEmptyClassOffsets(PrimaryBase, Offset, /*UpdateVBases=*/false); 1130ecafebe28f379bf45eaca4bf8469e2586eba9902Anders Carlsson } 11319606149722bedfc48fc56cafc58de1139aef481dAnders Carlsson} 11329606149722bedfc48fc56cafc58de1139aef481dAnders Carlsson 1133a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlssonvoid 11347d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders CarlssonRecordLayoutBuilder::UpdateEmptyClassOffsets(const FieldDecl *FD, 1135a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson uint64_t Offset) { 1136a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson QualType T = FD->getType(); 1137a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson 1138a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson if (const RecordType *RT = T->getAs<RecordType>()) { 1139a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) { 1140ecafebe28f379bf45eaca4bf8469e2586eba9902Anders Carlsson UpdateEmptyClassOffsets(RD, Offset, /*UpdateVBases=*/true); 1141a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson return; 1142a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson } 1143a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson } 1144bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 11450f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson if (const ConstantArrayType *AT = Context.getAsConstantArrayType(T)) { 11460f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson QualType ElemTy = Context.getBaseElementType(AT); 1147a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson const RecordType *RT = ElemTy->getAs<RecordType>(); 1148a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson if (!RT) 1149a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson return; 1150a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()); 1151a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson if (!RD) 1152a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson return; 1153bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 11540f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson const ASTRecordLayout &Info = Context.getASTRecordLayout(RD); 1155a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson 11560f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson uint64_t NumElements = Context.getConstantArrayElementCount(AT); 1157968db3364611a475909b5e76969d2f5472e65597Mike Stump uint64_t ElementOffset = Offset; 1158a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson 1159a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson for (uint64_t I = 0; I != NumElements; ++I) { 1160ecafebe28f379bf45eaca4bf8469e2586eba9902Anders Carlsson UpdateEmptyClassOffsets(RD, ElementOffset, /*UpdateVBases=*/true); 1161a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson ElementOffset += Info.getSize(); 1162a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson } 1163a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson } 1164a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson} 1165a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson 1166c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbarvoid RecordLayoutBuilder::InitializeLayout(const Decl *D) { 1167c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar if (const RecordDecl *RD = dyn_cast<RecordDecl>(D)) 1168c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar IsUnion = RD->isUnion(); 11690aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1170a5dd722bdf2f74a1a249fe6661d96a7236aee0f0Anders Carlsson Packed = D->hasAttr<PackedAttr>(); 11710aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1172c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar // mac68k alignment supersedes maximum field alignment and attribute aligned, 1173c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar // and forces all structures to have 2-byte alignment. The IBM docs on it 1174c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar // allude to additional (more complicated) semantics, especially with regard 1175c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar // to bit-fields, but gcc appears not to follow that. 1176c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar if (D->hasAttr<AlignMac68kAttr>()) { 1177c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar IsMac68kAlign = true; 1178c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar MaxFieldAlignment = 2 * 8; 1179c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar Alignment = 2 * 8; 1180c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar } else { 1181c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar if (const MaxFieldAlignmentAttr *MFAA = D->getAttr<MaxFieldAlignmentAttr>()) 1182c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar MaxFieldAlignment = MFAA->getAlignment(); 11830aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1184c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) 1185c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar UpdateAlignment(AA->getMaxAlignment()); 1186c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar } 1187c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson} 118874cbe226207fd101623638dadfa7fbada04ff2a6Anders Carlsson 1189c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlssonvoid RecordLayoutBuilder::Layout(const RecordDecl *D) { 1190c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson InitializeLayout(D); 1191a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson LayoutFields(D); 11921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1193c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson // Finally, round the size of the total struct up to the alignment of the 1194c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson // struct itself. 1195c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson FinishLayout(); 1196c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson} 1197c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 1198c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlssonvoid RecordLayoutBuilder::Layout(const CXXRecordDecl *RD) { 1199c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson InitializeLayout(RD); 1200c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 1201c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson // Lay out the vtable and the non-virtual bases. 1202c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson LayoutNonVirtualBases(RD); 1203c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 1204c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson LayoutFields(RD); 1205c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 1206b2fafd4978166114c54748a73738d8b2c3a37e2bAnders Carlsson NonVirtualSize = Size; 1207b2fafd4978166114c54748a73738d8b2c3a37e2bAnders Carlsson NonVirtualAlignment = Alignment; 12083dee6efcad9ad56d14f7edd1c29924f0b876a7f9Mike Stump 1209c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson // Lay out the virtual bases and add the primary virtual base offsets. 1210c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson LayoutVirtualBases(RD, RD); 121197913576dbe624971bf18726899983d211d742c0Anders Carlsson 1212c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson VisitedVirtualBases.clear(); 1213c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson AddPrimaryVirtualBaseOffsets(RD, 0, RD); 1214eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump 1215bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // Finally, round the size of the total struct up to the alignment of the 1216bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // struct itself. 1217bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson FinishLayout(); 1218c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 1219a1e87162d36f94d3dc58ff3f0743d6026635a0c6Anders Carlsson#ifndef NDEBUG 1220c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson // Check that we have base offsets for all bases. 1221c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1222c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson E = RD->bases_end(); I != E; ++I) { 1223c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson if (I->isVirtual()) 1224c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson continue; 12250aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1226c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson const CXXRecordDecl *BaseDecl = 1227c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1228c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 1229c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson assert(Bases.count(BaseDecl) && "Did not find base offset!"); 1230c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson } 12310aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1232c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson // And all virtual bases. 1233c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(), 1234c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson E = RD->vbases_end(); I != E; ++I) { 1235c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson const CXXRecordDecl *BaseDecl = 1236c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 12370aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1238c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson assert(VBases.count(BaseDecl) && "Did not find base offset!"); 1239a1e87162d36f94d3dc58ff3f0743d6026635a0c6Anders Carlsson } 1240a1e87162d36f94d3dc58ff3f0743d6026635a0c6Anders Carlsson#endif 1241bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson} 1242bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 12437d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonvoid RecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D) { 124493fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson if (ObjCInterfaceDecl *SD = D->getSuperClass()) { 12450f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson const ASTRecordLayout &SL = Context.getASTObjCInterfaceLayout(SD); 124693fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson 124793fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson UpdateAlignment(SL.getAlignment()); 12481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 124993fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson // We start laying out ivars not at the end of the superclass 125093fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson // structure, but at the next byte following the last field. 1251243a68551ac9ec71bf341e062418e33eb4f286ffAnders Carlsson Size = llvm::RoundUpToAlignment(SL.getDataSize(), 8); 1252a223935e5cf82e939e1ca1da4111d63025a04e39Anders Carlsson DataSize = Size; 125393fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson } 12541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1255c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar InitializeLayout(D); 12568a2c92cab213bd7e28ff669577e815cd70bafbe3Daniel Dunbar 125793fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson // Layout each ivar sequentially. 125893fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson llvm::SmallVector<ObjCIvarDecl*, 16> Ivars; 12590f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson Context.ShallowCollectObjCIvars(D, Ivars); 126093fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson for (unsigned i = 0, e = Ivars.size(); i != e; ++i) 126193fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson LayoutField(Ivars[i]); 12621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 126393fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson // Finally, round the size of the total struct up to the alignment of the 126493fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson // struct itself. 126593fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson FinishLayout(); 126693fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson} 126793fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson 12687d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonvoid RecordLayoutBuilder::LayoutFields(const RecordDecl *D) { 1269a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson // Layout each field, for now, just sequentially, respecting alignment. In 1270a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson // the future, this will need to be tweakable by targets. 12711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump for (RecordDecl::field_iterator Field = D->field_begin(), 1272bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar FieldEnd = D->field_end(); Field != FieldEnd; ++Field) 1273a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson LayoutField(*Field); 1274a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson} 1275a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson 12760aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbarvoid RecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize, 12774cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson uint64_t TypeSize) { 12784cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson assert(Context.getLangOptions().CPlusPlus && 12794cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson "Can only have wide bit-fields in C++!"); 12800aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 12814cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson // Itanium C++ ABI 2.4: 12820aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar // If sizeof(T)*8 < n, let T' be the largest integral POD type with 12834cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson // sizeof(T')*8 <= n. 12840aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 12854cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson QualType IntegralPODTypes[] = { 12860aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar Context.UnsignedCharTy, Context.UnsignedShortTy, Context.UnsignedIntTy, 12874cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson Context.UnsignedLongTy, Context.UnsignedLongLongTy 12884cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson }; 12894cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 12904cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson QualType Type; 12914cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson for (unsigned I = 0, E = llvm::array_lengthof(IntegralPODTypes); 12924cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson I != E; ++I) { 12934cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson uint64_t Size = Context.getTypeSize(IntegralPODTypes[I]); 12944cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 12954cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson if (Size > FieldSize) 12964cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson break; 12974cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 12984cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson Type = IntegralPODTypes[I]; 12994cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson } 13004cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson assert(!Type.isNull() && "Did not find a type!"); 13010aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 13024cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson unsigned TypeAlign = Context.getTypeAlign(Type); 13034cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 13044cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson // We're not going to use any of the unfilled bits in the last byte. 13054cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson UnfilledBitsInLastByte = 0; 13064cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 1307de9f153b2348f590151504888c22cb937134cd27Anders Carlsson uint64_t FieldOffset; 13080aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 13094cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson if (IsUnion) { 13104cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson DataSize = std::max(DataSize, FieldSize); 1311de9f153b2348f590151504888c22cb937134cd27Anders Carlsson FieldOffset = 0; 13124cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson } else { 1313de9f153b2348f590151504888c22cb937134cd27Anders Carlsson // The bitfield is allocated starting at the next offset aligned appropriately 13140aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar // for T', with length n bits. 1315de9f153b2348f590151504888c22cb937134cd27Anders Carlsson FieldOffset = llvm::RoundUpToAlignment(DataSize, TypeAlign); 13160aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 13174cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson uint64_t NewSizeInBits = FieldOffset + FieldSize; 13180aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 13194cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson DataSize = llvm::RoundUpToAlignment(NewSizeInBits, 8); 13204cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson UnfilledBitsInLastByte = DataSize - NewSizeInBits; 13214cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson } 13224cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 13234cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson // Place this field at the current location. 13244cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson FieldOffsets.push_back(FieldOffset); 13254cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 13264cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson // Update the size. 13274cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson Size = std::max(Size, DataSize); 13280aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 13294cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson // Remember max struct/class alignment. 13304cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson UpdateAlignment(TypeAlign); 13314cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson} 13324cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 13337d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonvoid RecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { 133442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson bool FieldPacked = Packed || D->hasAttr<PackedAttr>(); 1335e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson uint64_t FieldOffset = IsUnion ? 0 : (DataSize - UnfilledBitsInLastByte); 13360f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson uint64_t FieldSize = D->getBitWidth()->EvaluateAsInt(Context).getZExtValue(); 1337bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 13380f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson std::pair<uint64_t, unsigned> FieldInfo = Context.getTypeInfo(D->getType()); 133942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson uint64_t TypeSize = FieldInfo.first; 134042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson unsigned FieldAlign = FieldInfo.second; 1341bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 13424cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson if (FieldSize > TypeSize) { 13434cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson LayoutWideBitField(FieldSize, TypeSize); 13444cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson return; 13454cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson } 13464cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 13470f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson if (FieldPacked || !Context.Target.useBitFieldTypeAlignment()) 134842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldAlign = 1; 134942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) 135042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldAlign = std::max(FieldAlign, AA->getMaxAlignment()); 13511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 135242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // The maximum field alignment overrides the aligned attribute. 135342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (MaxFieldAlignment) 135442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldAlign = std::min(FieldAlign, MaxFieldAlignment); 1355bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1356b6a169395c1b30c76daffebcbd2164b6247a5d21Daniel Dunbar // Check if we need to add padding to give the field the correct alignment. 135742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (FieldSize == 0 || (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize) 135842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldOffset = (FieldOffset + (FieldAlign-1)) & ~(FieldAlign-1); 1359bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1360b6a169395c1b30c76daffebcbd2164b6247a5d21Daniel Dunbar // Padding members don't affect overall alignment. 136142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (!D->getIdentifier()) 136242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldAlign = 1; 1363bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 136442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // Place this field at the current location. 136542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldOffsets.push_back(FieldOffset); 1366bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1367e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson // Update DataSize to include the last byte containing (part of) the bitfield. 1368e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson if (IsUnion) { 1369e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson // FIXME: I think FieldSize should be TypeSize here. 1370e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson DataSize = std::max(DataSize, FieldSize); 1371e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson } else { 1372e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson uint64_t NewSizeInBits = FieldOffset + FieldSize; 1373bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1374e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson DataSize = llvm::RoundUpToAlignment(NewSizeInBits, 8); 1375e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson UnfilledBitsInLastByte = DataSize - NewSizeInBits; 1376e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson } 1377bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1378e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson // Update the size. 1379e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson Size = std::max(Size, DataSize); 1380bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 138142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // Remember max struct/class alignment. 138242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson UpdateAlignment(FieldAlign); 138342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson} 13841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13857d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonvoid RecordLayoutBuilder::LayoutField(const FieldDecl *D) { 138642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (D->isBitField()) { 138742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson LayoutBitField(D); 138842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson return; 138942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson } 13901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1391e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson // Reset the unfilled bits. 1392e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson UnfilledBitsInLastByte = 0; 1393e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson 139442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson bool FieldPacked = Packed || D->hasAttr<PackedAttr>(); 139542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson uint64_t FieldOffset = IsUnion ? 0 : DataSize; 139642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson uint64_t FieldSize; 139742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson unsigned FieldAlign; 1398bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 139942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (D->getType()->isIncompleteArrayType()) { 140042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // This is a flexible array member; we can't directly 140142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // query getTypeInfo about these, so we figure it out here. 140242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // Flexible array members don't have any size, but they 140342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // have to be aligned appropriately for their element type. 140442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldSize = 0; 14050f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson const ArrayType* ATy = Context.getAsArrayType(D->getType()); 14060f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson FieldAlign = Context.getTypeAlign(ATy->getElementType()); 140742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson } else if (const ReferenceType *RT = D->getType()->getAs<ReferenceType>()) { 140842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson unsigned AS = RT->getPointeeType().getAddressSpace(); 14090f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson FieldSize = Context.Target.getPointerWidth(AS); 14100f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson FieldAlign = Context.Target.getPointerAlign(AS); 141142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson } else { 14120f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson std::pair<uint64_t, unsigned> FieldInfo = Context.getTypeInfo(D->getType()); 141342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldSize = FieldInfo.first; 1414bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson FieldAlign = FieldInfo.second; 141542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson } 14161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 141742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (FieldPacked) 141842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldAlign = 8; 141942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) 142042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldAlign = std::max(FieldAlign, AA->getMaxAlignment()); 14211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 142242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // The maximum field alignment overrides the aligned attribute. 142342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (MaxFieldAlignment) 142442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldAlign = std::min(FieldAlign, MaxFieldAlignment); 14251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 142642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // Round up the current record size to the field's alignment boundary. 142742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign); 1428bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 142942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (!IsUnion) { 143042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson while (true) { 143142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // Check if we can place the field at this offset. 143242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (canPlaceFieldAtOffset(D, FieldOffset)) 143342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson break; 1434bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 143542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // We couldn't place the field at the offset. Try again at a new offset. 143642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldOffset += FieldAlign; 14376026504302763f74102592602b392cecd5ced3aeAnders Carlsson } 1438bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 143942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson UpdateEmptyClassOffsets(D, FieldOffset); 1440bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson } 1441bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1442bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // Place this field at the current location. 1443bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson FieldOffsets.push_back(FieldOffset); 14441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1445bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // Reserve space for this field. 1446bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson if (IsUnion) 1447bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson Size = std::max(Size, FieldSize); 1448bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson else 1449bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson Size = FieldOffset + FieldSize; 14501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1451a223935e5cf82e939e1ca1da4111d63025a04e39Anders Carlsson // Update the data size. 1452a223935e5cf82e939e1ca1da4111d63025a04e39Anders Carlsson DataSize = Size; 14531eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1454bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // Remember max struct/class alignment. 1455bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson UpdateAlignment(FieldAlign); 1456bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson} 1457bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 14587d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonvoid RecordLayoutBuilder::FinishLayout() { 1459bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // In C++, records cannot be of size 0. 14600f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson if (Context.getLangOptions().CPlusPlus && Size == 0) 1461bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson Size = 8; 1462bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // Finally, round the size of the record up to the alignment of the 1463bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // record itself. 146442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson Size = llvm::RoundUpToAlignment(Size, Alignment); 1465bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson} 1466bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 14677d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonvoid RecordLayoutBuilder::UpdateAlignment(unsigned NewAlignment) { 1468c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar // The alignment is not modified when using 'mac68k' alignment. 1469c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar if (IsMac68kAlign) 1470c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar return; 1471c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar 1472bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson if (NewAlignment <= Alignment) 1473bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson return; 14741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1475bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson assert(llvm::isPowerOf2_32(NewAlignment && "Alignment not a power of 2")); 14761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1477bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson Alignment = NewAlignment; 1478bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson} 14791eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1480f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlssonconst CXXMethodDecl * 14817d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders CarlssonRecordLayoutBuilder::ComputeKeyFunction(const CXXRecordDecl *RD) { 1482f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson assert(RD->isDynamicClass() && "Class does not have any virtual methods!"); 1483f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson 14848d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar // If a class isn't polymorphic it doesn't have a key function. 1485f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (!RD->isPolymorphic()) 1486f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson return 0; 148761eab8872168af6eb1e0047a82901096cf145e27Eli Friedman 148861eab8872168af6eb1e0047a82901096cf145e27Eli Friedman // A class inside an anonymous namespace doesn't have a key function. (Or 148961eab8872168af6eb1e0047a82901096cf145e27Eli Friedman // at least, there's no point to assigning a key function to such a class; 149061eab8872168af6eb1e0047a82901096cf145e27Eli Friedman // this doesn't affect the ABI.) 149161eab8872168af6eb1e0047a82901096cf145e27Eli Friedman if (RD->isInAnonymousNamespace()) 149261eab8872168af6eb1e0047a82901096cf145e27Eli Friedman return 0; 149361eab8872168af6eb1e0047a82901096cf145e27Eli Friedman 1494bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar for (CXXRecordDecl::method_iterator I = RD->method_begin(), 1495bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->method_end(); I != E; ++I) { 1496f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson const CXXMethodDecl *MD = *I; 1497bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1498f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (!MD->isVirtual()) 1499f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson continue; 1500bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1501f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (MD->isPure()) 1502f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson continue; 150361eab8872168af6eb1e0047a82901096cf145e27Eli Friedman 1504f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson // Ignore implicit member functions, they are always marked as inline, but 1505f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson // they don't have a body until they're defined. 1506f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (MD->isImplicit()) 1507f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson continue; 1508bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1509bd6d6197fcfc98356ea60e816365eb0648b69556Douglas Gregor if (MD->isInlineSpecified()) 1510bd6d6197fcfc98356ea60e816365eb0648b69556Douglas Gregor continue; 1511f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson 1512f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (MD->hasInlineBody()) 1513f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson continue; 1514bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1515f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson // We found it. 1516f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson return MD; 1517f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson } 1518bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1519f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson return 0; 1520f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson} 1521f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson 15221e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// getASTRecordLayout - Get or compute information about the layout of the 15231e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// specified record (struct/union/class), which indicates its size and field 15241e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// position information. 15251e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlssonconst ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D) { 15261e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson D = D->getDefinition(); 15271e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson assert(D && "Cannot get layout of forward declarations!"); 15281e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 15291e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // Look up this layout, if already laid out, return what we have. 15301e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // Note that we can't save a reference to the entry because this function 15311e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // is recursive. 15321e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson const ASTRecordLayout *Entry = ASTRecordLayouts[D]; 15331e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson if (Entry) return *Entry; 15341e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 15352f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson const ASTRecordLayout *NewEntry; 15362f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson 15372f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) { 1538261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson EmptySubobjectMap EmptySubobjects(*this, RD); 153958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 1540261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson RecordLayoutBuilder Builder(*this, &EmptySubobjects); 15412f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson Builder.Layout(RD); 15422f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson 15432f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson // FIXME: This is not always correct. See the part about bitfields at 15442f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson // http://www.codesourcery.com/public/cxx-abi/abi.html#POD for more info. 15452f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson // FIXME: IsPODForThePurposeOfLayout should be stored in the record layout. 15462f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson bool IsPODForThePurposeOfLayout = cast<CXXRecordDecl>(D)->isPOD(); 15472f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson 15482f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson // FIXME: This should be done in FinalizeLayout. 15492f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson uint64_t DataSize = 15502f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson IsPODForThePurposeOfLayout ? Builder.Size : Builder.DataSize; 15512f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson uint64_t NonVirtualSize = 15522f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson IsPODForThePurposeOfLayout ? DataSize : Builder.NonVirtualSize; 15532f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson 15540aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar NewEntry = 15552f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson new (*this) ASTRecordLayout(*this, Builder.Size, Builder.Alignment, 15562f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson DataSize, Builder.FieldOffsets.data(), 15572f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson Builder.FieldOffsets.size(), 15582f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson NonVirtualSize, 15592f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson Builder.NonVirtualAlignment, 1560261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson EmptySubobjects.SizeOfLargestEmptySubobject, 15612f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson Builder.PrimaryBase, 15624831710518be9f506f0bc2d11bec6205061fc119Anders Carlsson Builder.PrimaryBaseIsVirtual, 15632f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson Builder.Bases, Builder.VBases); 15642f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson } else { 1565261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0); 15662f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson Builder.Layout(D); 15670aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 15682f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson NewEntry = 15692f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson new (*this) ASTRecordLayout(*this, Builder.Size, Builder.Alignment, 15702f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson Builder.Size, 15712f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson Builder.FieldOffsets.data(), 15722f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson Builder.FieldOffsets.size()); 15732f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson } 15742f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson 15751e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson ASTRecordLayouts[D] = NewEntry; 15761e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 15771e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson if (getLangOptions().DumpRecordLayouts) { 15781e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson llvm::errs() << "\n*** Dumping AST Record Layout\n"; 15791e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson DumpRecordLayout(D, llvm::errs()); 15801e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson } 15811e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 15821e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson return *NewEntry; 15831e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson} 15841e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 15851e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlssonconst CXXMethodDecl *ASTContext::getKeyFunction(const CXXRecordDecl *RD) { 15861e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson RD = cast<CXXRecordDecl>(RD->getDefinition()); 15871e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson assert(RD && "Cannot get key function for forward declarations!"); 15880aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 15891e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson const CXXMethodDecl *&Entry = KeyFunctions[RD]; 15900aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar if (!Entry) 15917d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlsson Entry = RecordLayoutBuilder::ComputeKeyFunction(RD); 15921e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson else 15937d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlsson assert(Entry == RecordLayoutBuilder::ComputeKeyFunction(RD) && 15941e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson "Key function changed!"); 15950aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 15961e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson return Entry; 15971e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson} 15981e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 15991e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// getInterfaceLayoutImpl - Get or compute information about the 16001e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// layout of the given interface. 16011e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// 16021e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// \param Impl - If given, also include the layout of the interface's 16031e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// implementation. This may differ by including synthesized ivars. 16041e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlssonconst ASTRecordLayout & 16051e641ce1c169b4b0cac3d7ad6da44b323453049cAnders CarlssonASTContext::getObjCLayout(const ObjCInterfaceDecl *D, 16061e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson const ObjCImplementationDecl *Impl) { 16071e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson assert(!D->isForwardDecl() && "Invalid interface decl!"); 16081e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 16091e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // Look up this layout, if already laid out, return what we have. 16101e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson ObjCContainerDecl *Key = 16111e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson Impl ? (ObjCContainerDecl*) Impl : (ObjCContainerDecl*) D; 16121e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson if (const ASTRecordLayout *Entry = ObjCLayouts[Key]) 16131e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson return *Entry; 16141e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 16151e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // Add in synthesized ivar count if laying out an implementation. 16161e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson if (Impl) { 16171e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson unsigned SynthCount = CountNonClassIvars(D); 16181e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // If there aren't any sythesized ivars then reuse the interface 16191e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // entry. Note we can't cache this because we simply free all 16201e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // entries later; however we shouldn't look up implementations 16211e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // frequently. 16221e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson if (SynthCount == 0) 16231e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson return getObjCLayout(D, 0); 16241e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson } 16251e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 1626261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0); 162736cdc61b98460c06ee07710f77b911675fdce6a7Anders Carlsson Builder.Layout(D); 162836cdc61b98460c06ee07710f77b911675fdce6a7Anders Carlsson 16291e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson const ASTRecordLayout *NewEntry = 163036cdc61b98460c06ee07710f77b911675fdce6a7Anders Carlsson new (*this) ASTRecordLayout(*this, Builder.Size, Builder.Alignment, 163136cdc61b98460c06ee07710f77b911675fdce6a7Anders Carlsson Builder.DataSize, 163236cdc61b98460c06ee07710f77b911675fdce6a7Anders Carlsson Builder.FieldOffsets.data(), 163336cdc61b98460c06ee07710f77b911675fdce6a7Anders Carlsson Builder.FieldOffsets.size()); 16340aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 16351e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson ObjCLayouts[Key] = NewEntry; 16361e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 16371e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson return *NewEntry; 16381e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson} 16391e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 1640bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbarstatic void PrintOffset(llvm::raw_ostream &OS, 1641bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar uint64_t Offset, unsigned IndentLevel) { 1642bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << llvm::format("%4d | ", Offset); 1643bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS.indent(IndentLevel * 2); 1644bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar} 1645bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1646bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbarstatic void DumpCXXRecordLayout(llvm::raw_ostream &OS, 1647bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar const CXXRecordDecl *RD, ASTContext &C, 1648bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar uint64_t Offset, 1649bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar unsigned IndentLevel, 1650bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar const char* Description, 1651bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar bool IncludeVirtualBases) { 1652bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar const ASTRecordLayout &Info = C.getASTRecordLayout(RD); 1653bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1654bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar PrintOffset(OS, Offset, IndentLevel); 1655cb421fa690da545b58a720abe5f1c49b166dbde7Dan Gohman OS << C.getTypeDeclType(const_cast<CXXRecordDecl *>(RD)).getAsString(); 1656bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (Description) 1657bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << ' ' << Description; 1658bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (RD->isEmpty()) 1659bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << " (empty)"; 1660bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << '\n'; 1661bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1662bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar IndentLevel++; 1663bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1664bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar const CXXRecordDecl *PrimaryBase = Info.getPrimaryBase(); 1665bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1666bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar // Vtable pointer. 1667bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (RD->isDynamicClass() && !PrimaryBase) { 1668bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar PrintOffset(OS, Offset, IndentLevel); 1669900fc6388e803868a34b9483510c345e9b49d7ebBenjamin Kramer OS << '(' << RD << " vtable pointer)\n"; 1670bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar } 1671bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar // Dump (non-virtual) bases 1672bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1673bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->bases_end(); I != E; ++I) { 1674bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar assert(!I->getType()->isDependentType() && 1675bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar "Cannot layout class with dependent bases."); 1676bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (I->isVirtual()) 1677bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar continue; 1678bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1679bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar const CXXRecordDecl *Base = 1680bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1681bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1682bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar uint64_t BaseOffset = Offset + Info.getBaseClassOffset(Base) / 8; 1683bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1684bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar DumpCXXRecordLayout(OS, Base, C, BaseOffset, IndentLevel, 1685bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar Base == PrimaryBase ? "(primary base)" : "(base)", 1686bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar /*IncludeVirtualBases=*/false); 1687bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar } 1688bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1689bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar // Dump fields. 1690bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar uint64_t FieldNo = 0; 1691bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar for (CXXRecordDecl::field_iterator I = RD->field_begin(), 1692bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->field_end(); I != E; ++I, ++FieldNo) { 1693bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar const FieldDecl *Field = *I; 1694bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar uint64_t FieldOffset = Offset + Info.getFieldOffset(FieldNo) / 8; 1695bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1696bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (const RecordType *RT = Field->getType()->getAs<RecordType>()) { 1697bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (const CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(RT->getDecl())) { 1698bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar DumpCXXRecordLayout(OS, D, C, FieldOffset, IndentLevel, 1699bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar Field->getNameAsCString(), 1700bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar /*IncludeVirtualBases=*/true); 1701bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar continue; 1702bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar } 1703bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar } 1704bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1705bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar PrintOffset(OS, FieldOffset, IndentLevel); 1706900fc6388e803868a34b9483510c345e9b49d7ebBenjamin Kramer OS << Field->getType().getAsString() << ' ' << Field << '\n'; 1707bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar } 1708bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1709bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (!IncludeVirtualBases) 1710bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar return; 1711bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1712bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar // Dump virtual bases. 1713bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(), 1714bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->vbases_end(); I != E; ++I) { 1715bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar assert(I->isVirtual() && "Found non-virtual class!"); 1716bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar const CXXRecordDecl *VBase = 1717bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1718bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1719bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar uint64_t VBaseOffset = Offset + Info.getVBaseClassOffset(VBase) / 8; 1720bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar DumpCXXRecordLayout(OS, VBase, C, VBaseOffset, IndentLevel, 1721bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar VBase == PrimaryBase ? 1722bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar "(primary virtual base)" : "(virtual base)", 1723bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar /*IncludeVirtualBases=*/false); 1724bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar } 1725bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1726bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << " sizeof=" << Info.getSize() / 8; 1727bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << ", dsize=" << Info.getDataSize() / 8; 1728bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << ", align=" << Info.getAlignment() / 8 << '\n'; 1729bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << " nvsize=" << Info.getNonVirtualSize() / 8; 1730bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << ", nvalign=" << Info.getNonVirtualAlign() / 8 << '\n'; 1731bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << '\n'; 1732bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar} 17338d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar 17348d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbarvoid ASTContext::DumpRecordLayout(const RecordDecl *RD, 17358d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar llvm::raw_ostream &OS) { 17368d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar const ASTRecordLayout &Info = getASTRecordLayout(RD); 17378d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar 17388d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) 17398d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar return DumpCXXRecordLayout(OS, CXXRD, *this, 0, 0, 0, 17408d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar /*IncludeVirtualBases=*/true); 17418d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar 17428d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << "Type: " << getTypeDeclType(RD).getAsString() << "\n"; 17438d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << "Record: "; 17448d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar RD->dump(); 17458d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << "\nLayout: "; 17468d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << "<ASTRecordLayout\n"; 17478d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << " Size:" << Info.getSize() << "\n"; 17488d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << " DataSize:" << Info.getDataSize() << "\n"; 17498d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << " Alignment:" << Info.getAlignment() << "\n"; 17508d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << " FieldOffsets: ["; 17518d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar for (unsigned i = 0, e = Info.getFieldCount(); i != e; ++i) { 17528d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar if (i) OS << ", "; 17538d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << Info.getFieldOffset(i); 17548d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar } 17558d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << "]>\n"; 17568d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar} 1757