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