RecordLayoutBuilder.cpp revision 9dc82d2193971ed57dc657dbd21249a2c57da376
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) {
66200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson
67d76264e0b20470267249660ab947197cf6d6e31fMike Stump  for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
68d76264e0b20470267249660ab947197cf6d6e31fMike Stump         e = RD->bases_end(); i != e; ++i) {
699994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl    assert(!i->getType()->isDependentType() &&
709994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl           "Cannot layout class with dependent bases.");
711eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    const CXXRecordDecl *Base =
72d76264e0b20470267249660ab947197cf6d6e31fMike Stump      cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
73d76264e0b20470267249660ab947197cf6d6e31fMike Stump    if (!i->isVirtual()) {
74200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson      SelectPrimaryVBase(Base);
75261fba6cf57a09a1f1d0c4a4c4856aaa62753242Anders Carlsson      if (PrimaryBase.getBase())
76d76264e0b20470267249660ab947197cf6d6e31fMike Stump        return;
77d76264e0b20470267249660ab947197cf6d6e31fMike Stump      continue;
78d76264e0b20470267249660ab947197cf6d6e31fMike Stump    }
79d76264e0b20470267249660ab947197cf6d6e31fMike Stump    if (IsNearlyEmpty(Base)) {
80200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson      // Is this the first nearly empty primary virtual base?
81200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson      if (!FirstNearlyEmptyVBase)
82200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson        FirstNearlyEmptyVBase = Base;
83200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson
843f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson      if (!IndirectPrimaryBases.count(Base)) {
85200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson        PrimaryBase = ASTRecordLayout::PrimaryBaseInfo(Base,
86200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson                                                       /*IsVirtual=*/true);
87d76264e0b20470267249660ab947197cf6d6e31fMike Stump        return;
88d76264e0b20470267249660ab947197cf6d6e31fMike Stump      }
89d76264e0b20470267249660ab947197cf6d6e31fMike Stump    }
90200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson
9194ba380b820cde3fb9d97d5f07ac709ebbb6ac1eZhongxing Xu    assert(i->isVirtual());
92200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson    SelectPrimaryVBase(Base);
9394ba380b820cde3fb9d97d5f07ac709ebbb6ac1eZhongxing Xu    if (PrimaryBase.getBase())
9494ba380b820cde3fb9d97d5f07ac709ebbb6ac1eZhongxing Xu      return;
95d76264e0b20470267249660ab947197cf6d6e31fMike Stump  }
96d76264e0b20470267249660ab947197cf6d6e31fMike Stump}
97d76264e0b20470267249660ab947197cf6d6e31fMike Stump
98200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson/// DeterminePrimaryBase - Determine the primary base of the given class.
99200c5c2d9488165626925235ff918e3d744d785aAnders Carlssonvoid ASTRecordLayoutBuilder::DeterminePrimaryBase(const CXXRecordDecl *RD) {
100200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  // If the class isn't dynamic, it won't have a primary base.
101200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  if (!RD->isDynamicClass())
102200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson    return;
103200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson
1043f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson  // Compute all the primary virtual bases for all of our direct and
1050880e75541899bc1cdd73c50eb549110b5916c59Mike Stump  // indirect bases, and record all their primary virtual base classes.
1060880e75541899bc1cdd73c50eb549110b5916c59Mike Stump  for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
1070880e75541899bc1cdd73c50eb549110b5916c59Mike Stump       e = RD->bases_end(); i != e; ++i) {
1089994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl    assert(!i->getType()->isDependentType() &&
109200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson           "Cannot lay out class with dependent bases.");
1101eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    const CXXRecordDecl *Base =
1110880e75541899bc1cdd73c50eb549110b5916c59Mike Stump      cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
1123f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson    IdentifyPrimaryBases(Base);
1130880e75541899bc1cdd73c50eb549110b5916c59Mike Stump  }
1140880e75541899bc1cdd73c50eb549110b5916c59Mike Stump
1153f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson  // If the record has a dynamic base class, attempt to choose a primary base
1163f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson  // class. It is the first (in direct base class order) non-virtual dynamic
1173f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson  // base class, if one exists.
1186f376336138ea719e3c4757ae046a5768043b276Mike Stump  for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
1196f376336138ea719e3c4757ae046a5768043b276Mike Stump       e = RD->bases_end(); i != e; ++i) {
120ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson    // Ignore virtual bases.
121ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson    if (i->isVirtual())
122ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson      continue;
123ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson
124ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson    const CXXRecordDecl *Base =
125ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson      cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
126ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson
127ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson    if (Base->isDynamicClass()) {
128ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson      // We found it.
129ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson      PrimaryBase = ASTRecordLayout::PrimaryBaseInfo(Base, /*IsVirtual=*/false);
130ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson      return;
1316f376336138ea719e3c4757ae046a5768043b276Mike Stump    }
1326f376336138ea719e3c4757ae046a5768043b276Mike Stump  }
1336f376336138ea719e3c4757ae046a5768043b276Mike Stump
1346f376336138ea719e3c4757ae046a5768043b276Mike Stump  // Otherwise, it is the first nearly empty virtual base that is not an
13549520944c688a9d5fc78d0c2af544b825873477bMike Stump  // indirect primary virtual base class, if one exists.
136200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  if (RD->getNumVBases() != 0) {
137200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson    SelectPrimaryVBase(RD);
138200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson    if (PrimaryBase.getBase())
139200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson      return;
140200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  }
1416f376336138ea719e3c4757ae046a5768043b276Mike Stump
142200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  // Otherwise, it is the first nearly empty virtual base that is not an
143200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  // indirect primary virtual base class, if one exists.
144200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  if (FirstNearlyEmptyVBase) {
145200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson    PrimaryBase =
146200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson      ASTRecordLayout::PrimaryBaseInfo(FirstNearlyEmptyVBase, /*IsVirtual=*/true);
1476f376336138ea719e3c4757ae046a5768043b276Mike Stump    return;
148200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  }
1493f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson
150200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  // Otherwise there is no primary base class.
151200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  assert(!PrimaryBase.getBase() && "Should not get here with a primary base!");
152200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson
153200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  // Allocate the virtual table pointer at offset zero.
154200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  assert(DataSize == 0 && "Vtable pointer must be at offset zero!");
155200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson
156200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  // Update the size.
157200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  Size += Ctx.Target.getPointerWidth(0);
158200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  DataSize = Size;
159200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson
160200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  // Update the alignment.
161200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  UpdateAlignment(Ctx.Target.getPointerAlign(0));
1626f376336138ea719e3c4757ae046a5768043b276Mike Stump}
1636f376336138ea719e3c4757ae046a5768043b276Mike Stump
164968db3364611a475909b5e76969d2f5472e65597Mike Stumpuint64_t ASTRecordLayoutBuilder::getBaseOffset(const CXXRecordDecl *Base) {
165968db3364611a475909b5e76969d2f5472e65597Mike Stump  for (size_t i = 0; i < Bases.size(); ++i) {
166968db3364611a475909b5e76969d2f5472e65597Mike Stump    if (Bases[i].first == Base)
167968db3364611a475909b5e76969d2f5472e65597Mike Stump      return Bases[i].second;
168968db3364611a475909b5e76969d2f5472e65597Mike Stump  }
169968db3364611a475909b5e76969d2f5472e65597Mike Stump  for (size_t i = 0; i < VBases.size(); ++i) {
170968db3364611a475909b5e76969d2f5472e65597Mike Stump    if (VBases[i].first == Base)
171968db3364611a475909b5e76969d2f5472e65597Mike Stump      return VBases[i].second;
172968db3364611a475909b5e76969d2f5472e65597Mike Stump  }
173968db3364611a475909b5e76969d2f5472e65597Mike Stump  assert(0 && "missing base");
174968db3364611a475909b5e76969d2f5472e65597Mike Stump  return 0;
175968db3364611a475909b5e76969d2f5472e65597Mike Stump}
176968db3364611a475909b5e76969d2f5472e65597Mike Stump
177e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlssonvoid
178e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders CarlssonASTRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) {
179200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  // First, determine the primary base class.
180200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  DeterminePrimaryBase(RD);
181200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson
182200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  // If we have a primary base class, lay it out.
183200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  if (const CXXRecordDecl *Base = PrimaryBase.getBase()) {
184200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson    if (PrimaryBase.isVirtual()) {
185200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson      // We have a virtual primary base, insert it as an indirect primary base.
186200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson      IndirectPrimaryBases.insert(Base);
187200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson
188200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson      LayoutVirtualBase(Base);
189200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson    } else
190200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson      LayoutNonVirtualBase(Base);
191200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  }
192200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson
193200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  // Now lay out the non-virtual bases.
194200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
195200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson       E = RD->bases_end(); I != E; ++I) {
196200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson
197200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson    // Ignore virtual bases.
198200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson    if (I->isVirtual())
199200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson      continue;
200200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson
201200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson    const CXXRecordDecl *Base =
202200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
203200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson
204200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson    // Skip the primary base.
205200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson    if (Base == PrimaryBase.getBase() && !PrimaryBase.isVirtual())
206200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson      continue;
207200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson
208200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson    // Lay out the base.
209200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson    LayoutNonVirtualBase(Base);
210e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson  }
211e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson}
212e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson
213e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlssonvoid ASTRecordLayoutBuilder::LayoutNonVirtualBase(const CXXRecordDecl *RD) {
214e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson  // Layout the base.
215e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson  uint64_t Offset = LayoutBase(RD);
216e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson
217e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson  // Add its base class offset.
218e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson  Bases.push_back(std::make_pair(RD, Offset));
219e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson}
220968db3364611a475909b5e76969d2f5472e65597Mike Stump
221968db3364611a475909b5e76969d2f5472e65597Mike Stumpvoid ASTRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *Class,
222968db3364611a475909b5e76969d2f5472e65597Mike Stump                                                const CXXRecordDecl *RD,
223fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump                                                const CXXRecordDecl *PB,
224968db3364611a475909b5e76969d2f5472e65597Mike Stump                                                uint64_t Offset,
2259dc82d2193971ed57dc657dbd21249a2c57da376Anders Carlsson                               llvm::SmallSet<const CXXRecordDecl*, 32> &mark) {
2264ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump  for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(),
2274ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump         e = RD->bases_end(); i != e; ++i) {
2289994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl    assert(!i->getType()->isDependentType() &&
2299994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl           "Cannot layout class with dependent bases.");
2301eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump    const CXXRecordDecl *Base =
231eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump      cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl());
232968db3364611a475909b5e76969d2f5472e65597Mike Stump    uint64_t BaseOffset = Offset;
233276b9f1d814f4f6551cc3000590759a34185d6daMike Stump    if (i->isVirtual()) {
234fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump      if (Base == PB) {
235fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump        // Only lay things out once.
236fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump        if (mark.count(Base))
237fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump          continue;
238fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump        // Mark it so we don't lay it out twice.
239fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump        mark.insert(Base);
2409dc82d2193971ed57dc657dbd21249a2c57da376Anders Carlsson        assert (IndirectPrimaryBases.count(Base) && "IndirectPrimary was wrong");
241e4feb834fb1a6b03291ed78fd32d13729b5a3c4aAnders Carlsson        VBases.push_back(std::make_pair(Base, Offset));
2429dc82d2193971ed57dc657dbd21249a2c57da376Anders Carlsson      } else if (IndirectPrimaryBases.count(Base)) {
243fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump        // Someone else will eventually lay this out.
244fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump        ;
245fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump      } else {
246fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump        // Only lay things out once.
247fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump        if (mark.count(Base))
248fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump          continue;
249fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump        // Mark it so we don't lay it out twice.
250fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump        mark.insert(Base);
251276b9f1d814f4f6551cc3000590759a34185d6daMike Stump        LayoutVirtualBase(Base);
252e4feb834fb1a6b03291ed78fd32d13729b5a3c4aAnders Carlsson        BaseOffset = VBases.back().second;
253fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump      }
254968db3364611a475909b5e76969d2f5472e65597Mike Stump    } else {
255968db3364611a475909b5e76969d2f5472e65597Mike Stump      if (RD == Class)
256968db3364611a475909b5e76969d2f5472e65597Mike Stump        BaseOffset = getBaseOffset(Base);
257968db3364611a475909b5e76969d2f5472e65597Mike Stump      else {
25837acf5a57f87abdbb4ac6115c5f3f09295ec2dc3Mike Stump        const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
259968db3364611a475909b5e76969d2f5472e65597Mike Stump        BaseOffset = Offset + Layout.getBaseClassOffset(Base);
260968db3364611a475909b5e76969d2f5472e65597Mike Stump      }
261fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump    }
262968db3364611a475909b5e76969d2f5472e65597Mike Stump
263fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump    if (Base->getNumVBases()) {
264ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson      const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(Base);
265261fba6cf57a09a1f1d0c4a4c4856aaa62753242Anders Carlsson      const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBaseInfo().getBase();
2669dc82d2193971ed57dc657dbd21249a2c57da376Anders Carlsson      LayoutVirtualBases(Class, Base, PrimaryBase, BaseOffset, mark);
2674ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump    }
268eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump  }
269eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump}
270eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump
271e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlssonvoid ASTRecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *RD) {
272e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson  // Layout the base.
273e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson  uint64_t Offset = LayoutBase(RD);
274e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson
275e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson  // Add its base class offset.
276e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson  VBases.push_back(std::make_pair(RD, Offset));
277e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson}
278e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson
279e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlssonuint64_t ASTRecordLayoutBuilder::LayoutBase(const CXXRecordDecl *RD) {
280e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson  const ASTRecordLayout &BaseInfo = Ctx.getASTRecordLayout(RD);
281e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson
282e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson  // If we have an empty base class, try to place it at offset 0.
283e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson  if (RD->isEmpty() && canPlaceRecordAtOffset(RD, 0)) {
284e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson    // We were able to place the class at offset 0.
285e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson    UpdateEmptyClassOffsets(RD, 0);
286e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson
287e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson    Size = std::max(Size, BaseInfo.getSize());
288e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson
289e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson    return 0;
290e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson  }
291e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson
292e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson  unsigned BaseAlign = BaseInfo.getNonVirtualAlign();
293e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson
294e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson  // Round up the current record size to the base's alignment boundary.
295e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson  uint64_t Offset = llvm::RoundUpToAlignment(DataSize, BaseAlign);
296e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson
297e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson  // Try to place the base.
298e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson  while (true) {
299e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson    if (canPlaceRecordAtOffset(RD, Offset))
300e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson      break;
301e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson
302e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson    Offset += BaseAlign;
303e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson  }
304e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson
305e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson  if (!RD->isEmpty()) {
306e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson    // Update the data size.
307e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson    DataSize = Offset + BaseInfo.getNonVirtualSize();
308e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson
309e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson    Size = std::max(Size, DataSize);
310e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson  } else
311e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson    Size = std::max(Size, Offset + BaseInfo.getSize());
312e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson
313e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson  // Remember max struct/class alignment.
314e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson  UpdateAlignment(BaseAlign);
315e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson
316e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson  UpdateEmptyClassOffsets(RD, Offset);
317e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson  return Offset;
318e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson}
319e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson
3209606149722bedfc48fc56cafc58de1139aef481dAnders Carlssonbool ASTRecordLayoutBuilder::canPlaceRecordAtOffset(const CXXRecordDecl *RD,
3219606149722bedfc48fc56cafc58de1139aef481dAnders Carlsson                                                    uint64_t Offset) const {
3221345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson  // Look for an empty class with the same type at the same offset.
3231345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson  for (EmptyClassOffsetsTy::const_iterator I =
3241345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson        EmptyClassOffsets.lower_bound(Offset),
3251345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson       E = EmptyClassOffsets.upper_bound(Offset); I != E; ++I) {
3261345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson
3271345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson    if (I->second == RD)
3281345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson      return false;
3291345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson  }
3301345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson
331ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson  const ASTRecordLayout &Info = Ctx.getASTRecordLayout(RD);
332ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson
333ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson  // Check bases.
334ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
335ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson       E = RD->bases_end(); I != E; ++I) {
3369994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl    assert(!I->getType()->isDependentType() &&
3379994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl           "Cannot layout class with dependent bases.");
338ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson    if (I->isVirtual())
339ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson      continue;
340ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson
341ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson    const CXXRecordDecl *Base =
342ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
343ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson
344ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson    uint64_t BaseClassOffset = Info.getBaseClassOffset(Base);
345ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson
346ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson    if (!canPlaceRecordAtOffset(Base, Offset + BaseClassOffset))
347ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson      return false;
348ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson  }
349ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson
3501eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson  // Check fields.
3511eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson  unsigned FieldNo = 0;
3521eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson  for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
3531eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson       I != E; ++I, ++FieldNo) {
3541eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson    const FieldDecl *FD = *I;
3551eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson
3561eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson    uint64_t FieldOffset = Info.getFieldOffset(FieldNo);
3571eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson
3581eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson    if (!canPlaceFieldAtOffset(FD, Offset + FieldOffset))
3591eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson      return false;
3601eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson  }
3611eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson
362ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson  // FIXME: virtual bases.
3639606149722bedfc48fc56cafc58de1139aef481dAnders Carlsson  return true;
3649606149722bedfc48fc56cafc58de1139aef481dAnders Carlsson}
3659606149722bedfc48fc56cafc58de1139aef481dAnders Carlsson
3666026504302763f74102592602b392cecd5ced3aeAnders Carlssonbool ASTRecordLayoutBuilder::canPlaceFieldAtOffset(const FieldDecl *FD,
3676026504302763f74102592602b392cecd5ced3aeAnders Carlsson                                                   uint64_t Offset) const {
368fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson  QualType T = FD->getType();
369fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson  if (const RecordType *RT = T->getAs<RecordType>()) {
3706026504302763f74102592602b392cecd5ced3aeAnders Carlsson    if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
3716026504302763f74102592602b392cecd5ced3aeAnders Carlsson      return canPlaceRecordAtOffset(RD, Offset);
3726026504302763f74102592602b392cecd5ced3aeAnders Carlsson  }
3736026504302763f74102592602b392cecd5ced3aeAnders Carlsson
374fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson  if (const ConstantArrayType *AT = Ctx.getAsConstantArrayType(T)) {
375fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson    QualType ElemTy = Ctx.getBaseElementType(AT);
376fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson    const RecordType *RT = ElemTy->getAs<RecordType>();
377fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson    if (!RT)
378fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson      return true;
379fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson    const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
380fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson    if (!RD)
381fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson      return true;
382fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson
383fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson    const ASTRecordLayout &Info = Ctx.getASTRecordLayout(RD);
384fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson
385fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson    uint64_t NumElements = Ctx.getConstantArrayElementCount(AT);
386968db3364611a475909b5e76969d2f5472e65597Mike Stump    uint64_t ElementOffset = Offset;
387fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson    for (uint64_t I = 0; I != NumElements; ++I) {
388fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson      if (!canPlaceRecordAtOffset(RD, ElementOffset))
389fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson        return false;
390fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson
391fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson      ElementOffset += Info.getSize();
392fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson    }
393fbbce49c116aa8c8c7c0707cb6048b55f70461a9Anders Carlsson  }
3946026504302763f74102592602b392cecd5ced3aeAnders Carlsson
3956026504302763f74102592602b392cecd5ced3aeAnders Carlsson  return true;
3966026504302763f74102592602b392cecd5ced3aeAnders Carlsson}
3976026504302763f74102592602b392cecd5ced3aeAnders Carlsson
3989606149722bedfc48fc56cafc58de1139aef481dAnders Carlssonvoid ASTRecordLayoutBuilder::UpdateEmptyClassOffsets(const CXXRecordDecl *RD,
3999606149722bedfc48fc56cafc58de1139aef481dAnders Carlsson                                                     uint64_t Offset) {
4001345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson  if (RD->isEmpty())
4011345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson    EmptyClassOffsets.insert(std::make_pair(Offset, RD));
402ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson
403ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson  const ASTRecordLayout &Info = Ctx.getASTRecordLayout(RD);
404ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson
405ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson  // Update bases.
406ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
407ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson       E = RD->bases_end(); I != E; ++I) {
4089994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl    assert(!I->getType()->isDependentType() &&
4099994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl           "Cannot layout class with dependent bases.");
410ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson    if (I->isVirtual())
411ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson      continue;
412ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson
413ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson    const CXXRecordDecl *Base =
414ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
4151345bd2b093e78620c32f5148b1279ed290188e8Anders Carlsson
416ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson    uint64_t BaseClassOffset = Info.getBaseClassOffset(Base);
417ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson    UpdateEmptyClassOffsets(Base, Offset + BaseClassOffset);
418ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson  }
419ffbdefc7a24c01a0f77425423278774796a3aa53Anders Carlsson
4201eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson  // Update fields.
4211eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson  unsigned FieldNo = 0;
4221eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson  for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end();
4231eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson       I != E; ++I, ++FieldNo) {
4241eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson    const FieldDecl *FD = *I;
4251eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson
4261eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson    uint64_t FieldOffset = Info.getFieldOffset(FieldNo);
4271eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson    UpdateEmptyClassOffsets(FD, Offset + FieldOffset);
4281eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson  }
4291eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson
4301eca99b815e531eba63233c0558af0dc971387aaAnders Carlsson  // FIXME: Update virtual bases.
4319606149722bedfc48fc56cafc58de1139aef481dAnders Carlsson}
4329606149722bedfc48fc56cafc58de1139aef481dAnders Carlsson
433a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlssonvoid
434a4c6081abd5582515b110bdcb576b4b85536467bAnders CarlssonASTRecordLayoutBuilder::UpdateEmptyClassOffsets(const FieldDecl *FD,
435a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson                                                uint64_t Offset) {
436a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson  QualType T = FD->getType();
437a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson
438a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson  if (const RecordType *RT = T->getAs<RecordType>()) {
439a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson    if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
440a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson      UpdateEmptyClassOffsets(RD, Offset);
441a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson      return;
442a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson    }
443a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson  }
444a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson
445a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson  if (const ConstantArrayType *AT = Ctx.getAsConstantArrayType(T)) {
446a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson    QualType ElemTy = Ctx.getBaseElementType(AT);
447a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson    const RecordType *RT = ElemTy->getAs<RecordType>();
448a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson    if (!RT)
449a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson      return;
450a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson    const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
451a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson    if (!RD)
452a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson      return;
453a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson
454a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson    const ASTRecordLayout &Info = Ctx.getASTRecordLayout(RD);
455a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson
456a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson    uint64_t NumElements = Ctx.getConstantArrayElementCount(AT);
457968db3364611a475909b5e76969d2f5472e65597Mike Stump    uint64_t ElementOffset = Offset;
458a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson
459a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson    for (uint64_t I = 0; I != NumElements; ++I) {
460a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson      UpdateEmptyClassOffsets(RD, ElementOffset);
461a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson      ElementOffset += Info.getSize();
462a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson    }
463a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson  }
464a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson}
465a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson
466bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlssonvoid ASTRecordLayoutBuilder::Layout(const RecordDecl *D) {
467bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson  IsUnion = D->isUnion();
468a860e755f1f9f071b6a6a2f96128a6a258f5c331Anders Carlsson
469a5dd722bdf2f74a1a249fe6661d96a7236aee0f0Anders Carlsson  Packed = D->hasAttr<PackedAttr>();
470a5dd722bdf2f74a1a249fe6661d96a7236aee0f0Anders Carlsson
471a5dd722bdf2f74a1a249fe6661d96a7236aee0f0Anders Carlsson  // The #pragma pack attribute specifies the maximum field alignment.
472a860e755f1f9f071b6a6a2f96128a6a258f5c331Anders Carlsson  if (const PragmaPackAttr *PPA = D->getAttr<PragmaPackAttr>())
473a5dd722bdf2f74a1a249fe6661d96a7236aee0f0Anders Carlsson    MaxFieldAlignment = PPA->getAlignment();
4741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
475bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson  if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
476bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    UpdateAlignment(AA->getMaxAlignment());
47774cbe226207fd101623638dadfa7fbada04ff2a6Anders Carlsson
478276b9f1d814f4f6551cc3000590759a34185d6daMike Stump  // If this is a C++ class, lay out the vtable and the non-virtual bases.
479eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump  const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D);
480200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson  if (RD)
4813dee6efcad9ad56d14f7edd1c29924f0b876a7f9Mike Stump    LayoutNonVirtualBases(RD);
48274cbe226207fd101623638dadfa7fbada04ff2a6Anders Carlsson
483a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson  LayoutFields(D);
4841eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
485b2fafd4978166114c54748a73738d8b2c3a37e2bAnders Carlsson  NonVirtualSize = Size;
486b2fafd4978166114c54748a73738d8b2c3a37e2bAnders Carlsson  NonVirtualAlignment = Alignment;
4873dee6efcad9ad56d14f7edd1c29924f0b876a7f9Mike Stump
488276b9f1d814f4f6551cc3000590759a34185d6daMike Stump  if (RD) {
489276b9f1d814f4f6551cc3000590759a34185d6daMike Stump    llvm::SmallSet<const CXXRecordDecl*, 32> mark;
4909dc82d2193971ed57dc657dbd21249a2c57da376Anders Carlsson    LayoutVirtualBases(RD, RD, PrimaryBase.getBase(), 0, mark);
491276b9f1d814f4f6551cc3000590759a34185d6daMike Stump  }
492eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump
493bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson  // Finally, round the size of the total struct up to the alignment of the
494bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson  // struct itself.
495bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson  FinishLayout();
496bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson}
497bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson
49811062e11236b7bc689dad150e8b490fd6b063ec3Fariborz Jahanian// FIXME. Impl is no longer needed.
49993fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlssonvoid ASTRecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D,
50093fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson                                    const ObjCImplementationDecl *Impl) {
50193fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson  if (ObjCInterfaceDecl *SD = D->getSuperClass()) {
50293fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson    const ASTRecordLayout &SL = Ctx.getASTObjCInterfaceLayout(SD);
50393fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson
50493fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson    UpdateAlignment(SL.getAlignment());
5051eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
50693fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson    // We start laying out ivars not at the end of the superclass
50793fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson    // structure, but at the next byte following the last field.
508243a68551ac9ec71bf341e062418e33eb4f286ffAnders Carlsson    Size = llvm::RoundUpToAlignment(SL.getDataSize(), 8);
509a223935e5cf82e939e1ca1da4111d63025a04e39Anders Carlsson    DataSize = Size;
51093fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson  }
5111eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
512a5dd722bdf2f74a1a249fe6661d96a7236aee0f0Anders Carlsson  Packed = D->hasAttr<PackedAttr>();
5131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
514a5dd722bdf2f74a1a249fe6661d96a7236aee0f0Anders Carlsson  // The #pragma pack attribute specifies the maximum field alignment.
515a5dd722bdf2f74a1a249fe6661d96a7236aee0f0Anders Carlsson  if (const PragmaPackAttr *PPA = D->getAttr<PragmaPackAttr>())
516a5dd722bdf2f74a1a249fe6661d96a7236aee0f0Anders Carlsson    MaxFieldAlignment = PPA->getAlignment();
5171eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
51893fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson  if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
519bbd37c62e34db3f5a95c899723484a76c71d7757Sean Hunt    UpdateAlignment(AA->getMaxAlignment());
52093fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson  // Layout each ivar sequentially.
52193fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson  llvm::SmallVector<ObjCIvarDecl*, 16> Ivars;
52211062e11236b7bc689dad150e8b490fd6b063ec3Fariborz Jahanian  Ctx.ShallowCollectObjCIvars(D, Ivars);
52393fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson  for (unsigned i = 0, e = Ivars.size(); i != e; ++i)
52493fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson    LayoutField(Ivars[i]);
5251eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
52693fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson  // Finally, round the size of the total struct up to the alignment of the
52793fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson  // struct itself.
52893fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson  FinishLayout();
52993fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson}
53093fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson
531a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlssonvoid ASTRecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
532a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson  // Layout each field, for now, just sequentially, respecting alignment.  In
533a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson  // the future, this will need to be tweakable by targets.
5341eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  for (RecordDecl::field_iterator Field = D->field_begin(),
535a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson       FieldEnd = D->field_end(); Field != FieldEnd; ++Field)
536a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson    LayoutField(*Field);
537a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson}
538a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson
53942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlssonvoid ASTRecordLayoutBuilder::LayoutBitField(const FieldDecl *D) {
54042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  bool FieldPacked = Packed || D->hasAttr<PackedAttr>();
541e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson  uint64_t FieldOffset = IsUnion ? 0 : (DataSize - UnfilledBitsInLastByte);
54242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  uint64_t FieldSize = D->getBitWidth()->EvaluateAsInt(Ctx).getZExtValue();
54342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson
54442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  std::pair<uint64_t, unsigned> FieldInfo = Ctx.getTypeInfo(D->getType());
54542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  uint64_t TypeSize = FieldInfo.first;
54642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  unsigned FieldAlign = FieldInfo.second;
54742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson
54842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  if (FieldPacked)
54942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson    FieldAlign = 1;
55042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
55142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson    FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
5521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
55342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  // The maximum field alignment overrides the aligned attribute.
55442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  if (MaxFieldAlignment)
55542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson    FieldAlign = std::min(FieldAlign, MaxFieldAlignment);
55642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson
55742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  // Check if we need to add padding to give the field the correct
55842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  // alignment.
55942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  if (FieldSize == 0 || (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize)
56042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson    FieldOffset = (FieldOffset + (FieldAlign-1)) & ~(FieldAlign-1);
56142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson
56242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  // Padding members don't affect overall alignment
56342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  if (!D->getIdentifier())
56442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson    FieldAlign = 1;
56542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson
56642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  // Place this field at the current location.
56742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  FieldOffsets.push_back(FieldOffset);
56842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson
569e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson  // Update DataSize to include the last byte containing (part of) the bitfield.
570e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson  if (IsUnion) {
571e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson    // FIXME: I think FieldSize should be TypeSize here.
572e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson    DataSize = std::max(DataSize, FieldSize);
573e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson  } else {
574e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson    uint64_t NewSizeInBits = FieldOffset + FieldSize;
575e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson
576e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson    DataSize = llvm::RoundUpToAlignment(NewSizeInBits, 8);
577e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson    UnfilledBitsInLastByte = DataSize - NewSizeInBits;
578e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson  }
57942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson
580e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson  // Update the size.
581e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson  Size = std::max(Size, DataSize);
58242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson
58342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  // Remember max struct/class alignment.
58442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  UpdateAlignment(FieldAlign);
58542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson}
5861eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
58742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlssonvoid ASTRecordLayoutBuilder::LayoutField(const FieldDecl *D) {
58842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  if (D->isBitField()) {
58942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson    LayoutBitField(D);
59042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson    return;
59142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  }
5921eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
593e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson  // Reset the unfilled bits.
594e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson  UnfilledBitsInLastByte = 0;
595e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson
59642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  bool FieldPacked = Packed || D->hasAttr<PackedAttr>();
59742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  uint64_t FieldOffset = IsUnion ? 0 : DataSize;
59842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  uint64_t FieldSize;
59942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  unsigned FieldAlign;
60042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson
60142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  if (D->getType()->isIncompleteArrayType()) {
60242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson    // This is a flexible array member; we can't directly
60342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson    // query getTypeInfo about these, so we figure it out here.
60442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson    // Flexible array members don't have any size, but they
60542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson    // have to be aligned appropriately for their element type.
60642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson    FieldSize = 0;
60742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson    const ArrayType* ATy = Ctx.getAsArrayType(D->getType());
60842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson    FieldAlign = Ctx.getTypeAlign(ATy->getElementType());
60942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  } else if (const ReferenceType *RT = D->getType()->getAs<ReferenceType>()) {
61042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson    unsigned AS = RT->getPointeeType().getAddressSpace();
61142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson    FieldSize = Ctx.Target.getPointerWidth(AS);
61242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson    FieldAlign = Ctx.Target.getPointerAlign(AS);
61342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  } else {
614bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson    std::pair<uint64_t, unsigned> FieldInfo = Ctx.getTypeInfo(D->getType());
61542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson    FieldSize = FieldInfo.first;
616bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson    FieldAlign = FieldInfo.second;
61742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  }
6181eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
61942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  if (FieldPacked)
62042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson    FieldAlign = 8;
62142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  if (const AlignedAttr *AA = D->getAttr<AlignedAttr>())
62242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson    FieldAlign = std::max(FieldAlign, AA->getMaxAlignment());
6231eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
62442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  // The maximum field alignment overrides the aligned attribute.
62542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  if (MaxFieldAlignment)
62642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson    FieldAlign = std::min(FieldAlign, MaxFieldAlignment);
6271eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
62842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  // Round up the current record size to the field's alignment boundary.
62942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign);
63042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson
63142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  if (!IsUnion) {
63242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson    while (true) {
63342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson      // Check if we can place the field at this offset.
63442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson      if (canPlaceFieldAtOffset(D, FieldOffset))
63542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson        break;
636a4c6081abd5582515b110bdcb576b4b85536467bAnders Carlsson
63742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson      // We couldn't place the field at the offset. Try again at a new offset.
63842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson      FieldOffset += FieldAlign;
6396026504302763f74102592602b392cecd5ced3aeAnders Carlsson    }
64042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson
64142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson    UpdateEmptyClassOffsets(D, FieldOffset);
642bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson  }
64342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson
644bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson  // Place this field at the current location.
645bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson  FieldOffsets.push_back(FieldOffset);
6461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
647bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson  // Reserve space for this field.
648bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson  if (IsUnion)
649bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson    Size = std::max(Size, FieldSize);
650bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson  else
651bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson    Size = FieldOffset + FieldSize;
6521eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
653a223935e5cf82e939e1ca1da4111d63025a04e39Anders Carlsson  // Update the data size.
654a223935e5cf82e939e1ca1da4111d63025a04e39Anders Carlsson  DataSize = Size;
6551eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
656bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson  // Remember max struct/class alignment.
657bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson  UpdateAlignment(FieldAlign);
658bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson}
659bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson
660bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlssonvoid ASTRecordLayoutBuilder::FinishLayout() {
661bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson  // In C++, records cannot be of size 0.
662bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson  if (Ctx.getLangOptions().CPlusPlus && Size == 0)
663bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson    Size = 8;
664bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson  // Finally, round the size of the record up to the alignment of the
665bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson  // record itself.
66642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson  Size = llvm::RoundUpToAlignment(Size, Alignment);
667bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson}
668bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson
669bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlssonvoid ASTRecordLayoutBuilder::UpdateAlignment(unsigned NewAlignment) {
670bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson  if (NewAlignment <= Alignment)
671bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson    return;
6721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
673bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson  assert(llvm::isPowerOf2_32(NewAlignment && "Alignment not a power of 2"));
6741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
675bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson  Alignment = NewAlignment;
676bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson}
6771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
678bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlssonconst ASTRecordLayout *
6791eb4433ac451dc16f4133a88af2d002ac26c58efMike StumpASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
680bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson                                      const RecordDecl *D) {
681bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson  ASTRecordLayoutBuilder Builder(Ctx);
682bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson
683bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson  Builder.Layout(D);
684bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson
685b2fafd4978166114c54748a73738d8b2c3a37e2bAnders Carlsson  if (!isa<CXXRecordDecl>(D))
686503524acc73f2f8280080ca0d200377406001b65Ted Kremenek    return new (Ctx) ASTRecordLayout(Ctx, Builder.Size, Builder.Alignment,
687503524acc73f2f8280080ca0d200377406001b65Ted Kremenek                                     Builder.Size,
688503524acc73f2f8280080ca0d200377406001b65Ted Kremenek                                     Builder.FieldOffsets.data(),
689503524acc73f2f8280080ca0d200377406001b65Ted Kremenek                                     Builder.FieldOffsets.size());
6901eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
691b2fafd4978166114c54748a73738d8b2c3a37e2bAnders Carlsson  // FIXME: This is not always correct. See the part about bitfields at
692b2fafd4978166114c54748a73738d8b2c3a37e2bAnders Carlsson  // http://www.codesourcery.com/public/cxx-abi/abi.html#POD for more info.
693b2fafd4978166114c54748a73738d8b2c3a37e2bAnders Carlsson  // FIXME: IsPODForThePurposeOfLayout should be stored in the record layout.
694b2fafd4978166114c54748a73738d8b2c3a37e2bAnders Carlsson  bool IsPODForThePurposeOfLayout = cast<CXXRecordDecl>(D)->isPOD();
6951eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
696b2fafd4978166114c54748a73738d8b2c3a37e2bAnders Carlsson  // FIXME: This should be done in FinalizeLayout.
6971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  uint64_t DataSize =
698a223935e5cf82e939e1ca1da4111d63025a04e39Anders Carlsson    IsPODForThePurposeOfLayout ? Builder.Size : Builder.DataSize;
6991eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump  uint64_t NonVirtualSize =
700b2fafd4978166114c54748a73738d8b2c3a37e2bAnders Carlsson    IsPODForThePurposeOfLayout ? DataSize : Builder.NonVirtualSize;
7011eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
702503524acc73f2f8280080ca0d200377406001b65Ted Kremenek  return new (Ctx) ASTRecordLayout(Ctx, Builder.Size, Builder.Alignment,
703503524acc73f2f8280080ca0d200377406001b65Ted Kremenek                                   DataSize, Builder.FieldOffsets.data(),
704503524acc73f2f8280080ca0d200377406001b65Ted Kremenek                                   Builder.FieldOffsets.size(),
705503524acc73f2f8280080ca0d200377406001b65Ted Kremenek                                   NonVirtualSize,
706503524acc73f2f8280080ca0d200377406001b65Ted Kremenek                                   Builder.NonVirtualAlignment,
707503524acc73f2f8280080ca0d200377406001b65Ted Kremenek                                   Builder.PrimaryBase,
708503524acc73f2f8280080ca0d200377406001b65Ted Kremenek                                   Builder.Bases.data(),
709503524acc73f2f8280080ca0d200377406001b65Ted Kremenek                                   Builder.Bases.size(),
710503524acc73f2f8280080ca0d200377406001b65Ted Kremenek                                   Builder.VBases.data(),
711503524acc73f2f8280080ca0d200377406001b65Ted Kremenek                                   Builder.VBases.size());
71293fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson}
71393fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson
71493fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlssonconst ASTRecordLayout *
71593fab9d67ca62e3e291803e5a1309473d6e00344Anders CarlssonASTRecordLayoutBuilder::ComputeLayout(ASTContext &Ctx,
71693fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson                                      const ObjCInterfaceDecl *D,
71793fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson                                      const ObjCImplementationDecl *Impl) {
71893fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson  ASTRecordLayoutBuilder Builder(Ctx);
7191eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
72093fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson  Builder.Layout(D, Impl);
7211eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump
722503524acc73f2f8280080ca0d200377406001b65Ted Kremenek  return new (Ctx) ASTRecordLayout(Ctx, Builder.Size, Builder.Alignment,
723503524acc73f2f8280080ca0d200377406001b65Ted Kremenek                                   Builder.DataSize,
724503524acc73f2f8280080ca0d200377406001b65Ted Kremenek                                   Builder.FieldOffsets.data(),
725503524acc73f2f8280080ca0d200377406001b65Ted Kremenek                                   Builder.FieldOffsets.size());
726bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson}
727f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson
728f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlssonconst CXXMethodDecl *
729f53df2398e07d13be9962b95aebc19b31706fa33Anders CarlssonASTRecordLayoutBuilder::ComputeKeyFunction(const CXXRecordDecl *RD) {
730f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson  assert(RD->isDynamicClass() && "Class does not have any virtual methods!");
731f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson
732f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson  // If a class isnt' polymorphic it doesn't have a key function.
733f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson  if (!RD->isPolymorphic())
734f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson    return 0;
73561eab8872168af6eb1e0047a82901096cf145e27Eli Friedman
73661eab8872168af6eb1e0047a82901096cf145e27Eli Friedman  // A class inside an anonymous namespace doesn't have a key function.  (Or
73761eab8872168af6eb1e0047a82901096cf145e27Eli Friedman  // at least, there's no point to assigning a key function to such a class;
73861eab8872168af6eb1e0047a82901096cf145e27Eli Friedman  // this doesn't affect the ABI.)
73961eab8872168af6eb1e0047a82901096cf145e27Eli Friedman  if (RD->isInAnonymousNamespace())
74061eab8872168af6eb1e0047a82901096cf145e27Eli Friedman    return 0;
74161eab8872168af6eb1e0047a82901096cf145e27Eli Friedman
742f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson  for (CXXRecordDecl::method_iterator I = RD->method_begin(),
743f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson       E = RD->method_end(); I != E; ++I) {
744f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson    const CXXMethodDecl *MD = *I;
745f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson
746f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson    if (!MD->isVirtual())
747f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson      continue;
748f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson
749f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson    if (MD->isPure())
750f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson      continue;
75161eab8872168af6eb1e0047a82901096cf145e27Eli Friedman
752f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson    // Ignore implicit member functions, they are always marked as inline, but
753f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson    // they don't have a body until they're defined.
754f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson    if (MD->isImplicit())
755f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson      continue;
756bd6d6197fcfc98356ea60e816365eb0648b69556Douglas Gregor
757bd6d6197fcfc98356ea60e816365eb0648b69556Douglas Gregor    if (MD->isInlineSpecified())
758bd6d6197fcfc98356ea60e816365eb0648b69556Douglas Gregor      continue;
759f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson
760f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson    if (MD->hasInlineBody())
761f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson      continue;
762f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson
763f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson    // We found it.
764f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson    return MD;
765f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson  }
766f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson
767f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson  return 0;
768f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson}
769f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson
770