RecordLayoutBuilder.cpp revision 584e1dfaf6ab682cebe4fe51f55f0ae3215d303f
1bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson//=== ASTRecordLayoutBuilder.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 "RecordLayoutBuilder.h" 11bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 12bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson#include "clang/AST/Attr.h" 13bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson#include "clang/AST/Decl.h" 1474cbe226207fd101623638dadfa7fbada04ff2a6Anders Carlsson#include "clang/AST/DeclCXX.h" 1593fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson#include "clang/AST/DeclObjC.h" 16bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson#include "clang/AST/Expr.h" 17bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson#include "clang/Basic/TargetInfo.h" 186f376336138ea719e3c4757ae046a5768043b276Mike Stump#include <llvm/ADT/SmallSet.h> 19bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson#include <llvm/Support/MathExtras.h> 20bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 21bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlssonusing namespace clang; 22bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 231eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpASTRecordLayoutBuilder::ASTRecordLayoutBuilder(ASTContext &Ctx) 24e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson : Ctx(Ctx), Size(0), Alignment(8), Packed(false), UnfilledBitsInLastByte(0), 25e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson MaxFieldAlignment(0), DataSize(0), IsUnion(false), NonVirtualSize(0), 26200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson NonVirtualAlignment(8), FirstNearlyEmptyVBase(0) { } 273dee6efcad9ad56d14f7edd1c29924f0b876a7f9Mike Stump 286f376336138ea719e3c4757ae046a5768043b276Mike Stump/// IsNearlyEmpty - Indicates when a class has a vtable pointer, but 296f376336138ea719e3c4757ae046a5768043b276Mike Stump/// no other data. 303f066522342538509cf0aa4f381503b43fbdb68bAnders Carlssonbool ASTRecordLayoutBuilder::IsNearlyEmpty(const CXXRecordDecl *RD) const { 316f376336138ea719e3c4757ae046a5768043b276Mike Stump // FIXME: Audit the corners 326f376336138ea719e3c4757ae046a5768043b276Mike Stump if (!RD->isDynamicClass()) 336f376336138ea719e3c4757ae046a5768043b276Mike Stump return false; 346f376336138ea719e3c4757ae046a5768043b276Mike Stump const ASTRecordLayout &BaseInfo = Ctx.getASTRecordLayout(RD); 356f376336138ea719e3c4757ae046a5768043b276Mike Stump if (BaseInfo.getNonVirtualSize() == Ctx.Target.getPointerWidth(0)) 366f376336138ea719e3c4757ae046a5768043b276Mike Stump return true; 376f376336138ea719e3c4757ae046a5768043b276Mike Stump return false; 386f376336138ea719e3c4757ae046a5768043b276Mike Stump} 396f376336138ea719e3c4757ae046a5768043b276Mike Stump 403f066522342538509cf0aa4f381503b43fbdb68bAnders Carlssonvoid ASTRecordLayoutBuilder::IdentifyPrimaryBases(const CXXRecordDecl *RD) { 41ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson const ASTRecordLayout::PrimaryBaseInfo &BaseInfo = 42ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson Ctx.getASTRecordLayout(RD).getPrimaryBaseInfo(); 433f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson 443f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson // If the record has a primary base class that is virtual, add it to the set 453f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson // of primary bases. 46261fba6cf57a09a1f1d0c4a4c4856aaa62753242Anders Carlsson if (BaseInfo.isVirtual()) 47261fba6cf57a09a1f1d0c4a4c4856aaa62753242Anders Carlsson IndirectPrimaryBases.insert(BaseInfo.getBase()); 483f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson 493f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson // Now traverse all bases and find primary bases for them. 506f376336138ea719e3c4757ae046a5768043b276Mike Stump for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), 516f376336138ea719e3c4757ae046a5768043b276Mike Stump e = RD->bases_end(); i != e; ++i) { 529994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl assert(!i->getType()->isDependentType() && 539994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl "Cannot layout class with dependent bases."); 541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const CXXRecordDecl *Base = 5549520944c688a9d5fc78d0c2af544b825873477bMike Stump cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 563f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson 5749520944c688a9d5fc78d0c2af544b825873477bMike Stump // Only bases with virtual bases participate in computing the 5849520944c688a9d5fc78d0c2af544b825873477bMike Stump // indirect primary virtual base classes. 594ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump if (Base->getNumVBases()) 603f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson IdentifyPrimaryBases(Base); 616f376336138ea719e3c4757ae046a5768043b276Mike Stump } 626f376336138ea719e3c4757ae046a5768043b276Mike Stump} 636f376336138ea719e3c4757ae046a5768043b276Mike Stump 643f066522342538509cf0aa4f381503b43fbdb68bAnders Carlssonvoid 65200c5c2d9488165626925235ff918e3d744d785aAnders CarlssonASTRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD) { 66584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 67584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson E = RD->bases_end(); I != E; ++I) { 68584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson assert(!I->getType()->isDependentType() && 699994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl "Cannot layout class with dependent bases."); 70584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson 711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const CXXRecordDecl *Base = 72584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 73200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 74584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson // Check if this is a nearly empty virtual base. 75584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson if (I->isVirtual() && IsNearlyEmpty(Base)) { 76584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson // If it's not an indirect primary base, then we've found our primary 77584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson // base. 783f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson if (!IndirectPrimaryBases.count(Base)) { 79200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson PrimaryBase = ASTRecordLayout::PrimaryBaseInfo(Base, 80200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson /*IsVirtual=*/true); 81d76264e0b20470267249660ab947197cf6d6e31fMike Stump return; 82d76264e0b20470267249660ab947197cf6d6e31fMike Stump } 83584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson 84584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson // Is this the first nearly empty virtual base? 85584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson if (!FirstNearlyEmptyVBase) 86584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson FirstNearlyEmptyVBase = Base; 87d76264e0b20470267249660ab947197cf6d6e31fMike Stump } 88200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 89200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson SelectPrimaryVBase(Base); 9094ba380b820cde3fb9d97d5f07ac709ebbb6ac1eZhongxing Xu if (PrimaryBase.getBase()) 9194ba380b820cde3fb9d97d5f07ac709ebbb6ac1eZhongxing Xu return; 92d76264e0b20470267249660ab947197cf6d6e31fMike Stump } 93d76264e0b20470267249660ab947197cf6d6e31fMike Stump} 94d76264e0b20470267249660ab947197cf6d6e31fMike Stump 95200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson/// DeterminePrimaryBase - Determine the primary base of the given class. 96200c5c2d9488165626925235ff918e3d744d785aAnders Carlssonvoid ASTRecordLayoutBuilder::DeterminePrimaryBase(const CXXRecordDecl *RD) { 97200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // If the class isn't dynamic, it won't have a primary base. 98200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson if (!RD->isDynamicClass()) 99200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson return; 100200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 1013f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson // Compute all the primary virtual bases for all of our direct and 1020880e75541899bc1cdd73c50eb549110b5916c59Mike Stump // indirect bases, and record all their primary virtual base classes. 1030880e75541899bc1cdd73c50eb549110b5916c59Mike Stump for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), 1040880e75541899bc1cdd73c50eb549110b5916c59Mike Stump e = RD->bases_end(); i != e; ++i) { 1059994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl assert(!i->getType()->isDependentType() && 106200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson "Cannot lay out class with dependent bases."); 1071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const CXXRecordDecl *Base = 1080880e75541899bc1cdd73c50eb549110b5916c59Mike Stump cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 1093f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson IdentifyPrimaryBases(Base); 1100880e75541899bc1cdd73c50eb549110b5916c59Mike Stump } 1110880e75541899bc1cdd73c50eb549110b5916c59Mike Stump 1123f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson // If the record has a dynamic base class, attempt to choose a primary base 1133f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson // class. It is the first (in direct base class order) non-virtual dynamic 1143f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson // base class, if one exists. 1156f376336138ea719e3c4757ae046a5768043b276Mike Stump for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), 1166f376336138ea719e3c4757ae046a5768043b276Mike Stump e = RD->bases_end(); i != e; ++i) { 117ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson // Ignore virtual bases. 118ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson if (i->isVirtual()) 119ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson continue; 120ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson 121ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson const CXXRecordDecl *Base = 122ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 123ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson 124ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson if (Base->isDynamicClass()) { 125ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson // We found it. 126ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson PrimaryBase = ASTRecordLayout::PrimaryBaseInfo(Base, /*IsVirtual=*/false); 127ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson return; 1286f376336138ea719e3c4757ae046a5768043b276Mike Stump } 1296f376336138ea719e3c4757ae046a5768043b276Mike Stump } 1306f376336138ea719e3c4757ae046a5768043b276Mike Stump 1316f376336138ea719e3c4757ae046a5768043b276Mike Stump // Otherwise, it is the first nearly empty virtual base that is not an 13249520944c688a9d5fc78d0c2af544b825873477bMike Stump // indirect primary virtual base class, if one exists. 133200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson if (RD->getNumVBases() != 0) { 134200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson SelectPrimaryVBase(RD); 135200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson if (PrimaryBase.getBase()) 136200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson return; 137200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson } 1386f376336138ea719e3c4757ae046a5768043b276Mike Stump 139200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Otherwise, it is the first nearly empty virtual base that is not an 140200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // indirect primary virtual base class, if one exists. 141200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson if (FirstNearlyEmptyVBase) { 142584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson PrimaryBase = ASTRecordLayout::PrimaryBaseInfo(FirstNearlyEmptyVBase, 143584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson /*IsVirtual=*/true); 1446f376336138ea719e3c4757ae046a5768043b276Mike Stump return; 145200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson } 1463f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson 147200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Otherwise there is no primary base class. 148200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson assert(!PrimaryBase.getBase() && "Should not get here with a primary base!"); 149200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 150200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Allocate the virtual table pointer at offset zero. 151200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson assert(DataSize == 0 && "Vtable pointer must be at offset zero!"); 152200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 153200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Update the size. 154200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson Size += Ctx.Target.getPointerWidth(0); 155200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson DataSize = Size; 156200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 157200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Update the alignment. 158200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson UpdateAlignment(Ctx.Target.getPointerAlign(0)); 1596f376336138ea719e3c4757ae046a5768043b276Mike Stump} 1606f376336138ea719e3c4757ae046a5768043b276Mike Stump 161968db3364611a475909b5e76969d2f5472e65597Mike Stumpuint64_t ASTRecordLayoutBuilder::getBaseOffset(const CXXRecordDecl *Base) { 162968db3364611a475909b5e76969d2f5472e65597Mike Stump for (size_t i = 0; i < Bases.size(); ++i) { 163968db3364611a475909b5e76969d2f5472e65597Mike Stump if (Bases[i].first == Base) 164968db3364611a475909b5e76969d2f5472e65597Mike Stump return Bases[i].second; 165968db3364611a475909b5e76969d2f5472e65597Mike Stump } 166968db3364611a475909b5e76969d2f5472e65597Mike Stump for (size_t i = 0; i < VBases.size(); ++i) { 167968db3364611a475909b5e76969d2f5472e65597Mike Stump if (VBases[i].first == Base) 168968db3364611a475909b5e76969d2f5472e65597Mike Stump return VBases[i].second; 169968db3364611a475909b5e76969d2f5472e65597Mike Stump } 170968db3364611a475909b5e76969d2f5472e65597Mike Stump assert(0 && "missing base"); 171968db3364611a475909b5e76969d2f5472e65597Mike Stump return 0; 172968db3364611a475909b5e76969d2f5472e65597Mike Stump} 173968db3364611a475909b5e76969d2f5472e65597Mike Stump 174e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlssonvoid 175e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders CarlssonASTRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) { 176200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // First, determine the primary base class. 177200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson DeterminePrimaryBase(RD); 178200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 179200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // If we have a primary base class, lay it out. 180200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson if (const CXXRecordDecl *Base = PrimaryBase.getBase()) { 181200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson if (PrimaryBase.isVirtual()) { 182200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // We have a virtual primary base, insert it as an indirect primary base. 183200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson IndirectPrimaryBases.insert(Base); 184200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 185200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson LayoutVirtualBase(Base); 186200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson } else 187200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson LayoutNonVirtualBase(Base); 188200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson } 189200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 190200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Now lay out the non-virtual bases. 191200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 192200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson E = RD->bases_end(); I != E; ++I) { 193200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 194200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Ignore virtual bases. 195200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson if (I->isVirtual()) 196200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson continue; 197200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 198200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson const CXXRecordDecl *Base = 199200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 200200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 201200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Skip the primary base. 202200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson if (Base == PrimaryBase.getBase() && !PrimaryBase.isVirtual()) 203200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson continue; 204200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 205200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Lay out the base. 206200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson LayoutNonVirtualBase(Base); 207e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson } 208e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson} 209e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 210e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlssonvoid ASTRecordLayoutBuilder::LayoutNonVirtualBase(const CXXRecordDecl *RD) { 211e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson // Layout the base. 212e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson uint64_t Offset = LayoutBase(RD); 213e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson 214e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson // Add its base class offset. 215e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson Bases.push_back(std::make_pair(RD, Offset)); 216e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson} 217968db3364611a475909b5e76969d2f5472e65597Mike Stump 218968db3364611a475909b5e76969d2f5472e65597Mike Stumpvoid ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *Class, 219968db3364611a475909b5e76969d2f5472e65597Mike Stump const CXXRecordDecl *RD, 220fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump const CXXRecordDecl *PB, 22123a5fcba194c3dec737f296860d75327d85cc349Anders Carlsson uint64_t Offset) { 2224ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), 2234ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump e = RD->bases_end(); i != e; ++i) { 2249994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl assert(!i->getType()->isDependentType() && 2259994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl "Cannot layout class with dependent bases."); 2261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const CXXRecordDecl *Base = 227eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 228968db3364611a475909b5e76969d2f5472e65597Mike Stump uint64_t BaseOffset = Offset; 229276b9f1d814f4f6551cc3000590759a34185d6daMike Stump if (i->isVirtual()) { 230fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump if (Base == PB) { 231fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump // Only lay things out once. 23223a5fcba194c3dec737f296860d75327d85cc349Anders Carlsson if (VisitedVirtualBases.count(Base)) 233fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump continue; 234fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump // Mark it so we don't lay it out twice. 23523a5fcba194c3dec737f296860d75327d85cc349Anders Carlsson VisitedVirtualBases.insert(Base); 2369dc82d2193971ed57dc657dbd21249a2c57da376Anders Carlsson assert (IndirectPrimaryBases.count(Base) && "IndirectPrimary was wrong"); 237e4feb834fb1a6b03291ed78fd32d13729b5a3c4aAnders Carlsson VBases.push_back(std::make_pair(Base, Offset)); 2389dc82d2193971ed57dc657dbd21249a2c57da376Anders Carlsson } else if (IndirectPrimaryBases.count(Base)) { 239fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump // Someone else will eventually lay this out. 240fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump ; 241fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump } else { 242fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump // Only lay things out once. 24323a5fcba194c3dec737f296860d75327d85cc349Anders Carlsson if (VisitedVirtualBases.count(Base)) 244fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump continue; 245fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump // Mark it so we don't lay it out twice. 24623a5fcba194c3dec737f296860d75327d85cc349Anders Carlsson VisitedVirtualBases.insert(Base); 247276b9f1d814f4f6551cc3000590759a34185d6daMike Stump LayoutVirtualBase(Base); 248e4feb834fb1a6b03291ed78fd32d13729b5a3c4aAnders Carlsson BaseOffset = VBases.back().second; 249fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump } 250968db3364611a475909b5e76969d2f5472e65597Mike Stump } else { 251968db3364611a475909b5e76969d2f5472e65597Mike Stump if (RD == Class) 252968db3364611a475909b5e76969d2f5472e65597Mike Stump BaseOffset = getBaseOffset(Base); 253968db3364611a475909b5e76969d2f5472e65597Mike Stump else { 25437acf5a57f87abdbb4ac6115c5f3f09295ec2dc3Mike Stump const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD); 255968db3364611a475909b5e76969d2f5472e65597Mike Stump BaseOffset = Offset + Layout.getBaseClassOffset(Base); 256968db3364611a475909b5e76969d2f5472e65597Mike Stump } 257fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump } 258968db3364611a475909b5e76969d2f5472e65597Mike Stump 259fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump if (Base->getNumVBases()) { 260ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(Base); 261261fba6cf57a09a1f1d0c4a4c4856aaa62753242Anders Carlsson const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBaseInfo().getBase(); 26223a5fcba194c3dec737f296860d75327d85cc349Anders Carlsson LayoutVirtualBases(Class, Base, PrimaryBase, BaseOffset); 2634ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump } 264eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump } 265eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump} 266eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump 267e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlssonvoid ASTRecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *RD) { 268e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson // Layout the base. 269e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson uint64_t Offset = LayoutBase(RD); 270e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson 271e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson // Add its base class offset. 272e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson VBases.push_back(std::make_pair(RD, Offset)); 273e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson} 274e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 275e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlssonuint64_t ASTRecordLayoutBuilder::LayoutBase(const CXXRecordDecl *RD) { 276e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson const ASTRecordLayout &BaseInfo = Ctx.getASTRecordLayout(RD); 277e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 278e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // If we have an empty base class, try to place it at offset 0. 279e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson if (RD->isEmpty() && canPlaceRecordAtOffset(RD, 0)) { 280e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // We were able to place the class at offset 0. 281e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson UpdateEmptyClassOffsets(RD, 0); 282e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 283e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson Size = std::max(Size, BaseInfo.getSize()); 284e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 285e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson return 0; 286e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson } 287e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 288e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson unsigned BaseAlign = BaseInfo.getNonVirtualAlign(); 289e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 290e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // Round up the current record size to the base's alignment boundary. 291e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson uint64_t Offset = llvm::RoundUpToAlignment(DataSize, BaseAlign); 292e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 293e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // Try to place the base. 294e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson while (true) { 295e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson if (canPlaceRecordAtOffset(RD, Offset)) 296e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson break; 297e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 298e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson Offset += BaseAlign; 299e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson } 300e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 301e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson if (!RD->isEmpty()) { 302e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // Update the data size. 303e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson DataSize = Offset + BaseInfo.getNonVirtualSize(); 304e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 305e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson Size = std::max(Size, DataSize); 306e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson } else 307e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson Size = std::max(Size, Offset + BaseInfo.getSize()); 308e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 309e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // Remember max struct/class alignment. 310e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson UpdateAlignment(BaseAlign); 311e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 312e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson UpdateEmptyClassOffsets(RD, Offset); 313e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson return Offset; 314e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson} 315e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 3169606149722bedfc48fc56cafc58de1139aef481dAnders Carlssonbool ASTRecordLayoutBuilder::canPlaceRecordAtOffset(const CXXRecordDecl *RD, 3179606149722bedfc48fc56cafc58de1139aef481dAnders Carlsson uint64_t Offset) const { 3181345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson // Look for an empty class with the same type at the same offset. 3191345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson for (EmptyClassOffsetsTy::const_iterator I = 3201345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson EmptyClassOffsets.lower_bound(Offset), 3211345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson E = EmptyClassOffsets.upper_bound(Offset); I != E; ++I) { 3221345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson 3231345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson if (I->second == RD) 3241345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson return false; 3251345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson } 3261345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson 327ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson const ASTRecordLayout &Info = Ctx.getASTRecordLayout(RD); 328ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson 329ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson // Check bases. 330ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 331ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson E = RD->bases_end(); I != E; ++I) { 3329994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl assert(!I->getType()->isDependentType() && 3339994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl "Cannot layout class with dependent bases."); 334ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson if (I->isVirtual()) 335ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson continue; 336ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson 337ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson const CXXRecordDecl *Base = 338ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 339ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson 340ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson uint64_t BaseClassOffset = Info.getBaseClassOffset(Base); 341ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson 342ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson if (!canPlaceRecordAtOffset(Base, Offset + BaseClassOffset)) 343ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson return false; 344ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson } 345ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson 3461eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson // Check fields. 3471eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson unsigned FieldNo = 0; 3481eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); 3491eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson I != E; ++I, ++FieldNo) { 3501eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson const FieldDecl *FD = *I; 3511eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson 3521eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson uint64_t FieldOffset = Info.getFieldOffset(FieldNo); 3531eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson 3541eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson if (!canPlaceFieldAtOffset(FD, Offset + FieldOffset)) 3551eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson return false; 3561eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson } 3571eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson 358ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson // FIXME: virtual bases. 3599606149722bedfc48fc56cafc58de1139aef481dAnders Carlsson return true; 3609606149722bedfc48fc56cafc58de1139aef481dAnders Carlsson} 3619606149722bedfc48fc56cafc58de1139aef481dAnders Carlsson 3626026504302763f74102592602b392cecd5ced3aeAnders Carlssonbool ASTRecordLayoutBuilder::canPlaceFieldAtOffset(const FieldDecl *FD, 3636026504302763f74102592602b392cecd5ced3aeAnders Carlsson uint64_t Offset) const { 364fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson QualType T = FD->getType(); 365fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson if (const RecordType *RT = T->getAs<RecordType>()) { 3666026504302763f74102592602b392cecd5ced3aeAnders Carlsson if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) 3676026504302763f74102592602b392cecd5ced3aeAnders Carlsson return canPlaceRecordAtOffset(RD, Offset); 3686026504302763f74102592602b392cecd5ced3aeAnders Carlsson } 3696026504302763f74102592602b392cecd5ced3aeAnders Carlsson 370fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson if (const ConstantArrayType *AT = Ctx.getAsConstantArrayType(T)) { 371fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson QualType ElemTy = Ctx.getBaseElementType(AT); 372fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson const RecordType *RT = ElemTy->getAs<RecordType>(); 373fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson if (!RT) 374fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson return true; 375fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()); 376fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson if (!RD) 377fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson return true; 378fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson 379fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson const ASTRecordLayout &Info = Ctx.getASTRecordLayout(RD); 380fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson 381fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson uint64_t NumElements = Ctx.getConstantArrayElementCount(AT); 382968db3364611a475909b5e76969d2f5472e65597Mike Stump uint64_t ElementOffset = Offset; 383fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson for (uint64_t I = 0; I != NumElements; ++I) { 384fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson if (!canPlaceRecordAtOffset(RD, ElementOffset)) 385fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson return false; 386fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson 387fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson ElementOffset += Info.getSize(); 388fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson } 389fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson } 3906026504302763f74102592602b392cecd5ced3aeAnders Carlsson 3916026504302763f74102592602b392cecd5ced3aeAnders Carlsson return true; 3926026504302763f74102592602b392cecd5ced3aeAnders Carlsson} 3936026504302763f74102592602b392cecd5ced3aeAnders Carlsson 3949606149722bedfc48fc56cafc58de1139aef481dAnders Carlssonvoid ASTRecordLayoutBuilder::UpdateEmptyClassOffsets(const CXXRecordDecl *RD, 3959606149722bedfc48fc56cafc58de1139aef481dAnders Carlsson uint64_t Offset) { 3961345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson if (RD->isEmpty()) 3971345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson EmptyClassOffsets.insert(std::make_pair(Offset, RD)); 398ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson 399ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson const ASTRecordLayout &Info = Ctx.getASTRecordLayout(RD); 400ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson 401ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson // Update bases. 402ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 403ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson E = RD->bases_end(); I != E; ++I) { 4049994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl assert(!I->getType()->isDependentType() && 4059994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl "Cannot layout class with dependent bases."); 406ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson if (I->isVirtual()) 407ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson continue; 408ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson 409ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson const CXXRecordDecl *Base = 410ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 4111345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson 412ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson uint64_t BaseClassOffset = Info.getBaseClassOffset(Base); 413ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson UpdateEmptyClassOffsets(Base, Offset + BaseClassOffset); 414ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson } 415ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson 4161eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson // Update fields. 4171eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson unsigned FieldNo = 0; 4181eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); 4191eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson I != E; ++I, ++FieldNo) { 4201eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson const FieldDecl *FD = *I; 4211eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson 4221eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson uint64_t FieldOffset = Info.getFieldOffset(FieldNo); 4231eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson UpdateEmptyClassOffsets(FD, Offset + FieldOffset); 4241eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson } 4251eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson 4261eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson // FIXME: Update virtual bases. 4279606149722bedfc48fc56cafc58de1139aef481dAnders Carlsson} 4289606149722bedfc48fc56cafc58de1139aef481dAnders Carlsson 429a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlssonvoid 430a4c6081abd5582515b110bdcb576b4b85536467bAnders CarlssonASTRecordLayoutBuilder::UpdateEmptyClassOffsets(const FieldDecl *FD, 431a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson uint64_t Offset) { 432a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson QualType T = FD->getType(); 433a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson 434a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson if (const RecordType *RT = T->getAs<RecordType>()) { 435a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) { 436a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson UpdateEmptyClassOffsets(RD, Offset); 437a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson return; 438a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson } 439a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson } 440a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson 441a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson if (const ConstantArrayType *AT = Ctx.getAsConstantArrayType(T)) { 442a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson QualType ElemTy = Ctx.getBaseElementType(AT); 443a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson const RecordType *RT = ElemTy->getAs<RecordType>(); 444a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson if (!RT) 445a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson return; 446a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()); 447a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson if (!RD) 448a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson return; 449a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson 450a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson const ASTRecordLayout &Info = Ctx.getASTRecordLayout(RD); 451a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson 452a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson uint64_t NumElements = Ctx.getConstantArrayElementCount(AT); 453968db3364611a475909b5e76969d2f5472e65597Mike Stump uint64_t ElementOffset = Offset; 454a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson 455a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson for (uint64_t I = 0; I != NumElements; ++I) { 456a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson UpdateEmptyClassOffsets(RD, ElementOffset); 457a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson ElementOffset += Info.getSize(); 458a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson } 459a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson } 460a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson} 461a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson 462bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlssonvoid ASTRecordLayoutBuilder::Layout(const RecordDecl *D) { 463bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson IsUnion = D->isUnion(); 464a860e755f1f9f071b6a6a2f96128a6a258f5c331Anders Carlsson 465a5dd722bdf2f74a1a249fe6661d96a7236aee0f0Anders Carlsson Packed = D->hasAttr<PackedAttr>(); 466a5dd722bdf2f74a1a249fe6661d96a7236aee0f0Anders Carlsson 467a5dd722bdf2f74a1a249fe6661d96a7236aee0f0Anders Carlsson // The #pragma pack attribute specifies the maximum field alignment. 468a860e755f1f9f071b6a6a2f96128a6a258f5c331Anders Carlsson if (const PragmaPackAttr *PPA = D->getAttr<PragmaPackAttr>()) 469a5dd722bdf2f74a1a249fe6661d96a7236aee0f0Anders Carlsson MaxFieldAlignment = PPA->getAlignment(); 4701eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 471bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) 472bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt UpdateAlignment(AA->getMaxAlignment()); 47374cbe226207fd101623638dadfa7fbada04ff2a6Anders Carlsson 474276b9f1d814f4f6551cc3000590759a34185d6daMike Stump // If this is a C++ class, lay out the vtable and the non-virtual bases. 475eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D); 476200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson if (RD) 4773dee6efcad9ad56d14f7edd1c29924f0b876a7f9Mike Stump LayoutNonVirtualBases(RD); 47874cbe226207fd101623638dadfa7fbada04ff2a6Anders Carlsson 479a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson LayoutFields(D); 4801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 481b2fafd4978166114c54748a73738d8b2c3a37e2bAnders Carlsson NonVirtualSize = Size; 482b2fafd4978166114c54748a73738d8b2c3a37e2bAnders Carlsson NonVirtualAlignment = Alignment; 4833dee6efcad9ad56d14f7edd1c29924f0b876a7f9Mike Stump 484276b9f1d814f4f6551cc3000590759a34185d6daMike Stump if (RD) { 48523a5fcba194c3dec737f296860d75327d85cc349Anders Carlsson LayoutVirtualBases(RD, RD, PrimaryBase.getBase(), 0); 486276b9f1d814f4f6551cc3000590759a34185d6daMike Stump } 487eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump 488bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // Finally, round the size of the total struct up to the alignment of the 489bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // struct itself. 490bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson FinishLayout(); 491bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson} 492bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 49311062e11236b7bc689dad150e8b490fd6b063ec3Fariborz Jahanian// FIXME. Impl is no longer needed. 49493fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlssonvoid ASTRecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D, 49593fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson const ObjCImplementationDecl *Impl) { 49693fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson if (ObjCInterfaceDecl *SD = D->getSuperClass()) { 49793fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson const ASTRecordLayout &SL = Ctx.getASTObjCInterfaceLayout(SD); 49893fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson 49993fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson UpdateAlignment(SL.getAlignment()); 5001eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 50193fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson // We start laying out ivars not at the end of the superclass 50293fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson // structure, but at the next byte following the last field. 503243a68551ac9ec71bf341e062418e33eb4f286ffAnders Carlsson Size = llvm::RoundUpToAlignment(SL.getDataSize(), 8); 504a223935e5cf82e939e1ca1da4111d63025a04e39Anders Carlsson DataSize = Size; 50593fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson } 5061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 507a5dd722bdf2f74a1a249fe6661d96a7236aee0f0Anders Carlsson Packed = D->hasAttr<PackedAttr>(); 5081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 509a5dd722bdf2f74a1a249fe6661d96a7236aee0f0Anders Carlsson // The #pragma pack attribute specifies the maximum field alignment. 510a5dd722bdf2f74a1a249fe6661d96a7236aee0f0Anders Carlsson if (const PragmaPackAttr *PPA = D->getAttr<PragmaPackAttr>()) 511a5dd722bdf2f74a1a249fe6661d96a7236aee0f0Anders Carlsson MaxFieldAlignment = PPA->getAlignment(); 5121eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 51393fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) 514bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt UpdateAlignment(AA->getMaxAlignment()); 51593fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson // Layout each ivar sequentially. 51693fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson llvm::SmallVector<ObjCIvarDecl*, 16> Ivars; 51711062e11236b7bc689dad150e8b490fd6b063ec3Fariborz Jahanian Ctx.ShallowCollectObjCIvars(D, Ivars); 51893fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson for (unsigned i = 0, e = Ivars.size(); i != e; ++i) 51993fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson LayoutField(Ivars[i]); 5201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 52193fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson // Finally, round the size of the total struct up to the alignment of the 52293fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson // struct itself. 52393fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson FinishLayout(); 52493fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson} 52593fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson 526a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlssonvoid ASTRecordLayoutBuilder::LayoutFields(const RecordDecl *D) { 527a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson // Layout each field, for now, just sequentially, respecting alignment. In 528a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson // the future, this will need to be tweakable by targets. 5291eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump for (RecordDecl::field_iterator Field = D->field_begin(), 530a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson FieldEnd = D->field_end(); Field != FieldEnd; ++Field) 531a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson LayoutField(*Field); 532a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson} 533a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson 53442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlssonvoid ASTRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { 53542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson bool FieldPacked = Packed || D->hasAttr<PackedAttr>(); 536e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson uint64_t FieldOffset = IsUnion ? 0 : (DataSize - UnfilledBitsInLastByte); 53742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson uint64_t FieldSize = D->getBitWidth()->EvaluateAsInt(Ctx).getZExtValue(); 53842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson 53942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson std::pair<uint64_t, unsigned> FieldInfo = Ctx.getTypeInfo(D->getType()); 54042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson uint64_t TypeSize = FieldInfo.first; 54142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson unsigned FieldAlign = FieldInfo.second; 54242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson 54342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (FieldPacked) 54442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldAlign = 1; 54542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) 54642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldAlign = std::max(FieldAlign, AA->getMaxAlignment()); 5471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 54842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // The maximum field alignment overrides the aligned attribute. 54942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (MaxFieldAlignment) 55042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldAlign = std::min(FieldAlign, MaxFieldAlignment); 55142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson 55242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // Check if we need to add padding to give the field the correct 55342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // alignment. 55442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (FieldSize == 0 || (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize) 55542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldOffset = (FieldOffset + (FieldAlign-1)) & ~(FieldAlign-1); 55642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson 55742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // Padding members don't affect overall alignment 55842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (!D->getIdentifier()) 55942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldAlign = 1; 56042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson 56142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // Place this field at the current location. 56242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldOffsets.push_back(FieldOffset); 56342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson 564e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson // Update DataSize to include the last byte containing (part of) the bitfield. 565e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson if (IsUnion) { 566e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson // FIXME: I think FieldSize should be TypeSize here. 567e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson DataSize = std::max(DataSize, FieldSize); 568e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson } else { 569e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson uint64_t NewSizeInBits = FieldOffset + FieldSize; 570e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson 571e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson DataSize = llvm::RoundUpToAlignment(NewSizeInBits, 8); 572e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson UnfilledBitsInLastByte = DataSize - NewSizeInBits; 573e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson } 57442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson 575e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson // Update the size. 576e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson Size = std::max(Size, DataSize); 57742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson 57842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // Remember max struct/class alignment. 57942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson UpdateAlignment(FieldAlign); 58042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson} 5811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 58242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlssonvoid ASTRecordLayoutBuilder::LayoutField(const FieldDecl *D) { 58342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (D->isBitField()) { 58442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson LayoutBitField(D); 58542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson return; 58642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson } 5871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 588e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson // Reset the unfilled bits. 589e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson UnfilledBitsInLastByte = 0; 590e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson 59142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson bool FieldPacked = Packed || D->hasAttr<PackedAttr>(); 59242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson uint64_t FieldOffset = IsUnion ? 0 : DataSize; 59342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson uint64_t FieldSize; 59442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson unsigned FieldAlign; 59542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson 59642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (D->getType()->isIncompleteArrayType()) { 59742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // This is a flexible array member; we can't directly 59842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // query getTypeInfo about these, so we figure it out here. 59942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // Flexible array members don't have any size, but they 60042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // have to be aligned appropriately for their element type. 60142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldSize = 0; 60242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson const ArrayType* ATy = Ctx.getAsArrayType(D->getType()); 60342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldAlign = Ctx.getTypeAlign(ATy->getElementType()); 60442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson } else if (const ReferenceType *RT = D->getType()->getAs<ReferenceType>()) { 60542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson unsigned AS = RT->getPointeeType().getAddressSpace(); 60642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldSize = Ctx.Target.getPointerWidth(AS); 60742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldAlign = Ctx.Target.getPointerAlign(AS); 60842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson } else { 609bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson std::pair<uint64_t, unsigned> FieldInfo = Ctx.getTypeInfo(D->getType()); 61042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldSize = FieldInfo.first; 611bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson FieldAlign = FieldInfo.second; 61242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson } 6131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 61442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (FieldPacked) 61542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldAlign = 8; 61642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (const AlignedAttr *AA = D->getAttr<AlignedAttr>()) 61742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldAlign = std::max(FieldAlign, AA->getMaxAlignment()); 6181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 61942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // The maximum field alignment overrides the aligned attribute. 62042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (MaxFieldAlignment) 62142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldAlign = std::min(FieldAlign, MaxFieldAlignment); 6221eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 62342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // Round up the current record size to the field's alignment boundary. 62442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign); 62542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson 62642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (!IsUnion) { 62742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson while (true) { 62842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // Check if we can place the field at this offset. 62942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (canPlaceFieldAtOffset(D, FieldOffset)) 63042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson break; 631a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson 63242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // We couldn't place the field at the offset. Try again at a new offset. 63342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldOffset += FieldAlign; 6346026504302763f74102592602b392cecd5ced3aeAnders Carlsson } 63542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson 63642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson UpdateEmptyClassOffsets(D, FieldOffset); 637bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson } 63842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson 639bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // Place this field at the current location. 640bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson FieldOffsets.push_back(FieldOffset); 6411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 642bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // Reserve space for this field. 643bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson if (IsUnion) 644bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson Size = std::max(Size, FieldSize); 645bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson else 646bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson Size = FieldOffset + FieldSize; 6471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 648a223935e5cf82e939e1ca1da4111d63025a04e39Anders Carlsson // Update the data size. 649a223935e5cf82e939e1ca1da4111d63025a04e39Anders Carlsson DataSize = Size; 6501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 651bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // Remember max struct/class alignment. 652bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson UpdateAlignment(FieldAlign); 653bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson} 654bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 655bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlssonvoid ASTRecordLayoutBuilder::FinishLayout() { 656bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // In C++, records cannot be of size 0. 657bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson if (Ctx.getLangOptions().CPlusPlus && Size == 0) 658bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson Size = 8; 659bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // Finally, round the size of the record up to the alignment of the 660bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // record itself. 66142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson Size = llvm::RoundUpToAlignment(Size, Alignment); 662bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson} 663bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 664bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlssonvoid ASTRecordLayoutBuilder::UpdateAlignment(unsigned NewAlignment) { 665bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson if (NewAlignment <= Alignment) 666bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson return; 6671eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 668bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson assert(llvm::isPowerOf2_32(NewAlignment && "Alignment not a power of 2")); 6691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 670bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson Alignment = NewAlignment; 671bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson} 6721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 673bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlssonconst ASTRecordLayout * 6741eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx, 675bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson const RecordDecl *D) { 676bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson ASTRecordLayoutBuilder Builder(Ctx); 677bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 678bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson Builder.Layout(D); 679bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 680b2fafd4978166114c54748a73738d8b2c3a37e2bAnders Carlsson if (!isa<CXXRecordDecl>(D)) 681503524acc73f2f8280080ca0d200377406001b65Ted Kremenek return new (Ctx) ASTRecordLayout(Ctx, Builder.Size, Builder.Alignment, 682503524acc73f2f8280080ca0d200377406001b65Ted Kremenek Builder.Size, 683503524acc73f2f8280080ca0d200377406001b65Ted Kremenek Builder.FieldOffsets.data(), 684503524acc73f2f8280080ca0d200377406001b65Ted Kremenek Builder.FieldOffsets.size()); 6851eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 686b2fafd4978166114c54748a73738d8b2c3a37e2bAnders Carlsson // FIXME: This is not always correct. See the part about bitfields at 687b2fafd4978166114c54748a73738d8b2c3a37e2bAnders Carlsson // http://www.codesourcery.com/public/cxx-abi/abi.html#POD for more info. 688b2fafd4978166114c54748a73738d8b2c3a37e2bAnders Carlsson // FIXME: IsPODForThePurposeOfLayout should be stored in the record layout. 689b2fafd4978166114c54748a73738d8b2c3a37e2bAnders Carlsson bool IsPODForThePurposeOfLayout = cast<CXXRecordDecl>(D)->isPOD(); 6901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 691b2fafd4978166114c54748a73738d8b2c3a37e2bAnders Carlsson // FIXME: This should be done in FinalizeLayout. 6921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump uint64_t DataSize = 693a223935e5cf82e939e1ca1da4111d63025a04e39Anders Carlsson IsPODForThePurposeOfLayout ? Builder.Size : Builder.DataSize; 6941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump uint64_t NonVirtualSize = 695b2fafd4978166114c54748a73738d8b2c3a37e2bAnders Carlsson IsPODForThePurposeOfLayout ? DataSize : Builder.NonVirtualSize; 6961eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 697503524acc73f2f8280080ca0d200377406001b65Ted Kremenek return new (Ctx) ASTRecordLayout(Ctx, Builder.Size, Builder.Alignment, 698503524acc73f2f8280080ca0d200377406001b65Ted Kremenek DataSize, Builder.FieldOffsets.data(), 699503524acc73f2f8280080ca0d200377406001b65Ted Kremenek Builder.FieldOffsets.size(), 700503524acc73f2f8280080ca0d200377406001b65Ted Kremenek NonVirtualSize, 701503524acc73f2f8280080ca0d200377406001b65Ted Kremenek Builder.NonVirtualAlignment, 702503524acc73f2f8280080ca0d200377406001b65Ted Kremenek Builder.PrimaryBase, 703503524acc73f2f8280080ca0d200377406001b65Ted Kremenek Builder.Bases.data(), 704503524acc73f2f8280080ca0d200377406001b65Ted Kremenek Builder.Bases.size(), 705503524acc73f2f8280080ca0d200377406001b65Ted Kremenek Builder.VBases.data(), 706503524acc73f2f8280080ca0d200377406001b65Ted Kremenek Builder.VBases.size()); 70793fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson} 70893fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson 70993fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlssonconst ASTRecordLayout * 71093fab9d67ca62e3e291803e5a1309473d6e00344Anders CarlssonASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx, 71193fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson const ObjCInterfaceDecl *D, 71293fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson const ObjCImplementationDecl *Impl) { 71393fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson ASTRecordLayoutBuilder Builder(Ctx); 7141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 71593fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson Builder.Layout(D, Impl); 7161eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 717503524acc73f2f8280080ca0d200377406001b65Ted Kremenek return new (Ctx) ASTRecordLayout(Ctx, Builder.Size, Builder.Alignment, 718503524acc73f2f8280080ca0d200377406001b65Ted Kremenek Builder.DataSize, 719503524acc73f2f8280080ca0d200377406001b65Ted Kremenek Builder.FieldOffsets.data(), 720503524acc73f2f8280080ca0d200377406001b65Ted Kremenek Builder.FieldOffsets.size()); 721bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson} 722f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson 723f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlssonconst CXXMethodDecl * 724f53df2398e07d13be9962b95aebc19b31706fa33Anders CarlssonASTRecordLayoutBuilder::ComputeKeyFunction(const CXXRecordDecl *RD) { 725f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson assert(RD->isDynamicClass() && "Class does not have any virtual methods!"); 726f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson 727f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson // If a class isnt' polymorphic it doesn't have a key function. 728f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (!RD->isPolymorphic()) 729f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson return 0; 73061eab8872168af6eb1e0047a82901096cf145e27Eli Friedman 73161eab8872168af6eb1e0047a82901096cf145e27Eli Friedman // A class inside an anonymous namespace doesn't have a key function. (Or 73261eab8872168af6eb1e0047a82901096cf145e27Eli Friedman // at least, there's no point to assigning a key function to such a class; 73361eab8872168af6eb1e0047a82901096cf145e27Eli Friedman // this doesn't affect the ABI.) 73461eab8872168af6eb1e0047a82901096cf145e27Eli Friedman if (RD->isInAnonymousNamespace()) 73561eab8872168af6eb1e0047a82901096cf145e27Eli Friedman return 0; 73661eab8872168af6eb1e0047a82901096cf145e27Eli Friedman 737f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson for (CXXRecordDecl::method_iterator I = RD->method_begin(), 738f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson E = RD->method_end(); I != E; ++I) { 739f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson const CXXMethodDecl *MD = *I; 740f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson 741f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (!MD->isVirtual()) 742f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson continue; 743f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson 744f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (MD->isPure()) 745f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson continue; 74661eab8872168af6eb1e0047a82901096cf145e27Eli Friedman 747f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson // Ignore implicit member functions, they are always marked as inline, but 748f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson // they don't have a body until they're defined. 749f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (MD->isImplicit()) 750f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson continue; 751bd6d6197fcfc98356ea60e816365eb0648b69556Douglas Gregor 752bd6d6197fcfc98356ea60e816365eb0648b69556Douglas Gregor if (MD->isInlineSpecified()) 753bd6d6197fcfc98356ea60e816365eb0648b69556Douglas Gregor continue; 754f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson 755f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (MD->hasInlineBody()) 756f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson continue; 757f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson 758f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson // We found it. 759f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson return MD; 760f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson } 761f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson 762f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson return 0; 763f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson} 764f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson 765