RecordLayoutBuilder.cpp revision c23aca44753ff65303fb19d4d6d2114018629f07
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 10d4f5198ae07d9a4958d8191bac694ded12173ad9Benjamin Kramer#include "clang/AST/ASTContext.h" 11bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson#include "clang/AST/Attr.h" 12245656ec65ec600ef1ab05f4c8d9f780542d689dAnders Carlsson#include "clang/AST/CXXInheritance.h" 13bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson#include "clang/AST/Decl.h" 1474cbe226207fd101623638dadfa7fbada04ff2a6Anders Carlsson#include "clang/AST/DeclCXX.h" 1593fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson#include "clang/AST/DeclObjC.h" 16bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson#include "clang/AST/Expr.h" 179392fa63e45716e32061d05673fa28909f325b02Anders Carlsson#include "clang/AST/RecordLayout.h" 18bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson#include "clang/Basic/TargetInfo.h" 1978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis#include "clang/Sema/SemaDiagnostic.h" 20bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar#include "llvm/Support/Format.h" 21bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar#include "llvm/ADT/SmallSet.h" 22bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar#include "llvm/Support/MathExtras.h" 234d96d9f0e758fb9244749f99d4b0a3ab1e3e0592Ted Kremenek#include "llvm/Support/CrashRecoveryContext.h" 24bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 25bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlssonusing namespace clang; 26bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 277e220286410422ed1dc0409a9cb9708fe50e3df0Benjamin Kramernamespace { 286a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson 29ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// BaseSubobjectInfo - Represents a single base subobject in a complete class. 30ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// For a class hierarchy like 31ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// 32ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// class A { }; 33ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// class B : A { }; 34ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// class C : A, B { }; 35ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// 36ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// The BaseSubobjectInfo graph for C will have three BaseSubobjectInfo 37ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// instances, one for B and two for A. 38ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// 39ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson/// If a base is virtual, it will only have one BaseSubobjectInfo allocated. 40ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlssonstruct BaseSubobjectInfo { 41ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson /// Class - The class for this base info. 424a25799760982b3363f3c4eb6df953d70e35e37dAnders Carlsson const CXXRecordDecl *Class; 43ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson 44ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson /// IsVirtual - Whether the BaseInfo represents a virtual base or not. 454a25799760982b3363f3c4eb6df953d70e35e37dAnders Carlsson bool IsVirtual; 464a25799760982b3363f3c4eb6df953d70e35e37dAnders Carlsson 47ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson /// Bases - Information about the base subobjects. 485f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<BaseSubobjectInfo*, 4> Bases; 49ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson 506e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// PrimaryVirtualBaseInfo - Holds the base info for the primary virtual base 516e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// of this base info (if one exists). 526e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *PrimaryVirtualBaseInfo; 53ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson 54ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson // FIXME: Document. 55ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson const BaseSubobjectInfo *Derived; 564a25799760982b3363f3c4eb6df953d70e35e37dAnders Carlsson}; 574a25799760982b3363f3c4eb6df953d70e35e37dAnders Carlsson 586a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson/// EmptySubobjectMap - Keeps track of which empty subobjects exist at different 596a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson/// offsets while laying out a C++ class. 606a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlssonclass EmptySubobjectMap { 614ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad const ASTContext &Context; 628c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson uint64_t CharWidth; 638c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson 646a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson /// Class - The class whose empty entries we're keeping track of. 656a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson const CXXRecordDecl *Class; 660aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 6758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson /// EmptyClassOffsets - A map from offsets to empty record decls. 685f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner typedef SmallVector<const CXXRecordDecl *, 1> ClassVectorTy; 69d8da76365f40a0c12c7d802a0da2aaacf4b2cf99Anders Carlsson typedef llvm::DenseMap<CharUnits, ClassVectorTy> EmptyClassOffsetsMapTy; 7058b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson EmptyClassOffsetsMapTy EmptyClassOffsets; 7158b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 72c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson /// MaxEmptyClassOffset - The highest offset known to contain an empty 73c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson /// base subobject. 74fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson CharUnits MaxEmptyClassOffset; 75c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson 760aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// ComputeEmptySubobjectSizes - Compute the size of the largest base or 770c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson /// member subobject that is empty. 780c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson void ComputeEmptySubobjectSizes(); 7958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 80fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson void AddSubobjectAtOffset(const CXXRecordDecl *RD, CharUnits Offset); 81812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 82ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson void UpdateEmptyBaseSubobjects(const BaseSubobjectInfo *Info, 83a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits Offset, bool PlacingEmptyBase); 8458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 85812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson void UpdateEmptyFieldSubobjects(const CXXRecordDecl *RD, 86812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *Class, 87a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits Offset); 88a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson void UpdateEmptyFieldSubobjects(const FieldDecl *FD, CharUnits Offset); 89812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 90c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson /// AnyEmptySubobjectsBeyondOffset - Returns whether there are any empty 91c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson /// subobjects beyond the given offset. 92fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson bool AnyEmptySubobjectsBeyondOffset(CharUnits Offset) const { 93c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson return Offset <= MaxEmptyClassOffset; 94c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson } 95c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson 968c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson CharUnits 978c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson getFieldOffset(const ASTRecordLayout &Layout, unsigned FieldNo) const { 988c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson uint64_t FieldOffset = Layout.getFieldOffset(FieldNo); 998c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson assert(FieldOffset % CharWidth == 0 && 1008c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson "Field offset not at char boundary!"); 1018c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson 102ff3a5174d1f6e7dc98de348aecfdfe1d2fb7cd53Ken Dyck return Context.toCharUnitsFromBits(FieldOffset); 103d8da76365f40a0c12c7d802a0da2aaacf4b2cf99Anders Carlsson } 104d8da76365f40a0c12c7d802a0da2aaacf4b2cf99Anders Carlsson 105c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davisprotected: 106fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson bool CanPlaceSubobjectAtOffset(const CXXRecordDecl *RD, 107fe5ef73149514e513a231a1df1a5938f3ad1545aAnders Carlsson CharUnits Offset) const; 108c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis 109c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis bool CanPlaceBaseSubobjectAtOffset(const BaseSubobjectInfo *Info, 110a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits Offset); 111c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis 112c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis bool CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD, 113c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis const CXXRecordDecl *Class, 114a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits Offset) const; 115c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis bool CanPlaceFieldSubobjectAtOffset(const FieldDecl *FD, 1168c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson CharUnits Offset) const; 117c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis 1186a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlssonpublic: 1190c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson /// This holds the size of the largest empty subobject (either a base 1200aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// or a member). Will be zero if the record being built doesn't contain 1210c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson /// any empty classes. 122a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits SizeOfLargestEmptySubobject; 1230aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1244ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad EmptySubobjectMap(const ASTContext &Context, const CXXRecordDecl *Class) 125a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson : Context(Context), CharWidth(Context.getCharWidth()), Class(Class) { 126261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson ComputeEmptySubobjectSizes(); 127261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson } 128261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson 129261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson /// CanPlaceBaseAtOffset - Return whether the given base class can be placed 130261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson /// at the given offset. 1310aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// Returns false if placing the record will result in two components 132261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson /// (direct or indirect) of the same type having the same offset. 133c8cb462e57ac13518a170fe52b77bb8656234b35Anders Carlsson bool CanPlaceBaseAtOffset(const BaseSubobjectInfo *Info, 134a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits Offset); 135812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 136812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson /// CanPlaceFieldAtOffset - Return whether a field can be placed at the given 137812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson /// offset. 138a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson bool CanPlaceFieldAtOffset(const FieldDecl *FD, CharUnits Offset); 1396a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson}; 1400c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson 1410c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlssonvoid EmptySubobjectMap::ComputeEmptySubobjectSizes() { 1420c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // Check the bases. 1430c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = Class->bases_begin(), 1440c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson E = Class->bases_end(); I != E; ++I) { 1450c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson const CXXRecordDecl *BaseDecl = 1460c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1470c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson 148a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits EmptySize; 1490c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(BaseDecl); 1500c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson if (BaseDecl->isEmpty()) { 1510c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // If the class decl is empty, get its size. 1525f022d82696c84e4d127c558871d68ac6273274eKen Dyck EmptySize = Layout.getSize(); 1530c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson } else { 1540c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // Otherwise, we get the largest empty subobject for the decl. 1550c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson EmptySize = Layout.getSizeOfLargestEmptySubobject(); 1560c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson } 1570aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 158a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson if (EmptySize > SizeOfLargestEmptySubobject) 159a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson SizeOfLargestEmptySubobject = EmptySize; 1600c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson } 1610aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1620c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson // Check the fields. 1630c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson for (CXXRecordDecl::field_iterator I = Class->field_begin(), 1640c54fc91322faaa78422c3aaec261a26e45d7f8cAnders Carlsson E = Class->field_end(); I != E; ++I) { 1650aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1660aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar const RecordType *RT = 167581deb3da481053c4993c7600f97acf7768caac5David Blaikie Context.getBaseElementType(I->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) { 264581deb3da481053c4993c7600f97acf7768caac5David Blaikie if (I->isBitField()) 2658c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson continue; 2668c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson 267a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits FieldOffset = Offset + getFieldOffset(Layout, FieldNo); 268581deb3da481053c4993c7600f97acf7768caac5David Blaikie if (!CanPlaceFieldSubobjectAtOffset(*I, FieldOffset)) 269812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 270812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 271812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 27258b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson return true; 27358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson} 27458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 275ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlssonvoid EmptySubobjectMap::UpdateEmptyBaseSubobjects(const BaseSubobjectInfo *Info, 276a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits Offset, 277e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson bool PlacingEmptyBase) { 278e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson if (!PlacingEmptyBase && Offset >= SizeOfLargestEmptySubobject) { 279e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson // We know that the only empty subobjects that can conflict with empty 280e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson // subobject of non-empty bases, are empty bases that can be placed at 281e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson // offset zero. Because of this, we only need to keep track of empty base 282e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson // subobjects with offsets less than the size of the largest empty 283e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson // subobject for our class. 284e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson return; 285e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson } 286e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson 287a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson AddSubobjectAtOffset(Info->Class, Offset); 2884137d517700a1b0f834535545c3f1676f40abcfbAnders Carlsson 28958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson // Traverse all non-virtual bases. 2904137d517700a1b0f834535545c3f1676f40abcfbAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class); 29158b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson for (unsigned I = 0, E = Info->Bases.size(); I != E; ++I) { 292ea2f41c584b9741a591e11c83819b31856f5bc18Anders Carlsson BaseSubobjectInfo* Base = Info->Bases[I]; 29358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (Base->IsVirtual) 29458b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson continue; 2954137d517700a1b0f834535545c3f1676f40abcfbAnders Carlsson 2966a3567442307864eac52bb84ce41465753513635Anders Carlsson CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class); 297e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson UpdateEmptyBaseSubobjects(Base, BaseOffset, PlacingEmptyBase); 29858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } 29958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 3006e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (Info->PrimaryVirtualBaseInfo) { 3016e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *PrimaryVirtualBaseInfo = Info->PrimaryVirtualBaseInfo; 30258b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 30358b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (Info == PrimaryVirtualBaseInfo->Derived) 304e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson UpdateEmptyBaseSubobjects(PrimaryVirtualBaseInfo, Offset, 305e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson PlacingEmptyBase); 30658b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson } 307812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 308812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Traverse all member variables. 309812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson unsigned FieldNo = 0; 310812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (CXXRecordDecl::field_iterator I = Info->Class->field_begin(), 311812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson E = Info->Class->field_end(); I != E; ++I, ++FieldNo) { 312581deb3da481053c4993c7600f97acf7768caac5David Blaikie if (I->isBitField()) 3138c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson continue; 3144137d517700a1b0f834535545c3f1676f40abcfbAnders Carlsson 315a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits FieldOffset = Offset + getFieldOffset(Layout, FieldNo); 316581deb3da481053c4993c7600f97acf7768caac5David Blaikie UpdateEmptyFieldSubobjects(*I, FieldOffset); 317812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 31858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson} 31958b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson 3205b1319c78061e76d70cca50fb3343b25928e001bAnders Carlssonbool EmptySubobjectMap::CanPlaceBaseAtOffset(const BaseSubobjectInfo *Info, 321a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits Offset) { 322261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson // If we know this class doesn't have any empty subobjects we don't need to 323261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson // bother checking. 324a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson if (SizeOfLargestEmptySubobject.isZero()) 325261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson return true; 326261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson 32758b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson if (!CanPlaceBaseSubobjectAtOffset(Info, Offset)) 32858b16b6e46716e24f1cdaa0a5e1253415c4e30b3Anders Carlsson return false; 329812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 330812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // We are able to place the base at this offset. Make sure to update the 331812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // empty base subobject map. 332e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson UpdateEmptyBaseSubobjects(Info, Offset, Info->Class->isEmpty()); 333261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson return true; 334261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson} 335261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson 336812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlssonbool 337812a3456b63708a5972f712e9e4b54d3cc436378Anders CarlssonEmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const CXXRecordDecl *RD, 338812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *Class, 339a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits Offset) const { 3402177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson // We don't have to keep looking past the maximum offset that's known to 3412177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson // contain an empty class. 342a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson if (!AnyEmptySubobjectsBeyondOffset(Offset)) 3432177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson return true; 3442177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson 345a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson if (!CanPlaceSubobjectAtOffset(RD, Offset)) 346812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 347812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 348812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 349812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 350812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Traverse all non-virtual bases. 351812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 352812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson E = RD->bases_end(); I != E; ++I) { 353812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (I->isVirtual()) 354812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson continue; 355812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 356812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *BaseDecl = 357812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 358812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 3596a3567442307864eac52bb84ce41465753513635Anders Carlsson CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(BaseDecl); 360812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!CanPlaceFieldSubobjectAtOffset(BaseDecl, Class, BaseOffset)) 361812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 362812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 363812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 36445f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson if (RD == Class) { 36545f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson // This is the most derived class, traverse virtual bases as well. 36645f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(), 36745f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson E = RD->vbases_end(); I != E; ++I) { 36845f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson const CXXRecordDecl *VBaseDecl = 36945f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 37045f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson 3713069a0d28637ad0ad583d9fdd7bc6bc6aa677fb5Anders Carlsson CharUnits VBaseOffset = Offset + Layout.getVBaseClassOffset(VBaseDecl); 37245f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson if (!CanPlaceFieldSubobjectAtOffset(VBaseDecl, Class, VBaseOffset)) 37345f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson return false; 37445f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson } 37545f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson } 37645f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson 377812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Traverse all member variables. 378812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson unsigned FieldNo = 0; 379812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); 380812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson I != E; ++I, ++FieldNo) { 381581deb3da481053c4993c7600f97acf7768caac5David Blaikie if (I->isBitField()) 3828c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson continue; 3838c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson 384a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits FieldOffset = Offset + getFieldOffset(Layout, FieldNo); 385812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 386581deb3da481053c4993c7600f97acf7768caac5David Blaikie if (!CanPlaceFieldSubobjectAtOffset(*I, FieldOffset)) 387812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 388812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 389812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 390812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 391812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 392812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 3938c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlssonbool 3948c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders CarlssonEmptySubobjectMap::CanPlaceFieldSubobjectAtOffset(const FieldDecl *FD, 3958c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson CharUnits Offset) const { 3962177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson // We don't have to keep looking past the maximum offset that's known to 3972177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson // contain an empty class. 3988c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson if (!AnyEmptySubobjectsBeyondOffset(Offset)) 3992177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson return true; 4002177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson 401812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson QualType T = FD->getType(); 402812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (const RecordType *RT = T->getAs<RecordType>()) { 403812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 404a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson return CanPlaceFieldSubobjectAtOffset(RD, RD, Offset); 405812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 406812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 407812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // If we have an array type we need to look at every element. 408812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (const ConstantArrayType *AT = Context.getAsConstantArrayType(T)) { 409812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson QualType ElemTy = Context.getBaseElementType(AT); 410812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const RecordType *RT = ElemTy->getAs<RecordType>(); 411812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!RT) 412812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 413812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 414812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 415812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 416812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 417812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t NumElements = Context.getConstantArrayElementCount(AT); 4188c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson CharUnits ElementOffset = Offset; 419812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (uint64_t I = 0; I != NumElements; ++I) { 4202177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson // We don't have to keep looking past the maximum offset that's known to 4212177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson // contain an empty class. 4228c6acc6be0fbd4127d16c1c0e12a9362462e6e0cAnders Carlsson if (!AnyEmptySubobjectsBeyondOffset(ElementOffset)) 4232177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson return true; 4242177ab7be5256e691a115356fcb8f3eef9c9733fAnders Carlsson 425a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson if (!CanPlaceFieldSubobjectAtOffset(RD, RD, ElementOffset)) 426812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 427812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 4285f022d82696c84e4d127c558871d68ac6273274eKen Dyck ElementOffset += Layout.getSize(); 429812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 430812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 431812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 432812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 433812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 434812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 435812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlssonbool 436a3d4380d6662a373bc78f915947e5bc06e985e91Anders CarlssonEmptySubobjectMap::CanPlaceFieldAtOffset(const FieldDecl *FD, 437a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits Offset) { 438a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson if (!CanPlaceFieldSubobjectAtOffset(FD, Offset)) 439812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return false; 440812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 441812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // We are able to place the member variable at this offset. 442812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Make sure to update the empty base subobject map. 443812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson UpdateEmptyFieldSubobjects(FD, Offset); 444812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return true; 445812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 446812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 447812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlssonvoid EmptySubobjectMap::UpdateEmptyFieldSubobjects(const CXXRecordDecl *RD, 448812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *Class, 449a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits Offset) { 4505ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson // We know that the only empty subobjects that can conflict with empty 451e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson // field subobjects are subobjects of empty bases that can be placed at offset 4525ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson // zero. Because of this, we only need to keep track of empty field 4535ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson // subobjects with offsets less than the size of the largest empty 4545ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson // subobject for our class. 4555ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson if (Offset >= SizeOfLargestEmptySubobject) 4565ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson return; 4575ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson 458a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson AddSubobjectAtOffset(RD, Offset); 459812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 460812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 461812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 462812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Traverse all non-virtual bases. 463812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 464812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson E = RD->bases_end(); I != E; ++I) { 465812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (I->isVirtual()) 466812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson continue; 467812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 468812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *BaseDecl = 469812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 470812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 4716a3567442307864eac52bb84ce41465753513635Anders Carlsson CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(BaseDecl); 472812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson UpdateEmptyFieldSubobjects(BaseDecl, Class, BaseOffset); 473812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 474812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 47545f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson if (RD == Class) { 47645f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson // This is the most derived class, traverse virtual bases as well. 47745f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(), 47845f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson E = RD->vbases_end(); I != E; ++I) { 47945f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson const CXXRecordDecl *VBaseDecl = 48045f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 48145f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson 4823069a0d28637ad0ad583d9fdd7bc6bc6aa677fb5Anders Carlsson CharUnits VBaseOffset = Offset + Layout.getVBaseClassOffset(VBaseDecl); 48345f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson UpdateEmptyFieldSubobjects(VBaseDecl, Class, VBaseOffset); 48445f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson } 48545f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson } 48645f5b54d67215639ae6585d12df5133e99180c2bAnders Carlsson 487812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // Traverse all member variables. 488812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson unsigned FieldNo = 0; 489812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (CXXRecordDecl::field_iterator I = RD->field_begin(), E = RD->field_end(); 490812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson I != E; ++I, ++FieldNo) { 491581deb3da481053c4993c7600f97acf7768caac5David Blaikie if (I->isBitField()) 492fa84fbad4863e030b149febc88288514efca34b2Anders Carlsson continue; 493fa84fbad4863e030b149febc88288514efca34b2Anders Carlsson 494a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits FieldOffset = Offset + getFieldOffset(Layout, FieldNo); 495812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 496581deb3da481053c4993c7600f97acf7768caac5David Blaikie UpdateEmptyFieldSubobjects(*I, FieldOffset); 497812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 498812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 499812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 500812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlssonvoid EmptySubobjectMap::UpdateEmptyFieldSubobjects(const FieldDecl *FD, 501a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits Offset) { 502812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson QualType T = FD->getType(); 503812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (const RecordType *RT = T->getAs<RecordType>()) { 504812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 505812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson UpdateEmptyFieldSubobjects(RD, RD, Offset); 506812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return; 507812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 508812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 509812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson // If we have an array type we need to update every element. 510812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (const ConstantArrayType *AT = Context.getAsConstantArrayType(T)) { 511812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson QualType ElemTy = Context.getBaseElementType(AT); 512812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const RecordType *RT = ElemTy->getAs<RecordType>(); 513812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson if (!RT) 514812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson return; 515812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 516812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 517812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 518812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 519812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson uint64_t NumElements = Context.getConstantArrayElementCount(AT); 520a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson CharUnits ElementOffset = Offset; 521812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 522812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson for (uint64_t I = 0; I != NumElements; ++I) { 5235ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson // We know that the only empty subobjects that can conflict with empty 524e3362bc104f401564a68ef2e0e5fd89f440cf4fcAnders Carlsson // field subobjects are subobjects of empty bases that can be placed at 5255ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson // offset zero. Because of this, we only need to keep track of empty field 5265ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson // subobjects with offsets less than the size of the largest empty 5275ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson // subobject for our class. 5285ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson if (ElementOffset >= SizeOfLargestEmptySubobject) 5295ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson return; 5305ccfdd8d215c7bf324a14523c71ed328325c2bc8Anders Carlsson 531812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson UpdateEmptyFieldSubobjects(RD, RD, ElementOffset); 5325f022d82696c84e4d127c558871d68ac6273274eKen Dyck ElementOffset += Layout.getSize(); 533812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 534812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson } 535812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson} 536812a3456b63708a5972f712e9e4b54d3cc436378Anders Carlsson 537441c6239c6df8c759bacf6510efbfd434b647066John McCalltypedef llvm::SmallPtrSet<const CXXRecordDecl*, 4> ClassSetTy; 538441c6239c6df8c759bacf6510efbfd434b647066John McCall 5397d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonclass RecordLayoutBuilder { 540c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davisprotected: 5419392fa63e45716e32061d05673fa28909f325b02Anders Carlsson // FIXME: Remove this and make the appropriate fields public. 5429392fa63e45716e32061d05673fa28909f325b02Anders Carlsson friend class clang::ASTContext; 5430aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5444ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad const ASTContext &Context; 5459392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 5466a91c0328c81fe1be4e5380fb0e586cafee53b26Anders Carlsson EmptySubobjectMap *EmptySubobjects; 5470aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5489392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// Size - The current size of the record layout. 5499392fa63e45716e32061d05673fa28909f325b02Anders Carlsson uint64_t Size; 5500aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5519392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// Alignment - The current alignment of the record layout. 552ea7f6c2c53127b875ed432fd1793d48270d8ba6bKen Dyck CharUnits Alignment; 5530aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 55478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis /// \brief The alignment if attribute packed is not used. 5556feb4bb3defce7e5efc05a69c6bd7dfc9c59fa45Ken Dyck CharUnits UnpackedAlignment; 55678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 5575f9e272e632e951b1efe824cd16acb4d96077930Chris Lattner SmallVector<uint64_t, 16> FieldOffsets; 5589392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 559453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor /// \brief Whether the external AST source has provided a layout for this 560453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor /// record. 561453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor unsigned ExternalLayout : 1; 562394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor 563394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor /// \brief Whether we need to infer alignment, even when we have an 564394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor /// externally-provided layout. 565394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor unsigned InferAlignment : 1; 566453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor 5679392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// Packed - Whether the record is packed or not. 568c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar unsigned Packed : 1; 569c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar 570c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar unsigned IsUnion : 1; 571c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar 572c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar unsigned IsMac68kAlign : 1; 57362055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian 57462055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian unsigned IsMsStruct : 1; 5759392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 5769392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// UnfilledBitsInLastByte - If the last field laid out was a bitfield, 5779392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// this contains the number of bits in the last byte that can be used for 5789392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// an adjacent bitfield if necessary. 5799392fa63e45716e32061d05673fa28909f325b02Anders Carlsson unsigned char UnfilledBitsInLastByte; 5800aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5819392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// MaxFieldAlignment - The maximum allowed field alignment. This is set by 5820aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// #pragma pack. 583834945c19cfb87fc21dfb6980a0980618655d79dKen Dyck CharUnits MaxFieldAlignment; 5840aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5859392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// DataSize - The data size of the record being laid out. 5869392fa63e45716e32061d05673fa28909f325b02Anders Carlsson uint64_t DataSize; 5870aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 588a1fdb0bc09aa0d17841cdbdd8c52cd1368251cbfKen Dyck CharUnits NonVirtualSize; 589df205382dae666b011d857402114e4f4acd56c81Ken Dyck CharUnits NonVirtualAlignment; 5900aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 591855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian FieldDecl *ZeroLengthBitfield; 592340fa242130c2d8d74c83edca0952e771aebe0e6Fariborz Jahanian 5939392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// PrimaryBase - the primary base class (if one exists) of the class 5949392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// we're laying out. 5959392fa63e45716e32061d05673fa28909f325b02Anders Carlsson const CXXRecordDecl *PrimaryBase; 5960aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 5979392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// PrimaryBaseIsVirtual - Whether the primary base of the class we're laying 5989392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// out is virtual. 5999392fa63e45716e32061d05673fa28909f325b02Anders Carlsson bool PrimaryBaseIsVirtual; 6009392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 601441c6239c6df8c759bacf6510efbfd434b647066John McCall /// HasOwnVFPtr - Whether the class provides its own vtable/vftbl 602441c6239c6df8c759bacf6510efbfd434b647066John McCall /// pointer, as opposed to inheriting one from a primary base class. 603441c6239c6df8c759bacf6510efbfd434b647066John McCall bool HasOwnVFPtr; 604227e483cb1f77ea6dcd38c2ca9fb490894a5f887Eli Friedman 6052fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman /// VBPtrOffset - Virtual base table offset. Only for MS layout. 6062fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman CharUnits VBPtrOffset; 6072fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman 608376bda924ac92462a22d6a22ea65d8c1bb8f26f3Anders Carlsson typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy; 6090aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 6109392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// Bases - base classes and their offsets in the record. 6119392fa63e45716e32061d05673fa28909f325b02Anders Carlsson BaseOffsetsMapTy Bases; 6120aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 6139392fa63e45716e32061d05673fa28909f325b02Anders Carlsson // VBases - virtual base classes and their offsets in the record. 614441c6239c6df8c759bacf6510efbfd434b647066John McCall ASTRecordLayout::VBaseOffsetsMapTy VBases; 6159392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6169392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// IndirectPrimaryBases - Virtual base classes, direct or indirect, that are 6179392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// primary base classes for some other direct or indirect base class. 618245656ec65ec600ef1ab05f4c8d9f780542d689dAnders Carlsson CXXIndirectPrimaryBaseSet IndirectPrimaryBases; 6190aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 6209392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// FirstNearlyEmptyVBase - The first nearly empty virtual base class in 6219392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// inheritance graph order. Used for determining the primary base class. 6229392fa63e45716e32061d05673fa28909f325b02Anders Carlsson const CXXRecordDecl *FirstNearlyEmptyVBase; 6239392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6249392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// VisitedVirtualBases - A set of all the visited virtual bases, used to 6259392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// avoid visiting virtual bases more than once. 6269392fa63e45716e32061d05673fa28909f325b02Anders Carlsson llvm::SmallPtrSet<const CXXRecordDecl *, 4> VisitedVirtualBases; 6270aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 628453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor /// \brief Externally-provided size. 629453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor uint64_t ExternalSize; 630453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor 631453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor /// \brief Externally-provided alignment. 632453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor uint64_t ExternalAlign; 633453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor 634453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor /// \brief Externally-provided field offsets. 635453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor llvm::DenseMap<const FieldDecl *, uint64_t> ExternalFieldOffsets; 636453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor 637453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor /// \brief Externally-provided direct, non-virtual base offsets. 638453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor llvm::DenseMap<const CXXRecordDecl *, CharUnits> ExternalBaseOffsets; 639453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor 640453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor /// \brief Externally-provided virtual base offsets. 641453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor llvm::DenseMap<const CXXRecordDecl *, CharUnits> ExternalVirtualBaseOffsets; 642453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor 6439da235244c2de2bcca654b518c66133c30ebde53John McCall RecordLayoutBuilder(const ASTContext &Context, 6449da235244c2de2bcca654b518c66133c30ebde53John McCall EmptySubobjectMap *EmptySubobjects) 645ea7f6c2c53127b875ed432fd1793d48270d8ba6bKen Dyck : Context(Context), EmptySubobjects(EmptySubobjects), Size(0), 6469da235244c2de2bcca654b518c66133c30ebde53John McCall Alignment(CharUnits::One()), UnpackedAlignment(CharUnits::One()), 647394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor ExternalLayout(false), InferAlignment(false), 648394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor Packed(false), IsUnion(false), IsMac68kAlign(false), IsMsStruct(false), 649834945c19cfb87fc21dfb6980a0980618655d79dKen Dyck UnfilledBitsInLastByte(0), MaxFieldAlignment(CharUnits::Zero()), 650834945c19cfb87fc21dfb6980a0980618655d79dKen Dyck DataSize(0), NonVirtualSize(CharUnits::Zero()), 651340fa242130c2d8d74c83edca0952e771aebe0e6Fariborz Jahanian NonVirtualAlignment(CharUnits::One()), 652855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian ZeroLengthBitfield(0), PrimaryBase(0), 653227e483cb1f77ea6dcd38c2ca9fb490894a5f887Eli Friedman PrimaryBaseIsVirtual(false), 654441c6239c6df8c759bacf6510efbfd434b647066John McCall HasOwnVFPtr(false), 655227e483cb1f77ea6dcd38c2ca9fb490894a5f887Eli Friedman VBPtrOffset(CharUnits::fromQuantity(-1)), 6562fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman FirstNearlyEmptyVBase(0) { } 6570aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 6589da235244c2de2bcca654b518c66133c30ebde53John McCall /// Reset this RecordLayoutBuilder to a fresh state, using the given 6599da235244c2de2bcca654b518c66133c30ebde53John McCall /// alignment as the initial alignment. This is used for the 6609da235244c2de2bcca654b518c66133c30ebde53John McCall /// correct layout of vb-table pointers in MSVC. 6619da235244c2de2bcca654b518c66133c30ebde53John McCall void resetWithTargetAlignment(CharUnits TargetAlignment) { 6629da235244c2de2bcca654b518c66133c30ebde53John McCall const ASTContext &Context = this->Context; 6639da235244c2de2bcca654b518c66133c30ebde53John McCall EmptySubobjectMap *EmptySubobjects = this->EmptySubobjects; 6649da235244c2de2bcca654b518c66133c30ebde53John McCall this->~RecordLayoutBuilder(); 6659da235244c2de2bcca654b518c66133c30ebde53John McCall new (this) RecordLayoutBuilder(Context, EmptySubobjects); 6669da235244c2de2bcca654b518c66133c30ebde53John McCall Alignment = UnpackedAlignment = TargetAlignment; 6679da235244c2de2bcca654b518c66133c30ebde53John McCall } 6689da235244c2de2bcca654b518c66133c30ebde53John McCall 6699392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void Layout(const RecordDecl *D); 670c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson void Layout(const CXXRecordDecl *D); 6719392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void Layout(const ObjCInterfaceDecl *D); 6729392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6739392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void LayoutFields(const RecordDecl *D); 6749392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void LayoutField(const FieldDecl *D); 67578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis void LayoutWideBitField(uint64_t FieldSize, uint64_t TypeSize, 67678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis bool FieldPacked, const FieldDecl *D); 6779392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void LayoutBitField(const FieldDecl *D); 6789da235244c2de2bcca654b518c66133c30ebde53John McCall 6799da235244c2de2bcca654b518c66133c30ebde53John McCall bool isMicrosoftCXXABI() const { 6809da235244c2de2bcca654b518c66133c30ebde53John McCall return Context.getTargetInfo().getCXXABI() == CXXABI_Microsoft; 6819da235244c2de2bcca654b518c66133c30ebde53John McCall } 6829da235244c2de2bcca654b518c66133c30ebde53John McCall 6832fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman void MSLayoutVirtualBases(const CXXRecordDecl *RD); 6849392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 6856e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// BaseSubobjectInfoAllocator - Allocator for BaseSubobjectInfo objects. 6866e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson llvm::SpecificBumpPtrAllocator<BaseSubobjectInfo> BaseSubobjectInfoAllocator; 6876e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 6886e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson typedef llvm::DenseMap<const CXXRecordDecl *, BaseSubobjectInfo *> 6896e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfoMapTy; 6906e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 6916e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// VirtualBaseInfo - Map from all the (direct or indirect) virtual bases 6926e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// of the class we're laying out to their base subobject info. 6936e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfoMapTy VirtualBaseInfo; 6946e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 6956e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// NonVirtualBaseInfo - Map from all the direct non-virtual bases of the 6966e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// class we're laying out to their base subobject info. 6976e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfoMapTy NonVirtualBaseInfo; 6986e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 6996e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// ComputeBaseSubobjectInfo - Compute the base subobject information for the 7006e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// bases of the given class. 7016e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson void ComputeBaseSubobjectInfo(const CXXRecordDecl *RD); 7026e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 7036e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// ComputeBaseSubobjectInfo - Compute the base subobject information for a 7046e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson /// single class and all of its base classes. 7056e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *ComputeBaseSubobjectInfo(const CXXRecordDecl *RD, 7066e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson bool IsVirtual, 7076e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *Derived); 7089392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 7099392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// DeterminePrimaryBase - Determine the primary base of the given class. 7109392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void DeterminePrimaryBase(const CXXRecordDecl *RD); 7119392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 7129392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void SelectPrimaryVBase(const CXXRecordDecl *RD); 7130aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 714227e483cb1f77ea6dcd38c2ca9fb490894a5f887Eli Friedman void EnsureVTablePointerAlignment(CharUnits UnpackedBaseAlign); 715c9f8aece7e111f90265dfad9a81f3f517be948deCharles Davis 7160aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// LayoutNonVirtualBases - Determines the primary base class (if any) and 7179392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// lays it out. Will then proceed to lay out all non-virtual base clasess. 7189392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void LayoutNonVirtualBases(const CXXRecordDecl *RD); 7199392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 7209392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// LayoutNonVirtualBase - Lays out a single non-virtual base. 72107cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson void LayoutNonVirtualBase(const BaseSubobjectInfo *Base); 7229392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 723a2311513524ecef954d2b438bfbe09aa9511b660Anders Carlsson void AddPrimaryVirtualBaseOffsets(const BaseSubobjectInfo *Info, 724a2311513524ecef954d2b438bfbe09aa9511b660Anders Carlsson CharUnits Offset); 7259392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 7269da235244c2de2bcca654b518c66133c30ebde53John McCall bool needsVFTable(const CXXRecordDecl *RD) const; 727441c6239c6df8c759bacf6510efbfd434b647066John McCall bool hasNewVirtualFunction(const CXXRecordDecl *RD, 728441c6239c6df8c759bacf6510efbfd434b647066John McCall bool IgnoreDestructor = false) const; 7299da235244c2de2bcca654b518c66133c30ebde53John McCall bool isPossiblePrimaryBase(const CXXRecordDecl *Base) const; 73097c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman 731441c6239c6df8c759bacf6510efbfd434b647066John McCall void computeVtordisps(const CXXRecordDecl *RD, 732441c6239c6df8c759bacf6510efbfd434b647066John McCall ClassSetTy &VtordispVBases); 733441c6239c6df8c759bacf6510efbfd434b647066John McCall 7349392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// LayoutVirtualBases - Lays out all the virtual bases. 7359392fa63e45716e32061d05673fa28909f325b02Anders Carlsson void LayoutVirtualBases(const CXXRecordDecl *RD, 7369392fa63e45716e32061d05673fa28909f325b02Anders Carlsson const CXXRecordDecl *MostDerivedClass); 7379392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 7389392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// LayoutVirtualBase - Lays out a single virtual base. 739441c6239c6df8c759bacf6510efbfd434b647066John McCall void LayoutVirtualBase(const BaseSubobjectInfo *Base, 740441c6239c6df8c759bacf6510efbfd434b647066John McCall bool IsVtordispNeed = false); 7419392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 7420aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar /// LayoutBase - Will lay out a base and return the offset where it was 743a2311513524ecef954d2b438bfbe09aa9511b660Anders Carlsson /// placed, in chars. 744a2311513524ecef954d2b438bfbe09aa9511b660Anders Carlsson CharUnits LayoutBase(const BaseSubobjectInfo *Base); 7459392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 746c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson /// InitializeLayout - Initialize record layout for the given record decl. 747c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar void InitializeLayout(const Decl *D); 748c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 7499392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// FinishLayout - Finalize record layout. Adjust record size based on the 7509392fa63e45716e32061d05673fa28909f325b02Anders Carlsson /// alignment. 75178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis void FinishLayout(const NamedDecl *D); 75278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 7533263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck void UpdateAlignment(CharUnits NewAlignment, CharUnits UnpackedNewAlignment); 7543263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck void UpdateAlignment(CharUnits NewAlignment) { 75578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UpdateAlignment(NewAlignment, NewAlignment); 75678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 75778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 758394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor /// \brief Retrieve the externally-supplied field offset for the given 759394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor /// field. 760394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor /// 761394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor /// \param Field The field whose offset is being queried. 762394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor /// \param ComputedOffset The offset that we've computed for this field. 763394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor uint64_t updateExternalFieldOffset(const FieldDecl *Field, 764394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor uint64_t ComputedOffset); 765394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor 76678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis void CheckFieldPadding(uint64_t Offset, uint64_t UnpaddedOffset, 76778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis uint64_t UnpackedOffset, unsigned UnpackedAlign, 76878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis bool isPacked, const FieldDecl *D); 7699392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 77078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis DiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID); 7719392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 772a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck CharUnits getSize() const { 7739911344114cc493e089964f7602b619e5a47c7bcKen Dyck assert(Size % Context.getCharWidth() == 0); 774a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck return Context.toCharUnitsFromBits(Size); 775a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck } 776a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck uint64_t getSizeInBits() const { return Size; } 777a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck 778a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck void setSize(CharUnits NewSize) { Size = Context.toBits(NewSize); } 779a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck void setSize(uint64_t NewSize) { Size = NewSize; } 780a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck 7812fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman CharUnits getAligment() const { return Alignment; } 7822fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman 783a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck CharUnits getDataSize() const { 7849911344114cc493e089964f7602b619e5a47c7bcKen Dyck assert(DataSize % Context.getCharWidth() == 0); 785a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck return Context.toCharUnitsFromBits(DataSize); 786a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck } 787a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck uint64_t getDataSizeInBits() const { return DataSize; } 788a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck 789a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck void setDataSize(CharUnits NewSize) { DataSize = Context.toBits(NewSize); } 790a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck void setDataSize(uint64_t NewSize) { DataSize = NewSize; } 791a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck 792c83d2d7d8914a0fe00d679a262f2bdae7689f16dArgyrios Kyrtzidis RecordLayoutBuilder(const RecordLayoutBuilder&); // DO NOT IMPLEMENT 793c83d2d7d8914a0fe00d679a262f2bdae7689f16dArgyrios Kyrtzidis void operator=(const RecordLayoutBuilder&); // DO NOT IMPLEMENT 7949392fa63e45716e32061d05673fa28909f325b02Anders Carlssonpublic: 7959392fa63e45716e32061d05673fa28909f325b02Anders Carlsson static const CXXMethodDecl *ComputeKeyFunction(const CXXRecordDecl *RD); 7969392fa63e45716e32061d05673fa28909f325b02Anders Carlsson}; 7977e220286410422ed1dc0409a9cb9708fe50e3df0Benjamin Kramer} // end anonymous namespace 7989392fa63e45716e32061d05673fa28909f325b02Anders Carlsson 7993f066522342538509cf0aa4f381503b43fbdb68bAnders Carlssonvoid 8007d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders CarlssonRecordLayoutBuilder::SelectPrimaryVBase(const CXXRecordDecl *RD) { 801584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 802bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->bases_end(); I != E; ++I) { 803584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson assert(!I->getType()->isDependentType() && 8049994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl "Cannot layout class with dependent bases."); 805bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 8061eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump const CXXRecordDecl *Base = 807584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 808200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 809584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson // Check if this is a nearly empty virtual base. 810dae0cb52e4e3d46bbfc9a4510909522197a92e54Anders Carlsson if (I->isVirtual() && Context.isNearlyEmpty(Base)) { 811584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson // If it's not an indirect primary base, then we've found our primary 812584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson // base. 8133f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson if (!IndirectPrimaryBases.count(Base)) { 81428fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBase = Base; 81528fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBaseIsVirtual = true; 816d76264e0b20470267249660ab947197cf6d6e31fMike Stump return; 817d76264e0b20470267249660ab947197cf6d6e31fMike Stump } 818bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 819584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson // Is this the first nearly empty virtual base? 820584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson if (!FirstNearlyEmptyVBase) 821584e1dfaf6ab682cebe4fe51f55f0ae3215d303fAnders Carlsson FirstNearlyEmptyVBase = Base; 822d76264e0b20470267249660ab947197cf6d6e31fMike Stump } 823bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 824200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson SelectPrimaryVBase(Base); 82528fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson if (PrimaryBase) 82694ba380b820cde3fb9d97d5f07ac709ebbb6ac1eZhongxing Xu return; 827d76264e0b20470267249660ab947197cf6d6e31fMike Stump } 828d76264e0b20470267249660ab947197cf6d6e31fMike Stump} 829d76264e0b20470267249660ab947197cf6d6e31fMike Stump 830200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson/// DeterminePrimaryBase - Determine the primary base of the given class. 8317d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonvoid RecordLayoutBuilder::DeterminePrimaryBase(const CXXRecordDecl *RD) { 832200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // If the class isn't dynamic, it won't have a primary base. 833200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson if (!RD->isDynamicClass()) 834200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson return; 835bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 8363f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson // Compute all the primary virtual bases for all of our direct and 8370880e75541899bc1cdd73c50eb549110b5916c59Mike Stump // indirect bases, and record all their primary virtual base classes. 838245656ec65ec600ef1ab05f4c8d9f780542d689dAnders Carlsson RD->getIndirectPrimaryBases(IndirectPrimaryBases); 8390880e75541899bc1cdd73c50eb549110b5916c59Mike Stump 840bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar // If the record has a dynamic base class, attempt to choose a primary base 841bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar // class. It is the first (in direct base class order) non-virtual dynamic 8423f066522342538509cf0aa4f381503b43fbdb68bAnders Carlsson // base class, if one exists. 8436f376336138ea719e3c4757ae046a5768043b276Mike Stump for (CXXRecordDecl::base_class_const_iterator i = RD->bases_begin(), 844bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar e = RD->bases_end(); i != e; ++i) { 845ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson // Ignore virtual bases. 846ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson if (i->isVirtual()) 847ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson continue; 848bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 849ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson const CXXRecordDecl *Base = 850ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson cast<CXXRecordDecl>(i->getType()->getAs<RecordType>()->getDecl()); 851ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson 8529da235244c2de2bcca654b518c66133c30ebde53John McCall if (isPossiblePrimaryBase(Base)) { 853ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson // We found it. 85428fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBase = Base; 85528fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBaseIsVirtual = false; 856ce2009ab2f59894dbcc847e25e05abe78c296e95Anders Carlsson return; 8576f376336138ea719e3c4757ae046a5768043b276Mike Stump } 8586f376336138ea719e3c4757ae046a5768043b276Mike Stump } 8596f376336138ea719e3c4757ae046a5768043b276Mike Stump 86097c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman // The Microsoft ABI doesn't have primary virtual bases. 8619da235244c2de2bcca654b518c66133c30ebde53John McCall if (isMicrosoftCXXABI()) { 86297c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman assert(!PrimaryBase && "Should not get here with a primary base!"); 86397c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman return; 86497c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman } 86597c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman 86697c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman // Under the Itanium ABI, if there is no non-virtual primary base class, 86797c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman // try to compute the primary virtual base. The primary virtual base is 86897c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman // the first nearly empty virtual base that is not an indirect primary 86997c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman // virtual base class, if one exists. 870200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson if (RD->getNumVBases() != 0) { 871200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson SelectPrimaryVBase(RD); 87228fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson if (PrimaryBase) 873200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson return; 874200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson } 8756f376336138ea719e3c4757ae046a5768043b276Mike Stump 87697c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman // Otherwise, it is the first indirect primary base class, if one exists. 877200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson if (FirstNearlyEmptyVBase) { 87828fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBase = FirstNearlyEmptyVBase; 87928fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBaseIsVirtual = true; 8806f376336138ea719e3c4757ae046a5768043b276Mike Stump return; 881200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson } 882bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 88328fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson assert(!PrimaryBase && "Should not get here with a primary base!"); 8846f376336138ea719e3c4757ae046a5768043b276Mike Stump} 8856f376336138ea719e3c4757ae046a5768043b276Mike Stump 8866e26454ecceb20938b866717dc8a72c6d37d224dAnders CarlssonBaseSubobjectInfo * 8876e26454ecceb20938b866717dc8a72c6d37d224dAnders CarlssonRecordLayoutBuilder::ComputeBaseSubobjectInfo(const CXXRecordDecl *RD, 8886e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson bool IsVirtual, 8896e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *Derived) { 8906e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *Info; 8916e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 8926e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (IsVirtual) { 8936e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Check if we already have info about this virtual base. 8946e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *&InfoSlot = VirtualBaseInfo[RD]; 8956e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (InfoSlot) { 8966e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson assert(InfoSlot->Class == RD && "Wrong class for virtual base info!"); 8976e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson return InfoSlot; 8986e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 8996e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9006e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // We don't, create it. 9016e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson InfoSlot = new (BaseSubobjectInfoAllocator.Allocate()) BaseSubobjectInfo; 9026e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info = InfoSlot; 9036e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } else { 9046e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info = new (BaseSubobjectInfoAllocator.Allocate()) BaseSubobjectInfo; 9056e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 9066e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9076e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info->Class = RD; 9086e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info->IsVirtual = IsVirtual; 9096e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info->Derived = 0; 9106e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info->PrimaryVirtualBaseInfo = 0; 9116e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9126e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson const CXXRecordDecl *PrimaryVirtualBase = 0; 9136e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *PrimaryVirtualBaseInfo = 0; 9146e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9156e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Check if this base has a primary virtual base. 9166e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (RD->getNumVBases()) { 9176e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 918c9e814ba193f38a7b08268612248f63beb279bb3Anders Carlsson if (Layout.isPrimaryBaseVirtual()) { 9196e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // This base does have a primary virtual base. 9206e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson PrimaryVirtualBase = Layout.getPrimaryBase(); 9216e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson assert(PrimaryVirtualBase && "Didn't have a primary virtual base!"); 9226e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9236e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Now check if we have base subobject info about this primary base. 9246e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson PrimaryVirtualBaseInfo = VirtualBaseInfo.lookup(PrimaryVirtualBase); 9256e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9266e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (PrimaryVirtualBaseInfo) { 9276e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (PrimaryVirtualBaseInfo->Derived) { 9286e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // We did have info about this primary base, and it turns out that it 9296e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // has already been claimed as a primary virtual base for another 9306e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // base. 9316e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson PrimaryVirtualBase = 0; 9326e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } else { 9336e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // We can claim this base as our primary base. 9346e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info->PrimaryVirtualBaseInfo = PrimaryVirtualBaseInfo; 9356e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson PrimaryVirtualBaseInfo->Derived = Info; 9366e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 9376e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 9386e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 9396e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 9406e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9416e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Now go through all direct bases. 9426e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 9436e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson E = RD->bases_end(); I != E; ++I) { 9446e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson bool IsVirtual = I->isVirtual(); 9456e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9466e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson const CXXRecordDecl *BaseDecl = 9476e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 9486e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9496e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info->Bases.push_back(ComputeBaseSubobjectInfo(BaseDecl, IsVirtual, Info)); 9506e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 9516e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9526e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (PrimaryVirtualBase && !PrimaryVirtualBaseInfo) { 9536e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Traversing the bases must have created the base info for our primary 9546e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // virtual base. 9556e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson PrimaryVirtualBaseInfo = VirtualBaseInfo.lookup(PrimaryVirtualBase); 9566e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson assert(PrimaryVirtualBaseInfo && 9576e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson "Did not create a primary virtual base!"); 9586e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9596e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Claim the primary virtual base as our primary virtual base. 9606e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson Info->PrimaryVirtualBaseInfo = PrimaryVirtualBaseInfo; 9616e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson PrimaryVirtualBaseInfo->Derived = Info; 9626e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 9636e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9646e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson return Info; 9656e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson} 9666e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9676e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlssonvoid RecordLayoutBuilder::ComputeBaseSubobjectInfo(const CXXRecordDecl *RD) { 9686e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 9696e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson E = RD->bases_end(); I != E; ++I) { 9706e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson bool IsVirtual = I->isVirtual(); 9716e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9726e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson const CXXRecordDecl *BaseDecl = 9736e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 9746e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9756e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Compute the base subobject info for this base. 9766e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *Info = ComputeBaseSubobjectInfo(BaseDecl, IsVirtual, 0); 9776e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 9786e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson if (IsVirtual) { 9796e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // ComputeBaseInfo has already added this base for us. 9806e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson assert(VirtualBaseInfo.count(BaseDecl) && 9816e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson "Did not add virtual base!"); 9826e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } else { 9836e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Add the base info to the map of non-virtual bases. 9846e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson assert(!NonVirtualBaseInfo.count(BaseDecl) && 9856e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson "Non-virtual base already exists!"); 9866e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson NonVirtualBaseInfo.insert(std::make_pair(BaseDecl, Info)); 9876e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 9886e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson } 9896e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson} 9906e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 991e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlssonvoid 992227e483cb1f77ea6dcd38c2ca9fb490894a5f887Eli FriedmanRecordLayoutBuilder::EnsureVTablePointerAlignment(CharUnits UnpackedBaseAlign) { 99397c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman CharUnits BaseAlign = (Packed) ? CharUnits::One() : UnpackedBaseAlign; 99497c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman 99597c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman // The maximum field alignment overrides base align. 99697c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman if (!MaxFieldAlignment.isZero()) { 99797c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman BaseAlign = std::min(BaseAlign, MaxFieldAlignment); 99897c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman UnpackedBaseAlign = std::min(UnpackedBaseAlign, MaxFieldAlignment); 99997c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman } 100097c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman 100197c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman // Round up the current record size to pointer alignment. 1002227e483cb1f77ea6dcd38c2ca9fb490894a5f887Eli Friedman setSize(getSize().RoundUpToAlignment(BaseAlign)); 1003227e483cb1f77ea6dcd38c2ca9fb490894a5f887Eli Friedman setDataSize(getSize()); 100497c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman 100597c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman // Update the alignment. 100697c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman UpdateAlignment(BaseAlign, UnpackedBaseAlign); 100797c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman} 100897c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman 100997c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedmanvoid 10107d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders CarlssonRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD) { 10116e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Then, determine the primary base class. 1012200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson DeterminePrimaryBase(RD); 1013bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 10146e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // Compute base subobject info. 10156e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson ComputeBaseSubobjectInfo(RD); 10166e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 1017200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // If we have a primary base class, lay it out. 101828fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson if (PrimaryBase) { 101928fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson if (PrimaryBaseIsVirtual) { 10206e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // If the primary virtual base was a primary virtual base of some other 10216e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson // base class we'll have to steal it. 10226e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson BaseSubobjectInfo *PrimaryBaseInfo = VirtualBaseInfo.lookup(PrimaryBase); 10236e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson PrimaryBaseInfo->Derived = 0; 10246e26454ecceb20938b866717dc8a72c6d37d224dAnders Carlsson 1025200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // We have a virtual primary base, insert it as an indirect primary base. 102628fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson IndirectPrimaryBases.insert(PrimaryBase); 102737147ea14f39a8522e32e3ba4d043a2a33fff90cAnders Carlsson 10280aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar assert(!VisitedVirtualBases.count(PrimaryBase) && 102928fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson "vbase already visited!"); 103028fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson VisitedVirtualBases.insert(PrimaryBase); 10310aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1032276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson LayoutVirtualBase(PrimaryBaseInfo); 103307cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson } else { 103407cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson BaseSubobjectInfo *PrimaryBaseInfo = 103507cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson NonVirtualBaseInfo.lookup(PrimaryBase); 103607cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson assert(PrimaryBaseInfo && 103707cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson "Did not find base info for non-virtual primary base!"); 103807cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson 103907cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson LayoutNonVirtualBase(PrimaryBaseInfo); 104007cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson } 1041bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 10429da235244c2de2bcca654b518c66133c30ebde53John McCall // If this class needs a vtable/vf-table and didn't get one from a 10439da235244c2de2bcca654b518c66133c30ebde53John McCall // primary base, add it in now. 10449da235244c2de2bcca654b518c66133c30ebde53John McCall } else if (needsVFTable(RD)) { 104597c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman assert(DataSize == 0 && "Vtable pointer must be at offset zero!"); 104697c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman CharUnits PtrWidth = 104797c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0)); 1048227e483cb1f77ea6dcd38c2ca9fb490894a5f887Eli Friedman CharUnits PtrAlign = 1049227e483cb1f77ea6dcd38c2ca9fb490894a5f887Eli Friedman Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerAlign(0)); 1050227e483cb1f77ea6dcd38c2ca9fb490894a5f887Eli Friedman EnsureVTablePointerAlignment(PtrAlign); 1051441c6239c6df8c759bacf6510efbfd434b647066John McCall HasOwnVFPtr = true; 105297c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman setSize(getSize() + PtrWidth); 105397c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman setDataSize(getSize()); 105497c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman } 105597c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman 10569da235244c2de2bcca654b518c66133c30ebde53John McCall bool HasDirectVirtualBases = false; 10579da235244c2de2bcca654b518c66133c30ebde53John McCall bool HasNonVirtualBaseWithVBTable = false; 10589da235244c2de2bcca654b518c66133c30ebde53John McCall 1059200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Now lay out the non-virtual bases. 1060200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1061bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->bases_end(); I != E; ++I) { 1062200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 10639da235244c2de2bcca654b518c66133c30ebde53John McCall // Ignore virtual bases, but remember that we saw one. 10649da235244c2de2bcca654b518c66133c30ebde53John McCall if (I->isVirtual()) { 10659da235244c2de2bcca654b518c66133c30ebde53John McCall HasDirectVirtualBases = true; 1066200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson continue; 10679da235244c2de2bcca654b518c66133c30ebde53John McCall } 1068200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 106907cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson const CXXRecordDecl *BaseDecl = 10709da235244c2de2bcca654b518c66133c30ebde53John McCall cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl()); 10719da235244c2de2bcca654b518c66133c30ebde53John McCall 10729da235244c2de2bcca654b518c66133c30ebde53John McCall // Remember if this base has virtual bases itself. 10739da235244c2de2bcca654b518c66133c30ebde53John McCall if (BaseDecl->getNumVBases()) 10749da235244c2de2bcca654b518c66133c30ebde53John McCall HasNonVirtualBaseWithVBTable = true; 1075200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 10769da235244c2de2bcca654b518c66133c30ebde53John McCall // Skip the primary base, because we've already laid it out. The 10779da235244c2de2bcca654b518c66133c30ebde53John McCall // !PrimaryBaseIsVirtual check is required because we might have a 10789da235244c2de2bcca654b518c66133c30ebde53John McCall // non-virtual base of the same type as a primary virtual base. 107907cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson if (BaseDecl == PrimaryBase && !PrimaryBaseIsVirtual) 1080200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson continue; 1081200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson 1082200c5c2d9488165626925235ff918e3d744d785aAnders Carlsson // Lay out the base. 108307cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson BaseSubobjectInfo *BaseInfo = NonVirtualBaseInfo.lookup(BaseDecl); 108407cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson assert(BaseInfo && "Did not find base info for non-virtual base!"); 108507cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson 108607cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson LayoutNonVirtualBase(BaseInfo); 1087e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson } 108897c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman 10899da235244c2de2bcca654b518c66133c30ebde53John McCall // In the MS ABI, add the vb-table pointer if we need one, which is 10909da235244c2de2bcca654b518c66133c30ebde53John McCall // whenever we have a virtual base and we can't re-use a vb-table 10919da235244c2de2bcca654b518c66133c30ebde53John McCall // pointer from a non-virtual base. 10929da235244c2de2bcca654b518c66133c30ebde53John McCall if (isMicrosoftCXXABI() && 10939da235244c2de2bcca654b518c66133c30ebde53John McCall HasDirectVirtualBases && !HasNonVirtualBaseWithVBTable) { 109497c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman CharUnits PtrWidth = 109597c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(0)); 1096227e483cb1f77ea6dcd38c2ca9fb490894a5f887Eli Friedman CharUnits PtrAlign = 1097227e483cb1f77ea6dcd38c2ca9fb490894a5f887Eli Friedman Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerAlign(0)); 10989da235244c2de2bcca654b518c66133c30ebde53John McCall 10999da235244c2de2bcca654b518c66133c30ebde53John McCall // MSVC potentially over-aligns the vb-table pointer by giving it 11009da235244c2de2bcca654b518c66133c30ebde53John McCall // the max alignment of all the non-virtual objects in the class. 11019da235244c2de2bcca654b518c66133c30ebde53John McCall // This is completely unnecessary, but we're not here to pass 11029da235244c2de2bcca654b518c66133c30ebde53John McCall // judgment. 11039da235244c2de2bcca654b518c66133c30ebde53John McCall // 11049da235244c2de2bcca654b518c66133c30ebde53John McCall // Note that we've only laid out the non-virtual bases, so on the 11059da235244c2de2bcca654b518c66133c30ebde53John McCall // first pass Alignment won't be set correctly here, but if the 11069da235244c2de2bcca654b518c66133c30ebde53John McCall // vb-table doesn't end up aligned correctly we'll come through 11079da235244c2de2bcca654b518c66133c30ebde53John McCall // and redo the layout from scratch with the right alignment. 11089da235244c2de2bcca654b518c66133c30ebde53John McCall // 11099da235244c2de2bcca654b518c66133c30ebde53John McCall // TODO: Instead of doing this, just lay out the fields as if the 11109da235244c2de2bcca654b518c66133c30ebde53John McCall // vb-table were at offset zero, then retroactively bump the field 11119da235244c2de2bcca654b518c66133c30ebde53John McCall // offsets up. 1112227e483cb1f77ea6dcd38c2ca9fb490894a5f887Eli Friedman PtrAlign = std::max(PtrAlign, Alignment); 11139da235244c2de2bcca654b518c66133c30ebde53John McCall 11149da235244c2de2bcca654b518c66133c30ebde53John McCall EnsureVTablePointerAlignment(PtrAlign); 11159da235244c2de2bcca654b518c66133c30ebde53John McCall VBPtrOffset = getSize(); 11169da235244c2de2bcca654b518c66133c30ebde53John McCall setSize(getSize() + PtrWidth); 11179da235244c2de2bcca654b518c66133c30ebde53John McCall setDataSize(getSize()); 111897c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedman } 1119e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson} 1120e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 112107cebc57123db6a50c7c293e44a9647ce069952bAnders Carlssonvoid RecordLayoutBuilder::LayoutNonVirtualBase(const BaseSubobjectInfo *Base) { 1122e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson // Layout the base. 1123a2311513524ecef954d2b438bfbe09aa9511b660Anders Carlsson CharUnits Offset = LayoutBase(Base); 1124bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1125e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson // Add its base class offset. 112607cebc57123db6a50c7c293e44a9647ce069952bAnders Carlsson assert(!Bases.count(Base->Class) && "base offset already exists!"); 1127a2311513524ecef954d2b438bfbe09aa9511b660Anders Carlsson Bases.insert(std::make_pair(Base->Class, Offset)); 11283cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson 11293cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson AddPrimaryVirtualBaseOffsets(Base, Offset); 1130e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson} 1131968db3364611a475909b5e76969d2f5472e65597Mike Stump 1132bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbarvoid 11333cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders CarlssonRecordLayoutBuilder::AddPrimaryVirtualBaseOffsets(const BaseSubobjectInfo *Info, 1134a2311513524ecef954d2b438bfbe09aa9511b660Anders Carlsson CharUnits Offset) { 11353cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson // This base isn't interesting, it has no virtual bases. 11363cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson if (!Info->Class->getNumVBases()) 11373cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson return; 11383cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson 11393cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson // First, check if we have a virtual primary base to add offsets for. 11403cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson if (Info->PrimaryVirtualBaseInfo) { 11413cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson assert(Info->PrimaryVirtualBaseInfo->IsVirtual && 11423cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson "Primary virtual base is not virtual!"); 11433cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson if (Info->PrimaryVirtualBaseInfo->Derived == Info) { 11443cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson // Add the offset. 11453cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson assert(!VBases.count(Info->PrimaryVirtualBaseInfo->Class) && 11463cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson "primary vbase offset already exists!"); 11473cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson VBases.insert(std::make_pair(Info->PrimaryVirtualBaseInfo->Class, 1148441c6239c6df8c759bacf6510efbfd434b647066John McCall ASTRecordLayout::VBaseInfo(Offset, false))); 11493cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson 11503cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson // Traverse the primary virtual base. 11513cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson AddPrimaryVirtualBaseOffsets(Info->PrimaryVirtualBaseInfo, Offset); 11523cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson } 115397913576dbe624971bf18726899983d211d742c0Anders Carlsson } 115497913576dbe624971bf18726899983d211d742c0Anders Carlsson 11553cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson // Now go through all direct non-virtual bases. 11563cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(Info->Class); 11573cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson for (unsigned I = 0, E = Info->Bases.size(); I != E; ++I) { 11583cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson const BaseSubobjectInfo *Base = Info->Bases[I]; 11593cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson if (Base->IsVirtual) 116097913576dbe624971bf18726899983d211d742c0Anders Carlsson continue; 11610aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 11626a3567442307864eac52bb84ce41465753513635Anders Carlsson CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(Base->Class); 11633cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson AddPrimaryVirtualBaseOffsets(Base, BaseOffset); 116497913576dbe624971bf18726899983d211d742c0Anders Carlsson } 116597913576dbe624971bf18726899983d211d742c0Anders Carlsson} 116697913576dbe624971bf18726899983d211d742c0Anders Carlsson 11679da235244c2de2bcca654b518c66133c30ebde53John McCall/// needsVFTable - Return true if this class needs a vtable or vf-table 11689da235244c2de2bcca654b518c66133c30ebde53John McCall/// when laid out as a base class. These are treated the same because 11699da235244c2de2bcca654b518c66133c30ebde53John McCall/// they're both always laid out at offset zero. 11709da235244c2de2bcca654b518c66133c30ebde53John McCall/// 11719da235244c2de2bcca654b518c66133c30ebde53John McCall/// This function assumes that the class has no primary base. 11729da235244c2de2bcca654b518c66133c30ebde53John McCallbool RecordLayoutBuilder::needsVFTable(const CXXRecordDecl *RD) const { 11739da235244c2de2bcca654b518c66133c30ebde53John McCall assert(!PrimaryBase); 11749da235244c2de2bcca654b518c66133c30ebde53John McCall 11759da235244c2de2bcca654b518c66133c30ebde53John McCall // In the Itanium ABI, every dynamic class needs a vtable: even if 11769da235244c2de2bcca654b518c66133c30ebde53John McCall // this class has no virtual functions as a base class (i.e. it's 11779da235244c2de2bcca654b518c66133c30ebde53John McCall // non-polymorphic or only has virtual functions from virtual 11789da235244c2de2bcca654b518c66133c30ebde53John McCall // bases),x it still needs a vtable to locate its virtual bases. 11799da235244c2de2bcca654b518c66133c30ebde53John McCall if (!isMicrosoftCXXABI()) 11809da235244c2de2bcca654b518c66133c30ebde53John McCall return RD->isDynamicClass(); 11819da235244c2de2bcca654b518c66133c30ebde53John McCall 11829da235244c2de2bcca654b518c66133c30ebde53John McCall // In the MS ABI, we need a vfptr if the class has virtual functions 11839da235244c2de2bcca654b518c66133c30ebde53John McCall // other than those declared by its virtual bases. The AST doesn't 11849da235244c2de2bcca654b518c66133c30ebde53John McCall // tell us that directly, and checking manually for virtual 11859da235244c2de2bcca654b518c66133c30ebde53John McCall // functions that aren't overrides is expensive, but there are 11869da235244c2de2bcca654b518c66133c30ebde53John McCall // some important shortcuts: 11879da235244c2de2bcca654b518c66133c30ebde53John McCall 11889da235244c2de2bcca654b518c66133c30ebde53John McCall // - Non-polymorphic classes have no virtual functions at all. 11899da235244c2de2bcca654b518c66133c30ebde53John McCall if (!RD->isPolymorphic()) return false; 11909da235244c2de2bcca654b518c66133c30ebde53John McCall 11919da235244c2de2bcca654b518c66133c30ebde53John McCall // - Polymorphic classes with no virtual bases must either declare 11929da235244c2de2bcca654b518c66133c30ebde53John McCall // virtual functions directly or inherit them, but in the latter 11939da235244c2de2bcca654b518c66133c30ebde53John McCall // case we would have a primary base. 11949da235244c2de2bcca654b518c66133c30ebde53John McCall if (RD->getNumVBases() == 0) return true; 11959da235244c2de2bcca654b518c66133c30ebde53John McCall 11969da235244c2de2bcca654b518c66133c30ebde53John McCall return hasNewVirtualFunction(RD); 11979da235244c2de2bcca654b518c66133c30ebde53John McCall} 11989da235244c2de2bcca654b518c66133c30ebde53John McCall 1199441c6239c6df8c759bacf6510efbfd434b647066John McCall/// Does the given class inherit non-virtually from any of the classes 1200441c6239c6df8c759bacf6510efbfd434b647066John McCall/// in the given set? 1201441c6239c6df8c759bacf6510efbfd434b647066John McCallstatic bool hasNonVirtualBaseInSet(const CXXRecordDecl *RD, 1202441c6239c6df8c759bacf6510efbfd434b647066John McCall const ClassSetTy &set) { 1203441c6239c6df8c759bacf6510efbfd434b647066John McCall for (CXXRecordDecl::base_class_const_iterator 1204441c6239c6df8c759bacf6510efbfd434b647066John McCall I = RD->bases_begin(), E = RD->bases_end(); I != E; ++I) { 1205441c6239c6df8c759bacf6510efbfd434b647066John McCall // Ignore virtual links. 1206441c6239c6df8c759bacf6510efbfd434b647066John McCall if (I->isVirtual()) continue; 1207441c6239c6df8c759bacf6510efbfd434b647066John McCall 1208441c6239c6df8c759bacf6510efbfd434b647066John McCall // Check whether the set contains the base. 1209441c6239c6df8c759bacf6510efbfd434b647066John McCall const CXXRecordDecl *base = I->getType()->getAsCXXRecordDecl(); 1210441c6239c6df8c759bacf6510efbfd434b647066John McCall if (set.count(base)) 1211441c6239c6df8c759bacf6510efbfd434b647066John McCall return true; 1212441c6239c6df8c759bacf6510efbfd434b647066John McCall 1213441c6239c6df8c759bacf6510efbfd434b647066John McCall // Otherwise, recurse and propagate. 1214441c6239c6df8c759bacf6510efbfd434b647066John McCall if (hasNonVirtualBaseInSet(base, set)) 1215441c6239c6df8c759bacf6510efbfd434b647066John McCall return true; 1216441c6239c6df8c759bacf6510efbfd434b647066John McCall } 1217441c6239c6df8c759bacf6510efbfd434b647066John McCall 1218441c6239c6df8c759bacf6510efbfd434b647066John McCall return false; 1219441c6239c6df8c759bacf6510efbfd434b647066John McCall} 1220441c6239c6df8c759bacf6510efbfd434b647066John McCall 1221441c6239c6df8c759bacf6510efbfd434b647066John McCall/// Does the given method (B::foo()) already override a method (A::foo()) 1222441c6239c6df8c759bacf6510efbfd434b647066John McCall/// such that A requires a vtordisp in B? If so, we don't need to add a 1223441c6239c6df8c759bacf6510efbfd434b647066John McCall/// new vtordisp for B in a yet-more-derived class C providing C::foo(). 1224441c6239c6df8c759bacf6510efbfd434b647066John McCallstatic bool overridesMethodRequiringVtorDisp(const ASTContext &Context, 1225441c6239c6df8c759bacf6510efbfd434b647066John McCall const CXXMethodDecl *M) { 1226441c6239c6df8c759bacf6510efbfd434b647066John McCall CXXMethodDecl::method_iterator 1227441c6239c6df8c759bacf6510efbfd434b647066John McCall I = M->begin_overridden_methods(), E = M->end_overridden_methods(); 1228441c6239c6df8c759bacf6510efbfd434b647066John McCall if (I == E) return false; 1229441c6239c6df8c759bacf6510efbfd434b647066John McCall 1230441c6239c6df8c759bacf6510efbfd434b647066John McCall const ASTRecordLayout::VBaseOffsetsMapTy &offsets = 1231441c6239c6df8c759bacf6510efbfd434b647066John McCall Context.getASTRecordLayout(M->getParent()).getVBaseOffsetsMap(); 1232441c6239c6df8c759bacf6510efbfd434b647066John McCall do { 1233441c6239c6df8c759bacf6510efbfd434b647066John McCall const CXXMethodDecl *overridden = *I; 1234441c6239c6df8c759bacf6510efbfd434b647066John McCall 1235441c6239c6df8c759bacf6510efbfd434b647066John McCall // If the overridden method's class isn't recognized as a virtual 1236441c6239c6df8c759bacf6510efbfd434b647066John McCall // base in the derived class, ignore it. 1237441c6239c6df8c759bacf6510efbfd434b647066John McCall ASTRecordLayout::VBaseOffsetsMapTy::const_iterator 1238441c6239c6df8c759bacf6510efbfd434b647066John McCall it = offsets.find(overridden->getParent()); 1239441c6239c6df8c759bacf6510efbfd434b647066John McCall if (it == offsets.end()) continue; 1240441c6239c6df8c759bacf6510efbfd434b647066John McCall 1241441c6239c6df8c759bacf6510efbfd434b647066John McCall // Otherwise, check if the overridden method's class needs a vtordisp. 1242441c6239c6df8c759bacf6510efbfd434b647066John McCall if (it->second.hasVtorDisp()) return true; 1243441c6239c6df8c759bacf6510efbfd434b647066John McCall 1244441c6239c6df8c759bacf6510efbfd434b647066John McCall } while (++I != E); 1245441c6239c6df8c759bacf6510efbfd434b647066John McCall return false; 1246441c6239c6df8c759bacf6510efbfd434b647066John McCall} 1247441c6239c6df8c759bacf6510efbfd434b647066John McCall 1248441c6239c6df8c759bacf6510efbfd434b647066John McCall/// In the Microsoft ABI, decide which of the virtual bases require a 1249441c6239c6df8c759bacf6510efbfd434b647066John McCall/// vtordisp field. 1250441c6239c6df8c759bacf6510efbfd434b647066John McCallvoid RecordLayoutBuilder::computeVtordisps(const CXXRecordDecl *RD, 1251441c6239c6df8c759bacf6510efbfd434b647066John McCall ClassSetTy &vtordispVBases) { 1252441c6239c6df8c759bacf6510efbfd434b647066John McCall // Bail out if we have no virtual bases. 1253441c6239c6df8c759bacf6510efbfd434b647066John McCall assert(RD->getNumVBases()); 1254441c6239c6df8c759bacf6510efbfd434b647066John McCall 1255441c6239c6df8c759bacf6510efbfd434b647066John McCall // Build up the set of virtual bases that we haven't decided yet. 1256441c6239c6df8c759bacf6510efbfd434b647066John McCall ClassSetTy undecidedVBases; 1257441c6239c6df8c759bacf6510efbfd434b647066John McCall for (CXXRecordDecl::base_class_const_iterator 1258441c6239c6df8c759bacf6510efbfd434b647066John McCall I = RD->vbases_begin(), E = RD->vbases_end(); I != E; ++I) { 1259441c6239c6df8c759bacf6510efbfd434b647066John McCall const CXXRecordDecl *vbase = I->getType()->getAsCXXRecordDecl(); 1260441c6239c6df8c759bacf6510efbfd434b647066John McCall undecidedVBases.insert(vbase); 1261441c6239c6df8c759bacf6510efbfd434b647066John McCall } 1262441c6239c6df8c759bacf6510efbfd434b647066John McCall assert(!undecidedVBases.empty()); 1263441c6239c6df8c759bacf6510efbfd434b647066John McCall 1264441c6239c6df8c759bacf6510efbfd434b647066John McCall // A virtual base requires a vtordisp field in a derived class if it 1265441c6239c6df8c759bacf6510efbfd434b647066John McCall // requires a vtordisp field in a base class. Walk all the direct 1266441c6239c6df8c759bacf6510efbfd434b647066John McCall // bases and collect this information. 1267441c6239c6df8c759bacf6510efbfd434b647066John McCall for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1268441c6239c6df8c759bacf6510efbfd434b647066John McCall E = RD->bases_end(); I != E; ++I) { 1269441c6239c6df8c759bacf6510efbfd434b647066John McCall const CXXRecordDecl *base = I->getType()->getAsCXXRecordDecl(); 1270441c6239c6df8c759bacf6510efbfd434b647066John McCall const ASTRecordLayout &baseLayout = Context.getASTRecordLayout(base); 1271441c6239c6df8c759bacf6510efbfd434b647066John McCall 1272441c6239c6df8c759bacf6510efbfd434b647066John McCall // Iterate over the set of virtual bases provided by this class. 1273441c6239c6df8c759bacf6510efbfd434b647066John McCall for (ASTRecordLayout::VBaseOffsetsMapTy::const_iterator 1274441c6239c6df8c759bacf6510efbfd434b647066John McCall VI = baseLayout.getVBaseOffsetsMap().begin(), 1275441c6239c6df8c759bacf6510efbfd434b647066John McCall VE = baseLayout.getVBaseOffsetsMap().end(); VI != VE; ++VI) { 1276441c6239c6df8c759bacf6510efbfd434b647066John McCall // If it doesn't need a vtordisp in this base, ignore it. 1277441c6239c6df8c759bacf6510efbfd434b647066John McCall if (!VI->second.hasVtorDisp()) continue; 1278441c6239c6df8c759bacf6510efbfd434b647066John McCall 1279441c6239c6df8c759bacf6510efbfd434b647066John McCall // If we've already seen it and decided it needs a vtordisp, ignore it. 1280441c6239c6df8c759bacf6510efbfd434b647066John McCall if (!undecidedVBases.erase(VI->first)) 1281441c6239c6df8c759bacf6510efbfd434b647066John McCall continue; 1282441c6239c6df8c759bacf6510efbfd434b647066John McCall 1283441c6239c6df8c759bacf6510efbfd434b647066John McCall // Add it. 1284441c6239c6df8c759bacf6510efbfd434b647066John McCall vtordispVBases.insert(VI->first); 1285441c6239c6df8c759bacf6510efbfd434b647066John McCall 1286441c6239c6df8c759bacf6510efbfd434b647066John McCall // Quit as soon as we've decided everything. 1287441c6239c6df8c759bacf6510efbfd434b647066John McCall if (undecidedVBases.empty()) 1288441c6239c6df8c759bacf6510efbfd434b647066John McCall return; 1289441c6239c6df8c759bacf6510efbfd434b647066John McCall } 1290441c6239c6df8c759bacf6510efbfd434b647066John McCall } 1291441c6239c6df8c759bacf6510efbfd434b647066John McCall 1292441c6239c6df8c759bacf6510efbfd434b647066John McCall // Okay, we have virtual bases that we haven't yet decided about. A 1293441c6239c6df8c759bacf6510efbfd434b647066John McCall // virtual base requires a vtordisp if any the non-destructor 1294441c6239c6df8c759bacf6510efbfd434b647066John McCall // virtual methods declared in this class directly override a method 1295441c6239c6df8c759bacf6510efbfd434b647066John McCall // provided by that virtual base. (If so, we need to emit a thunk 1296441c6239c6df8c759bacf6510efbfd434b647066John McCall // for that method, to be used in the construction vftable, which 1297441c6239c6df8c759bacf6510efbfd434b647066John McCall // applies an additional 'vtordisp' this-adjustment.) 1298441c6239c6df8c759bacf6510efbfd434b647066John McCall 1299441c6239c6df8c759bacf6510efbfd434b647066John McCall // Collect the set of bases directly overridden by any method in this class. 1300441c6239c6df8c759bacf6510efbfd434b647066John McCall // It's possible that some of these classes won't be virtual bases, or won't be 1301441c6239c6df8c759bacf6510efbfd434b647066John McCall // provided by virtual bases, or won't be virtual bases in the overridden 1302441c6239c6df8c759bacf6510efbfd434b647066John McCall // instance but are virtual bases elsewhere. Only the last matters for what 1303441c6239c6df8c759bacf6510efbfd434b647066John McCall // we're doing, and we can ignore those: if we don't directly override 1304441c6239c6df8c759bacf6510efbfd434b647066John McCall // a method provided by a virtual copy of a base class, but we do directly 1305441c6239c6df8c759bacf6510efbfd434b647066John McCall // override a method provided by a non-virtual copy of that base class, 1306441c6239c6df8c759bacf6510efbfd434b647066John McCall // then we must indirectly override the method provided by the virtual base, 1307441c6239c6df8c759bacf6510efbfd434b647066John McCall // and so we should already have collected it in the loop above. 1308441c6239c6df8c759bacf6510efbfd434b647066John McCall ClassSetTy overriddenBases; 1309441c6239c6df8c759bacf6510efbfd434b647066John McCall for (CXXRecordDecl::method_iterator 1310441c6239c6df8c759bacf6510efbfd434b647066John McCall M = RD->method_begin(), E = RD->method_end(); M != E; ++M) { 1311441c6239c6df8c759bacf6510efbfd434b647066John McCall // Ignore non-virtual methods and destructors. 1312441c6239c6df8c759bacf6510efbfd434b647066John McCall if (isa<CXXDestructorDecl>(*M) || !M->isVirtual()) 1313441c6239c6df8c759bacf6510efbfd434b647066John McCall continue; 1314441c6239c6df8c759bacf6510efbfd434b647066John McCall 1315441c6239c6df8c759bacf6510efbfd434b647066John McCall for (CXXMethodDecl::method_iterator I = M->begin_overridden_methods(), 1316441c6239c6df8c759bacf6510efbfd434b647066John McCall E = M->end_overridden_methods(); I != E; ++I) { 1317441c6239c6df8c759bacf6510efbfd434b647066John McCall const CXXMethodDecl *overriddenMethod = (*I); 1318441c6239c6df8c759bacf6510efbfd434b647066John McCall 1319441c6239c6df8c759bacf6510efbfd434b647066John McCall // Ignore methods that override methods from vbases that require 1320441c6239c6df8c759bacf6510efbfd434b647066John McCall // require vtordisps. 1321441c6239c6df8c759bacf6510efbfd434b647066John McCall if (overridesMethodRequiringVtorDisp(Context, overriddenMethod)) 1322441c6239c6df8c759bacf6510efbfd434b647066John McCall continue; 1323441c6239c6df8c759bacf6510efbfd434b647066John McCall 1324441c6239c6df8c759bacf6510efbfd434b647066John McCall // As an optimization, check immediately whether we're overriding 1325441c6239c6df8c759bacf6510efbfd434b647066John McCall // something from the undecided set. 1326441c6239c6df8c759bacf6510efbfd434b647066John McCall const CXXRecordDecl *overriddenBase = overriddenMethod->getParent(); 1327441c6239c6df8c759bacf6510efbfd434b647066John McCall if (undecidedVBases.erase(overriddenBase)) { 1328441c6239c6df8c759bacf6510efbfd434b647066John McCall vtordispVBases.insert(overriddenBase); 1329441c6239c6df8c759bacf6510efbfd434b647066John McCall if (undecidedVBases.empty()) return; 1330441c6239c6df8c759bacf6510efbfd434b647066John McCall 1331441c6239c6df8c759bacf6510efbfd434b647066John McCall // We can't 'continue;' here because one of our undecided 1332441c6239c6df8c759bacf6510efbfd434b647066John McCall // vbases might non-virtually inherit from this base. 1333441c6239c6df8c759bacf6510efbfd434b647066John McCall // Consider: 1334441c6239c6df8c759bacf6510efbfd434b647066John McCall // struct A { virtual void foo(); }; 1335441c6239c6df8c759bacf6510efbfd434b647066John McCall // struct B : A {}; 1336441c6239c6df8c759bacf6510efbfd434b647066John McCall // struct C : virtual A, virtual B { virtual void foo(); }; 1337441c6239c6df8c759bacf6510efbfd434b647066John McCall // We need a vtordisp for B here. 1338441c6239c6df8c759bacf6510efbfd434b647066John McCall } 1339441c6239c6df8c759bacf6510efbfd434b647066John McCall 1340441c6239c6df8c759bacf6510efbfd434b647066John McCall // Otherwise, just collect it. 1341441c6239c6df8c759bacf6510efbfd434b647066John McCall overriddenBases.insert(overriddenBase); 1342441c6239c6df8c759bacf6510efbfd434b647066John McCall } 1343441c6239c6df8c759bacf6510efbfd434b647066John McCall } 1344441c6239c6df8c759bacf6510efbfd434b647066John McCall 1345441c6239c6df8c759bacf6510efbfd434b647066John McCall // Walk the undecided v-bases and check whether they (non-virtually) 1346441c6239c6df8c759bacf6510efbfd434b647066John McCall // provide any of the overridden bases. We don't need to consider 1347441c6239c6df8c759bacf6510efbfd434b647066John McCall // virtual links because the vtordisp inheres to the layout 1348441c6239c6df8c759bacf6510efbfd434b647066John McCall // subobject containing the base. 1349441c6239c6df8c759bacf6510efbfd434b647066John McCall for (ClassSetTy::const_iterator 1350441c6239c6df8c759bacf6510efbfd434b647066John McCall I = undecidedVBases.begin(), E = undecidedVBases.end(); I != E; ++I) { 1351441c6239c6df8c759bacf6510efbfd434b647066John McCall if (hasNonVirtualBaseInSet(*I, overriddenBases)) 1352441c6239c6df8c759bacf6510efbfd434b647066John McCall vtordispVBases.insert(*I); 1353441c6239c6df8c759bacf6510efbfd434b647066John McCall } 1354441c6239c6df8c759bacf6510efbfd434b647066John McCall} 1355441c6239c6df8c759bacf6510efbfd434b647066John McCall 13569da235244c2de2bcca654b518c66133c30ebde53John McCall/// hasNewVirtualFunction - Does the given polymorphic class declare a 13579da235244c2de2bcca654b518c66133c30ebde53John McCall/// virtual function that does not override a method from any of its 13589da235244c2de2bcca654b518c66133c30ebde53John McCall/// base classes? 13592fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedmanbool 1360441c6239c6df8c759bacf6510efbfd434b647066John McCallRecordLayoutBuilder::hasNewVirtualFunction(const CXXRecordDecl *RD, 1361441c6239c6df8c759bacf6510efbfd434b647066John McCall bool IgnoreDestructor) const { 13629da235244c2de2bcca654b518c66133c30ebde53John McCall if (!RD->getNumBases()) 13639da235244c2de2bcca654b518c66133c30ebde53John McCall return true; 13649da235244c2de2bcca654b518c66133c30ebde53John McCall 13652fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman for (CXXRecordDecl::method_iterator method = RD->method_begin(); 13662fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman method != RD->method_end(); 13672fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman ++method) { 1368441c6239c6df8c759bacf6510efbfd434b647066John McCall if (method->isVirtual() && !method->size_overridden_methods() && 1369441c6239c6df8c759bacf6510efbfd434b647066John McCall !(IgnoreDestructor && method->getKind() == Decl::CXXDestructor)) { 13702fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman return true; 13712fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman } 13722fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman } 13732fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman return false; 13742fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman} 13752fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman 13769da235244c2de2bcca654b518c66133c30ebde53John McCall/// isPossiblePrimaryBase - Is the given base class an acceptable 13779da235244c2de2bcca654b518c66133c30ebde53John McCall/// primary base class? 137897c0aefe8c0523417ffe8a500a220286e11e7a46Eli Friedmanbool 1379441c6239c6df8c759bacf6510efbfd434b647066John McCallRecordLayoutBuilder::isPossiblePrimaryBase(const CXXRecordDecl *base) const { 13809da235244c2de2bcca654b518c66133c30ebde53John McCall // In the Itanium ABI, a class can be a primary base class if it has 13819da235244c2de2bcca654b518c66133c30ebde53John McCall // a vtable for any reason. 13829da235244c2de2bcca654b518c66133c30ebde53John McCall if (!isMicrosoftCXXABI()) 1383441c6239c6df8c759bacf6510efbfd434b647066John McCall return base->isDynamicClass(); 13849da235244c2de2bcca654b518c66133c30ebde53John McCall 13859da235244c2de2bcca654b518c66133c30ebde53John McCall // In the MS ABI, a class can only be a primary base class if it 13869da235244c2de2bcca654b518c66133c30ebde53John McCall // provides a vf-table at a static offset. That means it has to be 13879da235244c2de2bcca654b518c66133c30ebde53John McCall // non-virtual base. The existence of a separate vb-table means 13889da235244c2de2bcca654b518c66133c30ebde53John McCall // that it's possible to get virtual functions only from a virtual 13899da235244c2de2bcca654b518c66133c30ebde53John McCall // base, which we have to guard against. 13909da235244c2de2bcca654b518c66133c30ebde53John McCall 13919da235244c2de2bcca654b518c66133c30ebde53John McCall // First off, it has to have virtual functions. 1392441c6239c6df8c759bacf6510efbfd434b647066John McCall if (!base->isPolymorphic()) return false; 1393441c6239c6df8c759bacf6510efbfd434b647066John McCall 1394441c6239c6df8c759bacf6510efbfd434b647066John McCall // If it has no virtual bases, then the vfptr must be at a static offset. 1395441c6239c6df8c759bacf6510efbfd434b647066John McCall if (!base->getNumVBases()) return true; 1396441c6239c6df8c759bacf6510efbfd434b647066John McCall 1397441c6239c6df8c759bacf6510efbfd434b647066John McCall // Otherwise, the necessary information is cached in the layout. 1398441c6239c6df8c759bacf6510efbfd434b647066John McCall const ASTRecordLayout &layout = Context.getASTRecordLayout(base); 13999da235244c2de2bcca654b518c66133c30ebde53John McCall 1400441c6239c6df8c759bacf6510efbfd434b647066John McCall // If the base has its own vfptr, it can be a primary base. 1401441c6239c6df8c759bacf6510efbfd434b647066John McCall if (layout.hasOwnVFPtr()) return true; 14029da235244c2de2bcca654b518c66133c30ebde53John McCall 1403441c6239c6df8c759bacf6510efbfd434b647066John McCall // If the base has a primary base class, then it can be a primary base. 1404441c6239c6df8c759bacf6510efbfd434b647066John McCall if (layout.getPrimaryBase()) return true; 1405441c6239c6df8c759bacf6510efbfd434b647066John McCall 1406441c6239c6df8c759bacf6510efbfd434b647066John McCall // Otherwise it can't. 1407441c6239c6df8c759bacf6510efbfd434b647066John McCall return false; 14082fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman} 14092fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman 141097913576dbe624971bf18726899983d211d742c0Anders Carlssonvoid 14117d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders CarlssonRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD, 141297913576dbe624971bf18726899983d211d742c0Anders Carlsson const CXXRecordDecl *MostDerivedClass) { 141388f4296e85d49e4ea63cda729cd5f696824c67ceAnders Carlsson const CXXRecordDecl *PrimaryBase; 1414bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson bool PrimaryBaseIsVirtual; 141537147ea14f39a8522e32e3ba4d043a2a33fff90cAnders Carlsson 1416bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson if (MostDerivedClass == RD) { 141728fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBase = this->PrimaryBase; 141828fdd0a8b450c1329b3303e5cf8e8a788a0ef85aAnders Carlsson PrimaryBaseIsVirtual = this->PrimaryBaseIsVirtual; 1419bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson } else { 14200f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD); 142188f4296e85d49e4ea63cda729cd5f696824c67ceAnders Carlsson PrimaryBase = Layout.getPrimaryBase(); 1422c9e814ba193f38a7b08268612248f63beb279bb3Anders Carlsson PrimaryBaseIsVirtual = Layout.isPrimaryBaseVirtual(); 1423bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson } 1424bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson 1425622e2477d0698d734671523389277e10d8566e26Anders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1426622e2477d0698d734671523389277e10d8566e26Anders Carlsson E = RD->bases_end(); I != E; ++I) { 1427622e2477d0698d734671523389277e10d8566e26Anders Carlsson assert(!I->getType()->isDependentType() && 14289994a34f6cf842721ba7723edc0b9036229fe387Sebastian Redl "Cannot layout class with dependent bases."); 1429bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1430276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson const CXXRecordDecl *BaseDecl = 14319da235244c2de2bcca654b518c66133c30ebde53John McCall cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl()); 1432622e2477d0698d734671523389277e10d8566e26Anders Carlsson 1433622e2477d0698d734671523389277e10d8566e26Anders Carlsson if (I->isVirtual()) { 1434276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson if (PrimaryBase != BaseDecl || !PrimaryBaseIsVirtual) { 1435276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson bool IndirectPrimaryBase = IndirectPrimaryBases.count(BaseDecl); 1436bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson 1437bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson // Only lay out the virtual base if it's not an indirect primary base. 1438bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson if (!IndirectPrimaryBase) { 1439bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson // Only visit virtual bases once. 1440276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson if (!VisitedVirtualBases.insert(BaseDecl)) 1441bdda6c1788dfdb890e1eccd13b949b1cc875eeaaAnders Carlsson continue; 14420aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1443276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson const BaseSubobjectInfo *BaseInfo = VirtualBaseInfo.lookup(BaseDecl); 1444276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson assert(BaseInfo && "Did not find virtual base info!"); 1445276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson LayoutVirtualBase(BaseInfo); 1446147b5ddc6c8618a9d70a83f90de409e444ae705bAnders Carlsson } 1447968db3364611a475909b5e76969d2f5472e65597Mike Stump } 1448fe3010d09cec5cd06e31a3d57fe188a04d9bfa17Mike Stump } 1449bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1450276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson if (!BaseDecl->getNumVBases()) { 1451622e2477d0698d734671523389277e10d8566e26Anders Carlsson // This base isn't interesting since it doesn't have any virtual bases. 1452622e2477d0698d734671523389277e10d8566e26Anders Carlsson continue; 1453622e2477d0698d734671523389277e10d8566e26Anders Carlsson } 1454622e2477d0698d734671523389277e10d8566e26Anders Carlsson 1455276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson LayoutVirtualBases(BaseDecl, MostDerivedClass); 1456eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump } 1457eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump} 1458eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump 14599da235244c2de2bcca654b518c66133c30ebde53John McCallvoid RecordLayoutBuilder::MSLayoutVirtualBases(const CXXRecordDecl *RD) { 14609da235244c2de2bcca654b518c66133c30ebde53John McCall if (!RD->getNumVBases()) 14619da235244c2de2bcca654b518c66133c30ebde53John McCall return; 14629da235244c2de2bcca654b518c66133c30ebde53John McCall 1463441c6239c6df8c759bacf6510efbfd434b647066John McCall ClassSetTy VtordispVBases; 1464441c6239c6df8c759bacf6510efbfd434b647066John McCall computeVtordisps(RD, VtordispVBases); 1465441c6239c6df8c759bacf6510efbfd434b647066John McCall 14669da235244c2de2bcca654b518c66133c30ebde53John McCall // This is substantially simplified because there are no virtual 14679da235244c2de2bcca654b518c66133c30ebde53John McCall // primary bases. 14689da235244c2de2bcca654b518c66133c30ebde53John McCall for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(), 14699da235244c2de2bcca654b518c66133c30ebde53John McCall E = RD->vbases_end(); I != E; ++I) { 14709da235244c2de2bcca654b518c66133c30ebde53John McCall const CXXRecordDecl *BaseDecl = I->getType()->getAsCXXRecordDecl(); 14719da235244c2de2bcca654b518c66133c30ebde53John McCall const BaseSubobjectInfo *BaseInfo = VirtualBaseInfo.lookup(BaseDecl); 14729da235244c2de2bcca654b518c66133c30ebde53John McCall assert(BaseInfo && "Did not find virtual base info!"); 1473441c6239c6df8c759bacf6510efbfd434b647066John McCall 1474441c6239c6df8c759bacf6510efbfd434b647066John McCall // If this base requires a vtordisp, add enough space for an int field. 1475441c6239c6df8c759bacf6510efbfd434b647066John McCall // This is apparently always 32-bits, even on x64. 1476441c6239c6df8c759bacf6510efbfd434b647066John McCall bool vtordispNeeded = false; 1477441c6239c6df8c759bacf6510efbfd434b647066John McCall if (VtordispVBases.count(BaseDecl)) { 1478441c6239c6df8c759bacf6510efbfd434b647066John McCall CharUnits IntSize = 1479441c6239c6df8c759bacf6510efbfd434b647066John McCall CharUnits::fromQuantity(Context.getTargetInfo().getIntWidth() / 8); 1480441c6239c6df8c759bacf6510efbfd434b647066John McCall 1481441c6239c6df8c759bacf6510efbfd434b647066John McCall setSize(getSize() + IntSize); 1482441c6239c6df8c759bacf6510efbfd434b647066John McCall setDataSize(getSize()); 1483441c6239c6df8c759bacf6510efbfd434b647066John McCall vtordispNeeded = true; 1484441c6239c6df8c759bacf6510efbfd434b647066John McCall } 1485441c6239c6df8c759bacf6510efbfd434b647066John McCall 1486441c6239c6df8c759bacf6510efbfd434b647066John McCall LayoutVirtualBase(BaseInfo, vtordispNeeded); 14879da235244c2de2bcca654b518c66133c30ebde53John McCall } 14889da235244c2de2bcca654b518c66133c30ebde53John McCall} 14899da235244c2de2bcca654b518c66133c30ebde53John McCall 1490441c6239c6df8c759bacf6510efbfd434b647066John McCallvoid RecordLayoutBuilder::LayoutVirtualBase(const BaseSubobjectInfo *Base, 1491441c6239c6df8c759bacf6510efbfd434b647066John McCall bool IsVtordispNeed) { 14923cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson assert(!Base->Derived && "Trying to lay out a primary virtual base!"); 14933cd09ccbb1a750a7b40593a7b0a2d95ee2a0ba0eAnders Carlsson 1494e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson // Layout the base. 1495a2311513524ecef954d2b438bfbe09aa9511b660Anders Carlsson CharUnits Offset = LayoutBase(Base); 1496e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson 1497e3bdbee47059839d5e24acab5ee7b925285f573eAnders Carlsson // Add its base class offset. 1498276b491b44b473d91610432aa335927b2c7ad152Anders Carlsson assert(!VBases.count(Base->Class) && "vbase offset already exists!"); 1499441c6239c6df8c759bacf6510efbfd434b647066John McCall VBases.insert(std::make_pair(Base->Class, 1500441c6239c6df8c759bacf6510efbfd434b647066John McCall ASTRecordLayout::VBaseInfo(Offset, IsVtordispNeed))); 1501441c6239c6df8c759bacf6510efbfd434b647066John McCall 1502441c6239c6df8c759bacf6510efbfd434b647066John McCall if (!isMicrosoftCXXABI()) 1503441c6239c6df8c759bacf6510efbfd434b647066John McCall AddPrimaryVirtualBaseOffsets(Base, Offset); 1504e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson} 1505e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 1506a2311513524ecef954d2b438bfbe09aa9511b660Anders CarlssonCharUnits RecordLayoutBuilder::LayoutBase(const BaseSubobjectInfo *Base) { 1507b1d880b15f6b254349bd7a700e6b4f2ec1c24f5bAnders Carlsson const ASTRecordLayout &Layout = Context.getASTRecordLayout(Base->Class); 1508e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 1509453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor 1510453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor CharUnits Offset; 1511453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor 1512453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor // Query the external layout to see if it provides an offset. 1513453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor bool HasExternalLayout = false; 1514453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor if (ExternalLayout) { 1515453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor llvm::DenseMap<const CXXRecordDecl *, CharUnits>::iterator Known; 1516453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor if (Base->IsVirtual) { 1517453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor Known = ExternalVirtualBaseOffsets.find(Base->Class); 1518453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor if (Known != ExternalVirtualBaseOffsets.end()) { 1519453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor Offset = Known->second; 1520453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor HasExternalLayout = true; 1521453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor } 1522453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor } else { 1523453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor Known = ExternalBaseOffsets.find(Base->Class); 1524453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor if (Known != ExternalBaseOffsets.end()) { 1525453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor Offset = Known->second; 1526453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor HasExternalLayout = true; 1527453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor } 1528453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor } 1529453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor } 1530453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor 1531e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // If we have an empty base class, try to place it at offset 0. 1532b1d880b15f6b254349bd7a700e6b4f2ec1c24f5bAnders Carlsson if (Base->Class->isEmpty() && 1533453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor (!HasExternalLayout || Offset == CharUnits::Zero()) && 1534a3d4380d6662a373bc78f915947e5bc06e985e91Anders Carlsson EmptySubobjects->CanPlaceBaseAtOffset(Base, CharUnits::Zero())) { 1535f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck setSize(std::max(getSize(), Layout.getSize())); 1536e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 1537a2311513524ecef954d2b438bfbe09aa9511b660Anders Carlsson return CharUnits::Zero(); 1538e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson } 1539bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 15403263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck CharUnits UnpackedBaseAlign = Layout.getNonVirtualAlign(); 15413263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck CharUnits BaseAlign = (Packed) ? CharUnits::One() : UnpackedBaseAlign; 154243ddd9f2027bdd9c36336a342e9c0dd2aa13f836Argyrios Kyrtzidis 154343ddd9f2027bdd9c36336a342e9c0dd2aa13f836Argyrios Kyrtzidis // The maximum field alignment overrides base align. 1544834945c19cfb87fc21dfb6980a0980618655d79dKen Dyck if (!MaxFieldAlignment.isZero()) { 15453263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck BaseAlign = std::min(BaseAlign, MaxFieldAlignment); 15463263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck UnpackedBaseAlign = std::min(UnpackedBaseAlign, MaxFieldAlignment); 154743ddd9f2027bdd9c36336a342e9c0dd2aa13f836Argyrios Kyrtzidis } 1548bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1549453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor if (!HasExternalLayout) { 1550453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor // Round up the current record size to the base's alignment boundary. 1551453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor Offset = getDataSize().RoundUpToAlignment(BaseAlign); 1552e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 1553453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor // Try to place the base. 1554453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor while (!EmptySubobjects->CanPlaceBaseAtOffset(Base, Offset)) 1555453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor Offset += BaseAlign; 1556453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor } else { 1557453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor bool Allowed = EmptySubobjects->CanPlaceBaseAtOffset(Base, Offset); 1558453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor (void)Allowed; 1559453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor assert(Allowed && "Base subobject externally placed at overlapping offset"); 1560453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor } 1561453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor 1562b1d880b15f6b254349bd7a700e6b4f2ec1c24f5bAnders Carlsson if (!Base->Class->isEmpty()) { 1563e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // Update the data size. 1564f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck setDataSize(Offset + Layout.getNonVirtualSize()); 1565e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 1566f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck setSize(std::max(getSize(), getDataSize())); 1567e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson } else 1568f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck setSize(std::max(getSize(), Offset + Layout.getSize())); 1569e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 1570e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson // Remember max struct/class alignment. 157143ddd9f2027bdd9c36336a342e9c0dd2aa13f836Argyrios Kyrtzidis UpdateAlignment(BaseAlign, UnpackedBaseAlign); 1572e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 1573f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck return Offset; 1574e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson} 1575e239b9d5da3bdc722d29c276b261c136ca9f4eaaAnders Carlsson 1576c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbarvoid RecordLayoutBuilder::InitializeLayout(const Decl *D) { 1577c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar if (const RecordDecl *RD = dyn_cast<RecordDecl>(D)) 1578c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar IsUnion = RD->isUnion(); 15790aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1580a5dd722bdf2f74a1a249fe6661d96a7236aee0f0Anders Carlsson Packed = D->hasAttr<PackedAttr>(); 158162055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian 158262055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian IsMsStruct = D->hasAttr<MsStructAttr>(); 15830aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 158488934e85f81abdc4fb5202325252be3bcab5ebf0Daniel Dunbar // Honor the default struct packing maximum alignment flag. 15854e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (unsigned DefaultMaxFieldAlignment = Context.getLangOpts().PackStruct) { 158688934e85f81abdc4fb5202325252be3bcab5ebf0Daniel Dunbar MaxFieldAlignment = CharUnits::fromQuantity(DefaultMaxFieldAlignment); 158788934e85f81abdc4fb5202325252be3bcab5ebf0Daniel Dunbar } 158888934e85f81abdc4fb5202325252be3bcab5ebf0Daniel Dunbar 1589c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar // mac68k alignment supersedes maximum field alignment and attribute aligned, 1590c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar // and forces all structures to have 2-byte alignment. The IBM docs on it 1591c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar // allude to additional (more complicated) semantics, especially with regard 1592c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar // to bit-fields, but gcc appears not to follow that. 1593c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar if (D->hasAttr<AlignMac68kAttr>()) { 1594c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar IsMac68kAlign = true; 1595834945c19cfb87fc21dfb6980a0980618655d79dKen Dyck MaxFieldAlignment = CharUnits::fromQuantity(2); 1596ea7f6c2c53127b875ed432fd1793d48270d8ba6bKen Dyck Alignment = CharUnits::fromQuantity(2); 1597c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar } else { 1598c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar if (const MaxFieldAlignmentAttr *MFAA = D->getAttr<MaxFieldAlignmentAttr>()) 1599834945c19cfb87fc21dfb6980a0980618655d79dKen Dyck MaxFieldAlignment = Context.toCharUnitsFromBits(MFAA->getAlignment()); 16000aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1601cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt if (unsigned MaxAlign = D->getMaxAlignment()) 16023263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck UpdateAlignment(Context.toCharUnitsFromBits(MaxAlign)); 1603c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar } 1604453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor 1605453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor // If there is an external AST source, ask it for the various offsets. 1606453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor if (const RecordDecl *RD = dyn_cast<RecordDecl>(D)) 1607453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor if (ExternalASTSource *External = Context.getExternalSource()) { 1608453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor ExternalLayout = External->layoutRecordType(RD, 1609453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor ExternalSize, 1610453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor ExternalAlign, 1611453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor ExternalFieldOffsets, 1612453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor ExternalBaseOffsets, 1613453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor ExternalVirtualBaseOffsets); 1614453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor 1615453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor // Update based on external alignment. 1616453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor if (ExternalLayout) { 1617394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor if (ExternalAlign > 0) { 1618394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor Alignment = Context.toCharUnitsFromBits(ExternalAlign); 1619394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor UnpackedAlignment = Alignment; 1620394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor } else { 1621394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor // The external source didn't have alignment information; infer it. 1622394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor InferAlignment = true; 1623394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor } 1624453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor } 1625453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor } 1626c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson} 162774cbe226207fd101623638dadfa7fbada04ff2a6Anders Carlsson 1628c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlssonvoid RecordLayoutBuilder::Layout(const RecordDecl *D) { 1629c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson InitializeLayout(D); 1630a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson LayoutFields(D); 16311eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1632c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson // Finally, round the size of the total struct up to the alignment of the 1633c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson // struct itself. 163478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis FinishLayout(D); 1635c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson} 1636c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 1637c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlssonvoid RecordLayoutBuilder::Layout(const CXXRecordDecl *RD) { 1638c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson InitializeLayout(RD); 1639c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 1640c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson // Lay out the vtable and the non-virtual bases. 1641c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson LayoutNonVirtualBases(RD); 1642c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 1643c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson LayoutFields(RD); 1644c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 164590ce2dba294b8443169fe1a583914908fae0e767Ken Dyck NonVirtualSize = Context.toCharUnitsFromBits( 164690ce2dba294b8443169fe1a583914908fae0e767Ken Dyck llvm::RoundUpToAlignment(getSizeInBits(), 1647bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor Context.getTargetInfo().getCharAlign())); 1648ea7f6c2c53127b875ed432fd1793d48270d8ba6bKen Dyck NonVirtualAlignment = Alignment; 16493dee6efcad9ad56d14f7edd1c29924f0b876a7f9Mike Stump 1650441c6239c6df8c759bacf6510efbfd434b647066John McCall if (isMicrosoftCXXABI()) { 1651441c6239c6df8c759bacf6510efbfd434b647066John McCall if (NonVirtualSize != NonVirtualSize.RoundUpToAlignment(Alignment)) { 16529da235244c2de2bcca654b518c66133c30ebde53John McCall CharUnits AlignMember = 16539da235244c2de2bcca654b518c66133c30ebde53John McCall NonVirtualSize.RoundUpToAlignment(Alignment) - NonVirtualSize; 165497913576dbe624971bf18726899983d211d742c0Anders Carlsson 16559da235244c2de2bcca654b518c66133c30ebde53John McCall setSize(getSize() + AlignMember); 16569da235244c2de2bcca654b518c66133c30ebde53John McCall setDataSize(getSize()); 1657eb19fa948173502f47c26357c2ec41aa4be197b4Mike Stump 16589da235244c2de2bcca654b518c66133c30ebde53John McCall NonVirtualSize = Context.toCharUnitsFromBits( 16599da235244c2de2bcca654b518c66133c30ebde53John McCall llvm::RoundUpToAlignment(getSizeInBits(), 16609da235244c2de2bcca654b518c66133c30ebde53John McCall Context.getTargetInfo().getCharAlign())); 1661441c6239c6df8c759bacf6510efbfd434b647066John McCall } 16629da235244c2de2bcca654b518c66133c30ebde53John McCall 16639da235244c2de2bcca654b518c66133c30ebde53John McCall MSLayoutVirtualBases(RD); 16649da235244c2de2bcca654b518c66133c30ebde53John McCall } else { 16659da235244c2de2bcca654b518c66133c30ebde53John McCall // Lay out the virtual bases and add the primary virtual base offsets. 16669da235244c2de2bcca654b518c66133c30ebde53John McCall LayoutVirtualBases(RD, RD); 16679da235244c2de2bcca654b518c66133c30ebde53John McCall } 16689da235244c2de2bcca654b518c66133c30ebde53John McCall 16699da235244c2de2bcca654b518c66133c30ebde53John McCall // Finally, round the size of the total struct up to the alignment 1670901dd668931a70932ad09092959c42693409a3cdEli Friedman // of the struct itself. 1671901dd668931a70932ad09092959c42693409a3cdEli Friedman FinishLayout(RD); 1672c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 1673a1e87162d36f94d3dc58ff3f0743d6026635a0c6Anders Carlsson#ifndef NDEBUG 1674c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson // Check that we have base offsets for all bases. 1675c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 1676c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson E = RD->bases_end(); I != E; ++I) { 1677c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson if (I->isVirtual()) 1678c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson continue; 16790aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1680c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson const CXXRecordDecl *BaseDecl = 1681c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 1682c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson 1683c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson assert(Bases.count(BaseDecl) && "Did not find base offset!"); 1684c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson } 16850aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1686c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson // And all virtual bases. 1687c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(), 1688c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson E = RD->vbases_end(); I != E; ++I) { 1689c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson const CXXRecordDecl *BaseDecl = 1690c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 16910aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1692c6cab68ae1f8ebdcabaf51391dba09bfbad02e4fAnders Carlsson assert(VBases.count(BaseDecl) && "Did not find base offset!"); 1693a1e87162d36f94d3dc58ff3f0743d6026635a0c6Anders Carlsson } 1694a1e87162d36f94d3dc58ff3f0743d6026635a0c6Anders Carlsson#endif 1695bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson} 1696bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 16977d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonvoid RecordLayoutBuilder::Layout(const ObjCInterfaceDecl *D) { 169893fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson if (ObjCInterfaceDecl *SD = D->getSuperClass()) { 16990f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson const ASTRecordLayout &SL = Context.getASTObjCInterfaceLayout(SD); 170093fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson 17013263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck UpdateAlignment(SL.getAlignment()); 17021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 170393fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson // We start laying out ivars not at the end of the superclass 170493fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson // structure, but at the next byte following the last field. 1705a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck setSize(SL.getDataSize()); 1706f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck setDataSize(getSize()); 170793fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson } 17081eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 1709c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar InitializeLayout(D); 171093fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson // Layout each ivar sequentially. 1711db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose for (const ObjCIvarDecl *IVD = D->all_declared_ivar_begin(); IVD; 1712db8264e4c5ffd7af6fbad4ca4306bd382bb02691Jordy Rose IVD = IVD->getNextIvar()) 1713bf9eb88792e022e54a658657bf22e1925948e384Fariborz Jahanian LayoutField(IVD); 17141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 171593fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson // Finally, round the size of the total struct up to the alignment of the 171693fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson // struct itself. 171778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis FinishLayout(D); 171893fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson} 171993fab9d67ca62e3e291803e5a1309473d6e00344Anders Carlsson 17207d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonvoid RecordLayoutBuilder::LayoutFields(const RecordDecl *D) { 1721a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson // Layout each field, for now, just sequentially, respecting alignment. In 1722a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson // the future, this will need to be tweakable by targets. 172362055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian const FieldDecl *LastFD = 0; 1724855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian ZeroLengthBitfield = 0; 17256ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian unsigned RemainingInAlignment = 0; 17261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump for (RecordDecl::field_iterator Field = D->field_begin(), 172762055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian FieldEnd = D->field_end(); Field != FieldEnd; ++Field) { 172862055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian if (IsMsStruct) { 1729581deb3da481053c4993c7600f97acf7768caac5David Blaikie FieldDecl *FD = *Field; 1730855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian if (Context.ZeroBitfieldFollowsBitfield(FD, LastFD)) 1731855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian ZeroLengthBitfield = FD; 173262055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian // Zero-length bitfields following non-bitfield members are 173362055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian // ignored: 1734855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian else if (Context.ZeroBitfieldFollowsNonBitfield(FD, LastFD)) 173562055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian continue; 173631e7f225fa3c603b84d66bc8ebdf7ed084e36e62Fariborz Jahanian // FIXME. streamline these conditions into a simple one. 173752bbe7a1133c3cb57e9246f1b96c12940ea3821aFariborz Jahanian else if (Context.BitfieldFollowsBitfield(FD, LastFD) || 1738dd7fddb5b6883326e52b278a9b7e9cefea29aae0Chad Rosier Context.BitfieldFollowsNonBitfield(FD, LastFD) || 1739dd7fddb5b6883326e52b278a9b7e9cefea29aae0Chad Rosier Context.NonBitfieldFollowsBitfield(FD, LastFD)) { 174031e7f225fa3c603b84d66bc8ebdf7ed084e36e62Fariborz Jahanian // 1) Adjacent bit fields are packed into the same 1-, 2-, or 17419b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian // 4-byte allocation unit if the integral types are the same 17429b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian // size and if the next bit field fits into the current 17439b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian // allocation unit without crossing the boundary imposed by the 17449b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian // common alignment requirements of the bit fields. 174531e7f225fa3c603b84d66bc8ebdf7ed084e36e62Fariborz Jahanian // 2) Establish a new alignment for a bitfield following 174652bbe7a1133c3cb57e9246f1b96c12940ea3821aFariborz Jahanian // a non-bitfield if size of their types differ. 174731e7f225fa3c603b84d66bc8ebdf7ed084e36e62Fariborz Jahanian // 3) Establish a new alignment for a non-bitfield following 174831e7f225fa3c603b84d66bc8ebdf7ed084e36e62Fariborz Jahanian // a bitfield if size of their types differ. 17499b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian std::pair<uint64_t, unsigned> FieldInfo = 17509b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian Context.getTypeInfo(FD->getType()); 17519b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian uint64_t TypeSize = FieldInfo.first; 17529b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian unsigned FieldAlign = FieldInfo.second; 175330364d0a6450315989f6613910b09f865044a2a0Fariborz Jahanian // This check is needed for 'long long' in -m32 mode. 1754364a59ed8f0b3adb6a9eb9f2d687650ec1d0d8e5Fariborz Jahanian if (TypeSize > FieldAlign && 1755364a59ed8f0b3adb6a9eb9f2d687650ec1d0d8e5Fariborz Jahanian (Context.hasSameType(FD->getType(), 1756364a59ed8f0b3adb6a9eb9f2d687650ec1d0d8e5Fariborz Jahanian Context.UnsignedLongLongTy) 1757364a59ed8f0b3adb6a9eb9f2d687650ec1d0d8e5Fariborz Jahanian ||Context.hasSameType(FD->getType(), 1758364a59ed8f0b3adb6a9eb9f2d687650ec1d0d8e5Fariborz Jahanian Context.LongLongTy))) 175930364d0a6450315989f6613910b09f865044a2a0Fariborz Jahanian FieldAlign = TypeSize; 17609b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian FieldInfo = Context.getTypeInfo(LastFD->getType()); 17619b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian uint64_t TypeSizeLastFD = FieldInfo.first; 17629b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian unsigned FieldAlignLastFD = FieldInfo.second; 176330364d0a6450315989f6613910b09f865044a2a0Fariborz Jahanian // This check is needed for 'long long' in -m32 mode. 1764364a59ed8f0b3adb6a9eb9f2d687650ec1d0d8e5Fariborz Jahanian if (TypeSizeLastFD > FieldAlignLastFD && 1765364a59ed8f0b3adb6a9eb9f2d687650ec1d0d8e5Fariborz Jahanian (Context.hasSameType(LastFD->getType(), 1766364a59ed8f0b3adb6a9eb9f2d687650ec1d0d8e5Fariborz Jahanian Context.UnsignedLongLongTy) 1767364a59ed8f0b3adb6a9eb9f2d687650ec1d0d8e5Fariborz Jahanian || Context.hasSameType(LastFD->getType(), 1768364a59ed8f0b3adb6a9eb9f2d687650ec1d0d8e5Fariborz Jahanian Context.LongLongTy))) 176930364d0a6450315989f6613910b09f865044a2a0Fariborz Jahanian FieldAlignLastFD = TypeSizeLastFD; 17706ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian 17719b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian if (TypeSizeLastFD != TypeSize) { 17726ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian if (RemainingInAlignment && 17736ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian LastFD && LastFD->isBitField() && 1774a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith LastFD->getBitWidthValue(Context)) { 17756ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian // If previous field was a bitfield with some remaining unfilled 17766ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian // bits, pad the field so current field starts on its type boundary. 17776ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian uint64_t FieldOffset = 17786ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian getDataSizeInBits() - UnfilledBitsInLastByte; 17796ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian uint64_t NewSizeInBits = RemainingInAlignment + FieldOffset; 17806ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian setDataSize(llvm::RoundUpToAlignment(NewSizeInBits, 1781bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor Context.getTargetInfo().getCharAlign())); 17826ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian setSize(std::max(getSizeInBits(), getDataSizeInBits())); 17836ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian RemainingInAlignment = 0; 17846ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian } 17856ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian 17869b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian uint64_t UnpaddedFieldOffset = 17879b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian getDataSizeInBits() - UnfilledBitsInLastByte; 17889b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian FieldAlign = std::max(FieldAlign, FieldAlignLastFD); 17896ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian 1790ed63e03e35f2c8ad1a06d7bbc2249d132a730175Fariborz Jahanian // The maximum field alignment overrides the aligned attribute. 1791ed63e03e35f2c8ad1a06d7bbc2249d132a730175Fariborz Jahanian if (!MaxFieldAlignment.isZero()) { 1792ed63e03e35f2c8ad1a06d7bbc2249d132a730175Fariborz Jahanian unsigned MaxFieldAlignmentInBits = 1793ed63e03e35f2c8ad1a06d7bbc2249d132a730175Fariborz Jahanian Context.toBits(MaxFieldAlignment); 1794ed63e03e35f2c8ad1a06d7bbc2249d132a730175Fariborz Jahanian FieldAlign = std::min(FieldAlign, MaxFieldAlignmentInBits); 1795ed63e03e35f2c8ad1a06d7bbc2249d132a730175Fariborz Jahanian } 17966ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian 17979b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian uint64_t NewSizeInBits = 17989b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian llvm::RoundUpToAlignment(UnpaddedFieldOffset, FieldAlign); 17999b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian setDataSize(llvm::RoundUpToAlignment(NewSizeInBits, 1800bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor Context.getTargetInfo().getCharAlign())); 18019b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian UnfilledBitsInLastByte = getDataSizeInBits() - NewSizeInBits; 18029b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian setSize(std::max(getSizeInBits(), getDataSizeInBits())); 18039b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian } 18046ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian if (FD->isBitField()) { 1805a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith uint64_t FieldSize = FD->getBitWidthValue(Context); 18066ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian assert (FieldSize > 0 && "LayoutFields - ms_struct layout"); 18076ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian if (RemainingInAlignment < FieldSize) 18086ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian RemainingInAlignment = TypeSize - FieldSize; 18096ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian else 18106ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian RemainingInAlignment -= FieldSize; 18116ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian } 18126ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian } 18136ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian else if (FD->isBitField()) { 1814a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith uint64_t FieldSize = FD->getBitWidthValue(Context); 18156ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian std::pair<uint64_t, unsigned> FieldInfo = 18166ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian Context.getTypeInfo(FD->getType()); 18176ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian uint64_t TypeSize = FieldInfo.first; 18186ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian RemainingInAlignment = TypeSize - FieldSize; 18199b3acaa32548d0ce78b9c39a3911397f6738a47cFariborz Jahanian } 182062055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian LastFD = FD; 182162055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian } 1822bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor else if (!Context.getTargetInfo().useBitFieldTypeAlignment() && 1823bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor Context.getTargetInfo().useZeroLengthBitfieldAlignment()) { 1824581deb3da481053c4993c7600f97acf7768caac5David Blaikie if (Field->isBitField() && Field->getBitWidthValue(Context) == 0) 1825581deb3da481053c4993c7600f97acf7768caac5David Blaikie ZeroLengthBitfield = *Field; 182661a62216a0bb33fb668ab653d9f9a704e43d2fc6Chad Rosier } 1827581deb3da481053c4993c7600f97acf7768caac5David Blaikie LayoutField(*Field); 182862055b0618fafb4747e783ba3fedd7bc7d57d27dFariborz Jahanian } 18296ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian if (IsMsStruct && RemainingInAlignment && 1830a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith LastFD && LastFD->isBitField() && LastFD->getBitWidthValue(Context)) { 18316ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian // If we ended a bitfield before the full length of the type then 18326ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian // pad the struct out to the full length of the last type. 18336ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian uint64_t FieldOffset = 18346ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian getDataSizeInBits() - UnfilledBitsInLastByte; 18356ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian uint64_t NewSizeInBits = RemainingInAlignment + FieldOffset; 18366ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian setDataSize(llvm::RoundUpToAlignment(NewSizeInBits, 1837bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor Context.getTargetInfo().getCharAlign())); 18386ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian setSize(std::max(getSizeInBits(), getDataSizeInBits())); 18396ec50ad4b12cbb6ca12036080808f912d5ee2515Fariborz Jahanian } 1840a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson} 1841a2df41c107d3c5f5bff2d090fab77734e0da735dAnders Carlsson 18420aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbarvoid RecordLayoutBuilder::LayoutWideBitField(uint64_t FieldSize, 184378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis uint64_t TypeSize, 184478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis bool FieldPacked, 184578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis const FieldDecl *D) { 18464e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie assert(Context.getLangOpts().CPlusPlus && 18474cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson "Can only have wide bit-fields in C++!"); 18480aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 18494cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson // Itanium C++ ABI 2.4: 18500aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar // If sizeof(T)*8 < n, let T' be the largest integral POD type with 18514cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson // sizeof(T')*8 <= n. 18520aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 18534cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson QualType IntegralPODTypes[] = { 18540aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar Context.UnsignedCharTy, Context.UnsignedShortTy, Context.UnsignedIntTy, 18554cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson Context.UnsignedLongTy, Context.UnsignedLongLongTy 18564cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson }; 18574cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 18584cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson QualType Type; 18594cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson for (unsigned I = 0, E = llvm::array_lengthof(IntegralPODTypes); 18604cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson I != E; ++I) { 18614cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson uint64_t Size = Context.getTypeSize(IntegralPODTypes[I]); 18624cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 18634cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson if (Size > FieldSize) 18644cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson break; 18654cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 18664cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson Type = IntegralPODTypes[I]; 18674cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson } 18684cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson assert(!Type.isNull() && "Did not find a type!"); 18690aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 18703b3e1a1e8b44842ac3f07999c0f1eb82f13ffae4Ken Dyck CharUnits TypeAlign = Context.getTypeAlignInChars(Type); 18714cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 18724cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson // We're not going to use any of the unfilled bits in the last byte. 18734cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson UnfilledBitsInLastByte = 0; 18744cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 1875de9f153b2348f590151504888c22cb937134cd27Anders Carlsson uint64_t FieldOffset; 1876a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck uint64_t UnpaddedFieldOffset = getDataSizeInBits() - UnfilledBitsInLastByte; 18770aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 18784cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson if (IsUnion) { 1879a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck setDataSize(std::max(getDataSizeInBits(), FieldSize)); 1880de9f153b2348f590151504888c22cb937134cd27Anders Carlsson FieldOffset = 0; 18814cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson } else { 1882b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier // The bitfield is allocated starting at the next offset aligned 1883b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier // appropriately for T', with length n bits. 18843b3e1a1e8b44842ac3f07999c0f1eb82f13ffae4Ken Dyck FieldOffset = llvm::RoundUpToAlignment(getDataSizeInBits(), 18853b3e1a1e8b44842ac3f07999c0f1eb82f13ffae4Ken Dyck Context.toBits(TypeAlign)); 18860aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 18874cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson uint64_t NewSizeInBits = FieldOffset + FieldSize; 18880aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 1889d5e3ed085032def4ac875d64cb029fc3926652edKen Dyck setDataSize(llvm::RoundUpToAlignment(NewSizeInBits, 1890bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor Context.getTargetInfo().getCharAlign())); 1891a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck UnfilledBitsInLastByte = getDataSizeInBits() - NewSizeInBits; 18924cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson } 18934cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 18944cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson // Place this field at the current location. 18954cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson FieldOffsets.push_back(FieldOffset); 18964cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 189778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis CheckFieldPadding(FieldOffset, UnpaddedFieldOffset, FieldOffset, 18983b3e1a1e8b44842ac3f07999c0f1eb82f13ffae4Ken Dyck Context.toBits(TypeAlign), FieldPacked, D); 189978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 19004cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson // Update the size. 1901a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck setSize(std::max(getSizeInBits(), getDataSizeInBits())); 19020aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 19034cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson // Remember max struct/class alignment. 19043b3e1a1e8b44842ac3f07999c0f1eb82f13ffae4Ken Dyck UpdateAlignment(TypeAlign); 19054cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson} 19064cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 19077d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlssonvoid RecordLayoutBuilder::LayoutBitField(const FieldDecl *D) { 190842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson bool FieldPacked = Packed || D->hasAttr<PackedAttr>(); 1909a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck uint64_t UnpaddedFieldOffset = getDataSizeInBits() - UnfilledBitsInLastByte; 191078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis uint64_t FieldOffset = IsUnion ? 0 : UnpaddedFieldOffset; 1911a6b8b2c09610b8bc4330e948ece8b940c2386406Richard Smith uint64_t FieldSize = D->getBitWidthValue(Context); 1912bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 19130f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson std::pair<uint64_t, unsigned> FieldInfo = Context.getTypeInfo(D->getType()); 191442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson uint64_t TypeSize = FieldInfo.first; 191542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson unsigned FieldAlign = FieldInfo.second; 1916855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian 191730364d0a6450315989f6613910b09f865044a2a0Fariborz Jahanian // This check is needed for 'long long' in -m32 mode. 1918364a59ed8f0b3adb6a9eb9f2d687650ec1d0d8e5Fariborz Jahanian if (IsMsStruct && (TypeSize > FieldAlign) && 1919364a59ed8f0b3adb6a9eb9f2d687650ec1d0d8e5Fariborz Jahanian (Context.hasSameType(D->getType(), 1920364a59ed8f0b3adb6a9eb9f2d687650ec1d0d8e5Fariborz Jahanian Context.UnsignedLongLongTy) 1921364a59ed8f0b3adb6a9eb9f2d687650ec1d0d8e5Fariborz Jahanian || Context.hasSameType(D->getType(), Context.LongLongTy))) 192230364d0a6450315989f6613910b09f865044a2a0Fariborz Jahanian FieldAlign = TypeSize; 192361a62216a0bb33fb668ab653d9f9a704e43d2fc6Chad Rosier 1924855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian if (ZeroLengthBitfield) { 1925b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier std::pair<uint64_t, unsigned> FieldInfo; 1926b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier unsigned ZeroLengthBitfieldAlignment; 1927b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier if (IsMsStruct) { 1928b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier // If a zero-length bitfield is inserted after a bitfield, 1929b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier // and the alignment of the zero-length bitfield is 1930b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier // greater than the member that follows it, `bar', `bar' 1931b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier // will be aligned as the type of the zero-length bitfield. 1932b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier if (ZeroLengthBitfield != D) { 1933b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier FieldInfo = Context.getTypeInfo(ZeroLengthBitfield->getType()); 1934b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier ZeroLengthBitfieldAlignment = FieldInfo.second; 1935b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier // Ignore alignment of subsequent zero-length bitfields. 1936b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier if ((ZeroLengthBitfieldAlignment > FieldAlign) || (FieldSize == 0)) 1937b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier FieldAlign = ZeroLengthBitfieldAlignment; 1938b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier if (FieldSize) 1939b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier ZeroLengthBitfield = 0; 1940b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier } 1941b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier } else { 1942b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier // The alignment of a zero-length bitfield affects the alignment 1943b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier // of the next member. The alignment is the max of the zero 1944b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier // length bitfield's alignment and a target specific fixed value. 1945b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier unsigned ZeroLengthBitfieldBoundary = 1946bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor Context.getTargetInfo().getZeroLengthBitfieldBoundary(); 1947b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier if (ZeroLengthBitfieldBoundary > FieldAlign) 1948b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier FieldAlign = ZeroLengthBitfieldBoundary; 1949855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian } 1950855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian } 1951bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 19524cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson if (FieldSize > TypeSize) { 195378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis LayoutWideBitField(FieldSize, TypeSize, FieldPacked, D); 19544cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson return; 19554cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson } 19564cf6f5fdc529f0b4412505e2e6af099370a479b3Anders Carlsson 195778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // The align if the field is not packed. This is to check if the attribute 195878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // was unnecessary (-Wpacked). 195978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis unsigned UnpackedFieldAlign = FieldAlign; 196078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis uint64_t UnpackedFieldOffset = FieldOffset; 1961bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (!Context.getTargetInfo().useBitFieldTypeAlignment() && !ZeroLengthBitfield) 196278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UnpackedFieldAlign = 1; 196378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 1964b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier if (FieldPacked || 1965bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor (!Context.getTargetInfo().useBitFieldTypeAlignment() && !ZeroLengthBitfield)) 196642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldAlign = 1; 1967cf807c4dfdb23e8fa3f400e0b24ef5b79db7a530Sean Hunt FieldAlign = std::max(FieldAlign, D->getMaxAlignment()); 196878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis UnpackedFieldAlign = std::max(UnpackedFieldAlign, D->getMaxAlignment()); 19691eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 197042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // The maximum field alignment overrides the aligned attribute. 1971bff22ac1f8b78e4c19d5c3e00226ecea3b24e60fEli Friedman if (!MaxFieldAlignment.isZero() && FieldSize != 0) { 1972834945c19cfb87fc21dfb6980a0980618655d79dKen Dyck unsigned MaxFieldAlignmentInBits = Context.toBits(MaxFieldAlignment); 1973834945c19cfb87fc21dfb6980a0980618655d79dKen Dyck FieldAlign = std::min(FieldAlign, MaxFieldAlignmentInBits); 1974834945c19cfb87fc21dfb6980a0980618655d79dKen Dyck UnpackedFieldAlign = std::min(UnpackedFieldAlign, MaxFieldAlignmentInBits); 197578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 1976bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1977394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor // Check if we need to add padding to give the field the correct alignment. 1978394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor if (FieldSize == 0 || 1979394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor (MaxFieldAlignment.isZero() && 1980394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor (FieldOffset & (FieldAlign-1)) + FieldSize > TypeSize)) 1981394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor FieldOffset = llvm::RoundUpToAlignment(FieldOffset, FieldAlign); 1982bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1983394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor if (FieldSize == 0 || 1984394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor (MaxFieldAlignment.isZero() && 1985394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor (UnpackedFieldOffset & (UnpackedFieldAlign-1)) + FieldSize > TypeSize)) 1986394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor UnpackedFieldOffset = llvm::RoundUpToAlignment(UnpackedFieldOffset, 1987394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor UnpackedFieldAlign); 198878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 1989b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier // Padding members don't affect overall alignment, unless zero length bitfield 1990b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier // alignment is enabled. 1991bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor if (!D->getIdentifier() && !Context.getTargetInfo().useZeroLengthBitfieldAlignment()) 199278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis FieldAlign = UnpackedFieldAlign = 1; 1993bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 1994b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier if (!IsMsStruct) 1995b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier ZeroLengthBitfield = 0; 1996b8fca90263760e579d2e463f02c846faa54d03a0Chad Rosier 1997394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor if (ExternalLayout) 1998394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor FieldOffset = updateExternalFieldOffset(D, FieldOffset); 1999394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor 200042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // Place this field at the current location. 200142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldOffsets.push_back(FieldOffset); 2002bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 2003453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor if (!ExternalLayout) 2004453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor CheckFieldPadding(FieldOffset, UnpaddedFieldOffset, UnpackedFieldOffset, 2005453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor UnpackedFieldAlign, FieldPacked, D); 200678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 2007e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson // Update DataSize to include the last byte containing (part of) the bitfield. 2008e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson if (IsUnion) { 2009e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson // FIXME: I think FieldSize should be TypeSize here. 2010a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck setDataSize(std::max(getDataSizeInBits(), FieldSize)); 2011e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson } else { 2012e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson uint64_t NewSizeInBits = FieldOffset + FieldSize; 2013bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 2014d5e3ed085032def4ac875d64cb029fc3926652edKen Dyck setDataSize(llvm::RoundUpToAlignment(NewSizeInBits, 2015bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor Context.getTargetInfo().getCharAlign())); 2016a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck UnfilledBitsInLastByte = getDataSizeInBits() - NewSizeInBits; 2017e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson } 2018bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 2019e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson // Update the size. 2020a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck setSize(std::max(getSizeInBits(), getDataSizeInBits())); 2021bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 202242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // Remember max struct/class alignment. 20233263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck UpdateAlignment(Context.toCharUnitsFromBits(FieldAlign), 20243263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck Context.toCharUnitsFromBits(UnpackedFieldAlign)); 202542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson} 20261eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2027453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregorvoid RecordLayoutBuilder::LayoutField(const FieldDecl *D) { 202842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (D->isBitField()) { 202942dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson LayoutBitField(D); 203042dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson return; 203142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson } 20321eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2033a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck uint64_t UnpaddedFieldOffset = getDataSizeInBits() - UnfilledBitsInLastByte; 203478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 2035e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson // Reset the unfilled bits. 2036e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson UnfilledBitsInLastByte = 0; 2037e4fc0d97420e13d13c9664a3c27c17aa7c1e47b9Anders Carlsson 203842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson bool FieldPacked = Packed || D->hasAttr<PackedAttr>(); 20399ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck CharUnits FieldOffset = 2040a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck IsUnion ? CharUnits::Zero() : getDataSize(); 20419ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck CharUnits FieldSize; 20429ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck CharUnits FieldAlign; 2043bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 204442dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (D->getType()->isIncompleteArrayType()) { 204542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // This is a flexible array member; we can't directly 204642dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // query getTypeInfo about these, so we figure it out here. 204742dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // Flexible array members don't have any size, but they 204842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // have to be aligned appropriately for their element type. 20499ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck FieldSize = CharUnits::Zero(); 20500f0e9b0ace2a970d31ac31811f07e0b1d93501d6Anders Carlsson const ArrayType* ATy = Context.getAsArrayType(D->getType()); 20519ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck FieldAlign = Context.getTypeAlignInChars(ATy->getElementType()); 205242dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson } else if (const ReferenceType *RT = D->getType()->getAs<ReferenceType>()) { 205342dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson unsigned AS = RT->getPointeeType().getAddressSpace(); 20549ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck FieldSize = 2055bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerWidth(AS)); 20569ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck FieldAlign = 2057bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor Context.toCharUnitsFromBits(Context.getTargetInfo().getPointerAlign(AS)); 205842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson } else { 20599ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck std::pair<CharUnits, CharUnits> FieldInfo = 20609ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck Context.getTypeInfoInChars(D->getType()); 206142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson FieldSize = FieldInfo.first; 2062bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson FieldAlign = FieldInfo.second; 206361a62216a0bb33fb668ab653d9f9a704e43d2fc6Chad Rosier 2064855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian if (ZeroLengthBitfield) { 206561a62216a0bb33fb668ab653d9f9a704e43d2fc6Chad Rosier CharUnits ZeroLengthBitfieldBoundary = 206661a62216a0bb33fb668ab653d9f9a704e43d2fc6Chad Rosier Context.toCharUnitsFromBits( 2067bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor Context.getTargetInfo().getZeroLengthBitfieldBoundary()); 206861a62216a0bb33fb668ab653d9f9a704e43d2fc6Chad Rosier if (ZeroLengthBitfieldBoundary == CharUnits::Zero()) { 206961a62216a0bb33fb668ab653d9f9a704e43d2fc6Chad Rosier // If a zero-length bitfield is inserted after a bitfield, 207061a62216a0bb33fb668ab653d9f9a704e43d2fc6Chad Rosier // and the alignment of the zero-length bitfield is 207161a62216a0bb33fb668ab653d9f9a704e43d2fc6Chad Rosier // greater than the member that follows it, `bar', `bar' 207261a62216a0bb33fb668ab653d9f9a704e43d2fc6Chad Rosier // will be aligned as the type of the zero-length bitfield. 207361a62216a0bb33fb668ab653d9f9a704e43d2fc6Chad Rosier std::pair<CharUnits, CharUnits> FieldInfo = 207461a62216a0bb33fb668ab653d9f9a704e43d2fc6Chad Rosier Context.getTypeInfoInChars(ZeroLengthBitfield->getType()); 207561a62216a0bb33fb668ab653d9f9a704e43d2fc6Chad Rosier CharUnits ZeroLengthBitfieldAlignment = FieldInfo.second; 207661a62216a0bb33fb668ab653d9f9a704e43d2fc6Chad Rosier if (ZeroLengthBitfieldAlignment > FieldAlign) 207761a62216a0bb33fb668ab653d9f9a704e43d2fc6Chad Rosier FieldAlign = ZeroLengthBitfieldAlignment; 20780e7bf40027f75c0c62fb002af7eab0882de6d332Chad Rosier } else if (ZeroLengthBitfieldBoundary > FieldAlign) { 207961a62216a0bb33fb668ab653d9f9a704e43d2fc6Chad Rosier // Align 'bar' based on a fixed alignment specified by the target. 2080bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor assert(Context.getTargetInfo().useZeroLengthBitfieldAlignment() && 20816e43f3f0e2fa7a4b50d2497de94a40437cd26003Chad Rosier "ZeroLengthBitfieldBoundary should only be used in conjunction" 20826e43f3f0e2fa7a4b50d2497de94a40437cd26003Chad Rosier " with useZeroLengthBitfieldAlignment."); 208361a62216a0bb33fb668ab653d9f9a704e43d2fc6Chad Rosier FieldAlign = ZeroLengthBitfieldBoundary; 208461a62216a0bb33fb668ab653d9f9a704e43d2fc6Chad Rosier } 2085855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian ZeroLengthBitfield = 0; 2086855a8e79f42e670b405b31efd3963f4d89732affFariborz Jahanian } 20876f75550e40a9177db9979fc130ce3ece026b137dDouglas Gregor 20884e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (Context.getLangOpts().MSBitfields || IsMsStruct) { 20896f75550e40a9177db9979fc130ce3ece026b137dDouglas Gregor // If MS bitfield layout is required, figure out what type is being 20906f75550e40a9177db9979fc130ce3ece026b137dDouglas Gregor // laid out and align the field to the width of that type. 20916f75550e40a9177db9979fc130ce3ece026b137dDouglas Gregor 20926f75550e40a9177db9979fc130ce3ece026b137dDouglas Gregor // Resolve all typedefs down to their base type and round up the field 20936f75550e40a9177db9979fc130ce3ece026b137dDouglas Gregor // alignment if necessary. 20946f75550e40a9177db9979fc130ce3ece026b137dDouglas Gregor QualType T = Context.getBaseElementType(D->getType()); 20956f75550e40a9177db9979fc130ce3ece026b137dDouglas Gregor if (const BuiltinType *BTy = T->getAs<BuiltinType>()) { 20969ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck CharUnits TypeSize = Context.getTypeSizeInChars(BTy); 20976f75550e40a9177db9979fc130ce3ece026b137dDouglas Gregor if (TypeSize > FieldAlign) 20986f75550e40a9177db9979fc130ce3ece026b137dDouglas Gregor FieldAlign = TypeSize; 20996f75550e40a9177db9979fc130ce3ece026b137dDouglas Gregor } 21006f75550e40a9177db9979fc130ce3ece026b137dDouglas Gregor } 210142dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson } 21021eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 210378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // The align if the field is not packed. This is to check if the attribute 210478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // was unnecessary (-Wpacked). 21059ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck CharUnits UnpackedFieldAlign = FieldAlign; 21069ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck CharUnits UnpackedFieldOffset = FieldOffset; 210778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 210842dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson if (FieldPacked) 21099ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck FieldAlign = CharUnits::One(); 21109ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck CharUnits MaxAlignmentInChars = 21119ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck Context.toCharUnitsFromBits(D->getMaxAlignment()); 21129ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck FieldAlign = std::max(FieldAlign, MaxAlignmentInChars); 21139ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck UnpackedFieldAlign = std::max(UnpackedFieldAlign, MaxAlignmentInChars); 21141eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 211542dbcc4d8f0c483693befc76f37ca6dc4e0844e1Anders Carlsson // The maximum field alignment overrides the aligned attribute. 2116834945c19cfb87fc21dfb6980a0980618655d79dKen Dyck if (!MaxFieldAlignment.isZero()) { 21179ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck FieldAlign = std::min(FieldAlign, MaxFieldAlignment); 21189ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck UnpackedFieldAlign = std::min(UnpackedFieldAlign, MaxFieldAlignment); 211978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 21201eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2121394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor // Round up the current record size to the field's alignment boundary. 2122394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor FieldOffset = FieldOffset.RoundUpToAlignment(FieldAlign); 2123394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor UnpackedFieldOffset = 2124394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor UnpackedFieldOffset.RoundUpToAlignment(UnpackedFieldAlign); 2125394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor 2126394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor if (ExternalLayout) { 2127394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor FieldOffset = Context.toCharUnitsFromBits( 2128394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor updateExternalFieldOffset(D, Context.toBits(FieldOffset))); 2129394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor 2130394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor if (!IsUnion && EmptySubobjects) { 2131394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor // Record the fact that we're placing a field at this offset. 2132394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor bool Allowed = EmptySubobjects->CanPlaceFieldAtOffset(D, FieldOffset); 2133394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor (void)Allowed; 2134394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor assert(Allowed && "Externally-placed field cannot be placed here"); 2135394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor } 2136394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor } else { 2137453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor if (!IsUnion && EmptySubobjects) { 2138453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor // Check if we can place the field at this offset. 2139453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor while (!EmptySubobjects->CanPlaceFieldAtOffset(D, FieldOffset)) { 2140453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor // We couldn't place the field at the offset. Try again at a new offset. 2141453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor FieldOffset += FieldAlign; 2142453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor } 21436026504302763f74102592602b392cecd5ced3aeAnders Carlsson } 2144bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson } 2145453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor 2146bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // Place this field at the current location. 21479ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck FieldOffsets.push_back(Context.toBits(FieldOffset)); 21481eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2149453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor if (!ExternalLayout) 2150453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor CheckFieldPadding(Context.toBits(FieldOffset), UnpaddedFieldOffset, 2151453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor Context.toBits(UnpackedFieldOffset), 2152453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor Context.toBits(UnpackedFieldAlign), FieldPacked, D); 215378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 2154bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // Reserve space for this field. 2155cd7a21b85ec94f9bddded4ed990dd2e2019011abEli Friedman uint64_t FieldSizeInBits = Context.toBits(FieldSize); 2156bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson if (IsUnion) 215783be12c8638a5136b937e602b3a9e25f4bc8e50dEli Friedman setDataSize(std::max(getDataSizeInBits(), FieldSizeInBits)); 2158bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson else 215983be12c8638a5136b937e602b3a9e25f4bc8e50dEli Friedman setDataSize(FieldOffset + FieldSize); 21601eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 216183be12c8638a5136b937e602b3a9e25f4bc8e50dEli Friedman // Update the size. 216283be12c8638a5136b937e602b3a9e25f4bc8e50dEli Friedman setSize(std::max(getSizeInBits(), getDataSizeInBits())); 21631eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2164bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // Remember max struct/class alignment. 21659ed9a250180f19b2c44df83a196fc3a2ac82f817Ken Dyck UpdateAlignment(FieldAlign, UnpackedFieldAlign); 2166bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson} 2167bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 216878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidisvoid RecordLayoutBuilder::FinishLayout(const NamedDecl *D) { 2169394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor if (ExternalLayout) { 2170394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor setSize(ExternalSize); 2171394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor return; 2172394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor } 2173394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor 2174bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // In C++, records cannot be of size 0. 21754e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (Context.getLangOpts().CPlusPlus && getSizeInBits() == 0) { 2176adf082e829eb71871b6043009888df3b79055dbaFariborz Jahanian if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) { 2177adf082e829eb71871b6043009888df3b79055dbaFariborz Jahanian // Compatibility with gcc requires a class (pod or non-pod) 2178adf082e829eb71871b6043009888df3b79055dbaFariborz Jahanian // which is not empty but of size 0; such as having fields of 2179adf082e829eb71871b6043009888df3b79055dbaFariborz Jahanian // array of zero-length, remains of Size 0 2180adf082e829eb71871b6043009888df3b79055dbaFariborz Jahanian if (RD->isEmpty()) 2181f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck setSize(CharUnits::One()); 2182adf082e829eb71871b6043009888df3b79055dbaFariborz Jahanian } 2183adf082e829eb71871b6043009888df3b79055dbaFariborz Jahanian else 2184f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck setSize(CharUnits::One()); 2185adf082e829eb71871b6043009888df3b79055dbaFariborz Jahanian } 2186901dd668931a70932ad09092959c42693409a3cdEli Friedman 2187901dd668931a70932ad09092959c42693409a3cdEli Friedman // MSVC doesn't round up to the alignment of the record with virtual bases. 2188901dd668931a70932ad09092959c42693409a3cdEli Friedman if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) { 2189901dd668931a70932ad09092959c42693409a3cdEli Friedman if (isMicrosoftCXXABI() && RD->getNumVBases()) 2190901dd668931a70932ad09092959c42693409a3cdEli Friedman return; 2191901dd668931a70932ad09092959c42693409a3cdEli Friedman } 2192901dd668931a70932ad09092959c42693409a3cdEli Friedman 2193bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // Finally, round the size of the record up to the alignment of the 2194bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson // record itself. 2195a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck uint64_t UnpaddedSize = getSizeInBits() - UnfilledBitsInLastByte; 2196f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck uint64_t UnpackedSizeInBits = 2197a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck llvm::RoundUpToAlignment(getSizeInBits(), 2198a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck Context.toBits(UnpackedAlignment)); 2199f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck CharUnits UnpackedSize = Context.toCharUnitsFromBits(UnpackedSizeInBits); 2200a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck setSize(llvm::RoundUpToAlignment(getSizeInBits(), Context.toBits(Alignment))); 220178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 2202bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor unsigned CharBitNum = Context.getTargetInfo().getCharWidth(); 220378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (const RecordDecl *RD = dyn_cast<RecordDecl>(D)) { 220478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // Warn if padding was introduced to the struct/class/union. 2205a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck if (getSizeInBits() > UnpaddedSize) { 2206a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck unsigned PadSize = getSizeInBits() - UnpaddedSize; 220778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis bool InBits = true; 220878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (PadSize % CharBitNum == 0) { 220978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis PadSize = PadSize / CharBitNum; 221078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis InBits = false; 221178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 221278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis Diag(RD->getLocation(), diag::warn_padded_struct_size) 221378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << Context.getTypeDeclType(RD) 221478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << PadSize 221578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << (InBits ? 1 : 0) /*(byte|bit)*/ << (PadSize > 1); // plural or not 221678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 221778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 221878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // Warn if we packed it unnecessarily. If the alignment is 1 byte don't 221978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // bother since there won't be alignment issues. 2220a0c21c4ec00ea083bf036edb08bb016085b53409Ken Dyck if (Packed && UnpackedAlignment > CharUnits::One() && 2221f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck getSize() == UnpackedSize) 222278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis Diag(D->getLocation(), diag::warn_unnecessary_packed) 222378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << Context.getTypeDeclType(RD); 222478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 2225bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson} 2226bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson 22273263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyckvoid RecordLayoutBuilder::UpdateAlignment(CharUnits NewAlignment, 22283263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck CharUnits UnpackedNewAlignment) { 2229453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor // The alignment is not modified when using 'mac68k' alignment or when 2230394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor // we have an externally-supplied layout that also provides overall alignment. 2231394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor if (IsMac68kAlign || (ExternalLayout && !InferAlignment)) 2232c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar return; 2233c6082fe347a414a2e19f2ad8fe41720f10733296Daniel Dunbar 22343263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck if (NewAlignment > Alignment) { 22353263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck assert(llvm::isPowerOf2_32(NewAlignment.getQuantity() && 22363263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck "Alignment not a power of 2")); 22373263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck Alignment = NewAlignment; 223878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 223978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 22403263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck if (UnpackedNewAlignment > UnpackedAlignment) { 22413263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck assert(llvm::isPowerOf2_32(UnpackedNewAlignment.getQuantity() && 224278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis "Alignment not a power of 2")); 22433263e09c8e0925edaa541d0d4bb995b4bfb454e7Ken Dyck UnpackedAlignment = UnpackedNewAlignment; 224478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 224578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis} 224678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 2247394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregoruint64_t 2248394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas GregorRecordLayoutBuilder::updateExternalFieldOffset(const FieldDecl *Field, 2249394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor uint64_t ComputedOffset) { 2250394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor assert(ExternalFieldOffsets.find(Field) != ExternalFieldOffsets.end() && 2251394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor "Field does not have an external offset"); 2252394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor 2253394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor uint64_t ExternalFieldOffset = ExternalFieldOffsets[Field]; 2254394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor 2255394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor if (InferAlignment && ExternalFieldOffset < ComputedOffset) { 2256394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor // The externally-supplied field offset is before the field offset we 2257394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor // computed. Assume that the structure is packed. 2258394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor Alignment = CharUnits::fromQuantity(1); 2259394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor InferAlignment = false; 2260394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor } 2261394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor 2262394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor // Use the externally-supplied field offset. 2263394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor return ExternalFieldOffset; 2264394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor} 2265394f7b650a03d5d4d8f740d6765f257b1c4e2ec0Douglas Gregor 226678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidisvoid RecordLayoutBuilder::CheckFieldPadding(uint64_t Offset, 226778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis uint64_t UnpaddedOffset, 226878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis uint64_t UnpackedOffset, 226978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis unsigned UnpackedAlign, 227078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis bool isPacked, 227178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis const FieldDecl *D) { 227278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // We let objc ivars without warning, objc interfaces generally are not used 227378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // for padding tricks. 227478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (isa<ObjCIvarDecl>(D)) 2275bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson return; 22761eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2277ae5860e1787230dd8b8948a08632c9be777d8522Ted Kremenek // Don't warn about structs created without a SourceLocation. This can 2278ae5860e1787230dd8b8948a08632c9be777d8522Ted Kremenek // be done by clients of the AST, such as codegen. 2279ae5860e1787230dd8b8948a08632c9be777d8522Ted Kremenek if (D->getLocation().isInvalid()) 2280ae5860e1787230dd8b8948a08632c9be777d8522Ted Kremenek return; 2281ae5860e1787230dd8b8948a08632c9be777d8522Ted Kremenek 2282bcfd1f55bfbb3e5944cd5e03d07b343e280838c4Douglas Gregor unsigned CharBitNum = Context.getTargetInfo().getCharWidth(); 22831eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 228478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // Warn if padding was introduced to the struct/class. 228578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (!IsUnion && Offset > UnpaddedOffset) { 228678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis unsigned PadSize = Offset - UnpaddedOffset; 228778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis bool InBits = true; 228878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (PadSize % CharBitNum == 0) { 228978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis PadSize = PadSize / CharBitNum; 229078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis InBits = false; 229178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 229278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (D->getIdentifier()) 229378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis Diag(D->getLocation(), diag::warn_padded_struct_field) 229478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << (D->getParent()->isStruct() ? 0 : 1) // struct|class 229578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << Context.getTypeDeclType(D->getParent()) 229678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << PadSize 229778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << (InBits ? 1 : 0) /*(byte|bit)*/ << (PadSize > 1) // plural or not 229878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << D->getIdentifier(); 229978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis else 230078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis Diag(D->getLocation(), diag::warn_padded_struct_anon_field) 230178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << (D->getParent()->isStruct() ? 0 : 1) // struct|class 230278a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << Context.getTypeDeclType(D->getParent()) 230378a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << PadSize 230478a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << (InBits ? 1 : 0) /*(byte|bit)*/ << (PadSize > 1); // plural or not 230578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis } 230678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 230778a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // Warn if we packed it unnecessarily. If the alignment is 1 byte don't 230878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis // bother since there won't be alignment issues. 230978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis if (isPacked && UnpackedAlign > CharBitNum && Offset == UnpackedOffset) 231078a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis Diag(D->getLocation(), diag::warn_unnecessary_packed) 231178a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis << D->getIdentifier(); 2312bda4c1015e27ac82d31afb4519dd53586e61a51aAnders Carlsson} 23131eb4433ac451dc16f4133a88af2d002ac26c58efMike Stump 2314f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlssonconst CXXMethodDecl * 23157d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders CarlssonRecordLayoutBuilder::ComputeKeyFunction(const CXXRecordDecl *RD) { 23168d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar // If a class isn't polymorphic it doesn't have a key function. 2317f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (!RD->isPolymorphic()) 2318f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson return 0; 231961eab8872168af6eb1e0047a82901096cf145e27Eli Friedman 2320cb5d2d0647fdab2e36c85b417e03bf18916ce10cEli Friedman // A class that is not externally visible doesn't have a key function. (Or 232161eab8872168af6eb1e0047a82901096cf145e27Eli Friedman // at least, there's no point to assigning a key function to such a class; 232261eab8872168af6eb1e0047a82901096cf145e27Eli Friedman // this doesn't affect the ABI.) 2323cb5d2d0647fdab2e36c85b417e03bf18916ce10cEli Friedman if (RD->getLinkage() != ExternalLinkage) 232461eab8872168af6eb1e0047a82901096cf145e27Eli Friedman return 0; 232561eab8872168af6eb1e0047a82901096cf145e27Eli Friedman 23263bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis // Template instantiations don't have key functions,see Itanium C++ ABI 5.2.6. 23273bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis // Same behavior as GCC. 23283bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis TemplateSpecializationKind TSK = RD->getTemplateSpecializationKind(); 23293bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis if (TSK == TSK_ImplicitInstantiation || 23303bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis TSK == TSK_ExplicitInstantiationDefinition) 23313bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis return 0; 23323bd5b6c3c2ad1d5a6f88cf21f627e8d4f03c4df4Argyrios Kyrtzidis 2333bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar for (CXXRecordDecl::method_iterator I = RD->method_begin(), 2334bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->method_end(); I != E; ++I) { 2335581deb3da481053c4993c7600f97acf7768caac5David Blaikie const CXXMethodDecl *MD = *I; 2336bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 2337f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (!MD->isVirtual()) 2338f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson continue; 2339bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 2340f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (MD->isPure()) 2341f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson continue; 234261eab8872168af6eb1e0047a82901096cf145e27Eli Friedman 2343f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson // Ignore implicit member functions, they are always marked as inline, but 2344f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson // they don't have a body until they're defined. 2345f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (MD->isImplicit()) 2346f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson continue; 2347bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 2348bd6d6197fcfc98356ea60e816365eb0648b69556Douglas Gregor if (MD->isInlineSpecified()) 2349bd6d6197fcfc98356ea60e816365eb0648b69556Douglas Gregor continue; 2350f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson 2351f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson if (MD->hasInlineBody()) 2352f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson continue; 2353bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 2354c23aca44753ff65303fb19d4d6d2114018629f07Benjamin Kramer // Ignore inline deleted or defaulted functions. 2355f3fce80bb2eafaa556779c84f38104003bddb0eaBenjamin Kramer if (!MD->isUserProvided()) 2356f3fce80bb2eafaa556779c84f38104003bddb0eaBenjamin Kramer continue; 2357f3fce80bb2eafaa556779c84f38104003bddb0eaBenjamin Kramer 2358f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson // We found it. 2359f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson return MD; 2360f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson } 2361bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 2362f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson return 0; 2363f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson} 2364f53df2398e07d13be9962b95aebc19b31706fa33Anders Carlsson 236578a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios KyrtzidisDiagnosticBuilder 236678a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios KyrtzidisRecordLayoutBuilder::Diag(SourceLocation Loc, unsigned DiagID) { 236733e4e70c8c0a17e0ccb7465d96556b077a68ecb1Argyrios Kyrtzidis return Context.getDiagnostics().Report(Loc, DiagID); 236878a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis} 236978a916ec5ff5b66adec3c499e1b9af7b87668309Argyrios Kyrtzidis 23701e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// getASTRecordLayout - Get or compute information about the layout of the 23711e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// specified record (struct/union/class), which indicates its size and field 23721e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// position information. 23734ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foadconst ASTRecordLayout & 23744ba2a17694148e16eaa8d3917f657ffcd3667be4Jay FoadASTContext::getASTRecordLayout(const RecordDecl *D) const { 23756595935602f57b4f2115785bb39dabc83e4232dcJohn McCall // These asserts test different things. A record has a definition 23766595935602f57b4f2115785bb39dabc83e4232dcJohn McCall // as soon as we begin to parse the definition. That definition is 23776595935602f57b4f2115785bb39dabc83e4232dcJohn McCall // not a complete definition (which is what isDefinition() tests) 23786595935602f57b4f2115785bb39dabc83e4232dcJohn McCall // until we *finish* parsing the definition. 2379fd5a5f547c5012197475ba628947d9755c96cfdcSean Callanan 2380fd5a5f547c5012197475ba628947d9755c96cfdcSean Callanan if (D->hasExternalLexicalStorage() && !D->getDefinition()) 2381fd5a5f547c5012197475ba628947d9755c96cfdcSean Callanan getExternalSource()->CompleteType(const_cast<RecordDecl*>(D)); 2382fd5a5f547c5012197475ba628947d9755c96cfdcSean Callanan 23831e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson D = D->getDefinition(); 23841e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson assert(D && "Cannot get layout of forward declarations!"); 23855e1cdac63c3d9c9b32fa41fa0b2d242a58a20d49John McCall assert(D->isCompleteDefinition() && "Cannot layout type before complete!"); 23861e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 23871e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // Look up this layout, if already laid out, return what we have. 23881e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // Note that we can't save a reference to the entry because this function 23891e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // is recursive. 23901e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson const ASTRecordLayout *Entry = ASTRecordLayouts[D]; 23911e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson if (Entry) return *Entry; 23921e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 23932f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson const ASTRecordLayout *NewEntry; 23942f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson 23952f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson if (const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) { 2396261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson EmptySubobjectMap EmptySubobjects(*this, RD); 23979da235244c2de2bcca654b518c66133c30ebde53John McCall RecordLayoutBuilder Builder(*this, &EmptySubobjects); 23989da235244c2de2bcca654b518c66133c30ebde53John McCall Builder.Layout(RD); 23999da235244c2de2bcca654b518c66133c30ebde53John McCall 24009da235244c2de2bcca654b518c66133c30ebde53John McCall // MSVC gives the vb-table pointer an alignment equal to that of 24019da235244c2de2bcca654b518c66133c30ebde53John McCall // the non-virtual part of the structure. That's an inherently 24029da235244c2de2bcca654b518c66133c30ebde53John McCall // multi-pass operation. If our first pass doesn't give us 24039da235244c2de2bcca654b518c66133c30ebde53John McCall // adequate alignment, try again with the specified minimum 24049da235244c2de2bcca654b518c66133c30ebde53John McCall // alignment. This is *much* more maintainable than computing the 24059da235244c2de2bcca654b518c66133c30ebde53John McCall // alignment in advance in a separately-coded pass; it's also 24069da235244c2de2bcca654b518c66133c30ebde53John McCall // significantly more efficient in the common case where the 24079da235244c2de2bcca654b518c66133c30ebde53John McCall // vb-table doesn't need extra padding. 24089da235244c2de2bcca654b518c66133c30ebde53John McCall if (Builder.VBPtrOffset != CharUnits::fromQuantity(-1) && 24099da235244c2de2bcca654b518c66133c30ebde53John McCall (Builder.VBPtrOffset % Builder.NonVirtualAlignment) != 0) { 24109da235244c2de2bcca654b518c66133c30ebde53John McCall Builder.resetWithTargetAlignment(Builder.NonVirtualAlignment); 24119da235244c2de2bcca654b518c66133c30ebde53John McCall Builder.Layout(RD); 24122fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman } 24132fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman 24142f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson // FIXME: This is not always correct. See the part about bitfields at 24152f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson // http://www.codesourcery.com/public/cxx-abi/abi.html#POD for more info. 24162f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson // FIXME: IsPODForThePurposeOfLayout should be stored in the record layout. 24172fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman // This does not affect the calculations of MSVC layouts 24182fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman bool IsPODForThePurposeOfLayout = 24199da235244c2de2bcca654b518c66133c30ebde53John McCall (!Builder.isMicrosoftCXXABI() && cast<CXXRecordDecl>(D)->isPOD()); 24202f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson 24212f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson // FIXME: This should be done in FinalizeLayout. 2422f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck CharUnits DataSize = 24239da235244c2de2bcca654b518c66133c30ebde53John McCall IsPODForThePurposeOfLayout ? Builder.getSize() : Builder.getDataSize(); 2424f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck CharUnits NonVirtualSize = 24259da235244c2de2bcca654b518c66133c30ebde53John McCall IsPODForThePurposeOfLayout ? DataSize : Builder.NonVirtualSize; 24262f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson 24270aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar NewEntry = 24289da235244c2de2bcca654b518c66133c30ebde53John McCall new (*this) ASTRecordLayout(*this, Builder.getSize(), 24299da235244c2de2bcca654b518c66133c30ebde53John McCall Builder.Alignment, 2430441c6239c6df8c759bacf6510efbfd434b647066John McCall Builder.HasOwnVFPtr, 24319da235244c2de2bcca654b518c66133c30ebde53John McCall Builder.VBPtrOffset, 2432f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck DataSize, 24339da235244c2de2bcca654b518c66133c30ebde53John McCall Builder.FieldOffsets.data(), 24349da235244c2de2bcca654b518c66133c30ebde53John McCall Builder.FieldOffsets.size(), 2435a1fdb0bc09aa0d17841cdbdd8c52cd1368251cbfKen Dyck NonVirtualSize, 24369da235244c2de2bcca654b518c66133c30ebde53John McCall Builder.NonVirtualAlignment, 2437261febd091cd05325ae202b7d388a2d266bbf126Anders Carlsson EmptySubobjects.SizeOfLargestEmptySubobject, 24389da235244c2de2bcca654b518c66133c30ebde53John McCall Builder.PrimaryBase, 24399da235244c2de2bcca654b518c66133c30ebde53John McCall Builder.PrimaryBaseIsVirtual, 24409da235244c2de2bcca654b518c66133c30ebde53John McCall Builder.Bases, Builder.VBases); 24412f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson } else { 24429da235244c2de2bcca654b518c66133c30ebde53John McCall RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0); 24432f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson Builder.Layout(D); 24440aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 24452f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson NewEntry = 2446f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck new (*this) ASTRecordLayout(*this, Builder.getSize(), 2447ea7f6c2c53127b875ed432fd1793d48270d8ba6bKen Dyck Builder.Alignment, 2448f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck Builder.getSize(), 24492f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson Builder.FieldOffsets.data(), 24502f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson Builder.FieldOffsets.size()); 24512f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson } 24522f64e377d1aa733b81a4c5e78e32a62c41426626Anders Carlsson 24531e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson ASTRecordLayouts[D] = NewEntry; 24541e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 24554e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie if (getLangOpts().DumpRecordLayouts) { 24561e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson llvm::errs() << "\n*** Dumping AST Record Layout\n"; 24574e4d08403ca5cfd4d558fa2936215d3a4e5a528dDavid Blaikie DumpRecordLayout(D, llvm::errs(), getLangOpts().DumpRecordLayoutsSimple); 24581e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson } 24591e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 24601e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson return *NewEntry; 24611e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson} 24621e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 24631e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlssonconst CXXMethodDecl *ASTContext::getKeyFunction(const CXXRecordDecl *RD) { 24641e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson RD = cast<CXXRecordDecl>(RD->getDefinition()); 24651e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson assert(RD && "Cannot get key function for forward declarations!"); 24660aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 24671e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson const CXXMethodDecl *&Entry = KeyFunctions[RD]; 24680aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar if (!Entry) 24697d0918acd134ab93b7d3eb6add93dfde37b1f7b3Anders Carlsson Entry = RecordLayoutBuilder::ComputeKeyFunction(RD); 24700aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 24711e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson return Entry; 24721e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson} 24731e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 24742d6a5670465cb3f1d811695a9f23e372508240d2Richard Smithstatic uint64_t getFieldOffset(const ASTContext &C, const FieldDecl *FD) { 24752d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith const ASTRecordLayout &Layout = C.getASTRecordLayout(FD->getParent()); 24762d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith return Layout.getFieldOffset(FD->getFieldIndex()); 24772d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith} 24782d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith 24792d6a5670465cb3f1d811695a9f23e372508240d2Richard Smithuint64_t ASTContext::getFieldOffset(const ValueDecl *VD) const { 24802d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith uint64_t OffsetInBits; 24812d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith if (const FieldDecl *FD = dyn_cast<FieldDecl>(VD)) { 24822d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith OffsetInBits = ::getFieldOffset(*this, FD); 24832d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith } else { 24842d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith const IndirectFieldDecl *IFD = cast<IndirectFieldDecl>(VD); 24852d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith 24862d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith OffsetInBits = 0; 24872d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith for (IndirectFieldDecl::chain_iterator CI = IFD->chain_begin(), 24882d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith CE = IFD->chain_end(); 24892d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith CI != CE; ++CI) 24902d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith OffsetInBits += ::getFieldOffset(*this, cast<FieldDecl>(*CI)); 24912d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith } 24922d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith 24932d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith return OffsetInBits; 24942d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith} 24952d6a5670465cb3f1d811695a9f23e372508240d2Richard Smith 249668395a7a9c5ec4400c4d76f16ee20d9b4c9326d8Eric Christopher/// getObjCLayout - Get or compute information about the layout of the 249768395a7a9c5ec4400c4d76f16ee20d9b4c9326d8Eric Christopher/// given interface. 24981e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// 24991e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// \param Impl - If given, also include the layout of the interface's 25001e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson/// implementation. This may differ by including synthesized ivars. 25011e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlssonconst ASTRecordLayout & 25021e641ce1c169b4b0cac3d7ad6da44b323453049cAnders CarlssonASTContext::getObjCLayout(const ObjCInterfaceDecl *D, 25034ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad const ObjCImplementationDecl *Impl) const { 2504e7aa27a826f0b353713df6bfa0715818db8cde74Douglas Gregor // Retrieve the definition 2505cad313bd7b28674e0e409e610c450a2411107443Sean Callanan if (D->hasExternalLexicalStorage() && !D->getDefinition()) 2506cad313bd7b28674e0e409e610c450a2411107443Sean Callanan getExternalSource()->CompleteType(const_cast<ObjCInterfaceDecl*>(D)); 2507e7aa27a826f0b353713df6bfa0715818db8cde74Douglas Gregor D = D->getDefinition(); 2508e7aa27a826f0b353713df6bfa0715818db8cde74Douglas Gregor assert(D && D->isThisDeclarationADefinition() && "Invalid interface decl!"); 25091e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 25101e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // Look up this layout, if already laid out, return what we have. 25111e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson ObjCContainerDecl *Key = 25121e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson Impl ? (ObjCContainerDecl*) Impl : (ObjCContainerDecl*) D; 25131e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson if (const ASTRecordLayout *Entry = ObjCLayouts[Key]) 25141e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson return *Entry; 25151e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 25161e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // Add in synthesized ivar count if laying out an implementation. 25171e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson if (Impl) { 25181e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson unsigned SynthCount = CountNonClassIvars(D); 25191e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // If there aren't any sythesized ivars then reuse the interface 25201e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // entry. Note we can't cache this because we simply free all 25211e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // entries later; however we shouldn't look up implementations 25221e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson // frequently. 25231e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson if (SynthCount == 0) 25241e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson return getObjCLayout(D, 0); 25251e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson } 25261e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 25279da235244c2de2bcca654b518c66133c30ebde53John McCall RecordLayoutBuilder Builder(*this, /*EmptySubobjects=*/0); 252836cdc61b98460c06ee07710f77b911675fdce6a7Anders Carlsson Builder.Layout(D); 252936cdc61b98460c06ee07710f77b911675fdce6a7Anders Carlsson 25301e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson const ASTRecordLayout *NewEntry = 2531f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck new (*this) ASTRecordLayout(*this, Builder.getSize(), 2532ea7f6c2c53127b875ed432fd1793d48270d8ba6bKen Dyck Builder.Alignment, 2533f079b735d876f75e67b8dcc6980d0b742903ce0dKen Dyck Builder.getDataSize(), 253436cdc61b98460c06ee07710f77b911675fdce6a7Anders Carlsson Builder.FieldOffsets.data(), 253536cdc61b98460c06ee07710f77b911675fdce6a7Anders Carlsson Builder.FieldOffsets.size()); 25360aa7edbc1f579787c4f69144fd1b04e777d89391Daniel Dunbar 25371e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson ObjCLayouts[Key] = NewEntry; 25381e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 25391e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson return *NewEntry; 25401e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson} 25411e641ce1c169b4b0cac3d7ad6da44b323453049cAnders Carlsson 25425f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic void PrintOffset(raw_ostream &OS, 25433069a0d28637ad0ad583d9fdd7bc6bc6aa677fb5Anders Carlsson CharUnits Offset, unsigned IndentLevel) { 2544e4ebbf79c7045343b9dbe49c721c6023be06f9eeBenjamin Kramer OS << llvm::format("%4" PRId64 " | ", (int64_t)Offset.getQuantity()); 2545bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS.indent(IndentLevel * 2); 2546bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar} 2547bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 25485f9e272e632e951b1efe824cd16acb4d96077930Chris Lattnerstatic void DumpCXXRecordLayout(raw_ostream &OS, 25494ba2a17694148e16eaa8d3917f657ffcd3667be4Jay Foad const CXXRecordDecl *RD, const ASTContext &C, 25503069a0d28637ad0ad583d9fdd7bc6bc6aa677fb5Anders Carlsson CharUnits Offset, 2551bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar unsigned IndentLevel, 2552bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar const char* Description, 2553bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar bool IncludeVirtualBases) { 25543069a0d28637ad0ad583d9fdd7bc6bc6aa677fb5Anders Carlsson const ASTRecordLayout &Layout = C.getASTRecordLayout(RD); 2555bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 2556bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar PrintOffset(OS, Offset, IndentLevel); 2557cb421fa690da545b58a720abe5f1c49b166dbde7Dan Gohman OS << C.getTypeDeclType(const_cast<CXXRecordDecl *>(RD)).getAsString(); 2558bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (Description) 2559bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << ' ' << Description; 2560bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (RD->isEmpty()) 2561bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << " (empty)"; 2562bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << '\n'; 2563bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 2564bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar IndentLevel++; 2565bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 25663069a0d28637ad0ad583d9fdd7bc6bc6aa677fb5Anders Carlsson const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 2567441c6239c6df8c759bacf6510efbfd434b647066John McCall bool HasVfptr = Layout.hasOwnVFPtr(); 25682fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman bool HasVbptr = Layout.getVBPtrOffset() != CharUnits::fromQuantity(-1); 2569bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 2570bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar // Vtable pointer. 2571227e483cb1f77ea6dcd38c2ca9fb490894a5f887Eli Friedman if (RD->isDynamicClass() && !PrimaryBase && 2572227e483cb1f77ea6dcd38c2ca9fb490894a5f887Eli Friedman C.getTargetInfo().getCXXABI() != CXXABI_Microsoft) { 2573bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar PrintOffset(OS, Offset, IndentLevel); 2574b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer OS << '(' << *RD << " vtable pointer)\n"; 2575bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar } 25762fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman 2577bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar // Dump (non-virtual) bases 2578bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 2579bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->bases_end(); I != E; ++I) { 2580bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar assert(!I->getType()->isDependentType() && 2581bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar "Cannot layout class with dependent bases."); 2582bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (I->isVirtual()) 2583bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar continue; 2584bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 2585bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar const CXXRecordDecl *Base = 2586bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 2587bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 25883069a0d28637ad0ad583d9fdd7bc6bc6aa677fb5Anders Carlsson CharUnits BaseOffset = Offset + Layout.getBaseClassOffset(Base); 2589bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 2590bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar DumpCXXRecordLayout(OS, Base, C, BaseOffset, IndentLevel, 2591bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar Base == PrimaryBase ? "(primary base)" : "(base)", 2592bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar /*IncludeVirtualBases=*/false); 2593bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar } 2594227e483cb1f77ea6dcd38c2ca9fb490894a5f887Eli Friedman 2595227e483cb1f77ea6dcd38c2ca9fb490894a5f887Eli Friedman // vfptr and vbptr (for Microsoft C++ ABI) 2596227e483cb1f77ea6dcd38c2ca9fb490894a5f887Eli Friedman if (HasVfptr) { 2597441c6239c6df8c759bacf6510efbfd434b647066John McCall PrintOffset(OS, Offset, IndentLevel); 2598227e483cb1f77ea6dcd38c2ca9fb490894a5f887Eli Friedman OS << '(' << *RD << " vftable pointer)\n"; 2599227e483cb1f77ea6dcd38c2ca9fb490894a5f887Eli Friedman } 26002fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman if (HasVbptr) { 26012fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman PrintOffset(OS, Offset + Layout.getVBPtrOffset(), IndentLevel); 2602b8989f27f116ff2400e92a52c067a69846119eb5Benjamin Kramer OS << '(' << *RD << " vbtable pointer)\n"; 26032fe363622c32c471e8a68c68ba5cc372644f24fbEli Friedman } 2604bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 2605bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar // Dump fields. 2606bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar uint64_t FieldNo = 0; 2607bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar for (CXXRecordDecl::field_iterator I = RD->field_begin(), 2608bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->field_end(); I != E; ++I, ++FieldNo) { 2609581deb3da481053c4993c7600f97acf7768caac5David Blaikie const FieldDecl &Field = **I; 26103069a0d28637ad0ad583d9fdd7bc6bc6aa677fb5Anders Carlsson CharUnits FieldOffset = Offset + 2611fb1e3bc29b667f4275e1d5a43d64ec173f4f9a7dKen Dyck C.toCharUnitsFromBits(Layout.getFieldOffset(FieldNo)); 2612bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 2613262bc18e32500558af7cb0afa205b34bd37bafedDavid Blaikie if (const RecordType *RT = Field.getType()->getAs<RecordType>()) { 2614bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (const CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(RT->getDecl())) { 2615bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar DumpCXXRecordLayout(OS, D, C, FieldOffset, IndentLevel, 2616262bc18e32500558af7cb0afa205b34bd37bafedDavid Blaikie Field.getName().data(), 2617bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar /*IncludeVirtualBases=*/true); 2618bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar continue; 2619bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar } 2620bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar } 2621bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 2622bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar PrintOffset(OS, FieldOffset, IndentLevel); 2623262bc18e32500558af7cb0afa205b34bd37bafedDavid Blaikie OS << Field.getType().getAsString() << ' ' << Field << '\n'; 2624bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar } 2625bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 2626bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar if (!IncludeVirtualBases) 2627bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar return; 2628bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 2629bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar // Dump virtual bases. 2630441c6239c6df8c759bacf6510efbfd434b647066John McCall const ASTRecordLayout::VBaseOffsetsMapTy &vtordisps = 2631441c6239c6df8c759bacf6510efbfd434b647066John McCall Layout.getVBaseOffsetsMap(); 2632bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(), 2633bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar E = RD->vbases_end(); I != E; ++I) { 2634bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar assert(I->isVirtual() && "Found non-virtual class!"); 2635bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar const CXXRecordDecl *VBase = 2636bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 2637bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 26383069a0d28637ad0ad583d9fdd7bc6bc6aa677fb5Anders Carlsson CharUnits VBaseOffset = Offset + Layout.getVBaseClassOffset(VBase); 2639441c6239c6df8c759bacf6510efbfd434b647066John McCall 2640441c6239c6df8c759bacf6510efbfd434b647066John McCall if (vtordisps.find(VBase)->second.hasVtorDisp()) { 2641441c6239c6df8c759bacf6510efbfd434b647066John McCall PrintOffset(OS, VBaseOffset - CharUnits::fromQuantity(4), IndentLevel); 2642441c6239c6df8c759bacf6510efbfd434b647066John McCall OS << "(vtordisp for vbase " << *VBase << ")\n"; 2643441c6239c6df8c759bacf6510efbfd434b647066John McCall } 2644441c6239c6df8c759bacf6510efbfd434b647066John McCall 2645bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar DumpCXXRecordLayout(OS, VBase, C, VBaseOffset, IndentLevel, 2646bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar VBase == PrimaryBase ? 2647bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar "(primary virtual base)" : "(virtual base)", 2648bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar /*IncludeVirtualBases=*/false); 2649bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar } 2650bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar 26515f022d82696c84e4d127c558871d68ac6273274eKen Dyck OS << " sizeof=" << Layout.getSize().getQuantity(); 2652ec2990351335f163601b98e39b52425e2e9f931eKen Dyck OS << ", dsize=" << Layout.getDataSize().getQuantity(); 2653dac54c124e302d6f028ea5723c425b7f66fc7c71Ken Dyck OS << ", align=" << Layout.getAlignment().getQuantity() << '\n'; 26545c3633fa57f27b0909ab5767715c4e66b8920165Ken Dyck OS << " nvsize=" << Layout.getNonVirtualSize().getQuantity(); 265568cf1a5a01ba43ed56a8624632fd65e0804430acKen Dyck OS << ", nvalign=" << Layout.getNonVirtualAlign().getQuantity() << '\n'; 2656bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar OS << '\n'; 2657bf9e48cbaaa23d990dbedf9489513500bd0b9751Daniel Dunbar} 26588d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar 26598d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbarvoid ASTContext::DumpRecordLayout(const RecordDecl *RD, 2660453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor raw_ostream &OS, 2661453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor bool Simple) const { 26628d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar const ASTRecordLayout &Info = getASTRecordLayout(RD); 26638d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar 26648d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) 2665453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor if (!Simple) 2666453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor return DumpCXXRecordLayout(OS, CXXRD, *this, CharUnits(), 0, 0, 2667453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor /*IncludeVirtualBases=*/true); 26688d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar 26698d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << "Type: " << getTypeDeclType(RD).getAsString() << "\n"; 2670453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor if (!Simple) { 2671453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor OS << "Record: "; 2672453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor RD->dump(); 2673453dbcbe30093fbf947a0bec2fbd46e9694eafe9Douglas Gregor } 26748d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << "\nLayout: "; 26758d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << "<ASTRecordLayout\n"; 2676dd76a9ab9ea675671200f94b18ce95766841952bKen Dyck OS << " Size:" << toBits(Info.getSize()) << "\n"; 2677ec2990351335f163601b98e39b52425e2e9f931eKen Dyck OS << " DataSize:" << toBits(Info.getDataSize()) << "\n"; 2678dac54c124e302d6f028ea5723c425b7f66fc7c71Ken Dyck OS << " Alignment:" << toBits(Info.getAlignment()) << "\n"; 26798d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << " FieldOffsets: ["; 26808d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar for (unsigned i = 0, e = Info.getFieldCount(); i != e; ++i) { 26818d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar if (i) OS << ", "; 26828d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << Info.getFieldOffset(i); 26838d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar } 26848d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar OS << "]>\n"; 26858d8ab749f6f8bb63ea2cd2b589c0f050b67fc5ccDaniel Dunbar} 2686