RecordLayoutBuilder.cpp revision fe5ef73149514e513a231a1df1a5938f3ad1545a
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" 1778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis#include "clang/Sema/SemaDiagnostic.h" 18bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar#include "llvm/Support/Format.h" 19bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar#include "llvm/ADT/SmallSet.h" 20bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar#include "llvm/Support/MathExtras.h" 219392fa63e45716e32061d05673fa28909f325b02Anders Carlsson#include <map> 22bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 23bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlssonusing namespace clang; 24bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 257e220286410422ed1dc0409a9cb9708fe50e3df0Benjamin Kramernamespace { 266a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson 27ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// BaseSubobjectInfo - Represents a single base subobject in a complete class. 28ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// For a class hierarchy like 29ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// 30ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// class A { }; 31ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// class B : A { }; 32ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// class C : A, B { }; 33ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// 34ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// The BaseSubobjectInfo graph for C will have three BaseSubobjectInfo 35ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// instances, one for B and two for A. 36ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// 37ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// If a base is virtual, it will only have one BaseSubobjectInfo allocated. 38ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlssonstruct BaseSubobjectInfo { 39ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson /// Class - The class for this base info. 404a25799760982b3363f3c4eb6df953d70e35e37dAnders Carlsson const CXXRecordDecl *Class; 41ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson 42ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson /// IsVirtual - Whether the BaseInfo represents a virtual base or not. 434a25799760982b3363f3c4eb6df953d70e35e37dAnders Carlsson bool IsVirtual; 444a25799760982b3363f3c4eb6df953d70e35e37dAnders Carlsson 45ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson /// Bases - Information about the base subobjects. 46ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson llvm::SmallVector<BaseSubobjectInfo*, 4> Bases; 47ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson 486e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// PrimaryVirtualBaseInfo - Holds the base info for the primary virtual base 496e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// of this base info (if one exists). 506e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *PrimaryVirtualBaseInfo; 51ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson 52ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson // FIXME: Document. 53ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson const BaseSubobjectInfo *Derived; 544a25799760982b3363f3c4eb6df953d70e35e37dAnders Carlsson}; 554a25799760982b3363f3c4eb6df953d70e35e37dAnders Carlsson 566a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson/// EmptySubobjectMap - Keeps track of which empty subobjects exist at different 576a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson/// offsets while laying out a C++ class. 586a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlssonclass EmptySubobjectMap { 596a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson ASTContext &Context; 600aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 616a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson /// Class - The class whose empty entries we're keeping track of. 626a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson const CXXRecordDecl *Class; 630aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 6458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson /// EmptyClassOffsets - A map from offsets to empty record decls. 6558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson typedef llvm::SmallVector<const CXXRecordDecl *, 1> ClassVectorTy; 66d8da76365f40a0c12c7d802a0da2aaacf4b2cf99Anders Carlsson typedef llvm::DenseMap<CharUnits, ClassVectorTy> EmptyClassOffsetsMapTy; 6758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson EmptyClassOffsetsMapTy EmptyClassOffsets; 6858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 69c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson /// MaxEmptyClassOffset - The highest offset known to contain an empty 70c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson /// base subobject. 71fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson CharUnits MaxEmptyClassOffset; 72c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson 730aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// ComputeEmptySubobjectSizes - Compute the size of the largest base or 740c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson /// member subobject that is empty. 750c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson void ComputeEmptySubobjectSizes(); 7658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 77fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson void AddSubobjectAtOffset(const CXXRecordDecl *RD, CharUnits Offset); 78812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 79ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson void UpdateEmptyBaseSubobjects(const BaseSubobjectInfo *Info, 80e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson uint64_t Offset, bool PlacingEmptyBase); 8158b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 82812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson void UpdateEmptyFieldSubobjects(const CXXRecordDecl *RD, 83812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *Class, 84812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t Offset); 85812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson void UpdateEmptyFieldSubobjects(const FieldDecl *FD, uint64_t Offset); 86812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 87c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson /// AnyEmptySubobjectsBeyondOffset - Returns whether there are any empty 88c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson /// subobjects beyond the given offset. 89fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson bool AnyEmptySubobjectsBeyondOffset(CharUnits Offset) const { 90c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson return Offset <= MaxEmptyClassOffset; 91c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson } 92c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson 93d8da76365f40a0c12c7d802a0da2aaacf4b2cf99Anders Carlsson // FIXME: Remove these. 94d8da76365f40a0c12c7d802a0da2aaacf4b2cf99Anders Carlsson CharUnits toCharUnits(uint64_t Offset) const { 95d8da76365f40a0c12c7d802a0da2aaacf4b2cf99Anders Carlsson return CharUnits::fromQuantity(Offset / Context.getCharWidth()); 96d8da76365f40a0c12c7d802a0da2aaacf4b2cf99Anders Carlsson } 97d8da76365f40a0c12c7d802a0da2aaacf4b2cf99Anders Carlsson uint64_t toOffset(CharUnits Offset) const { 98d8da76365f40a0c12c7d802a0da2aaacf4b2cf99Anders Carlsson return Offset.getQuantity() * Context.getCharWidth(); 99d8da76365f40a0c12c7d802a0da2aaacf4b2cf99Anders Carlsson } 100d8da76365f40a0c12c7d802a0da2aaacf4b2cf99Anders Carlsson 101c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davisprotected: 102fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson bool CanPlaceSubobjectAtOffset(const CXXRecordDecl *RD, 103fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson CharUnits Offset) const; 104c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis 105c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis bool CanPlaceBaseSubobjectAtOffset(const BaseSubobjectInfo *Info, 106c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis uint64_t Offset); 107c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis 108c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis bool CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD, 109c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis const CXXRecordDecl *Class, 110c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis uint64_t Offset) const; 111c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis bool CanPlaceFieldSubobjectAtOffset(const FieldDecl *FD, 112c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis uint64_t Offset) const; 113c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis 1146a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlssonpublic: 1150c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson /// This holds the size of the largest empty subobject (either a base 1160aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// or a member). Will be zero if the record being built doesn't contain 1170c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson /// any empty classes. 1180c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson uint64_t SizeOfLargestEmptySubobject; 1190aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1206a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson EmptySubobjectMap(ASTContext &Context, const CXXRecordDecl *Class) 121fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson : Context(Context), Class(Class), SizeOfLargestEmptySubobject(0) { 122261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson ComputeEmptySubobjectSizes(); 123261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson } 124261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson 125261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson /// CanPlaceBaseAtOffset - Return whether the given base class can be placed 126261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson /// at the given offset. 1270aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// Returns false if placing the record will result in two components 128261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson /// (direct or indirect) of the same type having the same offset. 129c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson bool CanPlaceBaseAtOffset(const BaseSubobjectInfo *Info, 130c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson uint64_t Offset); 131812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 132812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson /// CanPlaceFieldAtOffset - Return whether a field can be placed at the given 133812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson /// offset. 134812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson bool CanPlaceFieldAtOffset(const FieldDecl *FD, uint64_t Offset); 1356a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson}; 1360c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson 1370c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlssonvoid EmptySubobjectMap::ComputeEmptySubobjectSizes() { 1380c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // Check the bases. 1390c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(), 1400c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson E = Class->bases_end(); I != E; ++I) { 1410c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson const CXXRecordDecl *BaseDecl = 1420c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1430c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson 1440c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson uint64_t EmptySize = 0; 1450c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl); 1460c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson if (BaseDecl->isEmpty()) { 1470c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // If the class decl is empty, get its size. 1480c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson EmptySize = Layout.getSize(); 1490c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson } else { 1500c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // Otherwise, we get the largest empty subobject for the decl. 1510c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson EmptySize = Layout.getSizeOfLargestEmptySubobject(); 1520c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson } 1530aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1540aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar SizeOfLargestEmptySubobject = std::max(SizeOfLargestEmptySubobject, 1550c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson EmptySize); 1560c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson } 1570aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1580c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // Check the fields. 1590c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson for (CXXRecordDecl::field_iterator I = Class->field_begin(), 1600c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson E = Class->field_end(); I != E; ++I) { 1610c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson const FieldDecl *FD = *I; 1620aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1630aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar const RecordType *RT = 1640c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson Context.getBaseElementType(FD->getType())->getAs<RecordType>(); 1650aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1660c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // We only care about record types. 1670c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson if (!RT) 1680c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson continue; 1690c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson 1700c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson uint64_t EmptySize = 0; 1710c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson const CXXRecordDecl *MemberDecl = cast<CXXRecordDecl>(RT->getDecl()); 1720c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(MemberDecl); 1730c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson if (MemberDecl->isEmpty()) { 1740c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // If the class decl is empty, get its size. 1750c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson EmptySize = Layout.getSize(); 1760c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson } else { 1770c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // Otherwise, we get the largest empty subobject for the decl. 1780c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson EmptySize = Layout.getSizeOfLargestEmptySubobject(); 1790c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson } 1800aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1810aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar SizeOfLargestEmptySubobject = std::max(SizeOfLargestEmptySubobject, 1820c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson EmptySize); 1830c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson } 1840c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson} 1850c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson 1860aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbarbool 187812a3456b63708a5972f712e9e4b54d3cc436378Anders CarlssonEmptySubobjectMap::CanPlaceSubobjectAtOffset(const CXXRecordDecl *RD, 188fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson CharUnits Offset) const { 189812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // We only need to check empty bases. 190812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!RD->isEmpty()) 191812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 192812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 193fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson EmptyClassOffsetsMapTy::const_iterator I = EmptyClassOffsets.find(Offset); 194812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (I == EmptyClassOffsets.end()) 195812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 196812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 197812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const ClassVectorTy& Classes = I->second; 198812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (std::find(Classes.begin(), Classes.end(), RD) == Classes.end()) 199812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 200812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 201812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // There is already an empty class of the same type at this offset. 202812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 203812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 204812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 205812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlssonvoid EmptySubobjectMap::AddSubobjectAtOffset(const CXXRecordDecl *RD, 206fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson CharUnits Offset) { 207812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // We only care about empty bases. 208812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!RD->isEmpty()) 209812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return; 210812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 211fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson ClassVectorTy& Classes = EmptyClassOffsets[Offset]; 212812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson assert(std::find(Classes.begin(), Classes.end(), RD) == Classes.end() && 213812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson "Duplicate empty class detected!"); 21445f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson 215812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson Classes.push_back(RD); 216c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson 217c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson // Update the empty class offset. 218fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson if (Offset > MaxEmptyClassOffset) 219fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson MaxEmptyClassOffset = Offset; 220812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 221812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 222812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlssonbool 223ea2f41c584b9741a591e11c83819b31856f5bc18Anders CarlssonEmptySubobjectMap::CanPlaceBaseSubobjectAtOffset(const BaseSubobjectInfo *Info, 22458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson uint64_t Offset) { 2252177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson // We don't have to keep looking past the maximum offset that's known to 2262177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson // contain an empty class. 227fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson if (!AnyEmptySubobjectsBeyondOffset(toCharUnits(Offset))) 2282177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson return true; 2292177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson 230fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson if (!CanPlaceSubobjectAtOffset(Info->Class, toCharUnits(Offset))) 231812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 232812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 23358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson // Traverse all non-virtual bases. 2344137d517700a1b0f834535545c3f1676f40abcfbAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class); 23558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson for (unsigned I = 0, E = Info->Bases.size(); I != E; ++I) { 236ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson BaseSubobjectInfo* Base = Info->Bases[I]; 23758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (Base->IsVirtual) 23858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson continue; 23958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 24058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class); 24158b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 24258b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (!CanPlaceBaseSubobjectAtOffset(Base, BaseOffset)) 24358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson return false; 24458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } 24558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 2466e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (Info->PrimaryVirtualBaseInfo) { 2476e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *PrimaryVirtualBaseInfo = Info->PrimaryVirtualBaseInfo; 24858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 24958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (Info == PrimaryVirtualBaseInfo->Derived) { 25058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (!CanPlaceBaseSubobjectAtOffset(PrimaryVirtualBaseInfo, Offset)) 25158b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson return false; 25258b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } 25358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } 25458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 255812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Traverse all member variables. 256812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson unsigned FieldNo = 0; 257812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (CXXRecordDecl::field_iterator I = Info->Class->field_begin(), 258812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson E = Info->Class->field_end(); I != E; ++I, ++FieldNo) { 259812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const FieldDecl *FD = *I; 2604137d517700a1b0f834535545c3f1676f40abcfbAnders Carlsson 261812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t FieldOffset = Offset + Layout.getFieldOffset(FieldNo); 262812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!CanPlaceFieldSubobjectAtOffset(FD, FieldOffset)) 263812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 264812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 265812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 26658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson return true; 26758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson} 26858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 269ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlssonvoid EmptySubobjectMap::UpdateEmptyBaseSubobjects(const BaseSubobjectInfo *Info, 270e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson uint64_t Offset, 271e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson bool PlacingEmptyBase) { 272e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson if (!PlacingEmptyBase && Offset >= SizeOfLargestEmptySubobject) { 273e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson // We know that the only empty subobjects that can conflict with empty 274e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson // subobject of non-empty bases, are empty bases that can be placed at 275e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson // offset zero. Because of this, we only need to keep track of empty base 276e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson // subobjects with offsets less than the size of the largest empty 277e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson // subobject for our class. 278e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson return; 279e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson } 280e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson 281fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson AddSubobjectAtOffset(Info->Class, toCharUnits(Offset)); 2824137d517700a1b0f834535545c3f1676f40abcfbAnders Carlsson 28358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson // Traverse all non-virtual bases. 2844137d517700a1b0f834535545c3f1676f40abcfbAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class); 28558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson for (unsigned I = 0, E = Info->Bases.size(); I != E; ++I) { 286ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson BaseSubobjectInfo* Base = Info->Bases[I]; 28758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (Base->IsVirtual) 28858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson continue; 2894137d517700a1b0f834535545c3f1676f40abcfbAnders Carlsson 29058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class); 291e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson UpdateEmptyBaseSubobjects(Base, BaseOffset, PlacingEmptyBase); 29258b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } 29358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 2946e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (Info->PrimaryVirtualBaseInfo) { 2956e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *PrimaryVirtualBaseInfo = Info->PrimaryVirtualBaseInfo; 29658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 29758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (Info == PrimaryVirtualBaseInfo->Derived) 298e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson UpdateEmptyBaseSubobjects(PrimaryVirtualBaseInfo, Offset, 299e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson PlacingEmptyBase); 30058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } 301812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 302812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Traverse all member variables. 303812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson unsigned FieldNo = 0; 304812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (CXXRecordDecl::field_iterator I = Info->Class->field_begin(), 305812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson E = Info->Class->field_end(); I != E; ++I, ++FieldNo) { 306812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const FieldDecl *FD = *I; 3074137d517700a1b0f834535545c3f1676f40abcfbAnders Carlsson 308812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t FieldOffset = Offset + Layout.getFieldOffset(FieldNo); 309812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson UpdateEmptyFieldSubobjects(FD, FieldOffset); 310812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 31158b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson} 31258b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 3135b1319c78061e76d70cca50fb3343b25928e001bAnders Carlssonbool EmptySubobjectMap::CanPlaceBaseAtOffset(const BaseSubobjectInfo *Info, 31458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson uint64_t Offset) { 315261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson // If we know this class doesn't have any empty subobjects we don't need to 316261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson // bother checking. 317261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson if (!SizeOfLargestEmptySubobject) 318261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson return true; 319261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson 32058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (!CanPlaceBaseSubobjectAtOffset(Info, Offset)) 32158b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson return false; 322812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 323812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // We are able to place the base at this offset. Make sure to update the 324812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // empty base subobject map. 325e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson UpdateEmptyBaseSubobjects(Info, Offset, Info->Class->isEmpty()); 326261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson return true; 327261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson} 328261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson 329812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlssonbool 330812a3456b63708a5972f712e9e4b54d3cc436378Anders CarlssonEmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD, 331812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *Class, 332c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson uint64_t Offset) const { 3332177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson // We don't have to keep looking past the maximum offset that's known to 3342177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson // contain an empty class. 335fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson if (!AnyEmptySubobjectsBeyondOffset(toCharUnits(Offset))) 3362177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson return true; 3372177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson 338fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson if (!CanPlaceSubobjectAtOffset(RD, toCharUnits(Offset))) 339812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 340812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 341812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 342812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 343812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Traverse all non-virtual bases. 344812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 345812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson E = RD->bases_end(); I != E; ++I) { 346812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (I->isVirtual()) 347812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson continue; 348812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 349812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *BaseDecl = 350812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 351812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 352812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(BaseDecl); 353812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!CanPlaceFieldSubobjectAtOffset(BaseDecl, Class, BaseOffset)) 354812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 355812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 356812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 35745f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson if (RD == Class) { 35845f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson // This is the most derived class, traverse virtual bases as well. 35945f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(), 36045f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson E = RD->vbases_end(); I != E; ++I) { 36145f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson const CXXRecordDecl *VBaseDecl = 36245f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 36345f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson 36445f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson uint64_t VBaseOffset = Offset + Layout.getVBaseClassOffset(VBaseDecl); 36545f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson if (!CanPlaceFieldSubobjectAtOffset(VBaseDecl, Class, VBaseOffset)) 36645f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson return false; 36745f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson } 36845f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson } 36945f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson 370812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Traverse all member variables. 371812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson unsigned FieldNo = 0; 372812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); 373812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson I != E; ++I, ++FieldNo) { 374812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const FieldDecl *FD = *I; 375812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 376812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t FieldOffset = Offset + Layout.getFieldOffset(FieldNo); 377812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 378812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!CanPlaceFieldSubobjectAtOffset(FD, FieldOffset)) 379812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 380812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 381812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 382812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 383812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 384812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 385812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlssonbool EmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const FieldDecl *FD, 386c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson uint64_t Offset) const { 3872177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson // We don't have to keep looking past the maximum offset that's known to 3882177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson // contain an empty class. 389fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson if (!AnyEmptySubobjectsBeyondOffset(toCharUnits(Offset))) 3902177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson return true; 3912177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson 392812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson QualType T = FD->getType(); 393812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (const RecordType *RT = T->getAs<RecordType>()) { 394812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 395812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return CanPlaceFieldSubobjectAtOffset(RD, RD, Offset); 396812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 397812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 398812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // If we have an array type we need to look at every element. 399812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (const ConstantArrayType *AT = Context.getAsConstantArrayType(T)) { 400812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson QualType ElemTy = Context.getBaseElementType(AT); 401812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const RecordType *RT = ElemTy->getAs<RecordType>(); 402812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!RT) 403812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 404812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 405812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 406812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 407812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 408812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t NumElements = Context.getConstantArrayElementCount(AT); 409812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t ElementOffset = Offset; 410812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (uint64_t I = 0; I != NumElements; ++I) { 4112177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson // We don't have to keep looking past the maximum offset that's known to 4122177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson // contain an empty class. 413fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson if (!AnyEmptySubobjectsBeyondOffset(toCharUnits(ElementOffset))) 4142177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson return true; 4152177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson 416812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!CanPlaceFieldSubobjectAtOffset(RD, RD, ElementOffset)) 417812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 418812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 419812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson ElementOffset += Layout.getSize(); 420812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 421812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 422812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 423812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 424812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 425812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 426812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlssonbool 427812a3456b63708a5972f712e9e4b54d3cc436378Anders CarlssonEmptySubobjectMap::CanPlaceFieldAtOffset(const FieldDecl *FD, uint64_t Offset) { 428812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!CanPlaceFieldSubobjectAtOffset(FD, Offset)) 429812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 430812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 431812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // We are able to place the member variable at this offset. 432812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Make sure to update the empty base subobject map. 433812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson UpdateEmptyFieldSubobjects(FD, Offset); 434812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 435812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 436812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 437812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlssonvoid EmptySubobjectMap::UpdateEmptyFieldSubobjects(const CXXRecordDecl *RD, 438812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *Class, 439812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t Offset) { 4405ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson // We know that the only empty subobjects that can conflict with empty 441e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson // field subobjects are subobjects of empty bases that can be placed at offset 4425ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson // zero. Because of this, we only need to keep track of empty field 4435ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson // subobjects with offsets less than the size of the largest empty 4445ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson // subobject for our class. 4455ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson if (Offset >= SizeOfLargestEmptySubobject) 4465ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson return; 4475ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson 448fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson AddSubobjectAtOffset(RD, toCharUnits(Offset)); 449812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 450812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 451812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 452812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Traverse all non-virtual bases. 453812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 454812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson E = RD->bases_end(); I != E; ++I) { 455812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (I->isVirtual()) 456812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson continue; 457812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 458812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *BaseDecl = 459812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 460812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 461812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(BaseDecl); 462812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson UpdateEmptyFieldSubobjects(BaseDecl, Class, BaseOffset); 463812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 464812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 46545f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson if (RD == Class) { 46645f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson // This is the most derived class, traverse virtual bases as well. 46745f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(), 46845f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson E = RD->vbases_end(); I != E; ++I) { 46945f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson const CXXRecordDecl *VBaseDecl = 47045f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 47145f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson 47245f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson uint64_t VBaseOffset = Offset + Layout.getVBaseClassOffset(VBaseDecl); 47345f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson UpdateEmptyFieldSubobjects(VBaseDecl, Class, VBaseOffset); 47445f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson } 47545f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson } 47645f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson 477812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Traverse all member variables. 478812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson unsigned FieldNo = 0; 479812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); 480812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson I != E; ++I, ++FieldNo) { 481812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const FieldDecl *FD = *I; 482812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 483812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t FieldOffset = Offset + Layout.getFieldOffset(FieldNo); 484812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 485812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson UpdateEmptyFieldSubobjects(FD, FieldOffset); 486812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 487812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 488812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 489812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlssonvoid EmptySubobjectMap::UpdateEmptyFieldSubobjects(const FieldDecl *FD, 490812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t Offset) { 491812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson QualType T = FD->getType(); 492812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (const RecordType *RT = T->getAs<RecordType>()) { 493812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 494812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson UpdateEmptyFieldSubobjects(RD, RD, Offset); 495812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return; 496812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 497812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 498812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // If we have an array type we need to update every element. 499812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (const ConstantArrayType *AT = Context.getAsConstantArrayType(T)) { 500812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson QualType ElemTy = Context.getBaseElementType(AT); 501812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const RecordType *RT = ElemTy->getAs<RecordType>(); 502812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!RT) 503812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return; 504812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 505812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 506812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 507812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 508812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t NumElements = Context.getConstantArrayElementCount(AT); 509812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t ElementOffset = Offset; 510812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 511812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (uint64_t I = 0; I != NumElements; ++I) { 5125ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson // We know that the only empty subobjects that can conflict with empty 513e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson // field subobjects are subobjects of empty bases that can be placed at 5145ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson // offset zero. Because of this, we only need to keep track of empty field 5155ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson // subobjects with offsets less than the size of the largest empty 5165ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson // subobject for our class. 5175ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson if (ElementOffset >= SizeOfLargestEmptySubobject) 5185ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson return; 5195ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson 520812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson UpdateEmptyFieldSubobjects(RD, RD, ElementOffset); 521812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson ElementOffset += Layout.getSize(); 522812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 523812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 524812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 525812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 5267d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonclass RecordLayoutBuilder { 527c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davisprotected: 5289392fa63e45716e32061d05673fa28909f325b02Anders Carlsson // FIXME: Remove this and make the appropriate fields public. 5299392fa63e45716e32061d05673fa28909f325b02Anders Carlsson friend class clang::ASTContext; 5300aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5319392fa63e45716e32061d05673fa28909f325b02Anders Carlsson ASTContext &Context; 5329392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 5336a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson EmptySubobjectMap *EmptySubobjects; 5340aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5359392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// Size - The current size of the record layout. 5369392fa63e45716e32061d05673fa28909f325b02Anders Carlsson uint64_t Size; 5370aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5389392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// Alignment - The current alignment of the record layout. 5399392fa63e45716e32061d05673fa28909f325b02Anders Carlsson unsigned Alignment; 5400aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 54178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis /// \brief The alignment if attribute packed is not used. 54278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis unsigned UnpackedAlignment; 54378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 5449392fa63e45716e32061d05673fa28909f325b02Anders Carlsson llvm::SmallVector<uint64_t, 16> FieldOffsets; 5459392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 5469392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// Packed - Whether the record is packed or not. 547c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar unsigned Packed : 1; 548c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar 549c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar unsigned IsUnion : 1; 550c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar 551c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar unsigned IsMac68kAlign : 1; 5529392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 5539392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// UnfilledBitsInLastByte - If the last field laid out was a bitfield, 5549392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// this contains the number of bits in the last byte that can be used for 5559392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// an adjacent bitfield if necessary. 5569392fa63e45716e32061d05673fa28909f325b02Anders Carlsson unsigned char UnfilledBitsInLastByte; 5570aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5589392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// MaxFieldAlignment - The maximum allowed field alignment. This is set by 5590aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// #pragma pack. 5609392fa63e45716e32061d05673fa28909f325b02Anders Carlsson unsigned MaxFieldAlignment; 5610aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5629392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// DataSize - The data size of the record being laid out. 5639392fa63e45716e32061d05673fa28909f325b02Anders Carlsson uint64_t DataSize; 5640aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5659392fa63e45716e32061d05673fa28909f325b02Anders Carlsson uint64_t NonVirtualSize; 5669392fa63e45716e32061d05673fa28909f325b02Anders Carlsson unsigned NonVirtualAlignment; 5670aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5689392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// PrimaryBase - the primary base class (if one exists) of the class 5699392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// we're laying out. 5709392fa63e45716e32061d05673fa28909f325b02Anders Carlsson const CXXRecordDecl *PrimaryBase; 5710aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5729392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// PrimaryBaseIsVirtual - Whether the primary base of the class we're laying 5739392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// out is virtual. 5749392fa63e45716e32061d05673fa28909f325b02Anders Carlsson bool PrimaryBaseIsVirtual; 5759392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 576376bda924ac92462a22d6a22ea65d8c1bb8f26f3Anders Carlsson typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy; 5770aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5789392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// Bases - base classes and their offsets in the record. 5799392fa63e45716e32061d05673fa28909f325b02Anders Carlsson BaseOffsetsMapTy Bases; 5800aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5819392fa63e45716e32061d05673fa28909f325b02Anders Carlsson // VBases - virtual base classes and their offsets in the record. 5829392fa63e45716e32061d05673fa28909f325b02Anders Carlsson BaseOffsetsMapTy VBases; 5839392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 5849392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// IndirectPrimaryBases - Virtual base classes, direct or indirect, that are 5859392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// primary base classes for some other direct or indirect base class. 5869392fa63e45716e32061d05673fa28909f325b02Anders Carlsson llvm::SmallSet<const CXXRecordDecl*, 32> IndirectPrimaryBases; 5870aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5889392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// FirstNearlyEmptyVBase - The first nearly empty virtual base class in 5899392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// inheritance graph order. Used for determining the primary base class. 5909392fa63e45716e32061d05673fa28909f325b02Anders Carlsson const CXXRecordDecl *FirstNearlyEmptyVBase; 5919392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 5929392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// VisitedVirtualBases - A set of all the visited virtual bases, used to 5939392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// avoid visiting virtual bases more than once. 5949392fa63e45716e32061d05673fa28909f325b02Anders Carlsson llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases; 5950aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 596261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson RecordLayoutBuilder(ASTContext &Context, EmptySubobjectMap *EmptySubobjects) 597261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson : Context(Context), EmptySubobjects(EmptySubobjects), Size(0), Alignment(8), 59878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UnpackedAlignment(Alignment), Packed(false), IsUnion(false), 59978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis IsMac68kAlign(false), UnfilledBitsInLastByte(0), MaxFieldAlignment(0), 60078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis DataSize(0), NonVirtualSize(0), NonVirtualAlignment(8), PrimaryBase(0), 601c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar PrimaryBaseIsVirtual(false), FirstNearlyEmptyVBase(0) { } 6020aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 603fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson // FIXME: Remove these. 604fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson CharUnits toCharUnits(uint64_t Offset) const { 605fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson return CharUnits::fromQuantity(Offset / Context.getCharWidth()); 606fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson } 607fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson uint64_t toOffset(CharUnits Offset) const { 608fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson return Offset.getQuantity() * Context.getCharWidth(); 609fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson } 610fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson 6119392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void Layout(const RecordDecl *D); 612c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson void Layout(const CXXRecordDecl *D); 6139392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void Layout(const ObjCInterfaceDecl *D); 6149392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6159392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void LayoutFields(const RecordDecl *D); 6169392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void LayoutField(const FieldDecl *D); 61778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis void LayoutWideBitField(uint64_t FieldSize, uint64_t TypeSize, 61878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis bool FieldPacked, const FieldDecl *D); 6199392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void LayoutBitField(const FieldDecl *D); 6209392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6216e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// BaseSubobjectInfoAllocator - Allocator for BaseSubobjectInfo objects. 6226e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson llvm::SpecificBumpPtrAllocator<BaseSubobjectInfo> BaseSubobjectInfoAllocator; 6236e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 6246e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson typedef llvm::DenseMap<const CXXRecordDecl *, BaseSubobjectInfo *> 6256e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfoMapTy; 6266e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 6276e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// VirtualBaseInfo - Map from all the (direct or indirect) virtual bases 6286e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// of the class we're laying out to their base subobject info. 6296e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfoMapTy VirtualBaseInfo; 6306e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 6316e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// NonVirtualBaseInfo - Map from all the direct non-virtual bases of the 6326e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// class we're laying out to their base subobject info. 6336e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfoMapTy NonVirtualBaseInfo; 6346e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 6356e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// ComputeBaseSubobjectInfo - Compute the base subobject information for the 6366e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// bases of the given class. 6376e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson void ComputeBaseSubobjectInfo(const CXXRecordDecl *RD); 6386e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 6396e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// ComputeBaseSubobjectInfo - Compute the base subobject information for a 6406e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// single class and all of its base classes. 6416e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *ComputeBaseSubobjectInfo(const CXXRecordDecl *RD, 6426e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson bool IsVirtual, 6436e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *Derived); 6449392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6459392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// DeterminePrimaryBase - Determine the primary base of the given class. 6469392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void DeterminePrimaryBase(const CXXRecordDecl *RD); 6479392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6489392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void SelectPrimaryVBase(const CXXRecordDecl *RD); 6490aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 650c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis virtual uint64_t GetVirtualPointersSize(const CXXRecordDecl *RD) const; 651c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis 6520aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// IdentifyPrimaryBases - Identify all virtual base classes, direct or 6530aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// indirect, that are primary base classes for some other direct or indirect 6549392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// base class. 6559392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void IdentifyPrimaryBases(const CXXRecordDecl *RD); 6560aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 657c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis virtual bool IsNearlyEmpty(const CXXRecordDecl *RD) const; 6580aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 6590aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// LayoutNonVirtualBases - Determines the primary base class (if any) and 6609392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// lays it out. Will then proceed to lay out all non-virtual base clasess. 6619392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void LayoutNonVirtualBases(const CXXRecordDecl *RD); 6629392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6639392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// LayoutNonVirtualBase - Lays out a single non-virtual base. 66407cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson void LayoutNonVirtualBase(const BaseSubobjectInfo *Base); 6659392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6663cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson void AddPrimaryVirtualBaseOffsets(const BaseSubobjectInfo *Info, 667c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis uint64_t Offset); 6689392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6699392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// LayoutVirtualBases - Lays out all the virtual bases. 6709392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void LayoutVirtualBases(const CXXRecordDecl *RD, 6719392fa63e45716e32061d05673fa28909f325b02Anders Carlsson const CXXRecordDecl *MostDerivedClass); 6729392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6739392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// LayoutVirtualBase - Lays out a single virtual base. 674276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson void LayoutVirtualBase(const BaseSubobjectInfo *Base); 6759392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6760aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// LayoutBase - Will lay out a base and return the offset where it was 6779392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// placed, in bits. 678b1d880b15f6b254349bd7a700e6b4f2ec1c24f5bAnders Carlsson uint64_t LayoutBase(const BaseSubobjectInfo *Base); 6799392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 680c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson /// InitializeLayout - Initialize record layout for the given record decl. 681c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar void InitializeLayout(const Decl *D); 682c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 6839392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// FinishLayout - Finalize record layout. Adjust record size based on the 6849392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// alignment. 68578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis void FinishLayout(const NamedDecl *D); 68678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 68778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis void UpdateAlignment(unsigned NewAlignment, unsigned UnpackedNewAlignment); 68878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis void UpdateAlignment(unsigned NewAlignment) { 68978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UpdateAlignment(NewAlignment, NewAlignment); 69078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 69178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 69278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis void CheckFieldPadding(uint64_t Offset, uint64_t UnpaddedOffset, 69378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis uint64_t UnpackedOffset, unsigned UnpackedAlign, 69478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis bool isPacked, const FieldDecl *D); 6959392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 69678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID); 6979392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 698c83d2d7d8914a0fe00d679a262f2bdae7689f16dArgyrios Kyrtzidis RecordLayoutBuilder(const RecordLayoutBuilder&); // DO NOT IMPLEMENT 699c83d2d7d8914a0fe00d679a262f2bdae7689f16dArgyrios Kyrtzidis void operator=(const RecordLayoutBuilder&); // DO NOT IMPLEMENT 7009392fa63e45716e32061d05673fa28909f325b02Anders Carlssonpublic: 7019392fa63e45716e32061d05673fa28909f325b02Anders Carlsson static const CXXMethodDecl *ComputeKeyFunction(const CXXRecordDecl *RD); 702cfe17e5c82762cc854012e472b66f4278f0a4a2aArgyrios Kyrtzidis 703cfe17e5c82762cc854012e472b66f4278f0a4a2aArgyrios Kyrtzidis virtual ~RecordLayoutBuilder() { } 7049392fa63e45716e32061d05673fa28909f325b02Anders Carlsson}; 7057e220286410422ed1dc0409a9cb9708fe50e3df0Benjamin Kramer} // end anonymous namespace 7069392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 7076f376336138ea719e3c4757ae046a5768043b276Mike Stump/// IsNearlyEmpty - Indicates when a class has a vtable pointer, but 7086f376336138ea719e3c4757ae046a5768043b276Mike Stump/// no other data. 7097d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonbool RecordLayoutBuilder::IsNearlyEmpty(const CXXRecordDecl *RD) const { 7106f376336138ea719e3c4757ae046a5768043b276Mike Stump // FIXME: Audit the corners 7116f376336138ea719e3c4757ae046a5768043b276Mike Stump if (!RD->isDynamicClass()) 7126f376336138ea719e3c4757ae046a5768043b276Mike Stump return false; 7130f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson const ASTRecordLayout &BaseInfo = Context.getASTRecordLayout(RD); 7140f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson if (BaseInfo.getNonVirtualSize() == Context.Target.getPointerWidth(0)) 7156f376336138ea719e3c4757ae046a5768043b276Mike Stump return true; 7166f376336138ea719e3c4757ae046a5768043b276Mike Stump return false; 7176f376336138ea719e3c4757ae046a5768043b276Mike Stump} 7186f376336138ea719e3c4757ae046a5768043b276Mike Stump 7197d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonvoid RecordLayoutBuilder::IdentifyPrimaryBases(const CXXRecordDecl *RD) { 720bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar const ASTRecordLayout::PrimaryBaseInfo &BaseInfo = 7210f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson Context.getASTRecordLayout(RD).getPrimaryBaseInfo(); 722bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 7233f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson // If the record has a primary base class that is virtual, add it to the set 7243f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson // of primary bases. 725261fba6cf57a09a1f1d0c4a4c4856aaa62753242Anders Carlsson if (BaseInfo.isVirtual()) 726261fba6cf57a09a1f1d0c4a4c4856aaa62753242Anders Carlsson IndirectPrimaryBases.insert(BaseInfo.getBase()); 727bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 7283f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson // Now traverse all bases and find primary bases for them. 7296f376336138ea719e3c4757ae046a5768043b276Mike Stump for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), 730bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar e = RD->bases_end(); i != e; ++i) { 7319994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl assert(!i->getType()->isDependentType() && 7329994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl "Cannot layout class with dependent bases."); 7331eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const CXXRecordDecl *Base = 73449520944c688a9d5fc78d0c2af544b825873477bMike Stump cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 735bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 73649520944c688a9d5fc78d0c2af544b825873477bMike Stump // Only bases with virtual bases participate in computing the 73749520944c688a9d5fc78d0c2af544b825873477bMike Stump // indirect primary virtual base classes. 7384ef980984fd0e131fca3f9e6ba15e8a79cabf88cMike Stump if (Base->getNumVBases()) 7393f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson IdentifyPrimaryBases(Base); 7406f376336138ea719e3c4757ae046a5768043b276Mike Stump } 7416f376336138ea719e3c4757ae046a5768043b276Mike Stump} 7426f376336138ea719e3c4757ae046a5768043b276Mike Stump 7433f066522342538509cf0aa4f381503b43fbdb68bAnders Carlssonvoid 7447d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders CarlssonRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD) { 745584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 746bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->bases_end(); I != E; ++I) { 747584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson assert(!I->getType()->isDependentType() && 7489994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl "Cannot layout class with dependent bases."); 749bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 7501eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const CXXRecordDecl *Base = 751584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 752200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 753584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson // Check if this is a nearly empty virtual base. 754584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson if (I->isVirtual() && IsNearlyEmpty(Base)) { 755584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson // If it's not an indirect primary base, then we've found our primary 756584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson // base. 7573f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson if (!IndirectPrimaryBases.count(Base)) { 75828fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBase = Base; 75928fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBaseIsVirtual = true; 760d76264e0b20470267249660ab947197cf6d6e31fMike Stump return; 761d76264e0b20470267249660ab947197cf6d6e31fMike Stump } 762bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 763584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson // Is this the first nearly empty virtual base? 764584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson if (!FirstNearlyEmptyVBase) 765584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson FirstNearlyEmptyVBase = Base; 766d76264e0b20470267249660ab947197cf6d6e31fMike Stump } 767bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 768200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson SelectPrimaryVBase(Base); 76928fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson if (PrimaryBase) 77094ba380b820cde3fb9d97d5f07ac709ebbb6ac1eZhongxing Xu return; 771d76264e0b20470267249660ab947197cf6d6e31fMike Stump } 772d76264e0b20470267249660ab947197cf6d6e31fMike Stump} 773d76264e0b20470267249660ab947197cf6d6e31fMike Stump 774c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davisuint64_t 775c9f8aece7e111f90265dfad9a81f3f517be948deCharles DavisRecordLayoutBuilder::GetVirtualPointersSize(const CXXRecordDecl *RD) const { 776c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis return Context.Target.getPointerWidth(0); 777c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis} 778c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis 779200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson/// DeterminePrimaryBase - Determine the primary base of the given class. 7807d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonvoid RecordLayoutBuilder::DeterminePrimaryBase(const CXXRecordDecl *RD) { 781200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // If the class isn't dynamic, it won't have a primary base. 782200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson if (!RD->isDynamicClass()) 783200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson return; 784bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 7853f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson // Compute all the primary virtual bases for all of our direct and 7860880e75541899bc1cdd73c50eb549110b5916c59Mike Stump // indirect bases, and record all their primary virtual base classes. 7870880e75541899bc1cdd73c50eb549110b5916c59Mike Stump for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), 788bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar e = RD->bases_end(); i != e; ++i) { 7899994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl assert(!i->getType()->isDependentType() && 790200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson "Cannot lay out class with dependent bases."); 7911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const CXXRecordDecl *Base = 7920880e75541899bc1cdd73c50eb549110b5916c59Mike Stump cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 7933f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson IdentifyPrimaryBases(Base); 7940880e75541899bc1cdd73c50eb549110b5916c59Mike Stump } 7950880e75541899bc1cdd73c50eb549110b5916c59Mike Stump 796bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar // If the record has a dynamic base class, attempt to choose a primary base 797bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar // class. It is the first (in direct base class order) non-virtual dynamic 7983f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson // base class, if one exists. 7996f376336138ea719e3c4757ae046a5768043b276Mike Stump for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), 800bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar e = RD->bases_end(); i != e; ++i) { 801ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson // Ignore virtual bases. 802ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson if (i->isVirtual()) 803ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson continue; 804bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 805ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson const CXXRecordDecl *Base = 806ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 807ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson 808ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson if (Base->isDynamicClass()) { 809ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson // We found it. 81028fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBase = Base; 81128fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBaseIsVirtual = false; 812ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson return; 8136f376336138ea719e3c4757ae046a5768043b276Mike Stump } 8146f376336138ea719e3c4757ae046a5768043b276Mike Stump } 8156f376336138ea719e3c4757ae046a5768043b276Mike Stump 8166f376336138ea719e3c4757ae046a5768043b276Mike Stump // Otherwise, it is the first nearly empty virtual base that is not an 81749520944c688a9d5fc78d0c2af544b825873477bMike Stump // indirect primary virtual base class, if one exists. 818200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson if (RD->getNumVBases() != 0) { 819200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson SelectPrimaryVBase(RD); 82028fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson if (PrimaryBase) 821200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson return; 822200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson } 8236f376336138ea719e3c4757ae046a5768043b276Mike Stump 824200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Otherwise, it is the first nearly empty virtual base that is not an 825200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // indirect primary virtual base class, if one exists. 826200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson if (FirstNearlyEmptyVBase) { 82728fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBase = FirstNearlyEmptyVBase; 82828fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBaseIsVirtual = true; 8296f376336138ea719e3c4757ae046a5768043b276Mike Stump return; 830200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson } 831bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 832200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Otherwise there is no primary base class. 83328fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson assert(!PrimaryBase && "Should not get here with a primary base!"); 834200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 835200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Allocate the virtual table pointer at offset zero. 836200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson assert(DataSize == 0 && "Vtable pointer must be at offset zero!"); 837bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 838200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Update the size. 839c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis Size += GetVirtualPointersSize(RD); 840200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson DataSize = Size; 841200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 842200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Update the alignment. 8430f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson UpdateAlignment(Context.Target.getPointerAlign(0)); 8446f376336138ea719e3c4757ae046a5768043b276Mike Stump} 8456f376336138ea719e3c4757ae046a5768043b276Mike Stump 8466e26454ecceb20938b866717dc8a72c6d37d224dAnders CarlssonBaseSubobjectInfo * 8476e26454ecceb20938b866717dc8a72c6d37d224dAnders CarlssonRecordLayoutBuilder::ComputeBaseSubobjectInfo(const CXXRecordDecl *RD, 8486e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson bool IsVirtual, 8496e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *Derived) { 8506e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *Info; 8516e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 8526e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (IsVirtual) { 8536e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Check if we already have info about this virtual base. 8546e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *&InfoSlot = VirtualBaseInfo[RD]; 8556e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (InfoSlot) { 8566e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson assert(InfoSlot->Class == RD && "Wrong class for virtual base info!"); 8576e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson return InfoSlot; 8586e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 8596e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 8606e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // We don't, create it. 8616e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson InfoSlot = new (BaseSubobjectInfoAllocator.Allocate()) BaseSubobjectInfo; 8626e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info = InfoSlot; 8636e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } else { 8646e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info = new (BaseSubobjectInfoAllocator.Allocate()) BaseSubobjectInfo; 8656e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 8666e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 8676e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info->Class = RD; 8686e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info->IsVirtual = IsVirtual; 8696e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info->Derived = 0; 8706e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info->PrimaryVirtualBaseInfo = 0; 8716e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 8726e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson const CXXRecordDecl *PrimaryVirtualBase = 0; 8736e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *PrimaryVirtualBaseInfo = 0; 8746e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 8756e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Check if this base has a primary virtual base. 8766e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (RD->getNumVBases()) { 8776e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 8786e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (Layout.getPrimaryBaseWasVirtual()) { 8796e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // This base does have a primary virtual base. 8806e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson PrimaryVirtualBase = Layout.getPrimaryBase(); 8816e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson assert(PrimaryVirtualBase && "Didn't have a primary virtual base!"); 8826e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 8836e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Now check if we have base subobject info about this primary base. 8846e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson PrimaryVirtualBaseInfo = VirtualBaseInfo.lookup(PrimaryVirtualBase); 8856e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 8866e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (PrimaryVirtualBaseInfo) { 8876e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (PrimaryVirtualBaseInfo->Derived) { 8886e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // We did have info about this primary base, and it turns out that it 8896e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // has already been claimed as a primary virtual base for another 8906e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // base. 8916e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson PrimaryVirtualBase = 0; 8926e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } else { 8936e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // We can claim this base as our primary base. 8946e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info->PrimaryVirtualBaseInfo = PrimaryVirtualBaseInfo; 8956e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson PrimaryVirtualBaseInfo->Derived = Info; 8966e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 8976e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 8986e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 8996e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 9006e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9016e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Now go through all direct bases. 9026e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 9036e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson E = RD->bases_end(); I != E; ++I) { 9046e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson bool IsVirtual = I->isVirtual(); 9056e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9066e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson const CXXRecordDecl *BaseDecl = 9076e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 9086e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9096e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info->Bases.push_back(ComputeBaseSubobjectInfo(BaseDecl, IsVirtual, Info)); 9106e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 9116e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9126e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (PrimaryVirtualBase && !PrimaryVirtualBaseInfo) { 9136e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Traversing the bases must have created the base info for our primary 9146e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // virtual base. 9156e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson PrimaryVirtualBaseInfo = VirtualBaseInfo.lookup(PrimaryVirtualBase); 9166e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson assert(PrimaryVirtualBaseInfo && 9176e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson "Did not create a primary virtual base!"); 9186e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9196e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Claim the primary virtual base as our primary virtual base. 9206e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info->PrimaryVirtualBaseInfo = PrimaryVirtualBaseInfo; 9216e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson PrimaryVirtualBaseInfo->Derived = Info; 9226e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 9236e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9246e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson return Info; 9256e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson} 9266e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9276e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlssonvoid RecordLayoutBuilder::ComputeBaseSubobjectInfo(const CXXRecordDecl *RD) { 9286e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 9296e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson E = RD->bases_end(); I != E; ++I) { 9306e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson bool IsVirtual = I->isVirtual(); 9316e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9326e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson const CXXRecordDecl *BaseDecl = 9336e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 9346e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9356e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Compute the base subobject info for this base. 9366e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *Info = ComputeBaseSubobjectInfo(BaseDecl, IsVirtual, 0); 9376e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9386e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (IsVirtual) { 9396e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // ComputeBaseInfo has already added this base for us. 9406e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson assert(VirtualBaseInfo.count(BaseDecl) && 9416e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson "Did not add virtual base!"); 9426e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } else { 9436e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Add the base info to the map of non-virtual bases. 9446e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson assert(!NonVirtualBaseInfo.count(BaseDecl) && 9456e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson "Non-virtual base already exists!"); 9466e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson NonVirtualBaseInfo.insert(std::make_pair(BaseDecl, Info)); 9476e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 9486e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 9496e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson} 9506e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 951e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlssonvoid 9527d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders CarlssonRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) { 9536e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Then, determine the primary base class. 954200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson DeterminePrimaryBase(RD); 955bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 9566e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Compute base subobject info. 9576e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson ComputeBaseSubobjectInfo(RD); 9586e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 959200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // If we have a primary base class, lay it out. 96028fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson if (PrimaryBase) { 96128fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson if (PrimaryBaseIsVirtual) { 9626e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // If the primary virtual base was a primary virtual base of some other 9636e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // base class we'll have to steal it. 9646e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *PrimaryBaseInfo = VirtualBaseInfo.lookup(PrimaryBase); 9656e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson PrimaryBaseInfo->Derived = 0; 9666e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 967200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // We have a virtual primary base, insert it as an indirect primary base. 96828fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson IndirectPrimaryBases.insert(PrimaryBase); 96937147ea14f39a8522e32e3ba4d043a2a33fff90cAnders Carlsson 9700aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar assert(!VisitedVirtualBases.count(PrimaryBase) && 97128fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson "vbase already visited!"); 97228fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson VisitedVirtualBases.insert(PrimaryBase); 9730aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 974276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson LayoutVirtualBase(PrimaryBaseInfo); 97507cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson } else { 97607cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson BaseSubobjectInfo *PrimaryBaseInfo = 97707cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson NonVirtualBaseInfo.lookup(PrimaryBase); 97807cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson assert(PrimaryBaseInfo && 97907cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson "Did not find base info for non-virtual primary base!"); 98007cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson 98107cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson LayoutNonVirtualBase(PrimaryBaseInfo); 98207cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson } 983200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson } 984bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 985200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Now lay out the non-virtual bases. 986200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 987bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->bases_end(); I != E; ++I) { 988200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 989200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Ignore virtual bases. 990200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson if (I->isVirtual()) 991200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson continue; 992200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 99307cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson const CXXRecordDecl *BaseDecl = 994200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 995200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 996200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Skip the primary base. 99707cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson if (BaseDecl == PrimaryBase && !PrimaryBaseIsVirtual) 998200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson continue; 999200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 1000200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Lay out the base. 100107cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson BaseSubobjectInfo *BaseInfo = NonVirtualBaseInfo.lookup(BaseDecl); 100207cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson assert(BaseInfo && "Did not find base info for non-virtual base!"); 100307cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson 100407cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson LayoutNonVirtualBase(BaseInfo); 1005e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson } 1006e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson} 1007e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 100807cebc57123db6a50c7c293e44a9647ce069952bAnders Carlssonvoid RecordLayoutBuilder::LayoutNonVirtualBase(const BaseSubobjectInfo *Base) { 1009e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson // Layout the base. 1010b1d880b15f6b254349bd7a700e6b4f2ec1c24f5bAnders Carlsson uint64_t Offset = LayoutBase(Base); 1011376bda924ac92462a22d6a22ea65d8c1bb8f26f3Anders Carlsson CharUnits OffsetInChars = 1012376bda924ac92462a22d6a22ea65d8c1bb8f26f3Anders Carlsson CharUnits::fromQuantity(Offset / Context.getCharWidth()); 1013bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1014e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson // Add its base class offset. 101507cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson assert(!Bases.count(Base->Class) && "base offset already exists!"); 1016376bda924ac92462a22d6a22ea65d8c1bb8f26f3Anders Carlsson Bases.insert(std::make_pair(Base->Class, OffsetInChars)); 10173cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson 10183cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson AddPrimaryVirtualBaseOffsets(Base, Offset); 1019e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson} 1020968db3364611a475909b5e76969d2f5472e65597Mike Stump 1021bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbarvoid 10223cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders CarlssonRecordLayoutBuilder::AddPrimaryVirtualBaseOffsets(const BaseSubobjectInfo *Info, 10233cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson uint64_t Offset) { 10243cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson // This base isn't interesting, it has no virtual bases. 10253cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson if (!Info->Class->getNumVBases()) 10263cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson return; 10273cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson 10283cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson // First, check if we have a virtual primary base to add offsets for. 10293cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson if (Info->PrimaryVirtualBaseInfo) { 10303cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson assert(Info->PrimaryVirtualBaseInfo->IsVirtual && 10313cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson "Primary virtual base is not virtual!"); 10323cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson if (Info->PrimaryVirtualBaseInfo->Derived == Info) { 10333cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson // Add the offset. 10343cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson assert(!VBases.count(Info->PrimaryVirtualBaseInfo->Class) && 10353cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson "primary vbase offset already exists!"); 1036376bda924ac92462a22d6a22ea65d8c1bb8f26f3Anders Carlsson CharUnits OffsetInChars = 1037376bda924ac92462a22d6a22ea65d8c1bb8f26f3Anders Carlsson CharUnits::fromQuantity(Offset / Context.getCharWidth()); 10383cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson VBases.insert(std::make_pair(Info->PrimaryVirtualBaseInfo->Class, 1039376bda924ac92462a22d6a22ea65d8c1bb8f26f3Anders Carlsson OffsetInChars)); 10403cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson 10413cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson // Traverse the primary virtual base. 10423cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson AddPrimaryVirtualBaseOffsets(Info->PrimaryVirtualBaseInfo, Offset); 10433cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson } 104497913576dbe624971bf18726899983d211d742c0Anders Carlsson } 104597913576dbe624971bf18726899983d211d742c0Anders Carlsson 10463cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson // Now go through all direct non-virtual bases. 10473cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class); 10483cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson for (unsigned I = 0, E = Info->Bases.size(); I != E; ++I) { 10493cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson const BaseSubobjectInfo *Base = Info->Bases[I]; 10503cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson if (Base->IsVirtual) 105197913576dbe624971bf18726899983d211d742c0Anders Carlsson continue; 10520aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 10533cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson uint64_t BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class); 10543cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson AddPrimaryVirtualBaseOffsets(Base, BaseOffset); 105597913576dbe624971bf18726899983d211d742c0Anders Carlsson } 105697913576dbe624971bf18726899983d211d742c0Anders Carlsson} 105797913576dbe624971bf18726899983d211d742c0Anders Carlsson 105897913576dbe624971bf18726899983d211d742c0Anders Carlssonvoid 10597d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders CarlssonRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD, 106097913576dbe624971bf18726899983d211d742c0Anders Carlsson const CXXRecordDecl *MostDerivedClass) { 106188f4296e85d49e4ea63cda729cd5f696824c67ceAnders Carlsson const CXXRecordDecl *PrimaryBase; 1062bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson bool PrimaryBaseIsVirtual; 106337147ea14f39a8522e32e3ba4d043a2a33fff90cAnders Carlsson 1064bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson if (MostDerivedClass == RD) { 106528fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBase = this->PrimaryBase; 106628fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBaseIsVirtual = this->PrimaryBaseIsVirtual; 1067bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson } else { 10680f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 106988f4296e85d49e4ea63cda729cd5f696824c67ceAnders Carlsson PrimaryBase = Layout.getPrimaryBase(); 1070bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson PrimaryBaseIsVirtual = Layout.getPrimaryBaseWasVirtual(); 1071bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson } 1072bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson 1073622e2477d0698d734671523389277e10d8566e26Anders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1074622e2477d0698d734671523389277e10d8566e26Anders Carlsson E = RD->bases_end(); I != E; ++I) { 1075622e2477d0698d734671523389277e10d8566e26Anders Carlsson assert(!I->getType()->isDependentType() && 10769994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl "Cannot layout class with dependent bases."); 1077bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1078276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson const CXXRecordDecl *BaseDecl = 1079622e2477d0698d734671523389277e10d8566e26Anders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1080622e2477d0698d734671523389277e10d8566e26Anders Carlsson 1081622e2477d0698d734671523389277e10d8566e26Anders Carlsson if (I->isVirtual()) { 1082276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson if (PrimaryBase != BaseDecl || !PrimaryBaseIsVirtual) { 1083276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson bool IndirectPrimaryBase = IndirectPrimaryBases.count(BaseDecl); 1084bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson 1085bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson // Only lay out the virtual base if it's not an indirect primary base. 1086bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson if (!IndirectPrimaryBase) { 1087bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson // Only visit virtual bases once. 1088276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson if (!VisitedVirtualBases.insert(BaseDecl)) 1089bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson continue; 10900aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1091276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson const BaseSubobjectInfo *BaseInfo = VirtualBaseInfo.lookup(BaseDecl); 1092276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson assert(BaseInfo && "Did not find virtual base info!"); 1093276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson LayoutVirtualBase(BaseInfo); 1094147b5ddc6c8618a9d70a83f90de409e444ae705bAnders Carlsson } 1095968db3364611a475909b5e76969d2f5472e65597Mike Stump } 1096fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump } 1097bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1098276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson if (!BaseDecl->getNumVBases()) { 1099622e2477d0698d734671523389277e10d8566e26Anders Carlsson // This base isn't interesting since it doesn't have any virtual bases. 1100622e2477d0698d734671523389277e10d8566e26Anders Carlsson continue; 1101622e2477d0698d734671523389277e10d8566e26Anders Carlsson } 1102622e2477d0698d734671523389277e10d8566e26Anders Carlsson 1103276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson LayoutVirtualBases(BaseDecl, MostDerivedClass); 1104eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump } 1105eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump} 1106eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump 1107276b491b44b473d91610432aa335927b2c7ad152Anders Carlssonvoid RecordLayoutBuilder::LayoutVirtualBase(const BaseSubobjectInfo *Base) { 11083cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson assert(!Base->Derived && "Trying to lay out a primary virtual base!"); 11093cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson 1110e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson // Layout the base. 1111b1d880b15f6b254349bd7a700e6b4f2ec1c24f5bAnders Carlsson uint64_t Offset = LayoutBase(Base); 1112376bda924ac92462a22d6a22ea65d8c1bb8f26f3Anders Carlsson CharUnits OffsetInChars = 1113376bda924ac92462a22d6a22ea65d8c1bb8f26f3Anders Carlsson CharUnits::fromQuantity(Offset / Context.getCharWidth()); 1114e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson 1115e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson // Add its base class offset. 1116276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson assert(!VBases.count(Base->Class) && "vbase offset already exists!"); 1117376bda924ac92462a22d6a22ea65d8c1bb8f26f3Anders Carlsson VBases.insert(std::make_pair(Base->Class, OffsetInChars)); 11183cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson 11193cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson AddPrimaryVirtualBaseOffsets(Base, Offset); 1120e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson} 1121e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 1122b1d880b15f6b254349bd7a700e6b4f2ec1c24f5bAnders Carlssonuint64_t RecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) { 1123b1d880b15f6b254349bd7a700e6b4f2ec1c24f5bAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(Base->Class); 1124e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 1125e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // If we have an empty base class, try to place it at offset 0. 1126b1d880b15f6b254349bd7a700e6b4f2ec1c24f5bAnders Carlsson if (Base->Class->isEmpty() && 112783a45e7dab892e9efd3515eca4eb5b81bc3f2126Anders Carlsson EmptySubobjects->CanPlaceBaseAtOffset(Base, 0)) { 1128c3fddeb4384de2238ec03c77be6bee606725609eAnders Carlsson Size = std::max(Size, Layout.getSize()); 1129e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 1130e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson return 0; 1131e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson } 1132bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1133c3fddeb4384de2238ec03c77be6bee606725609eAnders Carlsson unsigned BaseAlign = Layout.getNonVirtualAlign(); 1134bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1135e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // Round up the current record size to the base's alignment boundary. 1136e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson uint64_t Offset = llvm::RoundUpToAlignment(DataSize, BaseAlign); 1137bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1138e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // Try to place the base. 113983a45e7dab892e9efd3515eca4eb5b81bc3f2126Anders Carlsson while (!EmptySubobjects->CanPlaceBaseAtOffset(Base, Offset)) 1140e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson Offset += BaseAlign; 1141e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 1142b1d880b15f6b254349bd7a700e6b4f2ec1c24f5bAnders Carlsson if (!Base->Class->isEmpty()) { 1143e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // Update the data size. 1144c3fddeb4384de2238ec03c77be6bee606725609eAnders Carlsson DataSize = Offset + Layout.getNonVirtualSize(); 1145e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 1146e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson Size = std::max(Size, DataSize); 1147e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson } else 1148c3fddeb4384de2238ec03c77be6bee606725609eAnders Carlsson Size = std::max(Size, Offset + Layout.getSize()); 1149e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 1150e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // Remember max struct/class alignment. 1151e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson UpdateAlignment(BaseAlign); 1152e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 1153e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson return Offset; 1154e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson} 1155e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 1156c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbarvoid RecordLayoutBuilder::InitializeLayout(const Decl *D) { 1157c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar if (const RecordDecl *RD = dyn_cast<RecordDecl>(D)) 1158c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar IsUnion = RD->isUnion(); 11590aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1160a5dd722bdf2f74a1a249fe6661d96a7236aee0f0Anders Carlsson Packed = D->hasAttr<PackedAttr>(); 11610aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1162c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar // mac68k alignment supersedes maximum field alignment and attribute aligned, 1163c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar // and forces all structures to have 2-byte alignment. The IBM docs on it 1164c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar // allude to additional (more complicated) semantics, especially with regard 1165c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar // to bit-fields, but gcc appears not to follow that. 1166c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar if (D->hasAttr<AlignMac68kAttr>()) { 1167c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar IsMac68kAlign = true; 1168c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar MaxFieldAlignment = 2 * 8; 1169c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar Alignment = 2 * 8; 1170c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar } else { 1171c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar if (const MaxFieldAlignmentAttr *MFAA = D->getAttr<MaxFieldAlignmentAttr>()) 1172c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar MaxFieldAlignment = MFAA->getAlignment(); 11730aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1174cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (unsigned MaxAlign = D->getMaxAlignment()) 1175cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt UpdateAlignment(MaxAlign); 1176c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar } 1177c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson} 117874cbe226207fd101623638dadfa7fbada04ff2a6Anders Carlsson 1179c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlssonvoid RecordLayoutBuilder::Layout(const RecordDecl *D) { 1180c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson InitializeLayout(D); 1181a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson LayoutFields(D); 11821eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1183c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson // Finally, round the size of the total struct up to the alignment of the 1184c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson // struct itself. 118578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis FinishLayout(D); 1186c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson} 1187c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 1188c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlssonvoid RecordLayoutBuilder::Layout(const CXXRecordDecl *RD) { 1189c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson InitializeLayout(RD); 1190c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 1191c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson // Lay out the vtable and the non-virtual bases. 1192c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson LayoutNonVirtualBases(RD); 1193c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 1194c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson LayoutFields(RD); 1195c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 1196b2fafd4978166114c54748a73738d8b2c3a37e2bAnders Carlsson NonVirtualSize = Size; 1197b2fafd4978166114c54748a73738d8b2c3a37e2bAnders Carlsson NonVirtualAlignment = Alignment; 11983dee6efcad9ad56d14f7edd1c29924f0b876a7f9Mike Stump 1199c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson // Lay out the virtual bases and add the primary virtual base offsets. 1200c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson LayoutVirtualBases(RD, RD); 120197913576dbe624971bf18726899983d211d742c0Anders Carlsson 1202c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson VisitedVirtualBases.clear(); 1203eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump 1204bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // Finally, round the size of the total struct up to the alignment of the 1205bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // struct itself. 120678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis FinishLayout(RD); 1207c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 1208a1e87162d36f94d3dc58ff3f0743d6026635a0c6Anders Carlsson#ifndef NDEBUG 1209c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson // Check that we have base offsets for all bases. 1210c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1211c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson E = RD->bases_end(); I != E; ++I) { 1212c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson if (I->isVirtual()) 1213c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson continue; 12140aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1215c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson const CXXRecordDecl *BaseDecl = 1216c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1217c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 1218c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson assert(Bases.count(BaseDecl) && "Did not find base offset!"); 1219c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson } 12200aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1221c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson // And all virtual bases. 1222c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(), 1223c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson E = RD->vbases_end(); I != E; ++I) { 1224c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson const CXXRecordDecl *BaseDecl = 1225c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 12260aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1227c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson assert(VBases.count(BaseDecl) && "Did not find base offset!"); 1228a1e87162d36f94d3dc58ff3f0743d6026635a0c6Anders Carlsson } 1229a1e87162d36f94d3dc58ff3f0743d6026635a0c6Anders Carlsson#endif 1230bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson} 1231bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 12327d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonvoid RecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D) { 123393fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson if (ObjCInterfaceDecl *SD = D->getSuperClass()) { 12340f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson const ASTRecordLayout &SL = Context.getASTObjCInterfaceLayout(SD); 123593fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson 123693fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson UpdateAlignment(SL.getAlignment()); 12371eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 123893fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson // We start laying out ivars not at the end of the superclass 123993fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson // structure, but at the next byte following the last field. 1240243a68551ac9ec71bf341e062418e33eb4f286ffAnders Carlsson Size = llvm::RoundUpToAlignment(SL.getDataSize(), 8); 1241a223935e5cf82e939e1ca1da4111d63025a04e39Anders Carlsson DataSize = Size; 124293fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson } 12431eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1244c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar InitializeLayout(D); 12458a2c92cab213bd7e28ff669577e815cd70bafbe3Daniel Dunbar 124693fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson // Layout each ivar sequentially. 124793fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson llvm::SmallVector<ObjCIvarDecl*, 16> Ivars; 12480f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson Context.ShallowCollectObjCIvars(D, Ivars); 124993fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson for (unsigned i = 0, e = Ivars.size(); i != e; ++i) 125093fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson LayoutField(Ivars[i]); 12511eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 125293fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson // Finally, round the size of the total struct up to the alignment of the 125393fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson // struct itself. 125478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis FinishLayout(D); 125593fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson} 125693fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson 12577d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonvoid RecordLayoutBuilder::LayoutFields(const RecordDecl *D) { 1258a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson // Layout each field, for now, just sequentially, respecting alignment. In 1259a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson // the future, this will need to be tweakable by targets. 12601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump for (RecordDecl::field_iterator Field = D->field_begin(), 1261bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar FieldEnd = D->field_end(); Field != FieldEnd; ++Field) 1262a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson LayoutField(*Field); 1263a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson} 1264a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson 12650aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbarvoid RecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize, 126678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis uint64_t TypeSize, 126778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis bool FieldPacked, 126878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis const FieldDecl *D) { 12694cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson assert(Context.getLangOptions().CPlusPlus && 12704cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson "Can only have wide bit-fields in C++!"); 12710aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 12724cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson // Itanium C++ ABI 2.4: 12730aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar // If sizeof(T)*8 < n, let T' be the largest integral POD type with 12744cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson // sizeof(T')*8 <= n. 12750aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 12764cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson QualType IntegralPODTypes[] = { 12770aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar Context.UnsignedCharTy, Context.UnsignedShortTy, Context.UnsignedIntTy, 12784cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson Context.UnsignedLongTy, Context.UnsignedLongLongTy 12794cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson }; 12804cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 12814cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson QualType Type; 12824cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson for (unsigned I = 0, E = llvm::array_lengthof(IntegralPODTypes); 12834cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson I != E; ++I) { 12844cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson uint64_t Size = Context.getTypeSize(IntegralPODTypes[I]); 12854cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 12864cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson if (Size > FieldSize) 12874cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson break; 12884cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 12894cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson Type = IntegralPODTypes[I]; 12904cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson } 12914cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson assert(!Type.isNull() && "Did not find a type!"); 12920aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 12934cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson unsigned TypeAlign = Context.getTypeAlign(Type); 12944cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 12954cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson // We're not going to use any of the unfilled bits in the last byte. 12964cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson UnfilledBitsInLastByte = 0; 12974cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 1298de9f153b2348f590151504888c22cb937134cd27Anders Carlsson uint64_t FieldOffset; 129978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis uint64_t UnpaddedFieldOffset = DataSize - UnfilledBitsInLastByte; 13000aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 13014cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson if (IsUnion) { 13024cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson DataSize = std::max(DataSize, FieldSize); 1303de9f153b2348f590151504888c22cb937134cd27Anders Carlsson FieldOffset = 0; 13044cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson } else { 1305de9f153b2348f590151504888c22cb937134cd27Anders Carlsson // The bitfield is allocated starting at the next offset aligned appropriately 13060aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar // for T', with length n bits. 1307de9f153b2348f590151504888c22cb937134cd27Anders Carlsson FieldOffset = llvm::RoundUpToAlignment(DataSize, TypeAlign); 13080aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 13094cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson uint64_t NewSizeInBits = FieldOffset + FieldSize; 13100aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 13114cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson DataSize = llvm::RoundUpToAlignment(NewSizeInBits, 8); 13124cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson UnfilledBitsInLastByte = DataSize - NewSizeInBits; 13134cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson } 13144cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 13154cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson // Place this field at the current location. 13164cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson FieldOffsets.push_back(FieldOffset); 13174cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 131878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis CheckFieldPadding(FieldOffset, UnpaddedFieldOffset, FieldOffset, 131978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis TypeAlign, FieldPacked, D); 132078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 13214cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson // Update the size. 13224cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson Size = std::max(Size, DataSize); 13230aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 13244cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson // Remember max struct/class alignment. 13254cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson UpdateAlignment(TypeAlign); 13264cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson} 13274cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 13287d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonvoid RecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { 132942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson bool FieldPacked = Packed || D->hasAttr<PackedAttr>(); 133078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis uint64_t UnpaddedFieldOffset = DataSize - UnfilledBitsInLastByte; 133178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis uint64_t FieldOffset = IsUnion ? 0 : UnpaddedFieldOffset; 13320f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson uint64_t FieldSize = D->getBitWidth()->EvaluateAsInt(Context).getZExtValue(); 1333bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 13340f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson std::pair<uint64_t, unsigned> FieldInfo = Context.getTypeInfo(D->getType()); 133542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson uint64_t TypeSize = FieldInfo.first; 133642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson unsigned FieldAlign = FieldInfo.second; 1337bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 13384cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson if (FieldSize > TypeSize) { 133978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis LayoutWideBitField(FieldSize, TypeSize, FieldPacked, D); 13404cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson return; 13414cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson } 13424cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 134378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // The align if the field is not packed. This is to check if the attribute 134478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // was unnecessary (-Wpacked). 134578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis unsigned UnpackedFieldAlign = FieldAlign; 134678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis uint64_t UnpackedFieldOffset = FieldOffset; 134778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (!Context.Target.useBitFieldTypeAlignment()) 134878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UnpackedFieldAlign = 1; 134978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 13500f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson if (FieldPacked || !Context.Target.useBitFieldTypeAlignment()) 135142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldAlign = 1; 1352cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt FieldAlign = std::max(FieldAlign, D->getMaxAlignment()); 135378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UnpackedFieldAlign = std::max(UnpackedFieldAlign, D->getMaxAlignment()); 13541eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 135542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // The maximum field alignment overrides the aligned attribute. 135678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (MaxFieldAlignment) { 135742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldAlign = std::min(FieldAlign, MaxFieldAlignment); 135878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UnpackedFieldAlign = std::min(UnpackedFieldAlign, MaxFieldAlignment); 135978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 1360bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1361b6a169395c1b30c76daffebcbd2164b6247a5d21Daniel Dunbar // Check if we need to add padding to give the field the correct alignment. 136242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (FieldSize == 0 || (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize) 136384b0316f720bd089d87acb21ec0002b2da33e6c9Daniel Dunbar FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign); 1364bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 136578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (FieldSize == 0 || 136678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis (UnpackedFieldOffset & (UnpackedFieldAlign-1)) + FieldSize > TypeSize) 136778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UnpackedFieldOffset = llvm::RoundUpToAlignment(UnpackedFieldOffset, 136878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UnpackedFieldAlign); 136978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 1370b6a169395c1b30c76daffebcbd2164b6247a5d21Daniel Dunbar // Padding members don't affect overall alignment. 137142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (!D->getIdentifier()) 137278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis FieldAlign = UnpackedFieldAlign = 1; 1373bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 137442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // Place this field at the current location. 137542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldOffsets.push_back(FieldOffset); 1376bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 137778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis CheckFieldPadding(FieldOffset, UnpaddedFieldOffset, UnpackedFieldOffset, 137878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UnpackedFieldAlign, FieldPacked, D); 137978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 1380e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson // Update DataSize to include the last byte containing (part of) the bitfield. 1381e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson if (IsUnion) { 1382e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson // FIXME: I think FieldSize should be TypeSize here. 1383e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson DataSize = std::max(DataSize, FieldSize); 1384e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson } else { 1385e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson uint64_t NewSizeInBits = FieldOffset + FieldSize; 1386bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1387e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson DataSize = llvm::RoundUpToAlignment(NewSizeInBits, 8); 1388e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson UnfilledBitsInLastByte = DataSize - NewSizeInBits; 1389e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson } 1390bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1391e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson // Update the size. 1392e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson Size = std::max(Size, DataSize); 1393bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 139442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // Remember max struct/class alignment. 139578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UpdateAlignment(FieldAlign, UnpackedFieldAlign); 139642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson} 13971eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 13987d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonvoid RecordLayoutBuilder::LayoutField(const FieldDecl *D) { 139942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (D->isBitField()) { 140042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson LayoutBitField(D); 140142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson return; 140242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson } 14031eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 140478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis uint64_t UnpaddedFieldOffset = DataSize - UnfilledBitsInLastByte; 140578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 1406e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson // Reset the unfilled bits. 1407e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson UnfilledBitsInLastByte = 0; 1408e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson 140942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson bool FieldPacked = Packed || D->hasAttr<PackedAttr>(); 141042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson uint64_t FieldOffset = IsUnion ? 0 : DataSize; 141142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson uint64_t FieldSize; 141242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson unsigned FieldAlign; 1413bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 141442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (D->getType()->isIncompleteArrayType()) { 141542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // This is a flexible array member; we can't directly 141642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // query getTypeInfo about these, so we figure it out here. 141742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // Flexible array members don't have any size, but they 141842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // have to be aligned appropriately for their element type. 141942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldSize = 0; 14200f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson const ArrayType* ATy = Context.getAsArrayType(D->getType()); 14210f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson FieldAlign = Context.getTypeAlign(ATy->getElementType()); 142242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson } else if (const ReferenceType *RT = D->getType()->getAs<ReferenceType>()) { 142342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson unsigned AS = RT->getPointeeType().getAddressSpace(); 14240f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson FieldSize = Context.Target.getPointerWidth(AS); 14250f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson FieldAlign = Context.Target.getPointerAlign(AS); 142642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson } else { 14270f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson std::pair<uint64_t, unsigned> FieldInfo = Context.getTypeInfo(D->getType()); 142842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldSize = FieldInfo.first; 1429bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson FieldAlign = FieldInfo.second; 143042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson } 14311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 143278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // The align if the field is not packed. This is to check if the attribute 143378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // was unnecessary (-Wpacked). 143478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis unsigned UnpackedFieldAlign = FieldAlign; 143578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis uint64_t UnpackedFieldOffset = FieldOffset; 143678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 143742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (FieldPacked) 143842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldAlign = 8; 1439cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt FieldAlign = std::max(FieldAlign, D->getMaxAlignment()); 144078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UnpackedFieldAlign = std::max(UnpackedFieldAlign, D->getMaxAlignment()); 14411eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 144242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // The maximum field alignment overrides the aligned attribute. 144378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (MaxFieldAlignment) { 144442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldAlign = std::min(FieldAlign, MaxFieldAlignment); 144578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UnpackedFieldAlign = std::min(UnpackedFieldAlign, MaxFieldAlignment); 144678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 14471eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 144842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // Round up the current record size to the field's alignment boundary. 144942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign); 145078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UnpackedFieldOffset = llvm::RoundUpToAlignment(UnpackedFieldOffset, 145178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UnpackedFieldAlign); 1452bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 145383a45e7dab892e9efd3515eca4eb5b81bc3f2126Anders Carlsson if (!IsUnion && EmptySubobjects) { 145483a45e7dab892e9efd3515eca4eb5b81bc3f2126Anders Carlsson // Check if we can place the field at this offset. 145583a45e7dab892e9efd3515eca4eb5b81bc3f2126Anders Carlsson while (!EmptySubobjects->CanPlaceFieldAtOffset(D, FieldOffset)) { 145642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // We couldn't place the field at the offset. Try again at a new offset. 145742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldOffset += FieldAlign; 14586026504302763f74102592602b392cecd5ced3aeAnders Carlsson } 1459bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson } 1460bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1461bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // Place this field at the current location. 1462bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson FieldOffsets.push_back(FieldOffset); 14631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 146478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis CheckFieldPadding(FieldOffset, UnpaddedFieldOffset, UnpackedFieldOffset, 146578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UnpackedFieldAlign, FieldPacked, D); 146678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 1467bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // Reserve space for this field. 1468bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson if (IsUnion) 1469bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson Size = std::max(Size, FieldSize); 1470bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson else 1471bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson Size = FieldOffset + FieldSize; 14721eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1473a223935e5cf82e939e1ca1da4111d63025a04e39Anders Carlsson // Update the data size. 1474a223935e5cf82e939e1ca1da4111d63025a04e39Anders Carlsson DataSize = Size; 14751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1476bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // Remember max struct/class alignment. 147778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UpdateAlignment(FieldAlign, UnpackedFieldAlign); 1478bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson} 1479bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 148078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidisvoid RecordLayoutBuilder::FinishLayout(const NamedDecl *D) { 1481bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // In C++, records cannot be of size 0. 14820f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson if (Context.getLangOptions().CPlusPlus && Size == 0) 1483bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson Size = 8; 1484bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // Finally, round the size of the record up to the alignment of the 1485bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // record itself. 148678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis uint64_t UnpaddedSize = Size - UnfilledBitsInLastByte; 148778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis uint64_t UnpackedSize = llvm::RoundUpToAlignment(Size, UnpackedAlignment); 148842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson Size = llvm::RoundUpToAlignment(Size, Alignment); 148978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 149078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis unsigned CharBitNum = Context.Target.getCharWidth(); 149178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (const RecordDecl *RD = dyn_cast<RecordDecl>(D)) { 149278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // Warn if padding was introduced to the struct/class/union. 149378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (Size > UnpaddedSize) { 149478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis unsigned PadSize = Size - UnpaddedSize; 149578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis bool InBits = true; 149678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (PadSize % CharBitNum == 0) { 149778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis PadSize = PadSize / CharBitNum; 149878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis InBits = false; 149978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 150078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis Diag(RD->getLocation(), diag::warn_padded_struct_size) 150178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << Context.getTypeDeclType(RD) 150278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << PadSize 150378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << (InBits ? 1 : 0) /*(byte|bit)*/ << (PadSize > 1); // plural or not 150478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 150578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 150678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // Warn if we packed it unnecessarily. If the alignment is 1 byte don't 150778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // bother since there won't be alignment issues. 150878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (Packed && UnpackedAlignment > CharBitNum && Size == UnpackedSize) 150978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis Diag(D->getLocation(), diag::warn_unnecessary_packed) 151078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << Context.getTypeDeclType(RD); 151178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 1512bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson} 1513bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 151478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidisvoid RecordLayoutBuilder::UpdateAlignment(unsigned NewAlignment, 151578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis unsigned UnpackedNewAlignment) { 1516c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar // The alignment is not modified when using 'mac68k' alignment. 1517c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar if (IsMac68kAlign) 1518c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar return; 1519c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar 152078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (NewAlignment > Alignment) { 152178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis assert(llvm::isPowerOf2_32(NewAlignment && "Alignment not a power of 2")); 152278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis Alignment = NewAlignment; 152378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 152478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 152578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (UnpackedNewAlignment > UnpackedAlignment) { 152678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis assert(llvm::isPowerOf2_32(UnpackedNewAlignment && 152778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis "Alignment not a power of 2")); 152878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UnpackedAlignment = UnpackedNewAlignment; 152978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 153078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis} 153178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 153278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidisvoid RecordLayoutBuilder::CheckFieldPadding(uint64_t Offset, 153378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis uint64_t UnpaddedOffset, 153478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis uint64_t UnpackedOffset, 153578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis unsigned UnpackedAlign, 153678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis bool isPacked, 153778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis const FieldDecl *D) { 153878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // We let objc ivars without warning, objc interfaces generally are not used 153978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // for padding tricks. 154078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (isa<ObjCIvarDecl>(D)) 1541bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson return; 15421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 154378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis unsigned CharBitNum = Context.Target.getCharWidth(); 15441eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 154578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // Warn if padding was introduced to the struct/class. 154678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (!IsUnion && Offset > UnpaddedOffset) { 154778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis unsigned PadSize = Offset - UnpaddedOffset; 154878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis bool InBits = true; 154978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (PadSize % CharBitNum == 0) { 155078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis PadSize = PadSize / CharBitNum; 155178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis InBits = false; 155278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 155378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (D->getIdentifier()) 155478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis Diag(D->getLocation(), diag::warn_padded_struct_field) 155578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << (D->getParent()->isStruct() ? 0 : 1) // struct|class 155678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << Context.getTypeDeclType(D->getParent()) 155778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << PadSize 155878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << (InBits ? 1 : 0) /*(byte|bit)*/ << (PadSize > 1) // plural or not 155978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << D->getIdentifier(); 156078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis else 156178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis Diag(D->getLocation(), diag::warn_padded_struct_anon_field) 156278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << (D->getParent()->isStruct() ? 0 : 1) // struct|class 156378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << Context.getTypeDeclType(D->getParent()) 156478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << PadSize 156578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << (InBits ? 1 : 0) /*(byte|bit)*/ << (PadSize > 1); // plural or not 156678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 156778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 156878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // Warn if we packed it unnecessarily. If the alignment is 1 byte don't 156978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // bother since there won't be alignment issues. 157078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (isPacked && UnpackedAlign > CharBitNum && Offset == UnpackedOffset) 157178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis Diag(D->getLocation(), diag::warn_unnecessary_packed) 157278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << D->getIdentifier(); 1573bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson} 15741eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1575f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlssonconst CXXMethodDecl * 15767d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders CarlssonRecordLayoutBuilder::ComputeKeyFunction(const CXXRecordDecl *RD) { 15778d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar // If a class isn't polymorphic it doesn't have a key function. 1578f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (!RD->isPolymorphic()) 1579f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson return 0; 158061eab8872168af6eb1e0047a82901096cf145e27Eli Friedman 158161eab8872168af6eb1e0047a82901096cf145e27Eli Friedman // A class inside an anonymous namespace doesn't have a key function. (Or 158261eab8872168af6eb1e0047a82901096cf145e27Eli Friedman // at least, there's no point to assigning a key function to such a class; 158361eab8872168af6eb1e0047a82901096cf145e27Eli Friedman // this doesn't affect the ABI.) 158461eab8872168af6eb1e0047a82901096cf145e27Eli Friedman if (RD->isInAnonymousNamespace()) 158561eab8872168af6eb1e0047a82901096cf145e27Eli Friedman return 0; 158661eab8872168af6eb1e0047a82901096cf145e27Eli Friedman 15873bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis // Template instantiations don't have key functions,see Itanium C++ ABI 5.2.6. 15883bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis // Same behavior as GCC. 15893bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis TemplateSpecializationKind TSK = RD->getTemplateSpecializationKind(); 15903bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis if (TSK == TSK_ImplicitInstantiation || 15913bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis TSK == TSK_ExplicitInstantiationDefinition) 15923bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis return 0; 15933bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis 1594bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar for (CXXRecordDecl::method_iterator I = RD->method_begin(), 1595bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->method_end(); I != E; ++I) { 1596f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson const CXXMethodDecl *MD = *I; 1597bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1598f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (!MD->isVirtual()) 1599f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson continue; 1600bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1601f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (MD->isPure()) 1602f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson continue; 160361eab8872168af6eb1e0047a82901096cf145e27Eli Friedman 1604f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson // Ignore implicit member functions, they are always marked as inline, but 1605f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson // they don't have a body until they're defined. 1606f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (MD->isImplicit()) 1607f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson continue; 1608bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1609bd6d6197fcfc98356ea60e816365eb0648b69556Douglas Gregor if (MD->isInlineSpecified()) 1610bd6d6197fcfc98356ea60e816365eb0648b69556Douglas Gregor continue; 1611f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson 1612f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (MD->hasInlineBody()) 1613f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson continue; 1614bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1615f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson // We found it. 1616f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson return MD; 1617f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson } 1618bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1619f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson return 0; 1620f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson} 1621f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson 162278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios KyrtzidisDiagnosticBuilder 162378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios KyrtzidisRecordLayoutBuilder::Diag(SourceLocation Loc, unsigned DiagID) { 162478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis return Context.getDiagnostics().Report( 162578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis FullSourceLoc(Loc, Context.getSourceManager()), DiagID); 162678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis} 162778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 1628cb9c07418b699bd2b8384d31ff4392df7d76eb7cBenjamin Kramernamespace { 1629cb9c07418b699bd2b8384d31ff4392df7d76eb7cBenjamin Kramer // This class implements layout specific to the Microsoft ABI. 1630cb9c07418b699bd2b8384d31ff4392df7d76eb7cBenjamin Kramer class MSRecordLayoutBuilder : public RecordLayoutBuilder { 1631cb9c07418b699bd2b8384d31ff4392df7d76eb7cBenjamin Kramer public: 1632cb9c07418b699bd2b8384d31ff4392df7d76eb7cBenjamin Kramer MSRecordLayoutBuilder(ASTContext& Ctx, EmptySubobjectMap *EmptySubobjects) : 1633cb9c07418b699bd2b8384d31ff4392df7d76eb7cBenjamin Kramer RecordLayoutBuilder(Ctx, EmptySubobjects) {} 1634cb9c07418b699bd2b8384d31ff4392df7d76eb7cBenjamin Kramer 1635cb9c07418b699bd2b8384d31ff4392df7d76eb7cBenjamin Kramer virtual bool IsNearlyEmpty(const CXXRecordDecl *RD) const; 1636cb9c07418b699bd2b8384d31ff4392df7d76eb7cBenjamin Kramer virtual uint64_t GetVirtualPointersSize(const CXXRecordDecl *RD) const; 1637cb9c07418b699bd2b8384d31ff4392df7d76eb7cBenjamin Kramer }; 1638cb9c07418b699bd2b8384d31ff4392df7d76eb7cBenjamin Kramer} 1639c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis 1640c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davisbool MSRecordLayoutBuilder::IsNearlyEmpty(const CXXRecordDecl *RD) const { 1641c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis // FIXME: Audit the corners 1642c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis if (!RD->isDynamicClass()) 1643c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis return false; 1644c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis const ASTRecordLayout &BaseInfo = Context.getASTRecordLayout(RD); 1645c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis // In the Microsoft ABI, classes can have one or two vtable pointers. 1646c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis if (BaseInfo.getNonVirtualSize() == Context.Target.getPointerWidth(0) || 1647c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis BaseInfo.getNonVirtualSize() == Context.Target.getPointerWidth(0) * 2) 1648c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis return true; 1649c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis return false; 1650c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis} 1651c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis 1652c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davisuint64_t 1653c9f8aece7e111f90265dfad9a81f3f517be948deCharles DavisMSRecordLayoutBuilder::GetVirtualPointersSize(const CXXRecordDecl *RD) const { 1654c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis // We should reserve space for two pointers if the class has both 1655c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis // virtual functions and virtual bases. 1656c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis if (RD->isPolymorphic() && RD->getNumVBases() > 0) 1657c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis return 2 * Context.Target.getPointerWidth(0); 1658c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis return Context.Target.getPointerWidth(0); 1659c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis} 1660c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis 16611e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// getASTRecordLayout - Get or compute information about the layout of the 16621e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// specified record (struct/union/class), which indicates its size and field 16631e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// position information. 16641e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlssonconst ASTRecordLayout &ASTContext::getASTRecordLayout(const RecordDecl *D) { 16651e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson D = D->getDefinition(); 16661e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson assert(D && "Cannot get layout of forward declarations!"); 16671e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 16681e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // Look up this layout, if already laid out, return what we have. 16691e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // Note that we can't save a reference to the entry because this function 16701e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // is recursive. 16711e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson const ASTRecordLayout *Entry = ASTRecordLayouts[D]; 16721e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson if (Entry) return *Entry; 16731e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 16742f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson const ASTRecordLayout *NewEntry; 16752f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson 16762f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) { 1677261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson EmptySubobjectMap EmptySubobjects(*this, RD); 167858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 1679c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis // When compiling for Microsoft, use the special MS builder. 1680cfe17e5c82762cc854012e472b66f4278f0a4a2aArgyrios Kyrtzidis llvm::OwningPtr<RecordLayoutBuilder> Builder; 168120cf717034ba1f20fc47c025ecb72ed9b631ad13Charles Davis switch (Target.getCXXABI()) { 168220cf717034ba1f20fc47c025ecb72ed9b631ad13Charles Davis default: 1683cfe17e5c82762cc854012e472b66f4278f0a4a2aArgyrios Kyrtzidis Builder.reset(new RecordLayoutBuilder(*this, &EmptySubobjects)); 168420cf717034ba1f20fc47c025ecb72ed9b631ad13Charles Davis break; 168520cf717034ba1f20fc47c025ecb72ed9b631ad13Charles Davis case CXXABI_Microsoft: 1686cfe17e5c82762cc854012e472b66f4278f0a4a2aArgyrios Kyrtzidis Builder.reset(new MSRecordLayoutBuilder(*this, &EmptySubobjects)); 168720cf717034ba1f20fc47c025ecb72ed9b631ad13Charles Davis } 1688c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis Builder->Layout(RD); 16892f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson 16902f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson // FIXME: This is not always correct. See the part about bitfields at 16912f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson // http://www.codesourcery.com/public/cxx-abi/abi.html#POD for more info. 16922f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson // FIXME: IsPODForThePurposeOfLayout should be stored in the record layout. 16932f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson bool IsPODForThePurposeOfLayout = cast<CXXRecordDecl>(D)->isPOD(); 16942f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson 16952f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson // FIXME: This should be done in FinalizeLayout. 16962f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson uint64_t DataSize = 1697c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis IsPODForThePurposeOfLayout ? Builder->Size : Builder->DataSize; 16982f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson uint64_t NonVirtualSize = 1699c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis IsPODForThePurposeOfLayout ? DataSize : Builder->NonVirtualSize; 17002f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson 17010aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar NewEntry = 1702c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis new (*this) ASTRecordLayout(*this, Builder->Size, Builder->Alignment, 1703c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis DataSize, Builder->FieldOffsets.data(), 1704c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis Builder->FieldOffsets.size(), 17052f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson NonVirtualSize, 1706c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis Builder->NonVirtualAlignment, 1707261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson EmptySubobjects.SizeOfLargestEmptySubobject, 1708c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis Builder->PrimaryBase, 1709c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis Builder->PrimaryBaseIsVirtual, 1710c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis Builder->Bases, Builder->VBases); 17112f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson } else { 1712261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0); 17132f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson Builder.Layout(D); 17140aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 17152f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson NewEntry = 17162f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson new (*this) ASTRecordLayout(*this, Builder.Size, Builder.Alignment, 17172f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson Builder.Size, 17182f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson Builder.FieldOffsets.data(), 17192f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson Builder.FieldOffsets.size()); 17202f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson } 17212f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson 17221e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson ASTRecordLayouts[D] = NewEntry; 17231e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 17241e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson if (getLangOptions().DumpRecordLayouts) { 17251e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson llvm::errs() << "\n*** Dumping AST Record Layout\n"; 17261e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson DumpRecordLayout(D, llvm::errs()); 17271e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson } 17281e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 17291e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson return *NewEntry; 17301e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson} 17311e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 17321e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlssonconst CXXMethodDecl *ASTContext::getKeyFunction(const CXXRecordDecl *RD) { 17331e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson RD = cast<CXXRecordDecl>(RD->getDefinition()); 17341e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson assert(RD && "Cannot get key function for forward declarations!"); 17350aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 17361e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson const CXXMethodDecl *&Entry = KeyFunctions[RD]; 17370aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar if (!Entry) 17387d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlsson Entry = RecordLayoutBuilder::ComputeKeyFunction(RD); 17390aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 17401e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson return Entry; 17411e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson} 17421e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 17431e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// getInterfaceLayoutImpl - Get or compute information about the 17441e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// layout of the given interface. 17451e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// 17461e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// \param Impl - If given, also include the layout of the interface's 17471e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// implementation. This may differ by including synthesized ivars. 17481e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlssonconst ASTRecordLayout & 17491e641ce1c169b4b0cac3d7ad6da44b323453049cAnders CarlssonASTContext::getObjCLayout(const ObjCInterfaceDecl *D, 17501e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson const ObjCImplementationDecl *Impl) { 17511e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson assert(!D->isForwardDecl() && "Invalid interface decl!"); 17521e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 17531e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // Look up this layout, if already laid out, return what we have. 17541e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson ObjCContainerDecl *Key = 17551e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson Impl ? (ObjCContainerDecl*) Impl : (ObjCContainerDecl*) D; 17561e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson if (const ASTRecordLayout *Entry = ObjCLayouts[Key]) 17571e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson return *Entry; 17581e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 17591e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // Add in synthesized ivar count if laying out an implementation. 17601e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson if (Impl) { 17611e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson unsigned SynthCount = CountNonClassIvars(D); 17621e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // If there aren't any sythesized ivars then reuse the interface 17631e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // entry. Note we can't cache this because we simply free all 17641e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // entries later; however we shouldn't look up implementations 17651e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // frequently. 17661e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson if (SynthCount == 0) 17671e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson return getObjCLayout(D, 0); 17681e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson } 17691e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 1770261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0); 177136cdc61b98460c06ee07710f77b911675fdce6a7Anders Carlsson Builder.Layout(D); 177236cdc61b98460c06ee07710f77b911675fdce6a7Anders Carlsson 17731e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson const ASTRecordLayout *NewEntry = 177436cdc61b98460c06ee07710f77b911675fdce6a7Anders Carlsson new (*this) ASTRecordLayout(*this, Builder.Size, Builder.Alignment, 177536cdc61b98460c06ee07710f77b911675fdce6a7Anders Carlsson Builder.DataSize, 177636cdc61b98460c06ee07710f77b911675fdce6a7Anders Carlsson Builder.FieldOffsets.data(), 177736cdc61b98460c06ee07710f77b911675fdce6a7Anders Carlsson Builder.FieldOffsets.size()); 17780aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 17791e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson ObjCLayouts[Key] = NewEntry; 17801e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 17811e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson return *NewEntry; 17821e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson} 17831e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 1784bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbarstatic void PrintOffset(llvm::raw_ostream &OS, 1785bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar uint64_t Offset, unsigned IndentLevel) { 1786bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << llvm::format("%4d | ", Offset); 1787bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS.indent(IndentLevel * 2); 1788bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar} 1789bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1790bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbarstatic void DumpCXXRecordLayout(llvm::raw_ostream &OS, 1791bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar const CXXRecordDecl *RD, ASTContext &C, 1792bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar uint64_t Offset, 1793bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar unsigned IndentLevel, 1794bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar const char* Description, 1795bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar bool IncludeVirtualBases) { 1796bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar const ASTRecordLayout &Info = C.getASTRecordLayout(RD); 1797bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1798bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar PrintOffset(OS, Offset, IndentLevel); 1799cb421fa690da545b58a720abe5f1c49b166dbde7Dan Gohman OS << C.getTypeDeclType(const_cast<CXXRecordDecl *>(RD)).getAsString(); 1800bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (Description) 1801bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << ' ' << Description; 1802bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (RD->isEmpty()) 1803bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << " (empty)"; 1804bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << '\n'; 1805bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1806bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar IndentLevel++; 1807bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1808bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar const CXXRecordDecl *PrimaryBase = Info.getPrimaryBase(); 1809bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1810bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar // Vtable pointer. 1811bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (RD->isDynamicClass() && !PrimaryBase) { 1812bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar PrintOffset(OS, Offset, IndentLevel); 1813900fc6388e803868a34b9483510c345e9b49d7ebBenjamin Kramer OS << '(' << RD << " vtable pointer)\n"; 1814bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar } 1815bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar // Dump (non-virtual) bases 1816bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1817bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->bases_end(); I != E; ++I) { 1818bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar assert(!I->getType()->isDependentType() && 1819bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar "Cannot layout class with dependent bases."); 1820bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (I->isVirtual()) 1821bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar continue; 1822bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1823bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar const CXXRecordDecl *Base = 1824bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1825bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1826bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar uint64_t BaseOffset = Offset + Info.getBaseClassOffset(Base) / 8; 1827bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1828bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar DumpCXXRecordLayout(OS, Base, C, BaseOffset, IndentLevel, 1829bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar Base == PrimaryBase ? "(primary base)" : "(base)", 1830bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar /*IncludeVirtualBases=*/false); 1831bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar } 1832bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1833bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar // Dump fields. 1834bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar uint64_t FieldNo = 0; 1835bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar for (CXXRecordDecl::field_iterator I = RD->field_begin(), 1836bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->field_end(); I != E; ++I, ++FieldNo) { 1837bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar const FieldDecl *Field = *I; 1838bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar uint64_t FieldOffset = Offset + Info.getFieldOffset(FieldNo) / 8; 1839bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1840bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (const RecordType *RT = Field->getType()->getAs<RecordType>()) { 1841bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (const CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(RT->getDecl())) { 1842bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar DumpCXXRecordLayout(OS, D, C, FieldOffset, IndentLevel, 18434087f27e5416c799bcb6be072f905be752acb61cDaniel Dunbar Field->getName().data(), 1844bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar /*IncludeVirtualBases=*/true); 1845bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar continue; 1846bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar } 1847bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar } 1848bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1849bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar PrintOffset(OS, FieldOffset, IndentLevel); 1850900fc6388e803868a34b9483510c345e9b49d7ebBenjamin Kramer OS << Field->getType().getAsString() << ' ' << Field << '\n'; 1851bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar } 1852bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1853bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (!IncludeVirtualBases) 1854bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar return; 1855bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1856bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar // Dump virtual bases. 1857bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(), 1858bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->vbases_end(); I != E; ++I) { 1859bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar assert(I->isVirtual() && "Found non-virtual class!"); 1860bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar const CXXRecordDecl *VBase = 1861bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1862bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1863bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar uint64_t VBaseOffset = Offset + Info.getVBaseClassOffset(VBase) / 8; 1864bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar DumpCXXRecordLayout(OS, VBase, C, VBaseOffset, IndentLevel, 1865bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar VBase == PrimaryBase ? 1866bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar "(primary virtual base)" : "(virtual base)", 1867bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar /*IncludeVirtualBases=*/false); 1868bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar } 1869bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1870bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << " sizeof=" << Info.getSize() / 8; 1871bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << ", dsize=" << Info.getDataSize() / 8; 1872bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << ", align=" << Info.getAlignment() / 8 << '\n'; 1873bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << " nvsize=" << Info.getNonVirtualSize() / 8; 1874bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << ", nvalign=" << Info.getNonVirtualAlign() / 8 << '\n'; 1875bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << '\n'; 1876bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar} 18778d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar 18788d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbarvoid ASTContext::DumpRecordLayout(const RecordDecl *RD, 18798d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar llvm::raw_ostream &OS) { 18808d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar const ASTRecordLayout &Info = getASTRecordLayout(RD); 18818d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar 18828d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) 18838d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar return DumpCXXRecordLayout(OS, CXXRD, *this, 0, 0, 0, 18848d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar /*IncludeVirtualBases=*/true); 18858d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar 18868d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << "Type: " << getTypeDeclType(RD).getAsString() << "\n"; 18878d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << "Record: "; 18888d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar RD->dump(); 18898d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << "\nLayout: "; 18908d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << "<ASTRecordLayout\n"; 18918d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << " Size:" << Info.getSize() << "\n"; 18928d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << " DataSize:" << Info.getDataSize() << "\n"; 18938d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << " Alignment:" << Info.getAlignment() << "\n"; 18948d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << " FieldOffsets: ["; 18958d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar for (unsigned i = 0, e = Info.getFieldCount(); i != e; ++i) { 18968d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar if (i) OS << ", "; 18978d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << Info.getFieldOffset(i); 18988d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar } 18998d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << "]>\n"; 19008d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar} 1901