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