RecordLayoutBuilder.cpp revision ed63e03e35f2c8ad1a06d7bbc2249d132a730175
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" 11245656ec65ec600ef1ab05f4c8d9f780542d689dAnders Carlsson#include "clang/AST/CXXInheritance.h" 12bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson#include "clang/AST/Decl.h" 1374cbe226207fd101623638dadfa7fbada04ff2a6Anders Carlsson#include "clang/AST/DeclCXX.h" 1493fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson#include "clang/AST/DeclObjC.h" 15bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson#include "clang/AST/Expr.h" 169392fa63e45716e32061d05673fa28909f325b02Anders Carlsson#include "clang/AST/RecordLayout.h" 17bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson#include "clang/Basic/TargetInfo.h" 1878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis#include "clang/Sema/SemaDiagnostic.h" 19bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar#include "llvm/Support/Format.h" 20bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar#include "llvm/ADT/SmallSet.h" 21bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar#include "llvm/Support/MathExtras.h" 224d96d9f0e758fb9244749f99d4b0a3ab1e3e0592Ted Kremenek#include "llvm/Support/CrashRecoveryContext.h" 23bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 24bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlssonusing namespace clang; 25bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 267e220286410422ed1dc0409a9cb9708fe50e3df0Benjamin Kramernamespace { 276a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson 28ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// BaseSubobjectInfo - Represents a single base subobject in a complete class. 29ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// For a class hierarchy like 30ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// 31ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// class A { }; 32ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// class B : A { }; 33ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// class C : A, B { }; 34ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// 35ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// The BaseSubobjectInfo graph for C will have three BaseSubobjectInfo 36ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// instances, one for B and two for A. 37ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// 38ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// If a base is virtual, it will only have one BaseSubobjectInfo allocated. 39ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlssonstruct BaseSubobjectInfo { 40ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson /// Class - The class for this base info. 414a25799760982b3363f3c4eb6df953d70e35e37dAnders Carlsson const CXXRecordDecl *Class; 42ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson 43ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson /// IsVirtual - Whether the BaseInfo represents a virtual base or not. 444a25799760982b3363f3c4eb6df953d70e35e37dAnders Carlsson bool IsVirtual; 454a25799760982b3363f3c4eb6df953d70e35e37dAnders Carlsson 46ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson /// Bases - Information about the base subobjects. 47ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson llvm::SmallVector<BaseSubobjectInfo*, 4> Bases; 48ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson 496e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// PrimaryVirtualBaseInfo - Holds the base info for the primary virtual base 506e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// of this base info (if one exists). 516e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *PrimaryVirtualBaseInfo; 52ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson 53ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson // FIXME: Document. 54ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson const BaseSubobjectInfo *Derived; 554a25799760982b3363f3c4eb6df953d70e35e37dAnders Carlsson}; 564a25799760982b3363f3c4eb6df953d70e35e37dAnders Carlsson 576a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson/// EmptySubobjectMap - Keeps track of which empty subobjects exist at different 586a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson/// offsets while laying out a C++ class. 596a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlssonclass EmptySubobjectMap { 604ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad const ASTContext &Context; 618c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson uint64_t CharWidth; 628c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson 636a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson /// Class - The class whose empty entries we're keeping track of. 646a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson const CXXRecordDecl *Class; 650aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 6658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson /// EmptyClassOffsets - A map from offsets to empty record decls. 6758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson typedef llvm::SmallVector<const CXXRecordDecl *, 1> ClassVectorTy; 68d8da76365f40a0c12c7d802a0da2aaacf4b2cf99Anders Carlsson typedef llvm::DenseMap<CharUnits, ClassVectorTy> EmptyClassOffsetsMapTy; 6958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson EmptyClassOffsetsMapTy EmptyClassOffsets; 7058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 71c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson /// MaxEmptyClassOffset - The highest offset known to contain an empty 72c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson /// base subobject. 73fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson CharUnits MaxEmptyClassOffset; 74c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson 750aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// ComputeEmptySubobjectSizes - Compute the size of the largest base or 760c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson /// member subobject that is empty. 770c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson void ComputeEmptySubobjectSizes(); 7858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 79fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson void AddSubobjectAtOffset(const CXXRecordDecl *RD, CharUnits Offset); 80812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 81ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson void UpdateEmptyBaseSubobjects(const BaseSubobjectInfo *Info, 82a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits Offset, bool PlacingEmptyBase); 8358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 84812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson void UpdateEmptyFieldSubobjects(const CXXRecordDecl *RD, 85812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *Class, 86a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits Offset); 87a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson void UpdateEmptyFieldSubobjects(const FieldDecl *FD, CharUnits Offset); 88812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 89c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson /// AnyEmptySubobjectsBeyondOffset - Returns whether there are any empty 90c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson /// subobjects beyond the given offset. 91fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson bool AnyEmptySubobjectsBeyondOffset(CharUnits Offset) const { 92c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson return Offset <= MaxEmptyClassOffset; 93c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson } 94c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson 958c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson CharUnits 968c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson getFieldOffset(const ASTRecordLayout &Layout, unsigned FieldNo) const { 978c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson uint64_t FieldOffset = Layout.getFieldOffset(FieldNo); 988c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson assert(FieldOffset % CharWidth == 0 && 998c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson "Field offset not at char boundary!"); 1008c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson 101ff3a5174d1f6e7dc98de348aecfdfe1d2fb7cd53Ken Dyck return Context.toCharUnitsFromBits(FieldOffset); 102d8da76365f40a0c12c7d802a0da2aaacf4b2cf99Anders Carlsson } 103d8da76365f40a0c12c7d802a0da2aaacf4b2cf99Anders Carlsson 104c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davisprotected: 105fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson bool CanPlaceSubobjectAtOffset(const CXXRecordDecl *RD, 106fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson CharUnits Offset) const; 107c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis 108c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis bool CanPlaceBaseSubobjectAtOffset(const BaseSubobjectInfo *Info, 109a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits Offset); 110c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis 111c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis bool CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD, 112c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis const CXXRecordDecl *Class, 113a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits Offset) const; 114c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis bool CanPlaceFieldSubobjectAtOffset(const FieldDecl *FD, 1158c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson CharUnits Offset) const; 116c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis 1176a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlssonpublic: 1180c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson /// This holds the size of the largest empty subobject (either a base 1190aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// or a member). Will be zero if the record being built doesn't contain 1200c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson /// any empty classes. 121a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits SizeOfLargestEmptySubobject; 1220aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1234ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad EmptySubobjectMap(const ASTContext &Context, const CXXRecordDecl *Class) 124a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson : Context(Context), CharWidth(Context.getCharWidth()), Class(Class) { 125261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson ComputeEmptySubobjectSizes(); 126261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson } 127261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson 128261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson /// CanPlaceBaseAtOffset - Return whether the given base class can be placed 129261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson /// at the given offset. 1300aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// Returns false if placing the record will result in two components 131261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson /// (direct or indirect) of the same type having the same offset. 132c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson bool CanPlaceBaseAtOffset(const BaseSubobjectInfo *Info, 133a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits Offset); 134812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 135812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson /// CanPlaceFieldAtOffset - Return whether a field can be placed at the given 136812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson /// offset. 137a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson bool CanPlaceFieldAtOffset(const FieldDecl *FD, CharUnits Offset); 1386a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson}; 1390c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson 1400c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlssonvoid EmptySubobjectMap::ComputeEmptySubobjectSizes() { 1410c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // Check the bases. 1420c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(), 1430c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson E = Class->bases_end(); I != E; ++I) { 1440c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson const CXXRecordDecl *BaseDecl = 1450c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1460c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson 147a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits EmptySize; 1480c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl); 1490c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson if (BaseDecl->isEmpty()) { 1500c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // If the class decl is empty, get its size. 1515f022d82696c84e4d127c558871d68ac6273274eKen Dyck EmptySize = Layout.getSize(); 1520c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson } else { 1530c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // Otherwise, we get the largest empty subobject for the decl. 1540c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson EmptySize = Layout.getSizeOfLargestEmptySubobject(); 1550c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson } 1560aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 157a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson if (EmptySize > SizeOfLargestEmptySubobject) 158a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson SizeOfLargestEmptySubobject = EmptySize; 1590c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson } 1600aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1610c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // Check the fields. 1620c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson for (CXXRecordDecl::field_iterator I = Class->field_begin(), 1630c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson E = Class->field_end(); I != E; ++I) { 1640c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson const FieldDecl *FD = *I; 1650aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1660aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar const RecordType *RT = 1670c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson Context.getBaseElementType(FD->getType())->getAs<RecordType>(); 1680aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1690c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // We only care about record types. 1700c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson if (!RT) 1710c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson continue; 1720c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson 173a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits EmptySize; 1740c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson const CXXRecordDecl *MemberDecl = cast<CXXRecordDecl>(RT->getDecl()); 1750c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(MemberDecl); 1760c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson if (MemberDecl->isEmpty()) { 1770c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // If the class decl is empty, get its size. 1785f022d82696c84e4d127c558871d68ac6273274eKen Dyck EmptySize = Layout.getSize(); 1790c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson } else { 1800c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // Otherwise, we get the largest empty subobject for the decl. 1810c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson EmptySize = Layout.getSizeOfLargestEmptySubobject(); 1820c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson } 1830aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 184a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson if (EmptySize > SizeOfLargestEmptySubobject) 185a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson SizeOfLargestEmptySubobject = EmptySize; 1860c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson } 1870c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson} 1880c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson 1890aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbarbool 190812a3456b63708a5972f712e9e4b54d3cc436378Anders CarlssonEmptySubobjectMap::CanPlaceSubobjectAtOffset(const CXXRecordDecl *RD, 191fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson CharUnits Offset) const { 192812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // We only need to check empty bases. 193812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!RD->isEmpty()) 194812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 195812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 196fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson EmptyClassOffsetsMapTy::const_iterator I = EmptyClassOffsets.find(Offset); 197812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (I == EmptyClassOffsets.end()) 198812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 199812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 200812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const ClassVectorTy& Classes = I->second; 201812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (std::find(Classes.begin(), Classes.end(), RD) == Classes.end()) 202812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 203812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 204812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // There is already an empty class of the same type at this offset. 205812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 206812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 207812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 208812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlssonvoid EmptySubobjectMap::AddSubobjectAtOffset(const CXXRecordDecl *RD, 209fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson CharUnits Offset) { 210812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // We only care about empty bases. 211812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!RD->isEmpty()) 212812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return; 213812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 214272324bc881450a71873d2f4e72f17837d8998dfRafael Espindola // If we have empty structures inside an union, we can assign both 215272324bc881450a71873d2f4e72f17837d8998dfRafael Espindola // the same offset. Just avoid pushing them twice in the list. 216fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson ClassVectorTy& Classes = EmptyClassOffsets[Offset]; 217272324bc881450a71873d2f4e72f17837d8998dfRafael Espindola if (std::find(Classes.begin(), Classes.end(), RD) != Classes.end()) 218272324bc881450a71873d2f4e72f17837d8998dfRafael Espindola return; 219272324bc881450a71873d2f4e72f17837d8998dfRafael Espindola 220812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson Classes.push_back(RD); 221c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson 222c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson // Update the empty class offset. 223fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson if (Offset > MaxEmptyClassOffset) 224fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson MaxEmptyClassOffset = Offset; 225812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 226812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 227812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlssonbool 228a3d4380d6662a373bc78f915947e5bc06e985e91Anders CarlssonEmptySubobjectMap::CanPlaceBaseSubobjectAtOffset(const BaseSubobjectInfo *Info, 229a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits Offset) { 2302177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson // We don't have to keep looking past the maximum offset that's known to 2312177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson // contain an empty class. 232a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson if (!AnyEmptySubobjectsBeyondOffset(Offset)) 2332177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson return true; 2342177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson 235a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson if (!CanPlaceSubobjectAtOffset(Info->Class, Offset)) 236812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 237812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 23858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson // Traverse all non-virtual bases. 2394137d517700a1b0f834535545c3f1676f40abcfbAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class); 24058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson for (unsigned I = 0, E = Info->Bases.size(); I != E; ++I) { 241ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson BaseSubobjectInfo* Base = Info->Bases[I]; 24258b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (Base->IsVirtual) 24358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson continue; 24458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 2456a3567442307864eac52bb84ce41465753513635Anders Carlsson CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class); 24658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 24758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (!CanPlaceBaseSubobjectAtOffset(Base, BaseOffset)) 24858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson return false; 24958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } 25058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 2516e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (Info->PrimaryVirtualBaseInfo) { 2526e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *PrimaryVirtualBaseInfo = Info->PrimaryVirtualBaseInfo; 25358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 25458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (Info == PrimaryVirtualBaseInfo->Derived) { 25558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (!CanPlaceBaseSubobjectAtOffset(PrimaryVirtualBaseInfo, Offset)) 25658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson return false; 25758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } 25858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } 25958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 260812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Traverse all member variables. 261812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson unsigned FieldNo = 0; 262812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (CXXRecordDecl::field_iterator I = Info->Class->field_begin(), 263812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson E = Info->Class->field_end(); I != E; ++I, ++FieldNo) { 264812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const FieldDecl *FD = *I; 2658c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson if (FD->isBitField()) 2668c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson continue; 2678c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson 268a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits FieldOffset = Offset + getFieldOffset(Layout, FieldNo); 269812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!CanPlaceFieldSubobjectAtOffset(FD, FieldOffset)) 270812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 271812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 272812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 27358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson return true; 27458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson} 27558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 276ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlssonvoid EmptySubobjectMap::UpdateEmptyBaseSubobjects(const BaseSubobjectInfo *Info, 277a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits Offset, 278e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson bool PlacingEmptyBase) { 279e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson if (!PlacingEmptyBase && Offset >= SizeOfLargestEmptySubobject) { 280e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson // We know that the only empty subobjects that can conflict with empty 281e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson // subobject of non-empty bases, are empty bases that can be placed at 282e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson // offset zero. Because of this, we only need to keep track of empty base 283e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson // subobjects with offsets less than the size of the largest empty 284e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson // subobject for our class. 285e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson return; 286e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson } 287e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson 288a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson AddSubobjectAtOffset(Info->Class, Offset); 2894137d517700a1b0f834535545c3f1676f40abcfbAnders Carlsson 29058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson // Traverse all non-virtual bases. 2914137d517700a1b0f834535545c3f1676f40abcfbAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class); 29258b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson for (unsigned I = 0, E = Info->Bases.size(); I != E; ++I) { 293ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson BaseSubobjectInfo* Base = Info->Bases[I]; 29458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (Base->IsVirtual) 29558b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson continue; 2964137d517700a1b0f834535545c3f1676f40abcfbAnders Carlsson 2976a3567442307864eac52bb84ce41465753513635Anders Carlsson CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class); 298e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson UpdateEmptyBaseSubobjects(Base, BaseOffset, PlacingEmptyBase); 29958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } 30058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 3016e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (Info->PrimaryVirtualBaseInfo) { 3026e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *PrimaryVirtualBaseInfo = Info->PrimaryVirtualBaseInfo; 30358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 30458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (Info == PrimaryVirtualBaseInfo->Derived) 305e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson UpdateEmptyBaseSubobjects(PrimaryVirtualBaseInfo, Offset, 306e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson PlacingEmptyBase); 30758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } 308812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 309812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Traverse all member variables. 310812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson unsigned FieldNo = 0; 311812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (CXXRecordDecl::field_iterator I = Info->Class->field_begin(), 312812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson E = Info->Class->field_end(); I != E; ++I, ++FieldNo) { 313812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const FieldDecl *FD = *I; 3148c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson if (FD->isBitField()) 3158c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson continue; 3164137d517700a1b0f834535545c3f1676f40abcfbAnders Carlsson 317a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits FieldOffset = Offset + getFieldOffset(Layout, FieldNo); 318a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson UpdateEmptyFieldSubobjects(FD, FieldOffset); 319812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 32058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson} 32158b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 3225b1319c78061e76d70cca50fb3343b25928e001bAnders Carlssonbool EmptySubobjectMap::CanPlaceBaseAtOffset(const BaseSubobjectInfo *Info, 323a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits Offset) { 324261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson // If we know this class doesn't have any empty subobjects we don't need to 325261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson // bother checking. 326a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson if (SizeOfLargestEmptySubobject.isZero()) 327261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson return true; 328261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson 32958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (!CanPlaceBaseSubobjectAtOffset(Info, Offset)) 33058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson return false; 331812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 332812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // We are able to place the base at this offset. Make sure to update the 333812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // empty base subobject map. 334e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson UpdateEmptyBaseSubobjects(Info, Offset, Info->Class->isEmpty()); 335261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson return true; 336261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson} 337261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson 338812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlssonbool 339812a3456b63708a5972f712e9e4b54d3cc436378Anders CarlssonEmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD, 340812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *Class, 341a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits Offset) const { 3422177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson // We don't have to keep looking past the maximum offset that's known to 3432177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson // contain an empty class. 344a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson if (!AnyEmptySubobjectsBeyondOffset(Offset)) 3452177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson return true; 3462177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson 347a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson if (!CanPlaceSubobjectAtOffset(RD, Offset)) 348812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 349812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 350812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 351812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 352812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Traverse all non-virtual bases. 353812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 354812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson E = RD->bases_end(); I != E; ++I) { 355812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (I->isVirtual()) 356812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson continue; 357812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 358812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *BaseDecl = 359812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 360812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 3616a3567442307864eac52bb84ce41465753513635Anders Carlsson CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(BaseDecl); 362812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!CanPlaceFieldSubobjectAtOffset(BaseDecl, Class, BaseOffset)) 363812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 364812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 365812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 36645f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson if (RD == Class) { 36745f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson // This is the most derived class, traverse virtual bases as well. 36845f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(), 36945f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson E = RD->vbases_end(); I != E; ++I) { 37045f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson const CXXRecordDecl *VBaseDecl = 37145f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 37245f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson 3733069a0d28637ad0ad583d9fdd7bc6bc6aa677fb5Anders Carlsson CharUnits VBaseOffset = Offset + Layout.getVBaseClassOffset(VBaseDecl); 37445f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson if (!CanPlaceFieldSubobjectAtOffset(VBaseDecl, Class, VBaseOffset)) 37545f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson return false; 37645f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson } 37745f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson } 37845f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson 379812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Traverse all member variables. 380812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson unsigned FieldNo = 0; 381812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); 382812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson I != E; ++I, ++FieldNo) { 383812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const FieldDecl *FD = *I; 3848c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson if (FD->isBitField()) 3858c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson continue; 3868c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson 387a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits FieldOffset = Offset + getFieldOffset(Layout, FieldNo); 388812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 389812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!CanPlaceFieldSubobjectAtOffset(FD, FieldOffset)) 390812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 391812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 392812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 393812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 394812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 395812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 3968c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlssonbool 3978c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders CarlssonEmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const FieldDecl *FD, 3988c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson CharUnits Offset) const { 3992177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson // We don't have to keep looking past the maximum offset that's known to 4002177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson // contain an empty class. 4018c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson if (!AnyEmptySubobjectsBeyondOffset(Offset)) 4022177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson return true; 4032177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson 404812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson QualType T = FD->getType(); 405812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (const RecordType *RT = T->getAs<RecordType>()) { 406812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 407a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson return CanPlaceFieldSubobjectAtOffset(RD, RD, Offset); 408812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 409812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 410812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // If we have an array type we need to look at every element. 411812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (const ConstantArrayType *AT = Context.getAsConstantArrayType(T)) { 412812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson QualType ElemTy = Context.getBaseElementType(AT); 413812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const RecordType *RT = ElemTy->getAs<RecordType>(); 414812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!RT) 415812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 416812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 417812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 418812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 419812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 420812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t NumElements = Context.getConstantArrayElementCount(AT); 4218c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson CharUnits ElementOffset = Offset; 422812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (uint64_t I = 0; I != NumElements; ++I) { 4232177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson // We don't have to keep looking past the maximum offset that's known to 4242177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson // contain an empty class. 4258c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson if (!AnyEmptySubobjectsBeyondOffset(ElementOffset)) 4262177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson return true; 4272177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson 428a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson if (!CanPlaceFieldSubobjectAtOffset(RD, RD, ElementOffset)) 429812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 430812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 4315f022d82696c84e4d127c558871d68ac6273274eKen Dyck ElementOffset += Layout.getSize(); 432812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 433812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 434812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 435812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 436812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 437812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 438812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlssonbool 439a3d4380d6662a373bc78f915947e5bc06e985e91Anders CarlssonEmptySubobjectMap::CanPlaceFieldAtOffset(const FieldDecl *FD, 440a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits Offset) { 441a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson if (!CanPlaceFieldSubobjectAtOffset(FD, Offset)) 442812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 443812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 444812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // We are able to place the member variable at this offset. 445812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Make sure to update the empty base subobject map. 446812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson UpdateEmptyFieldSubobjects(FD, Offset); 447812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 448812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 449812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 450812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlssonvoid EmptySubobjectMap::UpdateEmptyFieldSubobjects(const CXXRecordDecl *RD, 451812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *Class, 452a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits Offset) { 4535ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson // We know that the only empty subobjects that can conflict with empty 454e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson // field subobjects are subobjects of empty bases that can be placed at offset 4555ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson // zero. Because of this, we only need to keep track of empty field 4565ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson // subobjects with offsets less than the size of the largest empty 4575ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson // subobject for our class. 4585ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson if (Offset >= SizeOfLargestEmptySubobject) 4595ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson return; 4605ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson 461a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson AddSubobjectAtOffset(RD, Offset); 462812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 463812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 464812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 465812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Traverse all non-virtual bases. 466812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 467812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson E = RD->bases_end(); I != E; ++I) { 468812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (I->isVirtual()) 469812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson continue; 470812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 471812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *BaseDecl = 472812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 473812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 4746a3567442307864eac52bb84ce41465753513635Anders Carlsson CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(BaseDecl); 475812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson UpdateEmptyFieldSubobjects(BaseDecl, Class, BaseOffset); 476812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 477812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 47845f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson if (RD == Class) { 47945f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson // This is the most derived class, traverse virtual bases as well. 48045f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(), 48145f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson E = RD->vbases_end(); I != E; ++I) { 48245f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson const CXXRecordDecl *VBaseDecl = 48345f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 48445f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson 4853069a0d28637ad0ad583d9fdd7bc6bc6aa677fb5Anders Carlsson CharUnits VBaseOffset = Offset + Layout.getVBaseClassOffset(VBaseDecl); 48645f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson UpdateEmptyFieldSubobjects(VBaseDecl, Class, VBaseOffset); 48745f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson } 48845f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson } 48945f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson 490812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Traverse all member variables. 491812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson unsigned FieldNo = 0; 492812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); 493812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson I != E; ++I, ++FieldNo) { 494812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const FieldDecl *FD = *I; 495fa84fbad4863e030b149febc88288514efca34b2Anders Carlsson if (FD->isBitField()) 496fa84fbad4863e030b149febc88288514efca34b2Anders Carlsson continue; 497fa84fbad4863e030b149febc88288514efca34b2Anders Carlsson 498a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits FieldOffset = Offset + getFieldOffset(Layout, FieldNo); 499812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 500a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson UpdateEmptyFieldSubobjects(FD, FieldOffset); 501812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 502812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 503812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 504812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlssonvoid EmptySubobjectMap::UpdateEmptyFieldSubobjects(const FieldDecl *FD, 505a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits Offset) { 506812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson QualType T = FD->getType(); 507812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (const RecordType *RT = T->getAs<RecordType>()) { 508812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 509812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson UpdateEmptyFieldSubobjects(RD, RD, Offset); 510812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return; 511812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 512812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 513812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // If we have an array type we need to update every element. 514812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (const ConstantArrayType *AT = Context.getAsConstantArrayType(T)) { 515812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson QualType ElemTy = Context.getBaseElementType(AT); 516812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const RecordType *RT = ElemTy->getAs<RecordType>(); 517812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!RT) 518812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return; 519812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 520812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 521812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 522812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 523812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t NumElements = Context.getConstantArrayElementCount(AT); 524a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits ElementOffset = Offset; 525812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 526812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (uint64_t I = 0; I != NumElements; ++I) { 5275ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson // We know that the only empty subobjects that can conflict with empty 528e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson // field subobjects are subobjects of empty bases that can be placed at 5295ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson // offset zero. Because of this, we only need to keep track of empty field 5305ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson // subobjects with offsets less than the size of the largest empty 5315ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson // subobject for our class. 5325ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson if (ElementOffset >= SizeOfLargestEmptySubobject) 5335ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson return; 5345ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson 535812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson UpdateEmptyFieldSubobjects(RD, RD, ElementOffset); 5365f022d82696c84e4d127c558871d68ac6273274eKen Dyck ElementOffset += Layout.getSize(); 537812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 538812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 539812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 540812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 5417d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonclass RecordLayoutBuilder { 542c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davisprotected: 5439392fa63e45716e32061d05673fa28909f325b02Anders Carlsson // FIXME: Remove this and make the appropriate fields public. 5449392fa63e45716e32061d05673fa28909f325b02Anders Carlsson friend class clang::ASTContext; 5450aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5464ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad const ASTContext &Context; 5479392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 5486a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson EmptySubobjectMap *EmptySubobjects; 5490aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5509392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// Size - The current size of the record layout. 5519392fa63e45716e32061d05673fa28909f325b02Anders Carlsson uint64_t Size; 5520aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5539392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// Alignment - The current alignment of the record layout. 554ea7f6c2c53127b875ed432fd1793d48270d8ba6bKen Dyck CharUnits Alignment; 5550aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 55678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis /// \brief The alignment if attribute packed is not used. 5576feb4bb3defce7e5efc05a69c6bd7dfc9c59fa45Ken Dyck CharUnits UnpackedAlignment; 55878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 5599392fa63e45716e32061d05673fa28909f325b02Anders Carlsson llvm::SmallVector<uint64_t, 16> FieldOffsets; 5609392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 5619392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// Packed - Whether the record is packed or not. 562c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar unsigned Packed : 1; 563c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar 564c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar unsigned IsUnion : 1; 565c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar 566c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar unsigned IsMac68kAlign : 1; 56762055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian 56862055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian unsigned IsMsStruct : 1; 5699392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 5709392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// UnfilledBitsInLastByte - If the last field laid out was a bitfield, 5719392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// this contains the number of bits in the last byte that can be used for 5729392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// an adjacent bitfield if necessary. 5739392fa63e45716e32061d05673fa28909f325b02Anders Carlsson unsigned char UnfilledBitsInLastByte; 5740aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5759392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// MaxFieldAlignment - The maximum allowed field alignment. This is set by 5760aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// #pragma pack. 577834945c19cfb87fc21dfb6980a0980618655d79dKen Dyck CharUnits MaxFieldAlignment; 5780aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5799392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// DataSize - The data size of the record being laid out. 5809392fa63e45716e32061d05673fa28909f325b02Anders Carlsson uint64_t DataSize; 5810aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 582a1fdb0bc09aa0d17841cdbdd8c52cd1368251cbfKen Dyck CharUnits NonVirtualSize; 583df205382dae666b011d857402114e4f4acd56c81Ken Dyck CharUnits NonVirtualAlignment; 5840aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 585855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian FieldDecl *ZeroLengthBitfield; 586340fa242130c2d8d74c83edca0952e771aebe0e6Fariborz Jahanian 5879392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// PrimaryBase - the primary base class (if one exists) of the class 5889392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// we're laying out. 5899392fa63e45716e32061d05673fa28909f325b02Anders Carlsson const CXXRecordDecl *PrimaryBase; 5900aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5919392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// PrimaryBaseIsVirtual - Whether the primary base of the class we're laying 5929392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// out is virtual. 5939392fa63e45716e32061d05673fa28909f325b02Anders Carlsson bool PrimaryBaseIsVirtual; 5949392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 595376bda924ac92462a22d6a22ea65d8c1bb8f26f3Anders Carlsson typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy; 5960aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5979392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// Bases - base classes and their offsets in the record. 5989392fa63e45716e32061d05673fa28909f325b02Anders Carlsson BaseOffsetsMapTy Bases; 5990aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 6009392fa63e45716e32061d05673fa28909f325b02Anders Carlsson // VBases - virtual base classes and their offsets in the record. 6019392fa63e45716e32061d05673fa28909f325b02Anders Carlsson BaseOffsetsMapTy VBases; 6029392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6039392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// IndirectPrimaryBases - Virtual base classes, direct or indirect, that are 6049392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// primary base classes for some other direct or indirect base class. 605245656ec65ec600ef1ab05f4c8d9f780542d689dAnders Carlsson CXXIndirectPrimaryBaseSet IndirectPrimaryBases; 6060aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 6079392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// FirstNearlyEmptyVBase - The first nearly empty virtual base class in 6089392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// inheritance graph order. Used for determining the primary base class. 6099392fa63e45716e32061d05673fa28909f325b02Anders Carlsson const CXXRecordDecl *FirstNearlyEmptyVBase; 6109392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6119392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// VisitedVirtualBases - A set of all the visited virtual bases, used to 6129392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// avoid visiting virtual bases more than once. 6139392fa63e45716e32061d05673fa28909f325b02Anders Carlsson llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases; 6140aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 6154ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad RecordLayoutBuilder(const ASTContext &Context, EmptySubobjectMap 6164ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad *EmptySubobjects) 617ea7f6c2c53127b875ed432fd1793d48270d8ba6bKen Dyck : Context(Context), EmptySubobjects(EmptySubobjects), Size(0), 6186feb4bb3defce7e5efc05a69c6bd7dfc9c59fa45Ken Dyck Alignment(CharUnits::One()), UnpackedAlignment(Alignment), 61962055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian Packed(false), IsUnion(false), 62062055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian IsMac68kAlign(false), IsMsStruct(false), 621834945c19cfb87fc21dfb6980a0980618655d79dKen Dyck UnfilledBitsInLastByte(0), MaxFieldAlignment(CharUnits::Zero()), 622834945c19cfb87fc21dfb6980a0980618655d79dKen Dyck DataSize(0), NonVirtualSize(CharUnits::Zero()), 623340fa242130c2d8d74c83edca0952e771aebe0e6Fariborz Jahanian NonVirtualAlignment(CharUnits::One()), 624855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian ZeroLengthBitfield(0), PrimaryBase(0), 625834945c19cfb87fc21dfb6980a0980618655d79dKen Dyck PrimaryBaseIsVirtual(false), FirstNearlyEmptyVBase(0) { } 6260aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 6279392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void Layout(const RecordDecl *D); 628c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson void Layout(const CXXRecordDecl *D); 6299392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void Layout(const ObjCInterfaceDecl *D); 6309392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6319392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void LayoutFields(const RecordDecl *D); 6329392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void LayoutField(const FieldDecl *D); 63378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis void LayoutWideBitField(uint64_t FieldSize, uint64_t TypeSize, 63478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis bool FieldPacked, const FieldDecl *D); 6359392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void LayoutBitField(const FieldDecl *D); 6369392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6376e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// BaseSubobjectInfoAllocator - Allocator for BaseSubobjectInfo objects. 6386e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson llvm::SpecificBumpPtrAllocator<BaseSubobjectInfo> BaseSubobjectInfoAllocator; 6396e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 6406e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson typedef llvm::DenseMap<const CXXRecordDecl *, BaseSubobjectInfo *> 6416e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfoMapTy; 6426e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 6436e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// VirtualBaseInfo - Map from all the (direct or indirect) virtual bases 6446e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// of the class we're laying out to their base subobject info. 6456e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfoMapTy VirtualBaseInfo; 6466e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 6476e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// NonVirtualBaseInfo - Map from all the direct non-virtual bases of the 6486e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// class we're laying out to their base subobject info. 6496e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfoMapTy NonVirtualBaseInfo; 6506e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 6516e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// ComputeBaseSubobjectInfo - Compute the base subobject information for the 6526e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// bases of the given class. 6536e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson void ComputeBaseSubobjectInfo(const CXXRecordDecl *RD); 6546e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 6556e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// ComputeBaseSubobjectInfo - Compute the base subobject information for a 6566e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// single class and all of its base classes. 6576e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *ComputeBaseSubobjectInfo(const CXXRecordDecl *RD, 6586e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson bool IsVirtual, 6596e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *Derived); 6609392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6619392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// DeterminePrimaryBase - Determine the primary base of the given class. 6629392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void DeterminePrimaryBase(const CXXRecordDecl *RD); 6639392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6649392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void SelectPrimaryVBase(const CXXRecordDecl *RD); 6650aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 6665dc989c4f630acc3c0028b2d1229511063671a29Ken Dyck virtual CharUnits GetVirtualPointersSize(const CXXRecordDecl *RD) const; 667c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis 6680aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// LayoutNonVirtualBases - Determines the primary base class (if any) and 6699392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// lays it out. Will then proceed to lay out all non-virtual base clasess. 6709392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void LayoutNonVirtualBases(const CXXRecordDecl *RD); 6719392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6729392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// LayoutNonVirtualBase - Lays out a single non-virtual base. 67307cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson void LayoutNonVirtualBase(const BaseSubobjectInfo *Base); 6749392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 675a2311513524ecef954d2b438bfbe09aa9511b660Anders Carlsson void AddPrimaryVirtualBaseOffsets(const BaseSubobjectInfo *Info, 676a2311513524ecef954d2b438bfbe09aa9511b660Anders Carlsson CharUnits Offset); 6779392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6789392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// LayoutVirtualBases - Lays out all the virtual bases. 6799392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void LayoutVirtualBases(const CXXRecordDecl *RD, 6809392fa63e45716e32061d05673fa28909f325b02Anders Carlsson const CXXRecordDecl *MostDerivedClass); 6819392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6829392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// LayoutVirtualBase - Lays out a single virtual base. 683276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson void LayoutVirtualBase(const BaseSubobjectInfo *Base); 6849392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6850aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// LayoutBase - Will lay out a base and return the offset where it was 686a2311513524ecef954d2b438bfbe09aa9511b660Anders Carlsson /// placed, in chars. 687a2311513524ecef954d2b438bfbe09aa9511b660Anders Carlsson CharUnits LayoutBase(const BaseSubobjectInfo *Base); 6889392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 689c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson /// InitializeLayout - Initialize record layout for the given record decl. 690c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar void InitializeLayout(const Decl *D); 691c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 6929392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// FinishLayout - Finalize record layout. Adjust record size based on the 6939392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// alignment. 69478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis void FinishLayout(const NamedDecl *D); 69578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 6963263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck void UpdateAlignment(CharUnits NewAlignment, CharUnits UnpackedNewAlignment); 6973263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck void UpdateAlignment(CharUnits NewAlignment) { 69878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UpdateAlignment(NewAlignment, NewAlignment); 69978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 70078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 70178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis void CheckFieldPadding(uint64_t Offset, uint64_t UnpaddedOffset, 70278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis uint64_t UnpackedOffset, unsigned UnpackedAlign, 70378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis bool isPacked, const FieldDecl *D); 7049392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 70578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID); 7069392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 707a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck CharUnits getSize() const { 7089911344114cc493e089964f7602b619e5a47c7bcKen Dyck assert(Size % Context.getCharWidth() == 0); 709a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck return Context.toCharUnitsFromBits(Size); 710a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck } 711a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck uint64_t getSizeInBits() const { return Size; } 712a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck 713a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck void setSize(CharUnits NewSize) { Size = Context.toBits(NewSize); } 714a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck void setSize(uint64_t NewSize) { Size = NewSize; } 715a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck 716a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck CharUnits getDataSize() const { 7179911344114cc493e089964f7602b619e5a47c7bcKen Dyck assert(DataSize % Context.getCharWidth() == 0); 718a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck return Context.toCharUnitsFromBits(DataSize); 719a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck } 720a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck uint64_t getDataSizeInBits() const { return DataSize; } 721a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck 722a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck void setDataSize(CharUnits NewSize) { DataSize = Context.toBits(NewSize); } 723a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck void setDataSize(uint64_t NewSize) { DataSize = NewSize; } 724a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck 725a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck 726c83d2d7d8914a0fe00d679a262f2bdae7689f16dArgyrios Kyrtzidis RecordLayoutBuilder(const RecordLayoutBuilder&); // DO NOT IMPLEMENT 727c83d2d7d8914a0fe00d679a262f2bdae7689f16dArgyrios Kyrtzidis void operator=(const RecordLayoutBuilder&); // DO NOT IMPLEMENT 7289392fa63e45716e32061d05673fa28909f325b02Anders Carlssonpublic: 7299392fa63e45716e32061d05673fa28909f325b02Anders Carlsson static const CXXMethodDecl *ComputeKeyFunction(const CXXRecordDecl *RD); 730cfe17e5c82762cc854012e472b66f4278f0a4a2aArgyrios Kyrtzidis 731cfe17e5c82762cc854012e472b66f4278f0a4a2aArgyrios Kyrtzidis virtual ~RecordLayoutBuilder() { } 7329392fa63e45716e32061d05673fa28909f325b02Anders Carlsson}; 7337e220286410422ed1dc0409a9cb9708fe50e3df0Benjamin Kramer} // end anonymous namespace 7349392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 7353f066522342538509cf0aa4f381503b43fbdb68bAnders Carlssonvoid 7367d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders CarlssonRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD) { 737584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 738bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->bases_end(); I != E; ++I) { 739584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson assert(!I->getType()->isDependentType() && 7409994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl "Cannot layout class with dependent bases."); 741bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 7421eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const CXXRecordDecl *Base = 743584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 744200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 745584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson // Check if this is a nearly empty virtual base. 746dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson if (I->isVirtual() && Context.isNearlyEmpty(Base)) { 747584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson // If it's not an indirect primary base, then we've found our primary 748584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson // base. 7493f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson if (!IndirectPrimaryBases.count(Base)) { 75028fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBase = Base; 75128fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBaseIsVirtual = true; 752d76264e0b20470267249660ab947197cf6d6e31fMike Stump return; 753d76264e0b20470267249660ab947197cf6d6e31fMike Stump } 754bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 755584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson // Is this the first nearly empty virtual base? 756584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson if (!FirstNearlyEmptyVBase) 757584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson FirstNearlyEmptyVBase = Base; 758d76264e0b20470267249660ab947197cf6d6e31fMike Stump } 759bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 760200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson SelectPrimaryVBase(Base); 76128fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson if (PrimaryBase) 76294ba380b820cde3fb9d97d5f07ac709ebbb6ac1eZhongxing Xu return; 763d76264e0b20470267249660ab947197cf6d6e31fMike Stump } 764d76264e0b20470267249660ab947197cf6d6e31fMike Stump} 765d76264e0b20470267249660ab947197cf6d6e31fMike Stump 7665dc989c4f630acc3c0028b2d1229511063671a29Ken DyckCharUnits 767c9f8aece7e111f90265dfad9a81f3f517be948deCharles DavisRecordLayoutBuilder::GetVirtualPointersSize(const CXXRecordDecl *RD) const { 7685dc989c4f630acc3c0028b2d1229511063671a29Ken Dyck return Context.toCharUnitsFromBits(Context.Target.getPointerWidth(0)); 769c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis} 770c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis 771200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson/// DeterminePrimaryBase - Determine the primary base of the given class. 7727d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonvoid RecordLayoutBuilder::DeterminePrimaryBase(const CXXRecordDecl *RD) { 773200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // If the class isn't dynamic, it won't have a primary base. 774200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson if (!RD->isDynamicClass()) 775200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson return; 776bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 7773f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson // Compute all the primary virtual bases for all of our direct and 7780880e75541899bc1cdd73c50eb549110b5916c59Mike Stump // indirect bases, and record all their primary virtual base classes. 779245656ec65ec600ef1ab05f4c8d9f780542d689dAnders Carlsson RD->getIndirectPrimaryBases(IndirectPrimaryBases); 7800880e75541899bc1cdd73c50eb549110b5916c59Mike Stump 781bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar // If the record has a dynamic base class, attempt to choose a primary base 782bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar // class. It is the first (in direct base class order) non-virtual dynamic 7833f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson // base class, if one exists. 7846f376336138ea719e3c4757ae046a5768043b276Mike Stump for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), 785bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar e = RD->bases_end(); i != e; ++i) { 786ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson // Ignore virtual bases. 787ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson if (i->isVirtual()) 788ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson continue; 789bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 790ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson const CXXRecordDecl *Base = 791ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 792ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson 793ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson if (Base->isDynamicClass()) { 794ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson // We found it. 79528fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBase = Base; 79628fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBaseIsVirtual = false; 797ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson return; 7986f376336138ea719e3c4757ae046a5768043b276Mike Stump } 7996f376336138ea719e3c4757ae046a5768043b276Mike Stump } 8006f376336138ea719e3c4757ae046a5768043b276Mike Stump 8016f376336138ea719e3c4757ae046a5768043b276Mike Stump // Otherwise, it is the first nearly empty virtual base that is not an 80249520944c688a9d5fc78d0c2af544b825873477bMike Stump // indirect primary virtual base class, if one exists. 803200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson if (RD->getNumVBases() != 0) { 804200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson SelectPrimaryVBase(RD); 80528fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson if (PrimaryBase) 806200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson return; 807200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson } 8086f376336138ea719e3c4757ae046a5768043b276Mike Stump 809200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Otherwise, it is the first nearly empty virtual base that is not an 810200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // indirect primary virtual base class, if one exists. 811200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson if (FirstNearlyEmptyVBase) { 81228fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBase = FirstNearlyEmptyVBase; 81328fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBaseIsVirtual = true; 8146f376336138ea719e3c4757ae046a5768043b276Mike Stump return; 815200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson } 816bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 817200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Otherwise there is no primary base class. 81828fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson assert(!PrimaryBase && "Should not get here with a primary base!"); 819200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 820200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Allocate the virtual table pointer at offset zero. 821200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson assert(DataSize == 0 && "Vtable pointer must be at offset zero!"); 822bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 823200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Update the size. 8245dc989c4f630acc3c0028b2d1229511063671a29Ken Dyck setSize(getSize() + GetVirtualPointersSize(RD)); 825f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck setDataSize(getSize()); 826200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 8273263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck CharUnits UnpackedBaseAlign = 8283263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck Context.toCharUnitsFromBits(Context.Target.getPointerAlign(0)); 8293263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck CharUnits BaseAlign = (Packed) ? CharUnits::One() : UnpackedBaseAlign; 8305a821198203bdd469175408c4c4c805cc3240159Argyrios Kyrtzidis 8315a821198203bdd469175408c4c4c805cc3240159Argyrios Kyrtzidis // The maximum field alignment overrides base align. 832834945c19cfb87fc21dfb6980a0980618655d79dKen Dyck if (!MaxFieldAlignment.isZero()) { 8333263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck BaseAlign = std::min(BaseAlign, MaxFieldAlignment); 8343263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck UnpackedBaseAlign = std::min(UnpackedBaseAlign, MaxFieldAlignment); 8355a821198203bdd469175408c4c4c805cc3240159Argyrios Kyrtzidis } 8365a821198203bdd469175408c4c4c805cc3240159Argyrios Kyrtzidis 837200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Update the alignment. 8385a821198203bdd469175408c4c4c805cc3240159Argyrios Kyrtzidis UpdateAlignment(BaseAlign, UnpackedBaseAlign); 8396f376336138ea719e3c4757ae046a5768043b276Mike Stump} 8406f376336138ea719e3c4757ae046a5768043b276Mike Stump 8416e26454ecceb20938b866717dc8a72c6d37d224dAnders CarlssonBaseSubobjectInfo * 8426e26454ecceb20938b866717dc8a72c6d37d224dAnders CarlssonRecordLayoutBuilder::ComputeBaseSubobjectInfo(const CXXRecordDecl *RD, 8436e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson bool IsVirtual, 8446e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *Derived) { 8456e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *Info; 8466e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 8476e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (IsVirtual) { 8486e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Check if we already have info about this virtual base. 8496e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *&InfoSlot = VirtualBaseInfo[RD]; 8506e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (InfoSlot) { 8516e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson assert(InfoSlot->Class == RD && "Wrong class for virtual base info!"); 8526e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson return InfoSlot; 8536e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 8546e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 8556e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // We don't, create it. 8566e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson InfoSlot = new (BaseSubobjectInfoAllocator.Allocate()) BaseSubobjectInfo; 8576e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info = InfoSlot; 8586e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } else { 8596e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info = new (BaseSubobjectInfoAllocator.Allocate()) BaseSubobjectInfo; 8606e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 8616e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 8626e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info->Class = RD; 8636e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info->IsVirtual = IsVirtual; 8646e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info->Derived = 0; 8656e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info->PrimaryVirtualBaseInfo = 0; 8666e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 8676e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson const CXXRecordDecl *PrimaryVirtualBase = 0; 8686e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *PrimaryVirtualBaseInfo = 0; 8696e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 8706e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Check if this base has a primary virtual base. 8716e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (RD->getNumVBases()) { 8726e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 873c9e814ba193f38a7b08268612248f63beb279bb3Anders Carlsson if (Layout.isPrimaryBaseVirtual()) { 8746e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // This base does have a primary virtual base. 8756e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson PrimaryVirtualBase = Layout.getPrimaryBase(); 8766e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson assert(PrimaryVirtualBase && "Didn't have a primary virtual base!"); 8776e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 8786e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Now check if we have base subobject info about this primary base. 8796e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson PrimaryVirtualBaseInfo = VirtualBaseInfo.lookup(PrimaryVirtualBase); 8806e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 8816e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (PrimaryVirtualBaseInfo) { 8826e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (PrimaryVirtualBaseInfo->Derived) { 8836e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // We did have info about this primary base, and it turns out that it 8846e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // has already been claimed as a primary virtual base for another 8856e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // base. 8866e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson PrimaryVirtualBase = 0; 8876e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } else { 8886e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // We can claim this base as our primary base. 8896e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info->PrimaryVirtualBaseInfo = PrimaryVirtualBaseInfo; 8906e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson PrimaryVirtualBaseInfo->Derived = Info; 8916e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 8926e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 8936e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 8946e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 8956e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 8966e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Now go through all direct bases. 8976e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 8986e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson E = RD->bases_end(); I != E; ++I) { 8996e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson bool IsVirtual = I->isVirtual(); 9006e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9016e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson const CXXRecordDecl *BaseDecl = 9026e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 9036e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9046e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info->Bases.push_back(ComputeBaseSubobjectInfo(BaseDecl, IsVirtual, Info)); 9056e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 9066e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9076e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (PrimaryVirtualBase && !PrimaryVirtualBaseInfo) { 9086e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Traversing the bases must have created the base info for our primary 9096e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // virtual base. 9106e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson PrimaryVirtualBaseInfo = VirtualBaseInfo.lookup(PrimaryVirtualBase); 9116e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson assert(PrimaryVirtualBaseInfo && 9126e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson "Did not create a primary virtual base!"); 9136e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9146e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Claim the primary virtual base as our primary virtual base. 9156e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info->PrimaryVirtualBaseInfo = PrimaryVirtualBaseInfo; 9166e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson PrimaryVirtualBaseInfo->Derived = Info; 9176e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 9186e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9196e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson return Info; 9206e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson} 9216e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9226e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlssonvoid RecordLayoutBuilder::ComputeBaseSubobjectInfo(const CXXRecordDecl *RD) { 9236e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 9246e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson E = RD->bases_end(); I != E; ++I) { 9256e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson bool IsVirtual = I->isVirtual(); 9266e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9276e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson const CXXRecordDecl *BaseDecl = 9286e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 9296e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9306e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Compute the base subobject info for this base. 9316e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *Info = ComputeBaseSubobjectInfo(BaseDecl, IsVirtual, 0); 9326e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9336e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (IsVirtual) { 9346e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // ComputeBaseInfo has already added this base for us. 9356e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson assert(VirtualBaseInfo.count(BaseDecl) && 9366e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson "Did not add virtual base!"); 9376e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } else { 9386e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Add the base info to the map of non-virtual bases. 9396e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson assert(!NonVirtualBaseInfo.count(BaseDecl) && 9406e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson "Non-virtual base already exists!"); 9416e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson NonVirtualBaseInfo.insert(std::make_pair(BaseDecl, Info)); 9426e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 9436e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 9446e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson} 9456e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 946e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlssonvoid 9477d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders CarlssonRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) { 9486e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Then, determine the primary base class. 949200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson DeterminePrimaryBase(RD); 950bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 9516e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Compute base subobject info. 9526e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson ComputeBaseSubobjectInfo(RD); 9536e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 954200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // If we have a primary base class, lay it out. 95528fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson if (PrimaryBase) { 95628fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson if (PrimaryBaseIsVirtual) { 9576e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // If the primary virtual base was a primary virtual base of some other 9586e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // base class we'll have to steal it. 9596e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *PrimaryBaseInfo = VirtualBaseInfo.lookup(PrimaryBase); 9606e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson PrimaryBaseInfo->Derived = 0; 9616e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 962200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // We have a virtual primary base, insert it as an indirect primary base. 96328fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson IndirectPrimaryBases.insert(PrimaryBase); 96437147ea14f39a8522e32e3ba4d043a2a33fff90cAnders Carlsson 9650aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar assert(!VisitedVirtualBases.count(PrimaryBase) && 96628fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson "vbase already visited!"); 96728fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson VisitedVirtualBases.insert(PrimaryBase); 9680aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 969276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson LayoutVirtualBase(PrimaryBaseInfo); 97007cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson } else { 97107cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson BaseSubobjectInfo *PrimaryBaseInfo = 97207cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson NonVirtualBaseInfo.lookup(PrimaryBase); 97307cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson assert(PrimaryBaseInfo && 97407cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson "Did not find base info for non-virtual primary base!"); 97507cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson 97607cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson LayoutNonVirtualBase(PrimaryBaseInfo); 97707cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson } 978200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson } 979bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 980200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Now lay out the non-virtual bases. 981200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 982bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->bases_end(); I != E; ++I) { 983200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 984200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Ignore virtual bases. 985200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson if (I->isVirtual()) 986200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson continue; 987200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 98807cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson const CXXRecordDecl *BaseDecl = 989200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 990200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 991200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Skip the primary base. 99207cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson if (BaseDecl == PrimaryBase && !PrimaryBaseIsVirtual) 993200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson continue; 994200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 995200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Lay out the base. 99607cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson BaseSubobjectInfo *BaseInfo = NonVirtualBaseInfo.lookup(BaseDecl); 99707cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson assert(BaseInfo && "Did not find base info for non-virtual base!"); 99807cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson 99907cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson LayoutNonVirtualBase(BaseInfo); 1000e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson } 1001e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson} 1002e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 100307cebc57123db6a50c7c293e44a9647ce069952bAnders Carlssonvoid RecordLayoutBuilder::LayoutNonVirtualBase(const BaseSubobjectInfo *Base) { 1004e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson // Layout the base. 1005a2311513524ecef954d2b438bfbe09aa9511b660Anders Carlsson CharUnits Offset = LayoutBase(Base); 1006bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1007e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson // Add its base class offset. 100807cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson assert(!Bases.count(Base->Class) && "base offset already exists!"); 1009a2311513524ecef954d2b438bfbe09aa9511b660Anders Carlsson Bases.insert(std::make_pair(Base->Class, Offset)); 10103cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson 10113cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson AddPrimaryVirtualBaseOffsets(Base, Offset); 1012e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson} 1013968db3364611a475909b5e76969d2f5472e65597Mike Stump 1014bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbarvoid 10153cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders CarlssonRecordLayoutBuilder::AddPrimaryVirtualBaseOffsets(const BaseSubobjectInfo *Info, 1016a2311513524ecef954d2b438bfbe09aa9511b660Anders Carlsson CharUnits Offset) { 10173cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson // This base isn't interesting, it has no virtual bases. 10183cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson if (!Info->Class->getNumVBases()) 10193cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson return; 10203cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson 10213cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson // First, check if we have a virtual primary base to add offsets for. 10223cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson if (Info->PrimaryVirtualBaseInfo) { 10233cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson assert(Info->PrimaryVirtualBaseInfo->IsVirtual && 10243cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson "Primary virtual base is not virtual!"); 10253cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson if (Info->PrimaryVirtualBaseInfo->Derived == Info) { 10263cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson // Add the offset. 10273cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson assert(!VBases.count(Info->PrimaryVirtualBaseInfo->Class) && 10283cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson "primary vbase offset already exists!"); 10293cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson VBases.insert(std::make_pair(Info->PrimaryVirtualBaseInfo->Class, 1030a2311513524ecef954d2b438bfbe09aa9511b660Anders Carlsson Offset)); 10313cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson 10323cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson // Traverse the primary virtual base. 10333cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson AddPrimaryVirtualBaseOffsets(Info->PrimaryVirtualBaseInfo, Offset); 10343cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson } 103597913576dbe624971bf18726899983d211d742c0Anders Carlsson } 103697913576dbe624971bf18726899983d211d742c0Anders Carlsson 10373cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson // Now go through all direct non-virtual bases. 10383cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class); 10393cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson for (unsigned I = 0, E = Info->Bases.size(); I != E; ++I) { 10403cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson const BaseSubobjectInfo *Base = Info->Bases[I]; 10413cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson if (Base->IsVirtual) 104297913576dbe624971bf18726899983d211d742c0Anders Carlsson continue; 10430aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 10446a3567442307864eac52bb84ce41465753513635Anders Carlsson CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class); 10453cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson AddPrimaryVirtualBaseOffsets(Base, BaseOffset); 104697913576dbe624971bf18726899983d211d742c0Anders Carlsson } 104797913576dbe624971bf18726899983d211d742c0Anders Carlsson} 104897913576dbe624971bf18726899983d211d742c0Anders Carlsson 104997913576dbe624971bf18726899983d211d742c0Anders Carlssonvoid 10507d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders CarlssonRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD, 105197913576dbe624971bf18726899983d211d742c0Anders Carlsson const CXXRecordDecl *MostDerivedClass) { 105288f4296e85d49e4ea63cda729cd5f696824c67ceAnders Carlsson const CXXRecordDecl *PrimaryBase; 1053bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson bool PrimaryBaseIsVirtual; 105437147ea14f39a8522e32e3ba4d043a2a33fff90cAnders Carlsson 1055bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson if (MostDerivedClass == RD) { 105628fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBase = this->PrimaryBase; 105728fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBaseIsVirtual = this->PrimaryBaseIsVirtual; 1058bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson } else { 10590f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 106088f4296e85d49e4ea63cda729cd5f696824c67ceAnders Carlsson PrimaryBase = Layout.getPrimaryBase(); 1061c9e814ba193f38a7b08268612248f63beb279bb3Anders Carlsson PrimaryBaseIsVirtual = Layout.isPrimaryBaseVirtual(); 1062bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson } 1063bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson 1064622e2477d0698d734671523389277e10d8566e26Anders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1065622e2477d0698d734671523389277e10d8566e26Anders Carlsson E = RD->bases_end(); I != E; ++I) { 1066622e2477d0698d734671523389277e10d8566e26Anders Carlsson assert(!I->getType()->isDependentType() && 10679994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl "Cannot layout class with dependent bases."); 1068bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1069276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson const CXXRecordDecl *BaseDecl = 1070622e2477d0698d734671523389277e10d8566e26Anders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1071622e2477d0698d734671523389277e10d8566e26Anders Carlsson 1072622e2477d0698d734671523389277e10d8566e26Anders Carlsson if (I->isVirtual()) { 1073276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson if (PrimaryBase != BaseDecl || !PrimaryBaseIsVirtual) { 1074276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson bool IndirectPrimaryBase = IndirectPrimaryBases.count(BaseDecl); 1075bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson 1076bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson // Only lay out the virtual base if it's not an indirect primary base. 1077bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson if (!IndirectPrimaryBase) { 1078bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson // Only visit virtual bases once. 1079276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson if (!VisitedVirtualBases.insert(BaseDecl)) 1080bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson continue; 10810aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1082276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson const BaseSubobjectInfo *BaseInfo = VirtualBaseInfo.lookup(BaseDecl); 1083276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson assert(BaseInfo && "Did not find virtual base info!"); 1084276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson LayoutVirtualBase(BaseInfo); 1085147b5ddc6c8618a9d70a83f90de409e444ae705bAnders Carlsson } 1086968db3364611a475909b5e76969d2f5472e65597Mike Stump } 1087fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump } 1088bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1089276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson if (!BaseDecl->getNumVBases()) { 1090622e2477d0698d734671523389277e10d8566e26Anders Carlsson // This base isn't interesting since it doesn't have any virtual bases. 1091622e2477d0698d734671523389277e10d8566e26Anders Carlsson continue; 1092622e2477d0698d734671523389277e10d8566e26Anders Carlsson } 1093622e2477d0698d734671523389277e10d8566e26Anders Carlsson 1094276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson LayoutVirtualBases(BaseDecl, MostDerivedClass); 1095eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump } 1096eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump} 1097eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump 1098276b491b44b473d91610432aa335927b2c7ad152Anders Carlssonvoid RecordLayoutBuilder::LayoutVirtualBase(const BaseSubobjectInfo *Base) { 10993cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson assert(!Base->Derived && "Trying to lay out a primary virtual base!"); 11003cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson 1101e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson // Layout the base. 1102a2311513524ecef954d2b438bfbe09aa9511b660Anders Carlsson CharUnits Offset = LayoutBase(Base); 1103e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson 1104e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson // Add its base class offset. 1105276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson assert(!VBases.count(Base->Class) && "vbase offset already exists!"); 1106a2311513524ecef954d2b438bfbe09aa9511b660Anders Carlsson VBases.insert(std::make_pair(Base->Class, Offset)); 11073cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson 11083cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson AddPrimaryVirtualBaseOffsets(Base, Offset); 1109e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson} 1110e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 1111a2311513524ecef954d2b438bfbe09aa9511b660Anders CarlssonCharUnits RecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) { 1112b1d880b15f6b254349bd7a700e6b4f2ec1c24f5bAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(Base->Class); 1113e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 1114e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // If we have an empty base class, try to place it at offset 0. 1115b1d880b15f6b254349bd7a700e6b4f2ec1c24f5bAnders Carlsson if (Base->Class->isEmpty() && 1116a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson EmptySubobjects->CanPlaceBaseAtOffset(Base, CharUnits::Zero())) { 1117f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck setSize(std::max(getSize(), Layout.getSize())); 1118e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 1119a2311513524ecef954d2b438bfbe09aa9511b660Anders Carlsson return CharUnits::Zero(); 1120e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson } 1121bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 11223263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck CharUnits UnpackedBaseAlign = Layout.getNonVirtualAlign(); 11233263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck CharUnits BaseAlign = (Packed) ? CharUnits::One() : UnpackedBaseAlign; 112443ddd9f2027bdd9c36336a342e9c0dd2aa13f836Argyrios Kyrtzidis 112543ddd9f2027bdd9c36336a342e9c0dd2aa13f836Argyrios Kyrtzidis // The maximum field alignment overrides base align. 1126834945c19cfb87fc21dfb6980a0980618655d79dKen Dyck if (!MaxFieldAlignment.isZero()) { 11273263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck BaseAlign = std::min(BaseAlign, MaxFieldAlignment); 11283263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck UnpackedBaseAlign = std::min(UnpackedBaseAlign, MaxFieldAlignment); 112943ddd9f2027bdd9c36336a342e9c0dd2aa13f836Argyrios Kyrtzidis } 1130bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1131e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // Round up the current record size to the base's alignment boundary. 1132f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck CharUnits Offset = getDataSize().RoundUpToAlignment(BaseAlign); 1133bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1134e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // Try to place the base. 1135f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck while (!EmptySubobjects->CanPlaceBaseAtOffset(Base, Offset)) 1136f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck Offset += BaseAlign; 1137e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 1138b1d880b15f6b254349bd7a700e6b4f2ec1c24f5bAnders Carlsson if (!Base->Class->isEmpty()) { 1139e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // Update the data size. 1140f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck setDataSize(Offset + Layout.getNonVirtualSize()); 1141e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 1142f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck setSize(std::max(getSize(), getDataSize())); 1143e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson } else 1144f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck setSize(std::max(getSize(), Offset + Layout.getSize())); 1145e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 1146e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // Remember max struct/class alignment. 114743ddd9f2027bdd9c36336a342e9c0dd2aa13f836Argyrios Kyrtzidis UpdateAlignment(BaseAlign, UnpackedBaseAlign); 1148e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 1149f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck return Offset; 1150e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson} 1151e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 1152c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbarvoid RecordLayoutBuilder::InitializeLayout(const Decl *D) { 1153c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar if (const RecordDecl *RD = dyn_cast<RecordDecl>(D)) 1154c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar IsUnion = RD->isUnion(); 11550aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1156a5dd722bdf2f74a1a249fe6661d96a7236aee0f0Anders Carlsson Packed = D->hasAttr<PackedAttr>(); 115762055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian 115862055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian IsMsStruct = D->hasAttr<MsStructAttr>(); 11590aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1160c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar // mac68k alignment supersedes maximum field alignment and attribute aligned, 1161c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar // and forces all structures to have 2-byte alignment. The IBM docs on it 1162c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar // allude to additional (more complicated) semantics, especially with regard 1163c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar // to bit-fields, but gcc appears not to follow that. 1164c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar if (D->hasAttr<AlignMac68kAttr>()) { 1165c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar IsMac68kAlign = true; 1166834945c19cfb87fc21dfb6980a0980618655d79dKen Dyck MaxFieldAlignment = CharUnits::fromQuantity(2); 1167ea7f6c2c53127b875ed432fd1793d48270d8ba6bKen Dyck Alignment = CharUnits::fromQuantity(2); 1168c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar } else { 1169c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar if (const MaxFieldAlignmentAttr *MFAA = D->getAttr<MaxFieldAlignmentAttr>()) 1170834945c19cfb87fc21dfb6980a0980618655d79dKen Dyck MaxFieldAlignment = Context.toCharUnitsFromBits(MFAA->getAlignment()); 11710aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1172cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (unsigned MaxAlign = D->getMaxAlignment()) 11733263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck UpdateAlignment(Context.toCharUnitsFromBits(MaxAlign)); 1174c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar } 1175c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson} 117674cbe226207fd101623638dadfa7fbada04ff2a6Anders Carlsson 1177c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlssonvoid RecordLayoutBuilder::Layout(const RecordDecl *D) { 1178c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson InitializeLayout(D); 1179a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson LayoutFields(D); 11801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1181c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson // Finally, round the size of the total struct up to the alignment of the 1182c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson // struct itself. 118378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis FinishLayout(D); 1184c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson} 1185c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 1186c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlssonvoid RecordLayoutBuilder::Layout(const CXXRecordDecl *RD) { 1187c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson InitializeLayout(RD); 1188c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 1189c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson // Lay out the vtable and the non-virtual bases. 1190c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson LayoutNonVirtualBases(RD); 1191c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 1192c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson LayoutFields(RD); 1193c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 119490ce2dba294b8443169fe1a583914908fae0e767Ken Dyck NonVirtualSize = Context.toCharUnitsFromBits( 119590ce2dba294b8443169fe1a583914908fae0e767Ken Dyck llvm::RoundUpToAlignment(getSizeInBits(), 119690ce2dba294b8443169fe1a583914908fae0e767Ken Dyck Context.Target.getCharAlign())); 1197ea7f6c2c53127b875ed432fd1793d48270d8ba6bKen Dyck 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 12363263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck 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. 1240a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck setSize(SL.getDataSize()); 1241f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck setDataSize(getSize()); 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. 126062055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian const FieldDecl *LastFD = 0; 1261855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian ZeroLengthBitfield = 0; 12621eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump for (RecordDecl::field_iterator Field = D->field_begin(), 126362055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian FieldEnd = D->field_end(); Field != FieldEnd; ++Field) { 126462055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian if (IsMsStruct) { 1265855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian FieldDecl *FD = (*Field); 1266855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian if (Context.ZeroBitfieldFollowsBitfield(FD, LastFD)) 1267855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian ZeroLengthBitfield = FD; 126862055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian // Zero-length bitfields following non-bitfield members are 126962055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian // ignored: 1270855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian else if (Context.ZeroBitfieldFollowsNonBitfield(FD, LastFD)) 127162055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian continue; 127231e7f225fa3c603b84d66bc8ebdf7ed084e36e62Fariborz Jahanian // FIXME. streamline these conditions into a simple one. 127352bbe7a1133c3cb57e9246f1b96c12940ea3821aFariborz Jahanian else if (Context.BitfieldFollowsBitfield(FD, LastFD) || 127431e7f225fa3c603b84d66bc8ebdf7ed084e36e62Fariborz Jahanian Context.BitfieldFollowsNoneBitfield(FD, LastFD) || 127531e7f225fa3c603b84d66bc8ebdf7ed084e36e62Fariborz Jahanian Context.NoneBitfieldFollowsBitfield(FD, LastFD)) { 127631e7f225fa3c603b84d66bc8ebdf7ed084e36e62Fariborz Jahanian // 1) Adjacent bit fields are packed into the same 1-, 2-, or 12779b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian // 4-byte allocation unit if the integral types are the same 12789b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian // size and if the next bit field fits into the current 12799b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian // allocation unit without crossing the boundary imposed by the 12809b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian // common alignment requirements of the bit fields. 128131e7f225fa3c603b84d66bc8ebdf7ed084e36e62Fariborz Jahanian // 2) Establish a new alignment for a bitfield following 128252bbe7a1133c3cb57e9246f1b96c12940ea3821aFariborz Jahanian // a non-bitfield if size of their types differ. 128331e7f225fa3c603b84d66bc8ebdf7ed084e36e62Fariborz Jahanian // 3) Establish a new alignment for a non-bitfield following 128431e7f225fa3c603b84d66bc8ebdf7ed084e36e62Fariborz Jahanian // a bitfield if size of their types differ. 12859b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian std::pair<uint64_t, unsigned> FieldInfo = 12869b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian Context.getTypeInfo(FD->getType()); 12879b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian uint64_t TypeSize = FieldInfo.first; 12889b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian unsigned FieldAlign = FieldInfo.second; 128930364d0a6450315989f6613910b09f865044a2a0Fariborz Jahanian // This check is needed for 'long long' in -m32 mode. 129030364d0a6450315989f6613910b09f865044a2a0Fariborz Jahanian if (TypeSize > FieldAlign) 129130364d0a6450315989f6613910b09f865044a2a0Fariborz Jahanian FieldAlign = TypeSize; 12929b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian FieldInfo = Context.getTypeInfo(LastFD->getType()); 12939b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian uint64_t TypeSizeLastFD = FieldInfo.first; 12949b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian unsigned FieldAlignLastFD = FieldInfo.second; 129530364d0a6450315989f6613910b09f865044a2a0Fariborz Jahanian // This check is needed for 'long long' in -m32 mode. 129630364d0a6450315989f6613910b09f865044a2a0Fariborz Jahanian if (TypeSizeLastFD > FieldAlignLastFD) 129730364d0a6450315989f6613910b09f865044a2a0Fariborz Jahanian FieldAlignLastFD = TypeSizeLastFD; 12989b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian if (TypeSizeLastFD != TypeSize) { 12999b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian uint64_t UnpaddedFieldOffset = 13009b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian getDataSizeInBits() - UnfilledBitsInLastByte; 13019b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian FieldAlign = std::max(FieldAlign, FieldAlignLastFD); 1302ed63e03e35f2c8ad1a06d7bbc2249d132a730175Fariborz Jahanian // The maximum field alignment overrides the aligned attribute. 1303ed63e03e35f2c8ad1a06d7bbc2249d132a730175Fariborz Jahanian if (!MaxFieldAlignment.isZero()) { 1304ed63e03e35f2c8ad1a06d7bbc2249d132a730175Fariborz Jahanian unsigned MaxFieldAlignmentInBits = 1305ed63e03e35f2c8ad1a06d7bbc2249d132a730175Fariborz Jahanian Context.toBits(MaxFieldAlignment); 1306ed63e03e35f2c8ad1a06d7bbc2249d132a730175Fariborz Jahanian FieldAlign = std::min(FieldAlign, MaxFieldAlignmentInBits); 1307ed63e03e35f2c8ad1a06d7bbc2249d132a730175Fariborz Jahanian } 1308ed63e03e35f2c8ad1a06d7bbc2249d132a730175Fariborz Jahanian 13099b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian uint64_t NewSizeInBits = 13109b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian llvm::RoundUpToAlignment(UnpaddedFieldOffset, FieldAlign); 13119b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian setDataSize(llvm::RoundUpToAlignment(NewSizeInBits, 13129b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian Context.Target.getCharAlign())); 13139b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian UnfilledBitsInLastByte = getDataSizeInBits() - NewSizeInBits; 13149b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian setSize(std::max(getSizeInBits(), getDataSizeInBits())); 13159b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian } 13169b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian } 131762055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian LastFD = FD; 131862055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian } 1319a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson LayoutField(*Field); 132062055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian } 1321a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson} 1322a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson 13230aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbarvoid RecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize, 132478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis uint64_t TypeSize, 132578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis bool FieldPacked, 132678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis const FieldDecl *D) { 13274cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson assert(Context.getLangOptions().CPlusPlus && 13284cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson "Can only have wide bit-fields in C++!"); 13290aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 13304cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson // Itanium C++ ABI 2.4: 13310aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar // If sizeof(T)*8 < n, let T' be the largest integral POD type with 13324cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson // sizeof(T')*8 <= n. 13330aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 13344cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson QualType IntegralPODTypes[] = { 13350aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar Context.UnsignedCharTy, Context.UnsignedShortTy, Context.UnsignedIntTy, 13364cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson Context.UnsignedLongTy, Context.UnsignedLongLongTy 13374cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson }; 13384cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 13394cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson QualType Type; 13404cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson for (unsigned I = 0, E = llvm::array_lengthof(IntegralPODTypes); 13414cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson I != E; ++I) { 13424cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson uint64_t Size = Context.getTypeSize(IntegralPODTypes[I]); 13434cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 13444cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson if (Size > FieldSize) 13454cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson break; 13464cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 13474cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson Type = IntegralPODTypes[I]; 13484cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson } 13494cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson assert(!Type.isNull() && "Did not find a type!"); 13500aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 13513b3e1a1e8b44842ac3f07999c0f1eb82f13ffae4Ken Dyck CharUnits TypeAlign = Context.getTypeAlignInChars(Type); 13524cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 13534cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson // We're not going to use any of the unfilled bits in the last byte. 13544cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson UnfilledBitsInLastByte = 0; 13554cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 1356de9f153b2348f590151504888c22cb937134cd27Anders Carlsson uint64_t FieldOffset; 1357a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck uint64_t UnpaddedFieldOffset = getDataSizeInBits() - UnfilledBitsInLastByte; 13580aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 13594cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson if (IsUnion) { 1360a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck setDataSize(std::max(getDataSizeInBits(), FieldSize)); 1361de9f153b2348f590151504888c22cb937134cd27Anders Carlsson FieldOffset = 0; 13624cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson } else { 1363de9f153b2348f590151504888c22cb937134cd27Anders Carlsson // The bitfield is allocated starting at the next offset aligned appropriately 13640aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar // for T', with length n bits. 13653b3e1a1e8b44842ac3f07999c0f1eb82f13ffae4Ken Dyck FieldOffset = llvm::RoundUpToAlignment(getDataSizeInBits(), 13663b3e1a1e8b44842ac3f07999c0f1eb82f13ffae4Ken Dyck Context.toBits(TypeAlign)); 13670aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 13684cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson uint64_t NewSizeInBits = FieldOffset + FieldSize; 13690aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1370d5e3ed085032def4ac875d64cb029fc3926652edKen Dyck setDataSize(llvm::RoundUpToAlignment(NewSizeInBits, 1371d5e3ed085032def4ac875d64cb029fc3926652edKen Dyck Context.Target.getCharAlign())); 1372a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck UnfilledBitsInLastByte = getDataSizeInBits() - NewSizeInBits; 13734cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson } 13744cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 13754cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson // Place this field at the current location. 13764cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson FieldOffsets.push_back(FieldOffset); 13774cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 137878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis CheckFieldPadding(FieldOffset, UnpaddedFieldOffset, FieldOffset, 13793b3e1a1e8b44842ac3f07999c0f1eb82f13ffae4Ken Dyck Context.toBits(TypeAlign), FieldPacked, D); 138078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 13814cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson // Update the size. 1382a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck setSize(std::max(getSizeInBits(), getDataSizeInBits())); 13830aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 13844cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson // Remember max struct/class alignment. 13853b3e1a1e8b44842ac3f07999c0f1eb82f13ffae4Ken Dyck UpdateAlignment(TypeAlign); 13864cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson} 13874cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 13887d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonvoid RecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { 138942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson bool FieldPacked = Packed || D->hasAttr<PackedAttr>(); 1390a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck uint64_t UnpaddedFieldOffset = getDataSizeInBits() - UnfilledBitsInLastByte; 139178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis uint64_t FieldOffset = IsUnion ? 0 : UnpaddedFieldOffset; 13920f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson uint64_t FieldSize = D->getBitWidth()->EvaluateAsInt(Context).getZExtValue(); 1393bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 13940f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson std::pair<uint64_t, unsigned> FieldInfo = Context.getTypeInfo(D->getType()); 139542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson uint64_t TypeSize = FieldInfo.first; 139642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson unsigned FieldAlign = FieldInfo.second; 1397855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian 139830364d0a6450315989f6613910b09f865044a2a0Fariborz Jahanian // This check is needed for 'long long' in -m32 mode. 139930364d0a6450315989f6613910b09f865044a2a0Fariborz Jahanian if (IsMsStruct && (TypeSize > FieldAlign)) 140030364d0a6450315989f6613910b09f865044a2a0Fariborz Jahanian FieldAlign = TypeSize; 140130364d0a6450315989f6613910b09f865044a2a0Fariborz Jahanian 1402855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian if (ZeroLengthBitfield) { 1403855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian // If a zero-length bitfield is inserted after a bitfield, 1404855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian // and the alignment of the zero-length bitfield is 1405855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian // greater than the member that follows it, `bar', `bar' 1406855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian // will be aligned as the type of the zero-length bitfield. 1407855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian if (ZeroLengthBitfield != D) { 1408855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian std::pair<uint64_t, unsigned> FieldInfo = 1409855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian Context.getTypeInfo(ZeroLengthBitfield->getType()); 1410855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian unsigned ZeroLengthBitfieldAlignment = FieldInfo.second; 1411cc0f9f1a3b5df7fd308ff3d800fbbbbff805157dFariborz Jahanian // Ignore alignment of subsequent zero-length bitfields. 1412cc0f9f1a3b5df7fd308ff3d800fbbbbff805157dFariborz Jahanian if ((ZeroLengthBitfieldAlignment > FieldAlign) || (FieldSize == 0)) 1413855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian FieldAlign = ZeroLengthBitfieldAlignment; 1414cc0f9f1a3b5df7fd308ff3d800fbbbbff805157dFariborz Jahanian if (FieldSize) 1415cc0f9f1a3b5df7fd308ff3d800fbbbbff805157dFariborz Jahanian ZeroLengthBitfield = 0; 1416855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian } 1417855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian } 1418bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 14194cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson if (FieldSize > TypeSize) { 142078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis LayoutWideBitField(FieldSize, TypeSize, FieldPacked, D); 14214cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson return; 14224cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson } 14234cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 142478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // The align if the field is not packed. This is to check if the attribute 142578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // was unnecessary (-Wpacked). 142678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis unsigned UnpackedFieldAlign = FieldAlign; 142778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis uint64_t UnpackedFieldOffset = FieldOffset; 142878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (!Context.Target.useBitFieldTypeAlignment()) 142978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UnpackedFieldAlign = 1; 143078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 14310f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson if (FieldPacked || !Context.Target.useBitFieldTypeAlignment()) 143242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldAlign = 1; 1433cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt FieldAlign = std::max(FieldAlign, D->getMaxAlignment()); 143478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UnpackedFieldAlign = std::max(UnpackedFieldAlign, D->getMaxAlignment()); 14351eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 143642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // The maximum field alignment overrides the aligned attribute. 1437834945c19cfb87fc21dfb6980a0980618655d79dKen Dyck if (!MaxFieldAlignment.isZero()) { 1438834945c19cfb87fc21dfb6980a0980618655d79dKen Dyck unsigned MaxFieldAlignmentInBits = Context.toBits(MaxFieldAlignment); 1439834945c19cfb87fc21dfb6980a0980618655d79dKen Dyck FieldAlign = std::min(FieldAlign, MaxFieldAlignmentInBits); 1440834945c19cfb87fc21dfb6980a0980618655d79dKen Dyck UnpackedFieldAlign = std::min(UnpackedFieldAlign, MaxFieldAlignmentInBits); 144178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 1442bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1443b6a169395c1b30c76daffebcbd2164b6247a5d21Daniel Dunbar // Check if we need to add padding to give the field the correct alignment. 144442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (FieldSize == 0 || (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize) 144584b0316f720bd089d87acb21ec0002b2da33e6c9Daniel Dunbar FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign); 1446bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 144778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (FieldSize == 0 || 144878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis (UnpackedFieldOffset & (UnpackedFieldAlign-1)) + FieldSize > TypeSize) 144978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UnpackedFieldOffset = llvm::RoundUpToAlignment(UnpackedFieldOffset, 145078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UnpackedFieldAlign); 145178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 1452b6a169395c1b30c76daffebcbd2164b6247a5d21Daniel Dunbar // Padding members don't affect overall alignment. 145342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (!D->getIdentifier()) 145478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis FieldAlign = UnpackedFieldAlign = 1; 1455bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 145642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // Place this field at the current location. 145742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldOffsets.push_back(FieldOffset); 1458bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 145978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis CheckFieldPadding(FieldOffset, UnpaddedFieldOffset, UnpackedFieldOffset, 146078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UnpackedFieldAlign, FieldPacked, D); 146178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 1462e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson // Update DataSize to include the last byte containing (part of) the bitfield. 1463e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson if (IsUnion) { 1464e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson // FIXME: I think FieldSize should be TypeSize here. 1465a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck setDataSize(std::max(getDataSizeInBits(), FieldSize)); 1466e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson } else { 1467e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson uint64_t NewSizeInBits = FieldOffset + FieldSize; 1468bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1469d5e3ed085032def4ac875d64cb029fc3926652edKen Dyck setDataSize(llvm::RoundUpToAlignment(NewSizeInBits, 1470d5e3ed085032def4ac875d64cb029fc3926652edKen Dyck Context.Target.getCharAlign())); 1471a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck UnfilledBitsInLastByte = getDataSizeInBits() - NewSizeInBits; 1472e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson } 1473bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1474e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson // Update the size. 1475a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck setSize(std::max(getSizeInBits(), getDataSizeInBits())); 1476bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 147742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // Remember max struct/class alignment. 14783263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck UpdateAlignment(Context.toCharUnitsFromBits(FieldAlign), 14793263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck Context.toCharUnitsFromBits(UnpackedFieldAlign)); 148042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson} 14811eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 14827d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonvoid RecordLayoutBuilder::LayoutField(const FieldDecl *D) { 148342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (D->isBitField()) { 148442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson LayoutBitField(D); 148542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson return; 148642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson } 14871eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1488a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck uint64_t UnpaddedFieldOffset = getDataSizeInBits() - UnfilledBitsInLastByte; 148978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 1490e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson // Reset the unfilled bits. 1491e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson UnfilledBitsInLastByte = 0; 1492e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson 149342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson bool FieldPacked = Packed || D->hasAttr<PackedAttr>(); 14949ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck CharUnits FieldOffset = 1495a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck IsUnion ? CharUnits::Zero() : getDataSize(); 14969ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck CharUnits FieldSize; 14979ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck CharUnits FieldAlign; 1498bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 149942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (D->getType()->isIncompleteArrayType()) { 150042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // This is a flexible array member; we can't directly 150142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // query getTypeInfo about these, so we figure it out here. 150242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // Flexible array members don't have any size, but they 150342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // have to be aligned appropriately for their element type. 15049ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck FieldSize = CharUnits::Zero(); 15050f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson const ArrayType* ATy = Context.getAsArrayType(D->getType()); 15069ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck FieldAlign = Context.getTypeAlignInChars(ATy->getElementType()); 150742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson } else if (const ReferenceType *RT = D->getType()->getAs<ReferenceType>()) { 150842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson unsigned AS = RT->getPointeeType().getAddressSpace(); 15099ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck FieldSize = 15109ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck Context.toCharUnitsFromBits(Context.Target.getPointerWidth(AS)); 15119ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck FieldAlign = 15129ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck Context.toCharUnitsFromBits(Context.Target.getPointerAlign(AS)); 151342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson } else { 15149ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck std::pair<CharUnits, CharUnits> FieldInfo = 15159ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck Context.getTypeInfoInChars(D->getType()); 151642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldSize = FieldInfo.first; 1517bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson FieldAlign = FieldInfo.second; 1518855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian 1519855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian if (ZeroLengthBitfield) { 1520855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian // If a zero-length bitfield is inserted after a bitfield, 1521855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian // and the alignment of the zero-length bitfield is 1522855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian // greater than the member that follows it, `bar', `bar' 1523855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian // will be aligned as the type of the zero-length bitfield. 1524855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian std::pair<CharUnits, CharUnits> FieldInfo = 1525855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian Context.getTypeInfoInChars(ZeroLengthBitfield->getType()); 1526855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian CharUnits ZeroLengthBitfieldAlignment = FieldInfo.second; 1527855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian if (ZeroLengthBitfieldAlignment > FieldAlign) 1528855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian FieldAlign = ZeroLengthBitfieldAlignment; 1529855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian ZeroLengthBitfield = 0; 1530855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian } 15316f75550e40a9177db9979fc130ce3ece026b137dDouglas Gregor 15329b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian if (Context.getLangOptions().MSBitfields || IsMsStruct) { 15336f75550e40a9177db9979fc130ce3ece026b137dDouglas Gregor // If MS bitfield layout is required, figure out what type is being 15346f75550e40a9177db9979fc130ce3ece026b137dDouglas Gregor // laid out and align the field to the width of that type. 15356f75550e40a9177db9979fc130ce3ece026b137dDouglas Gregor 15366f75550e40a9177db9979fc130ce3ece026b137dDouglas Gregor // Resolve all typedefs down to their base type and round up the field 15376f75550e40a9177db9979fc130ce3ece026b137dDouglas Gregor // alignment if necessary. 15386f75550e40a9177db9979fc130ce3ece026b137dDouglas Gregor QualType T = Context.getBaseElementType(D->getType()); 15396f75550e40a9177db9979fc130ce3ece026b137dDouglas Gregor if (const BuiltinType *BTy = T->getAs<BuiltinType>()) { 15409ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck CharUnits TypeSize = Context.getTypeSizeInChars(BTy); 15416f75550e40a9177db9979fc130ce3ece026b137dDouglas Gregor if (TypeSize > FieldAlign) 15426f75550e40a9177db9979fc130ce3ece026b137dDouglas Gregor FieldAlign = TypeSize; 15436f75550e40a9177db9979fc130ce3ece026b137dDouglas Gregor } 15446f75550e40a9177db9979fc130ce3ece026b137dDouglas Gregor } 154542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson } 15461eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 154778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // The align if the field is not packed. This is to check if the attribute 154878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // was unnecessary (-Wpacked). 15499ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck CharUnits UnpackedFieldAlign = FieldAlign; 15509ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck CharUnits UnpackedFieldOffset = FieldOffset; 155178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 155242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (FieldPacked) 15539ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck FieldAlign = CharUnits::One(); 15549ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck CharUnits MaxAlignmentInChars = 15559ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck Context.toCharUnitsFromBits(D->getMaxAlignment()); 15569ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck FieldAlign = std::max(FieldAlign, MaxAlignmentInChars); 15579ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck UnpackedFieldAlign = std::max(UnpackedFieldAlign, MaxAlignmentInChars); 15581eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 155942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // The maximum field alignment overrides the aligned attribute. 1560834945c19cfb87fc21dfb6980a0980618655d79dKen Dyck if (!MaxFieldAlignment.isZero()) { 15619ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck FieldAlign = std::min(FieldAlign, MaxFieldAlignment); 15629ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck UnpackedFieldAlign = std::min(UnpackedFieldAlign, MaxFieldAlignment); 156378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 15641eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 156542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // Round up the current record size to the field's alignment boundary. 15669ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck FieldOffset = FieldOffset.RoundUpToAlignment(FieldAlign); 15679ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck UnpackedFieldOffset = 15689ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck UnpackedFieldOffset.RoundUpToAlignment(UnpackedFieldAlign); 1569bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 157083a45e7dab892e9efd3515eca4eb5b81bc3f2126Anders Carlsson if (!IsUnion && EmptySubobjects) { 157183a45e7dab892e9efd3515eca4eb5b81bc3f2126Anders Carlsson // Check if we can place the field at this offset. 15729ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck while (!EmptySubobjects->CanPlaceFieldAtOffset(D, FieldOffset)) { 157342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // We couldn't place the field at the offset. Try again at a new offset. 157442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldOffset += FieldAlign; 15756026504302763f74102592602b392cecd5ced3aeAnders Carlsson } 1576bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson } 1577bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1578bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // Place this field at the current location. 15799ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck FieldOffsets.push_back(Context.toBits(FieldOffset)); 15801eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 15819ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck CheckFieldPadding(Context.toBits(FieldOffset), UnpaddedFieldOffset, 15829ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck Context.toBits(UnpackedFieldOffset), 15839ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck Context.toBits(UnpackedFieldAlign), FieldPacked, D); 158478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 1585bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // Reserve space for this field. 15866b46cd9c8508e1a67c66cbb83a9077bb787a3ce2Daniel Dunbar uint64_t FieldSizeInBits = Context.toBits(FieldSize); 1587bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson if (IsUnion) 15886b46cd9c8508e1a67c66cbb83a9077bb787a3ce2Daniel Dunbar setSize(std::max(getSizeInBits(), FieldSizeInBits)); 1589bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson else 1590f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck setSize(FieldOffset + FieldSize); 15911eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1592a223935e5cf82e939e1ca1da4111d63025a04e39Anders Carlsson // Update the data size. 15936b46cd9c8508e1a67c66cbb83a9077bb787a3ce2Daniel Dunbar setDataSize(getSizeInBits()); 15941eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1595bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // Remember max struct/class alignment. 15969ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck UpdateAlignment(FieldAlign, UnpackedFieldAlign); 1597bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson} 1598bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 159978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidisvoid RecordLayoutBuilder::FinishLayout(const NamedDecl *D) { 1600bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // In C++, records cannot be of size 0. 1601a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck if (Context.getLangOptions().CPlusPlus && getSizeInBits() == 0) { 1602adf082e829eb71871b6043009888df3b79055dbaFariborz Jahanian if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) { 1603adf082e829eb71871b6043009888df3b79055dbaFariborz Jahanian // Compatibility with gcc requires a class (pod or non-pod) 1604adf082e829eb71871b6043009888df3b79055dbaFariborz Jahanian // which is not empty but of size 0; such as having fields of 1605adf082e829eb71871b6043009888df3b79055dbaFariborz Jahanian // array of zero-length, remains of Size 0 1606adf082e829eb71871b6043009888df3b79055dbaFariborz Jahanian if (RD->isEmpty()) 1607f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck setSize(CharUnits::One()); 1608adf082e829eb71871b6043009888df3b79055dbaFariborz Jahanian } 1609adf082e829eb71871b6043009888df3b79055dbaFariborz Jahanian else 1610f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck setSize(CharUnits::One()); 1611adf082e829eb71871b6043009888df3b79055dbaFariborz Jahanian } 1612bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // Finally, round the size of the record up to the alignment of the 1613bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // record itself. 1614a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck uint64_t UnpaddedSize = getSizeInBits() - UnfilledBitsInLastByte; 1615f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck uint64_t UnpackedSizeInBits = 1616a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck llvm::RoundUpToAlignment(getSizeInBits(), 1617a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck Context.toBits(UnpackedAlignment)); 1618f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck CharUnits UnpackedSize = Context.toCharUnitsFromBits(UnpackedSizeInBits); 1619a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck setSize(llvm::RoundUpToAlignment(getSizeInBits(), Context.toBits(Alignment))); 162078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 162178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis unsigned CharBitNum = Context.Target.getCharWidth(); 162278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (const RecordDecl *RD = dyn_cast<RecordDecl>(D)) { 162378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // Warn if padding was introduced to the struct/class/union. 1624a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck if (getSizeInBits() > UnpaddedSize) { 1625a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck unsigned PadSize = getSizeInBits() - UnpaddedSize; 162678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis bool InBits = true; 162778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (PadSize % CharBitNum == 0) { 162878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis PadSize = PadSize / CharBitNum; 162978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis InBits = false; 163078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 163178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis Diag(RD->getLocation(), diag::warn_padded_struct_size) 163278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << Context.getTypeDeclType(RD) 163378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << PadSize 163478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << (InBits ? 1 : 0) /*(byte|bit)*/ << (PadSize > 1); // plural or not 163578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 163678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 163778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // Warn if we packed it unnecessarily. If the alignment is 1 byte don't 163878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // bother since there won't be alignment issues. 1639a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck if (Packed && UnpackedAlignment > CharUnits::One() && 1640f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck getSize() == UnpackedSize) 164178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis Diag(D->getLocation(), diag::warn_unnecessary_packed) 164278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << Context.getTypeDeclType(RD); 164378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 1644bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson} 1645bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 16463263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyckvoid RecordLayoutBuilder::UpdateAlignment(CharUnits NewAlignment, 16473263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck CharUnits UnpackedNewAlignment) { 1648c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar // The alignment is not modified when using 'mac68k' alignment. 1649c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar if (IsMac68kAlign) 1650c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar return; 1651c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar 16523263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck if (NewAlignment > Alignment) { 16533263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck assert(llvm::isPowerOf2_32(NewAlignment.getQuantity() && 16543263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck "Alignment not a power of 2")); 16553263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck Alignment = NewAlignment; 165678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 165778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 16583263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck if (UnpackedNewAlignment > UnpackedAlignment) { 16593263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck assert(llvm::isPowerOf2_32(UnpackedNewAlignment.getQuantity() && 166078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis "Alignment not a power of 2")); 16613263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck UnpackedAlignment = UnpackedNewAlignment; 166278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 166378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis} 166478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 166578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidisvoid RecordLayoutBuilder::CheckFieldPadding(uint64_t Offset, 166678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis uint64_t UnpaddedOffset, 166778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis uint64_t UnpackedOffset, 166878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis unsigned UnpackedAlign, 166978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis bool isPacked, 167078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis const FieldDecl *D) { 167178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // We let objc ivars without warning, objc interfaces generally are not used 167278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // for padding tricks. 167378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (isa<ObjCIvarDecl>(D)) 1674bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson return; 16751eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 167678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis unsigned CharBitNum = Context.Target.getCharWidth(); 16771eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 167878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // Warn if padding was introduced to the struct/class. 167978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (!IsUnion && Offset > UnpaddedOffset) { 168078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis unsigned PadSize = Offset - UnpaddedOffset; 168178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis bool InBits = true; 168278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (PadSize % CharBitNum == 0) { 168378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis PadSize = PadSize / CharBitNum; 168478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis InBits = false; 168578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 168678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (D->getIdentifier()) 168778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis Diag(D->getLocation(), diag::warn_padded_struct_field) 168878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << (D->getParent()->isStruct() ? 0 : 1) // struct|class 168978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << Context.getTypeDeclType(D->getParent()) 169078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << PadSize 169178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << (InBits ? 1 : 0) /*(byte|bit)*/ << (PadSize > 1) // plural or not 169278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << D->getIdentifier(); 169378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis else 169478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis Diag(D->getLocation(), diag::warn_padded_struct_anon_field) 169578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << (D->getParent()->isStruct() ? 0 : 1) // struct|class 169678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << Context.getTypeDeclType(D->getParent()) 169778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << PadSize 169878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << (InBits ? 1 : 0) /*(byte|bit)*/ << (PadSize > 1); // plural or not 169978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 170078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 170178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // Warn if we packed it unnecessarily. If the alignment is 1 byte don't 170278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // bother since there won't be alignment issues. 170378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (isPacked && UnpackedAlign > CharBitNum && Offset == UnpackedOffset) 170478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis Diag(D->getLocation(), diag::warn_unnecessary_packed) 170578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << D->getIdentifier(); 1706bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson} 17071eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1708f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlssonconst CXXMethodDecl * 17097d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders CarlssonRecordLayoutBuilder::ComputeKeyFunction(const CXXRecordDecl *RD) { 17108d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar // If a class isn't polymorphic it doesn't have a key function. 1711f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (!RD->isPolymorphic()) 1712f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson return 0; 171361eab8872168af6eb1e0047a82901096cf145e27Eli Friedman 171461eab8872168af6eb1e0047a82901096cf145e27Eli Friedman // A class inside an anonymous namespace doesn't have a key function. (Or 171561eab8872168af6eb1e0047a82901096cf145e27Eli Friedman // at least, there's no point to assigning a key function to such a class; 171661eab8872168af6eb1e0047a82901096cf145e27Eli Friedman // this doesn't affect the ABI.) 171761eab8872168af6eb1e0047a82901096cf145e27Eli Friedman if (RD->isInAnonymousNamespace()) 171861eab8872168af6eb1e0047a82901096cf145e27Eli Friedman return 0; 171961eab8872168af6eb1e0047a82901096cf145e27Eli Friedman 17203bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis // Template instantiations don't have key functions,see Itanium C++ ABI 5.2.6. 17213bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis // Same behavior as GCC. 17223bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis TemplateSpecializationKind TSK = RD->getTemplateSpecializationKind(); 17233bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis if (TSK == TSK_ImplicitInstantiation || 17243bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis TSK == TSK_ExplicitInstantiationDefinition) 17253bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis return 0; 17263bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis 1727bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar for (CXXRecordDecl::method_iterator I = RD->method_begin(), 1728bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->method_end(); I != E; ++I) { 1729f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson const CXXMethodDecl *MD = *I; 1730bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1731f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (!MD->isVirtual()) 1732f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson continue; 1733bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1734f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (MD->isPure()) 1735f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson continue; 173661eab8872168af6eb1e0047a82901096cf145e27Eli Friedman 1737f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson // Ignore implicit member functions, they are always marked as inline, but 1738f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson // they don't have a body until they're defined. 1739f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (MD->isImplicit()) 1740f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson continue; 1741bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1742bd6d6197fcfc98356ea60e816365eb0648b69556Douglas Gregor if (MD->isInlineSpecified()) 1743bd6d6197fcfc98356ea60e816365eb0648b69556Douglas Gregor continue; 1744f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson 1745f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (MD->hasInlineBody()) 1746f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson continue; 1747bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1748f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson // We found it. 1749f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson return MD; 1750f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson } 1751bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1752f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson return 0; 1753f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson} 1754f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson 175578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios KyrtzidisDiagnosticBuilder 175678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios KyrtzidisRecordLayoutBuilder::Diag(SourceLocation Loc, unsigned DiagID) { 175733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis return Context.getDiagnostics().Report(Loc, DiagID); 175878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis} 175978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 1760cb9c07418b699bd2b8384d31ff4392df7d76eb7cBenjamin Kramernamespace { 1761cb9c07418b699bd2b8384d31ff4392df7d76eb7cBenjamin Kramer // This class implements layout specific to the Microsoft ABI. 1762cb9c07418b699bd2b8384d31ff4392df7d76eb7cBenjamin Kramer class MSRecordLayoutBuilder : public RecordLayoutBuilder { 1763cb9c07418b699bd2b8384d31ff4392df7d76eb7cBenjamin Kramer public: 17644ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad MSRecordLayoutBuilder(const ASTContext& Ctx, 17654ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad EmptySubobjectMap *EmptySubobjects) : 1766cb9c07418b699bd2b8384d31ff4392df7d76eb7cBenjamin Kramer RecordLayoutBuilder(Ctx, EmptySubobjects) {} 1767cb9c07418b699bd2b8384d31ff4392df7d76eb7cBenjamin Kramer 17685dc989c4f630acc3c0028b2d1229511063671a29Ken Dyck virtual CharUnits GetVirtualPointersSize(const CXXRecordDecl *RD) const; 1769cb9c07418b699bd2b8384d31ff4392df7d76eb7cBenjamin Kramer }; 1770cb9c07418b699bd2b8384d31ff4392df7d76eb7cBenjamin Kramer} 1771c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis 17725dc989c4f630acc3c0028b2d1229511063671a29Ken DyckCharUnits 1773c9f8aece7e111f90265dfad9a81f3f517be948deCharles DavisMSRecordLayoutBuilder::GetVirtualPointersSize(const CXXRecordDecl *RD) const { 1774c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis // We should reserve space for two pointers if the class has both 1775c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis // virtual functions and virtual bases. 17765dc989c4f630acc3c0028b2d1229511063671a29Ken Dyck CharUnits PointerWidth = 17775dc989c4f630acc3c0028b2d1229511063671a29Ken Dyck Context.toCharUnitsFromBits(Context.Target.getPointerWidth(0)); 1778c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis if (RD->isPolymorphic() && RD->getNumVBases() > 0) 17795dc989c4f630acc3c0028b2d1229511063671a29Ken Dyck return 2 * PointerWidth; 17805dc989c4f630acc3c0028b2d1229511063671a29Ken Dyck return PointerWidth; 1781c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis} 1782c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis 17831e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// getASTRecordLayout - Get or compute information about the layout of the 17841e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// specified record (struct/union/class), which indicates its size and field 17851e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// position information. 17864ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadconst ASTRecordLayout & 17874ba2a17694148e16eaa8d3917f657ffcd3667be4Jay FoadASTContext::getASTRecordLayout(const RecordDecl *D) const { 17881e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson D = D->getDefinition(); 17891e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson assert(D && "Cannot get layout of forward declarations!"); 17901e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 17911e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // Look up this layout, if already laid out, return what we have. 17921e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // Note that we can't save a reference to the entry because this function 17931e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // is recursive. 17941e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson const ASTRecordLayout *Entry = ASTRecordLayouts[D]; 17951e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson if (Entry) return *Entry; 17961e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 17972f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson const ASTRecordLayout *NewEntry; 17982f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson 17992f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) { 1800261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson EmptySubobjectMap EmptySubobjects(*this, RD); 180158b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 1802c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis // When compiling for Microsoft, use the special MS builder. 1803cfe17e5c82762cc854012e472b66f4278f0a4a2aArgyrios Kyrtzidis llvm::OwningPtr<RecordLayoutBuilder> Builder; 180420cf717034ba1f20fc47c025ecb72ed9b631ad13Charles Davis switch (Target.getCXXABI()) { 180520cf717034ba1f20fc47c025ecb72ed9b631ad13Charles Davis default: 1806cfe17e5c82762cc854012e472b66f4278f0a4a2aArgyrios Kyrtzidis Builder.reset(new RecordLayoutBuilder(*this, &EmptySubobjects)); 180720cf717034ba1f20fc47c025ecb72ed9b631ad13Charles Davis break; 180820cf717034ba1f20fc47c025ecb72ed9b631ad13Charles Davis case CXXABI_Microsoft: 1809cfe17e5c82762cc854012e472b66f4278f0a4a2aArgyrios Kyrtzidis Builder.reset(new MSRecordLayoutBuilder(*this, &EmptySubobjects)); 181020cf717034ba1f20fc47c025ecb72ed9b631ad13Charles Davis } 18114d96d9f0e758fb9244749f99d4b0a3ab1e3e0592Ted Kremenek // Recover resources if we crash before exiting this method. 181243d8bcfc3601aec7dd3e7ccc7b6ddd3ff6189c62Ted Kremenek llvm::CrashRecoveryContextCleanupRegistrar<RecordLayoutBuilder> 181343d8bcfc3601aec7dd3e7ccc7b6ddd3ff6189c62Ted Kremenek RecordBuilderCleanup(Builder.get()); 18144d96d9f0e758fb9244749f99d4b0a3ab1e3e0592Ted Kremenek 1815c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis Builder->Layout(RD); 18162f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson 18172f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson // FIXME: This is not always correct. See the part about bitfields at 18182f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson // http://www.codesourcery.com/public/cxx-abi/abi.html#POD for more info. 18192f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson // FIXME: IsPODForThePurposeOfLayout should be stored in the record layout. 18202f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson bool IsPODForThePurposeOfLayout = cast<CXXRecordDecl>(D)->isPOD(); 18212f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson 18222f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson // FIXME: This should be done in FinalizeLayout. 1823f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck CharUnits DataSize = 1824f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck IsPODForThePurposeOfLayout ? Builder->getSize() : Builder->getDataSize(); 1825f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck CharUnits NonVirtualSize = 1826f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck IsPODForThePurposeOfLayout ? DataSize : Builder->NonVirtualSize; 18272f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson 18280aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar NewEntry = 1829f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck new (*this) ASTRecordLayout(*this, Builder->getSize(), 1830ea7f6c2c53127b875ed432fd1793d48270d8ba6bKen Dyck Builder->Alignment, 1831f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck DataSize, 1832ec2990351335f163601b98e39b52425e2e9f931eKen Dyck Builder->FieldOffsets.data(), 1833c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis Builder->FieldOffsets.size(), 1834a1fdb0bc09aa0d17841cdbdd8c52cd1368251cbfKen Dyck NonVirtualSize, 1835df205382dae666b011d857402114e4f4acd56c81Ken Dyck Builder->NonVirtualAlignment, 1836261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson EmptySubobjects.SizeOfLargestEmptySubobject, 1837c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis Builder->PrimaryBase, 1838c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis Builder->PrimaryBaseIsVirtual, 1839c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis Builder->Bases, Builder->VBases); 18402f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson } else { 1841261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0); 18422f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson Builder.Layout(D); 18430aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 18442f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson NewEntry = 1845f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck new (*this) ASTRecordLayout(*this, Builder.getSize(), 1846ea7f6c2c53127b875ed432fd1793d48270d8ba6bKen Dyck Builder.Alignment, 1847f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck Builder.getSize(), 18482f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson Builder.FieldOffsets.data(), 18492f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson Builder.FieldOffsets.size()); 18502f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson } 18512f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson 18521e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson ASTRecordLayouts[D] = NewEntry; 18531e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 18541e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson if (getLangOptions().DumpRecordLayouts) { 18551e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson llvm::errs() << "\n*** Dumping AST Record Layout\n"; 18561e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson DumpRecordLayout(D, llvm::errs()); 18571e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson } 18581e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 18591e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson return *NewEntry; 18601e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson} 18611e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 18621e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlssonconst CXXMethodDecl *ASTContext::getKeyFunction(const CXXRecordDecl *RD) { 18631e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson RD = cast<CXXRecordDecl>(RD->getDefinition()); 18641e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson assert(RD && "Cannot get key function for forward declarations!"); 18650aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 18661e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson const CXXMethodDecl *&Entry = KeyFunctions[RD]; 18670aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar if (!Entry) 18687d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlsson Entry = RecordLayoutBuilder::ComputeKeyFunction(RD); 18690aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 18701e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson return Entry; 18711e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson} 18721e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 18731e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// getInterfaceLayoutImpl - Get or compute information about the 18741e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// layout of the given interface. 18751e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// 18761e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// \param Impl - If given, also include the layout of the interface's 18771e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// implementation. This may differ by including synthesized ivars. 18781e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlssonconst ASTRecordLayout & 18791e641ce1c169b4b0cac3d7ad6da44b323453049cAnders CarlssonASTContext::getObjCLayout(const ObjCInterfaceDecl *D, 18804ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad const ObjCImplementationDecl *Impl) const { 18811e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson assert(!D->isForwardDecl() && "Invalid interface decl!"); 18821e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 18831e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // Look up this layout, if already laid out, return what we have. 18841e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson ObjCContainerDecl *Key = 18851e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson Impl ? (ObjCContainerDecl*) Impl : (ObjCContainerDecl*) D; 18861e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson if (const ASTRecordLayout *Entry = ObjCLayouts[Key]) 18871e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson return *Entry; 18881e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 18891e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // Add in synthesized ivar count if laying out an implementation. 18901e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson if (Impl) { 18911e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson unsigned SynthCount = CountNonClassIvars(D); 18921e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // If there aren't any sythesized ivars then reuse the interface 18931e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // entry. Note we can't cache this because we simply free all 18941e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // entries later; however we shouldn't look up implementations 18951e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // frequently. 18961e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson if (SynthCount == 0) 18971e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson return getObjCLayout(D, 0); 18981e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson } 18991e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 1900261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0); 190136cdc61b98460c06ee07710f77b911675fdce6a7Anders Carlsson Builder.Layout(D); 190236cdc61b98460c06ee07710f77b911675fdce6a7Anders Carlsson 19031e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson const ASTRecordLayout *NewEntry = 1904f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck new (*this) ASTRecordLayout(*this, Builder.getSize(), 1905ea7f6c2c53127b875ed432fd1793d48270d8ba6bKen Dyck Builder.Alignment, 1906f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck Builder.getDataSize(), 190736cdc61b98460c06ee07710f77b911675fdce6a7Anders Carlsson Builder.FieldOffsets.data(), 190836cdc61b98460c06ee07710f77b911675fdce6a7Anders Carlsson Builder.FieldOffsets.size()); 19090aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 19101e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson ObjCLayouts[Key] = NewEntry; 19111e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 19121e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson return *NewEntry; 19131e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson} 19141e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 1915bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbarstatic void PrintOffset(llvm::raw_ostream &OS, 19163069a0d28637ad0ad583d9fdd7bc6bc6aa677fb5Anders Carlsson CharUnits Offset, unsigned IndentLevel) { 19173069a0d28637ad0ad583d9fdd7bc6bc6aa677fb5Anders Carlsson OS << llvm::format("%4d | ", Offset.getQuantity()); 1918bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS.indent(IndentLevel * 2); 1919bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar} 1920bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1921bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbarstatic void DumpCXXRecordLayout(llvm::raw_ostream &OS, 19224ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad const CXXRecordDecl *RD, const ASTContext &C, 19233069a0d28637ad0ad583d9fdd7bc6bc6aa677fb5Anders Carlsson CharUnits Offset, 1924bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar unsigned IndentLevel, 1925bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar const char* Description, 1926bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar bool IncludeVirtualBases) { 19273069a0d28637ad0ad583d9fdd7bc6bc6aa677fb5Anders Carlsson const ASTRecordLayout &Layout = C.getASTRecordLayout(RD); 1928bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1929bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar PrintOffset(OS, Offset, IndentLevel); 1930cb421fa690da545b58a720abe5f1c49b166dbde7Dan Gohman OS << C.getTypeDeclType(const_cast<CXXRecordDecl *>(RD)).getAsString(); 1931bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (Description) 1932bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << ' ' << Description; 1933bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (RD->isEmpty()) 1934bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << " (empty)"; 1935bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << '\n'; 1936bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1937bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar IndentLevel++; 1938bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 19393069a0d28637ad0ad583d9fdd7bc6bc6aa677fb5Anders Carlsson const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 1940bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1941bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar // Vtable pointer. 1942bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (RD->isDynamicClass() && !PrimaryBase) { 1943bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar PrintOffset(OS, Offset, IndentLevel); 1944900fc6388e803868a34b9483510c345e9b49d7ebBenjamin Kramer OS << '(' << RD << " vtable pointer)\n"; 1945bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar } 1946bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar // Dump (non-virtual) bases 1947bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1948bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->bases_end(); I != E; ++I) { 1949bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar assert(!I->getType()->isDependentType() && 1950bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar "Cannot layout class with dependent bases."); 1951bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (I->isVirtual()) 1952bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar continue; 1953bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1954bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar const CXXRecordDecl *Base = 1955bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1956bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 19573069a0d28637ad0ad583d9fdd7bc6bc6aa677fb5Anders Carlsson CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(Base); 1958bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1959bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar DumpCXXRecordLayout(OS, Base, C, BaseOffset, IndentLevel, 1960bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar Base == PrimaryBase ? "(primary base)" : "(base)", 1961bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar /*IncludeVirtualBases=*/false); 1962bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar } 1963bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1964bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar // Dump fields. 1965bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar uint64_t FieldNo = 0; 1966bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar for (CXXRecordDecl::field_iterator I = RD->field_begin(), 1967bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->field_end(); I != E; ++I, ++FieldNo) { 1968bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar const FieldDecl *Field = *I; 19693069a0d28637ad0ad583d9fdd7bc6bc6aa677fb5Anders Carlsson CharUnits FieldOffset = Offset + 1970fb1e3bc29b667f4275e1d5a43d64ec173f4f9a7dKen Dyck C.toCharUnitsFromBits(Layout.getFieldOffset(FieldNo)); 1971bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1972bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (const RecordType *RT = Field->getType()->getAs<RecordType>()) { 1973bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (const CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(RT->getDecl())) { 1974bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar DumpCXXRecordLayout(OS, D, C, FieldOffset, IndentLevel, 19754087f27e5416c799bcb6be072f905be752acb61cDaniel Dunbar Field->getName().data(), 1976bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar /*IncludeVirtualBases=*/true); 1977bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar continue; 1978bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar } 1979bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar } 1980bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1981bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar PrintOffset(OS, FieldOffset, IndentLevel); 1982900fc6388e803868a34b9483510c345e9b49d7ebBenjamin Kramer OS << Field->getType().getAsString() << ' ' << Field << '\n'; 1983bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar } 1984bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1985bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (!IncludeVirtualBases) 1986bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar return; 1987bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1988bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar // Dump virtual bases. 1989bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(), 1990bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->vbases_end(); I != E; ++I) { 1991bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar assert(I->isVirtual() && "Found non-virtual class!"); 1992bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar const CXXRecordDecl *VBase = 1993bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1994bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 19953069a0d28637ad0ad583d9fdd7bc6bc6aa677fb5Anders Carlsson CharUnits VBaseOffset = Offset + Layout.getVBaseClassOffset(VBase); 1996bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar DumpCXXRecordLayout(OS, VBase, C, VBaseOffset, IndentLevel, 1997bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar VBase == PrimaryBase ? 1998bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar "(primary virtual base)" : "(virtual base)", 1999bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar /*IncludeVirtualBases=*/false); 2000bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar } 2001bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 20025f022d82696c84e4d127c558871d68ac6273274eKen Dyck OS << " sizeof=" << Layout.getSize().getQuantity(); 2003ec2990351335f163601b98e39b52425e2e9f931eKen Dyck OS << ", dsize=" << Layout.getDataSize().getQuantity(); 2004dac54c124e302d6f028ea5723c425b7f66fc7c71Ken Dyck OS << ", align=" << Layout.getAlignment().getQuantity() << '\n'; 20055c3633fa57f27b0909ab5767715c4e66b8920165Ken Dyck OS << " nvsize=" << Layout.getNonVirtualSize().getQuantity(); 200668cf1a5a01ba43ed56a8624632fd65e0804430acKen Dyck OS << ", nvalign=" << Layout.getNonVirtualAlign().getQuantity() << '\n'; 2007bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << '\n'; 2008bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar} 20098d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar 20108d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbarvoid ASTContext::DumpRecordLayout(const RecordDecl *RD, 20114ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad llvm::raw_ostream &OS) const { 20128d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar const ASTRecordLayout &Info = getASTRecordLayout(RD); 20138d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar 20148d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) 20153069a0d28637ad0ad583d9fdd7bc6bc6aa677fb5Anders Carlsson return DumpCXXRecordLayout(OS, CXXRD, *this, CharUnits(), 0, 0, 20168d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar /*IncludeVirtualBases=*/true); 20178d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar 20188d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << "Type: " << getTypeDeclType(RD).getAsString() << "\n"; 20198d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << "Record: "; 20208d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar RD->dump(); 20218d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << "\nLayout: "; 20228d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << "<ASTRecordLayout\n"; 2023dd76a9ab9ea675671200f94b18ce95766841952bKen Dyck OS << " Size:" << toBits(Info.getSize()) << "\n"; 2024ec2990351335f163601b98e39b52425e2e9f931eKen Dyck OS << " DataSize:" << toBits(Info.getDataSize()) << "\n"; 2025dac54c124e302d6f028ea5723c425b7f66fc7c71Ken Dyck OS << " Alignment:" << toBits(Info.getAlignment()) << "\n"; 20268d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << " FieldOffsets: ["; 20278d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar for (unsigned i = 0, e = Info.getFieldCount(); i != e; ++i) { 20288d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar if (i) OS << ", "; 20298d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << Info.getFieldOffset(i); 20308d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar } 20318d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << "]>\n"; 20328d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar} 2033