1206084Srdivacky//===--- CGRecordLayoutBuilder.cpp - CGRecordLayout builder ----*- C++ -*-===// 2198092Srdivacky// 3198092Srdivacky// The LLVM Compiler Infrastructure 4198092Srdivacky// 5198092Srdivacky// This file is distributed under the University of Illinois Open Source 6198092Srdivacky// License. See LICENSE.TXT for details. 7198092Srdivacky// 8198092Srdivacky//===----------------------------------------------------------------------===// 9198092Srdivacky// 10206084Srdivacky// Builder implementation for CGRecordLayout objects. 11198092Srdivacky// 12198092Srdivacky//===----------------------------------------------------------------------===// 13198092Srdivacky 14206084Srdivacky#include "CGRecordLayout.h" 15249423Sdim#include "CGCXXABI.h" 16249423Sdim#include "CodeGenTypes.h" 17198092Srdivacky#include "clang/AST/ASTContext.h" 18198092Srdivacky#include "clang/AST/Attr.h" 19218893Sdim#include "clang/AST/CXXInheritance.h" 20198092Srdivacky#include "clang/AST/DeclCXX.h" 21198092Srdivacky#include "clang/AST/Expr.h" 22198092Srdivacky#include "clang/AST/RecordLayout.h" 23224145Sdim#include "clang/Frontend/CodeGenOptions.h" 24249423Sdim#include "llvm/IR/DataLayout.h" 25249423Sdim#include "llvm/IR/DerivedTypes.h" 26249423Sdim#include "llvm/IR/Type.h" 27207619Srdivacky#include "llvm/Support/Debug.h" 28207619Srdivacky#include "llvm/Support/raw_ostream.h" 29198092Srdivackyusing namespace clang; 30198092Srdivackyusing namespace CodeGen; 31198092Srdivacky 32218893Sdimnamespace { 33206084Srdivacky 34206084Srdivackyclass CGRecordLayoutBuilder { 35206084Srdivackypublic: 36206084Srdivacky /// FieldTypes - Holds the LLVM types that the struct is created from. 37218893Sdim /// 38226633Sdim SmallVector<llvm::Type *, 16> FieldTypes; 39206084Srdivacky 40218893Sdim /// BaseSubobjectType - Holds the LLVM type for the non-virtual part 41218893Sdim /// of the struct. For example, consider: 42218893Sdim /// 43218893Sdim /// struct A { int i; }; 44218893Sdim /// struct B { void *v; }; 45218893Sdim /// struct C : virtual A, B { }; 46218893Sdim /// 47218893Sdim /// The LLVM type of C will be 48218893Sdim /// %struct.C = type { i32 (...)**, %struct.A, i32, %struct.B } 49218893Sdim /// 50218893Sdim /// And the LLVM type of the non-virtual base struct will be 51218893Sdim /// %struct.C.base = type { i32 (...)**, %struct.A, i32 } 52218893Sdim /// 53218893Sdim /// This only gets initialized if the base subobject type is 54218893Sdim /// different from the complete-object type. 55224145Sdim llvm::StructType *BaseSubobjectType; 56206084Srdivacky 57218893Sdim /// FieldInfo - Holds a field and its corresponding LLVM field number. 58218893Sdim llvm::DenseMap<const FieldDecl *, unsigned> Fields; 59206084Srdivacky 60218893Sdim /// BitFieldInfo - Holds location and size information about a bit field. 61218893Sdim llvm::DenseMap<const FieldDecl *, CGBitFieldInfo> BitFields; 62218893Sdim 63218893Sdim llvm::DenseMap<const CXXRecordDecl *, unsigned> NonVirtualBases; 64218893Sdim llvm::DenseMap<const CXXRecordDecl *, unsigned> VirtualBases; 65218893Sdim 66218893Sdim /// IndirectPrimaryBases - Virtual base classes, direct or indirect, that are 67218893Sdim /// primary base classes for some other direct or indirect base class. 68218893Sdim CXXIndirectPrimaryBaseSet IndirectPrimaryBases; 69218893Sdim 70218893Sdim /// LaidOutVirtualBases - A set of all laid out virtual bases, used to avoid 71218893Sdim /// avoid laying out virtual bases more than once. 72218893Sdim llvm::SmallPtrSet<const CXXRecordDecl *, 4> LaidOutVirtualBases; 73208600Srdivacky 74212904Sdim /// IsZeroInitializable - Whether this struct can be C++ 75212904Sdim /// zero-initialized with an LLVM zeroinitializer. 76212904Sdim bool IsZeroInitializable; 77218893Sdim bool IsZeroInitializableAsBase; 78206084Srdivacky 79206084Srdivacky /// Packed - Whether the resulting LLVM struct will be packed or not. 80206084Srdivacky bool Packed; 81221345Sdim 82221345Sdim /// IsMsStruct - Whether ms_struct is in effect or not 83221345Sdim bool IsMsStruct; 84206084Srdivacky 85206084Srdivackyprivate: 86206084Srdivacky CodeGenTypes &Types; 87206084Srdivacky 88221345Sdim /// LastLaidOutBaseInfo - Contains the offset and non-virtual size of the 89221345Sdim /// last base laid out. Used so that we can replace the last laid out base 90221345Sdim /// type with an i8 array if needed. 91221345Sdim struct LastLaidOutBaseInfo { 92221345Sdim CharUnits Offset; 93221345Sdim CharUnits NonVirtualSize; 94221345Sdim 95221345Sdim bool isValid() const { return !NonVirtualSize.isZero(); } 96221345Sdim void invalidate() { NonVirtualSize = CharUnits::Zero(); } 97221345Sdim 98221345Sdim } LastLaidOutBase; 99221345Sdim 100206084Srdivacky /// Alignment - Contains the alignment of the RecordDecl. 101218893Sdim CharUnits Alignment; 102206084Srdivacky 103218893Sdim /// NextFieldOffset - Holds the next field offset. 104218893Sdim CharUnits NextFieldOffset; 105206084Srdivacky 106207619Srdivacky /// LayoutUnionField - Will layout a field in an union and return the type 107207619Srdivacky /// that the field will have. 108224145Sdim llvm::Type *LayoutUnionField(const FieldDecl *Field, 109224145Sdim const ASTRecordLayout &Layout); 110207619Srdivacky 111206084Srdivacky /// LayoutUnion - Will layout a union RecordDecl. 112206084Srdivacky void LayoutUnion(const RecordDecl *D); 113206084Srdivacky 114249423Sdim /// Lay out a sequence of contiguous bitfields. 115249423Sdim bool LayoutBitfields(const ASTRecordLayout &Layout, 116249423Sdim unsigned &FirstFieldNo, 117249423Sdim RecordDecl::field_iterator &FI, 118249423Sdim RecordDecl::field_iterator FE); 119249423Sdim 120206084Srdivacky /// LayoutField - try to layout all fields in the record decl. 121206084Srdivacky /// Returns false if the operation failed because the struct is not packed. 122206084Srdivacky bool LayoutFields(const RecordDecl *D); 123206084Srdivacky 124218893Sdim /// Layout a single base, virtual or non-virtual 125234353Sdim bool LayoutBase(const CXXRecordDecl *base, 126218893Sdim const CGRecordLayout &baseLayout, 127218893Sdim CharUnits baseOffset); 128218893Sdim 129218893Sdim /// LayoutVirtualBase - layout a single virtual base. 130234353Sdim bool LayoutVirtualBase(const CXXRecordDecl *base, 131218893Sdim CharUnits baseOffset); 132218893Sdim 133218893Sdim /// LayoutVirtualBases - layout the virtual bases of a record decl. 134234353Sdim bool LayoutVirtualBases(const CXXRecordDecl *RD, 135218893Sdim const ASTRecordLayout &Layout); 136234353Sdim 137234353Sdim /// MSLayoutVirtualBases - layout the virtual bases of a record decl, 138234353Sdim /// like MSVC. 139234353Sdim bool MSLayoutVirtualBases(const CXXRecordDecl *RD, 140234353Sdim const ASTRecordLayout &Layout); 141218893Sdim 142208600Srdivacky /// LayoutNonVirtualBase - layout a single non-virtual base. 143234353Sdim bool LayoutNonVirtualBase(const CXXRecordDecl *base, 144218893Sdim CharUnits baseOffset); 145208600Srdivacky 146218893Sdim /// LayoutNonVirtualBases - layout the virtual bases of a record decl. 147234353Sdim bool LayoutNonVirtualBases(const CXXRecordDecl *RD, 148208600Srdivacky const ASTRecordLayout &Layout); 149206084Srdivacky 150218893Sdim /// ComputeNonVirtualBaseType - Compute the non-virtual base field types. 151218893Sdim bool ComputeNonVirtualBaseType(const CXXRecordDecl *RD); 152218893Sdim 153206084Srdivacky /// LayoutField - layout a single field. Returns false if the operation failed 154206084Srdivacky /// because the current struct is not packed. 155206084Srdivacky bool LayoutField(const FieldDecl *D, uint64_t FieldOffset); 156206084Srdivacky 157206084Srdivacky /// LayoutBitField - layout a single bit field. 158206084Srdivacky void LayoutBitField(const FieldDecl *D, uint64_t FieldOffset); 159206084Srdivacky 160206084Srdivacky /// AppendField - Appends a field with the given offset and type. 161224145Sdim void AppendField(CharUnits fieldOffset, llvm::Type *FieldTy); 162206084Srdivacky 163206084Srdivacky /// AppendPadding - Appends enough padding bytes so that the total 164206084Srdivacky /// struct size is a multiple of the field alignment. 165218893Sdim void AppendPadding(CharUnits fieldOffset, CharUnits fieldAlignment); 166206084Srdivacky 167221345Sdim /// ResizeLastBaseFieldIfNecessary - Fields and bases can be laid out in the 168221345Sdim /// tail padding of a previous base. If this happens, the type of the previous 169221345Sdim /// base needs to be changed to an array of i8. Returns true if the last 170221345Sdim /// laid out base was resized. 171221345Sdim bool ResizeLastBaseFieldIfNecessary(CharUnits offset); 172221345Sdim 173218893Sdim /// getByteArrayType - Returns a byte array type with the given number of 174218893Sdim /// elements. 175224145Sdim llvm::Type *getByteArrayType(CharUnits NumBytes); 176218893Sdim 177206084Srdivacky /// AppendBytes - Append a given number of bytes to the record. 178218893Sdim void AppendBytes(CharUnits numBytes); 179206084Srdivacky 180206084Srdivacky /// AppendTailPadding - Append enough tail padding so that the type will have 181206084Srdivacky /// the passed size. 182221345Sdim void AppendTailPadding(CharUnits RecordSize); 183206084Srdivacky 184226633Sdim CharUnits getTypeAlignment(llvm::Type *Ty) const; 185206084Srdivacky 186218893Sdim /// getAlignmentAsLLVMStruct - Returns the maximum alignment of all the 187218893Sdim /// LLVM element types. 188218893Sdim CharUnits getAlignmentAsLLVMStruct() const; 189218893Sdim 190212904Sdim /// CheckZeroInitializable - Check if the given type contains a pointer 191206084Srdivacky /// to data member. 192212904Sdim void CheckZeroInitializable(QualType T); 193206084Srdivacky 194206084Srdivackypublic: 195206084Srdivacky CGRecordLayoutBuilder(CodeGenTypes &Types) 196218893Sdim : BaseSubobjectType(0), 197218893Sdim IsZeroInitializable(true), IsZeroInitializableAsBase(true), 198221345Sdim Packed(false), IsMsStruct(false), 199249423Sdim Types(Types) { } 200206084Srdivacky 201206084Srdivacky /// Layout - Will layout a RecordDecl. 202206084Srdivacky void Layout(const RecordDecl *D); 203206084Srdivacky}; 204206084Srdivacky 205206084Srdivacky} 206206084Srdivacky 207198092Srdivackyvoid CGRecordLayoutBuilder::Layout(const RecordDecl *D) { 208218893Sdim Alignment = Types.getContext().getASTRecordLayout(D).getAlignment(); 209198092Srdivacky Packed = D->hasAttr<PackedAttr>(); 210221345Sdim 211243830Sdim IsMsStruct = D->isMsStruct(Types.getContext()); 212198092Srdivacky 213198092Srdivacky if (D->isUnion()) { 214198092Srdivacky LayoutUnion(D); 215198092Srdivacky return; 216198092Srdivacky } 217198092Srdivacky 218198092Srdivacky if (LayoutFields(D)) 219198092Srdivacky return; 220198092Srdivacky 221198092Srdivacky // We weren't able to layout the struct. Try again with a packed struct 222198092Srdivacky Packed = true; 223221345Sdim LastLaidOutBase.invalidate(); 224218893Sdim NextFieldOffset = CharUnits::Zero(); 225198092Srdivacky FieldTypes.clear(); 226218893Sdim Fields.clear(); 227218893Sdim BitFields.clear(); 228218893Sdim NonVirtualBases.clear(); 229218893Sdim VirtualBases.clear(); 230198092Srdivacky 231198092Srdivacky LayoutFields(D); 232198092Srdivacky} 233198092Srdivacky 234212904SdimCGBitFieldInfo CGBitFieldInfo::MakeInfo(CodeGenTypes &Types, 235249423Sdim const FieldDecl *FD, 236249423Sdim uint64_t Offset, uint64_t Size, 237249423Sdim uint64_t StorageSize, 238249423Sdim uint64_t StorageAlignment) { 239226633Sdim llvm::Type *Ty = Types.ConvertTypeForMem(FD->getType()); 240219077Sdim CharUnits TypeSizeInBytes = 241243830Sdim CharUnits::fromQuantity(Types.getDataLayout().getTypeAllocSize(Ty)); 242219077Sdim uint64_t TypeSizeInBits = Types.getContext().toBits(TypeSizeInBytes); 243207619Srdivacky 244223017Sdim bool IsSigned = FD->getType()->isSignedIntegerOrEnumerationType(); 245207619Srdivacky 246249423Sdim if (Size > TypeSizeInBits) { 247207619Srdivacky // We have a wide bit-field. The extra bits are only used for padding, so 248207619Srdivacky // if we have a bitfield of type T, with size N: 249207619Srdivacky // 250207619Srdivacky // T t : N; 251207619Srdivacky // 252207619Srdivacky // We can just assume that it's: 253207619Srdivacky // 254207619Srdivacky // T t : sizeof(T); 255207619Srdivacky // 256249423Sdim Size = TypeSizeInBits; 257207619Srdivacky } 258207619Srdivacky 259249423Sdim // Reverse the bit offsets for big endian machines. Because we represent 260249423Sdim // a bitfield as a single large integer load, we can imagine the bits 261249423Sdim // counting from the most-significant-bit instead of the 262249423Sdim // least-significant-bit. 263243830Sdim if (Types.getDataLayout().isBigEndian()) { 264249423Sdim Offset = StorageSize - (Offset + Size); 265218893Sdim } 266218893Sdim 267249423Sdim return CGBitFieldInfo(Offset, Size, IsSigned, StorageSize, StorageAlignment); 268249423Sdim} 269207619Srdivacky 270249423Sdim/// \brief Layout the range of bitfields from BFI to BFE as contiguous storage. 271249423Sdimbool CGRecordLayoutBuilder::LayoutBitfields(const ASTRecordLayout &Layout, 272249423Sdim unsigned &FirstFieldNo, 273249423Sdim RecordDecl::field_iterator &FI, 274249423Sdim RecordDecl::field_iterator FE) { 275249423Sdim assert(FI != FE); 276249423Sdim uint64_t FirstFieldOffset = Layout.getFieldOffset(FirstFieldNo); 277249423Sdim uint64_t NextFieldOffsetInBits = Types.getContext().toBits(NextFieldOffset); 278224145Sdim 279251662Sdim unsigned CharAlign = Types.getTarget().getCharAlign(); 280249423Sdim assert(FirstFieldOffset % CharAlign == 0 && 281249423Sdim "First field offset is misaligned"); 282249423Sdim CharUnits FirstFieldOffsetInBytes 283249423Sdim = Types.getContext().toCharUnitsFromBits(FirstFieldOffset); 284207619Srdivacky 285249423Sdim unsigned StorageAlignment 286249423Sdim = llvm::MinAlign(Alignment.getQuantity(), 287249423Sdim FirstFieldOffsetInBytes.getQuantity()); 288207619Srdivacky 289249423Sdim if (FirstFieldOffset < NextFieldOffsetInBits) { 290249423Sdim CharUnits FieldOffsetInCharUnits = 291249423Sdim Types.getContext().toCharUnitsFromBits(FirstFieldOffset); 292207619Srdivacky 293249423Sdim // Try to resize the last base field. 294249423Sdim if (!ResizeLastBaseFieldIfNecessary(FieldOffsetInCharUnits)) 295249423Sdim llvm_unreachable("We must be able to resize the last base if we need to " 296249423Sdim "pack bits into it."); 297207619Srdivacky 298249423Sdim NextFieldOffsetInBits = Types.getContext().toBits(NextFieldOffset); 299249423Sdim assert(FirstFieldOffset >= NextFieldOffsetInBits); 300249423Sdim } 301207619Srdivacky 302249423Sdim // Append padding if necessary. 303249423Sdim AppendPadding(Types.getContext().toCharUnitsFromBits(FirstFieldOffset), 304249423Sdim CharUnits::One()); 305218893Sdim 306249423Sdim // Find the last bitfield in a contiguous run of bitfields. 307249423Sdim RecordDecl::field_iterator BFI = FI; 308249423Sdim unsigned LastFieldNo = FirstFieldNo; 309249423Sdim uint64_t NextContiguousFieldOffset = FirstFieldOffset; 310249423Sdim for (RecordDecl::field_iterator FJ = FI; 311249423Sdim (FJ != FE && (*FJ)->isBitField() && 312249423Sdim NextContiguousFieldOffset == Layout.getFieldOffset(LastFieldNo) && 313249423Sdim (*FJ)->getBitWidthValue(Types.getContext()) != 0); FI = FJ++) { 314249423Sdim NextContiguousFieldOffset += (*FJ)->getBitWidthValue(Types.getContext()); 315249423Sdim ++LastFieldNo; 316207619Srdivacky 317249423Sdim // We must use packed structs for packed fields, and also unnamed bit 318249423Sdim // fields since they don't affect the struct alignment. 319249423Sdim if (!Packed && ((*FJ)->hasAttr<PackedAttr>() || !(*FJ)->getDeclName())) 320249423Sdim return false; 321207619Srdivacky } 322249423Sdim RecordDecl::field_iterator BFE = llvm::next(FI); 323249423Sdim --LastFieldNo; 324249423Sdim assert(LastFieldNo >= FirstFieldNo && "Empty run of contiguous bitfields"); 325249423Sdim FieldDecl *LastFD = *FI; 326207619Srdivacky 327249423Sdim // Find the last bitfield's offset, add its size, and round it up to the 328249423Sdim // character alignment to compute the storage required. 329249423Sdim uint64_t LastFieldOffset = Layout.getFieldOffset(LastFieldNo); 330249423Sdim uint64_t LastFieldSize = LastFD->getBitWidthValue(Types.getContext()); 331249423Sdim uint64_t TotalBits = (LastFieldOffset + LastFieldSize) - FirstFieldOffset; 332249423Sdim CharUnits StorageBytes = Types.getContext().toCharUnitsFromBits( 333249423Sdim llvm::RoundUpToAlignment(TotalBits, CharAlign)); 334249423Sdim uint64_t StorageBits = Types.getContext().toBits(StorageBytes); 335207619Srdivacky 336249423Sdim // Grow the storage to encompass any known padding in the layout when doing 337249423Sdim // so will make the storage a power-of-two. There are two cases when we can 338249423Sdim // do this. The first is when we have a subsequent field and can widen up to 339249423Sdim // its offset. The second is when the data size of the AST record layout is 340249423Sdim // past the end of the current storage. The latter is true when there is tail 341249423Sdim // padding on a struct and no members of a super class can be packed into it. 342249423Sdim // 343249423Sdim // Note that we widen the storage as much as possible here to express the 344249423Sdim // maximum latitude the language provides, and rely on the backend to lower 345249423Sdim // these in conjunction with shifts and masks to narrower operations where 346249423Sdim // beneficial. 347249423Sdim uint64_t EndOffset = Types.getContext().toBits(Layout.getDataSize()); 348249423Sdim if (BFE != FE) 349249423Sdim // If there are more fields to be laid out, the offset at the end of the 350249423Sdim // bitfield is the offset of the next field in the record. 351249423Sdim EndOffset = Layout.getFieldOffset(LastFieldNo + 1); 352249423Sdim assert(EndOffset >= (FirstFieldOffset + TotalBits) && 353249423Sdim "End offset is not past the end of the known storage bits."); 354249423Sdim uint64_t SpaceBits = EndOffset - FirstFieldOffset; 355251662Sdim uint64_t LongBits = Types.getTarget().getLongWidth(); 356249423Sdim uint64_t WidenedBits = (StorageBits / LongBits) * LongBits + 357249423Sdim llvm::NextPowerOf2(StorageBits % LongBits - 1); 358249423Sdim assert(WidenedBits >= StorageBits && "Widening shrunk the bits!"); 359249423Sdim if (WidenedBits <= SpaceBits) { 360249423Sdim StorageBits = WidenedBits; 361249423Sdim StorageBytes = Types.getContext().toCharUnitsFromBits(StorageBits); 362249423Sdim assert(StorageBits == (uint64_t)Types.getContext().toBits(StorageBytes)); 363221345Sdim } 364221345Sdim 365249423Sdim unsigned FieldIndex = FieldTypes.size(); 366249423Sdim AppendBytes(StorageBytes); 367198092Srdivacky 368249423Sdim // Now walk the bitfields associating them with this field of storage and 369249423Sdim // building up the bitfield specific info. 370249423Sdim unsigned FieldNo = FirstFieldNo; 371249423Sdim for (; BFI != BFE; ++BFI, ++FieldNo) { 372249423Sdim FieldDecl *FD = *BFI; 373249423Sdim uint64_t FieldOffset = Layout.getFieldOffset(FieldNo) - FirstFieldOffset; 374249423Sdim uint64_t FieldSize = FD->getBitWidthValue(Types.getContext()); 375249423Sdim Fields[FD] = FieldIndex; 376249423Sdim BitFields[FD] = CGBitFieldInfo::MakeInfo(Types, FD, FieldOffset, FieldSize, 377249423Sdim StorageBits, StorageAlignment); 378198092Srdivacky } 379249423Sdim FirstFieldNo = LastFieldNo; 380249423Sdim return true; 381198092Srdivacky} 382198092Srdivacky 383198092Srdivackybool CGRecordLayoutBuilder::LayoutField(const FieldDecl *D, 384218893Sdim uint64_t fieldOffset) { 385198092Srdivacky // If the field is packed, then we need a packed struct. 386198092Srdivacky if (!Packed && D->hasAttr<PackedAttr>()) 387198092Srdivacky return false; 388198092Srdivacky 389249423Sdim assert(!D->isBitField() && "Bitfields should be laid out seperately."); 390198092Srdivacky 391212904Sdim CheckZeroInitializable(D->getType()); 392206084Srdivacky 393219077Sdim assert(fieldOffset % Types.getTarget().getCharWidth() == 0 394219077Sdim && "field offset is not on a byte boundary!"); 395219077Sdim CharUnits fieldOffsetInBytes 396219077Sdim = Types.getContext().toCharUnitsFromBits(fieldOffset); 397198092Srdivacky 398224145Sdim llvm::Type *Ty = Types.ConvertTypeForMem(D->getType()); 399218893Sdim CharUnits typeAlignment = getTypeAlignment(Ty); 400198092Srdivacky 401198092Srdivacky // If the type alignment is larger then the struct alignment, we must use 402198092Srdivacky // a packed struct. 403218893Sdim if (typeAlignment > Alignment) { 404198092Srdivacky assert(!Packed && "Alignment is wrong even with packed struct!"); 405198092Srdivacky return false; 406198092Srdivacky } 407198092Srdivacky 408218893Sdim if (!Packed) { 409218893Sdim if (const RecordType *RT = D->getType()->getAs<RecordType>()) { 410218893Sdim const RecordDecl *RD = cast<RecordDecl>(RT->getDecl()); 411218893Sdim if (const MaxFieldAlignmentAttr *MFAA = 412218893Sdim RD->getAttr<MaxFieldAlignmentAttr>()) { 413219077Sdim if (MFAA->getAlignment() != Types.getContext().toBits(typeAlignment)) 414218893Sdim return false; 415218893Sdim } 416198092Srdivacky } 417198092Srdivacky } 418198092Srdivacky 419198092Srdivacky // Round up the field offset to the alignment of the field type. 420218893Sdim CharUnits alignedNextFieldOffsetInBytes = 421218893Sdim NextFieldOffset.RoundUpToAlignment(typeAlignment); 422198092Srdivacky 423218893Sdim if (fieldOffsetInBytes < alignedNextFieldOffsetInBytes) { 424221345Sdim // Try to resize the last base field. 425221345Sdim if (ResizeLastBaseFieldIfNecessary(fieldOffsetInBytes)) { 426221345Sdim alignedNextFieldOffsetInBytes = 427221345Sdim NextFieldOffset.RoundUpToAlignment(typeAlignment); 428221345Sdim } 429221345Sdim } 430221345Sdim 431221345Sdim if (fieldOffsetInBytes < alignedNextFieldOffsetInBytes) { 432198092Srdivacky assert(!Packed && "Could not place field even with packed struct!"); 433198092Srdivacky return false; 434198092Srdivacky } 435198092Srdivacky 436218893Sdim AppendPadding(fieldOffsetInBytes, typeAlignment); 437198092Srdivacky 438198092Srdivacky // Now append the field. 439218893Sdim Fields[D] = FieldTypes.size(); 440218893Sdim AppendField(fieldOffsetInBytes, Ty); 441198092Srdivacky 442221345Sdim LastLaidOutBase.invalidate(); 443198092Srdivacky return true; 444198092Srdivacky} 445198092Srdivacky 446224145Sdimllvm::Type * 447207619SrdivackyCGRecordLayoutBuilder::LayoutUnionField(const FieldDecl *Field, 448207619Srdivacky const ASTRecordLayout &Layout) { 449249423Sdim Fields[Field] = 0; 450207619Srdivacky if (Field->isBitField()) { 451226633Sdim uint64_t FieldSize = Field->getBitWidthValue(Types.getContext()); 452207619Srdivacky 453207619Srdivacky // Ignore zero sized bit fields. 454207619Srdivacky if (FieldSize == 0) 455207619Srdivacky return 0; 456207619Srdivacky 457249423Sdim unsigned StorageBits = llvm::RoundUpToAlignment( 458251662Sdim FieldSize, Types.getTarget().getCharAlign()); 459249423Sdim CharUnits NumBytesToAppend 460249423Sdim = Types.getContext().toCharUnitsFromBits(StorageBits); 461249423Sdim 462224145Sdim llvm::Type *FieldTy = llvm::Type::getInt8Ty(Types.getLLVMContext()); 463221345Sdim if (NumBytesToAppend > CharUnits::One()) 464221345Sdim FieldTy = llvm::ArrayType::get(FieldTy, NumBytesToAppend.getQuantity()); 465207619Srdivacky 466207619Srdivacky // Add the bit field info. 467249423Sdim BitFields[Field] = CGBitFieldInfo::MakeInfo(Types, Field, 0, FieldSize, 468249423Sdim StorageBits, 469249423Sdim Alignment.getQuantity()); 470207619Srdivacky return FieldTy; 471207619Srdivacky } 472207619Srdivacky 473207619Srdivacky // This is a regular union field. 474224145Sdim return Types.ConvertTypeForMem(Field->getType()); 475207619Srdivacky} 476207619Srdivacky 477198092Srdivackyvoid CGRecordLayoutBuilder::LayoutUnion(const RecordDecl *D) { 478198092Srdivacky assert(D->isUnion() && "Can't call LayoutUnion on a non-union record!"); 479198092Srdivacky 480218893Sdim const ASTRecordLayout &layout = Types.getContext().getASTRecordLayout(D); 481198092Srdivacky 482224145Sdim llvm::Type *unionType = 0; 483218893Sdim CharUnits unionSize = CharUnits::Zero(); 484218893Sdim CharUnits unionAlign = CharUnits::Zero(); 485198092Srdivacky 486218893Sdim bool hasOnlyZeroSizedBitFields = true; 487234353Sdim bool checkedFirstFieldZeroInit = false; 488206084Srdivacky 489218893Sdim unsigned fieldNo = 0; 490218893Sdim for (RecordDecl::field_iterator field = D->field_begin(), 491218893Sdim fieldEnd = D->field_end(); field != fieldEnd; ++field, ++fieldNo) { 492218893Sdim assert(layout.getFieldOffset(fieldNo) == 0 && 493198092Srdivacky "Union field offset did not start at the beginning of record!"); 494224145Sdim llvm::Type *fieldType = LayoutUnionField(*field, layout); 495198092Srdivacky 496218893Sdim if (!fieldType) 497207619Srdivacky continue; 498198092Srdivacky 499234353Sdim if (field->getDeclName() && !checkedFirstFieldZeroInit) { 500234353Sdim CheckZeroInitializable(field->getType()); 501234353Sdim checkedFirstFieldZeroInit = true; 502234353Sdim } 503234353Sdim 504218893Sdim hasOnlyZeroSizedBitFields = false; 505206084Srdivacky 506218893Sdim CharUnits fieldAlign = CharUnits::fromQuantity( 507243830Sdim Types.getDataLayout().getABITypeAlignment(fieldType)); 508218893Sdim CharUnits fieldSize = CharUnits::fromQuantity( 509243830Sdim Types.getDataLayout().getTypeAllocSize(fieldType)); 510198092Srdivacky 511218893Sdim if (fieldAlign < unionAlign) 512198092Srdivacky continue; 513198092Srdivacky 514218893Sdim if (fieldAlign > unionAlign || fieldSize > unionSize) { 515218893Sdim unionType = fieldType; 516218893Sdim unionAlign = fieldAlign; 517218893Sdim unionSize = fieldSize; 518198092Srdivacky } 519198092Srdivacky } 520198092Srdivacky 521198092Srdivacky // Now add our field. 522218893Sdim if (unionType) { 523218893Sdim AppendField(CharUnits::Zero(), unionType); 524198092Srdivacky 525218893Sdim if (getTypeAlignment(unionType) > layout.getAlignment()) { 526198092Srdivacky // We need a packed struct. 527198092Srdivacky Packed = true; 528218893Sdim unionAlign = CharUnits::One(); 529198092Srdivacky } 530198092Srdivacky } 531218893Sdim if (unionAlign.isZero()) { 532234353Sdim (void)hasOnlyZeroSizedBitFields; 533218893Sdim assert(hasOnlyZeroSizedBitFields && 534203955Srdivacky "0-align record did not have all zero-sized bit-fields!"); 535218893Sdim unionAlign = CharUnits::One(); 536199482Srdivacky } 537206084Srdivacky 538198092Srdivacky // Append tail padding. 539218893Sdim CharUnits recordSize = layout.getSize(); 540218893Sdim if (recordSize > unionSize) 541218893Sdim AppendPadding(recordSize, unionAlign); 542198092Srdivacky} 543198092Srdivacky 544234353Sdimbool CGRecordLayoutBuilder::LayoutBase(const CXXRecordDecl *base, 545218893Sdim const CGRecordLayout &baseLayout, 546218893Sdim CharUnits baseOffset) { 547221345Sdim ResizeLastBaseFieldIfNecessary(baseOffset); 548221345Sdim 549218893Sdim AppendPadding(baseOffset, CharUnits::One()); 550208600Srdivacky 551218893Sdim const ASTRecordLayout &baseASTLayout 552218893Sdim = Types.getContext().getASTRecordLayout(base); 553208600Srdivacky 554221345Sdim LastLaidOutBase.Offset = NextFieldOffset; 555221345Sdim LastLaidOutBase.NonVirtualSize = baseASTLayout.getNonVirtualSize(); 556221345Sdim 557234353Sdim llvm::StructType *subobjectType = baseLayout.getBaseSubobjectLLVMType(); 558234353Sdim if (getTypeAlignment(subobjectType) > Alignment) 559234353Sdim return false; 560218893Sdim 561221345Sdim AppendField(baseOffset, subobjectType); 562234353Sdim return true; 563218893Sdim} 564218893Sdim 565234353Sdimbool CGRecordLayoutBuilder::LayoutNonVirtualBase(const CXXRecordDecl *base, 566218893Sdim CharUnits baseOffset) { 567218893Sdim // Ignore empty bases. 568234353Sdim if (base->isEmpty()) return true; 569218893Sdim 570218893Sdim const CGRecordLayout &baseLayout = Types.getCGRecordLayout(base); 571218893Sdim if (IsZeroInitializableAsBase) { 572218893Sdim assert(IsZeroInitializable && 573218893Sdim "class zero-initializable as base but not as complete object"); 574218893Sdim 575218893Sdim IsZeroInitializable = IsZeroInitializableAsBase = 576218893Sdim baseLayout.isZeroInitializableAsBase(); 577208600Srdivacky } 578208600Srdivacky 579234353Sdim if (!LayoutBase(base, baseLayout, baseOffset)) 580234353Sdim return false; 581218893Sdim NonVirtualBases[base] = (FieldTypes.size() - 1); 582234353Sdim return true; 583218893Sdim} 584208600Srdivacky 585234353Sdimbool 586218893SdimCGRecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *base, 587218893Sdim CharUnits baseOffset) { 588218893Sdim // Ignore empty bases. 589234353Sdim if (base->isEmpty()) return true; 590208600Srdivacky 591218893Sdim const CGRecordLayout &baseLayout = Types.getCGRecordLayout(base); 592218893Sdim if (IsZeroInitializable) 593218893Sdim IsZeroInitializable = baseLayout.isZeroInitializableAsBase(); 594218893Sdim 595234353Sdim if (!LayoutBase(base, baseLayout, baseOffset)) 596234353Sdim return false; 597218893Sdim VirtualBases[base] = (FieldTypes.size() - 1); 598234353Sdim return true; 599208600Srdivacky} 600208600Srdivacky 601234353Sdimbool 602234353SdimCGRecordLayoutBuilder::MSLayoutVirtualBases(const CXXRecordDecl *RD, 603234353Sdim const ASTRecordLayout &Layout) { 604234353Sdim if (!RD->getNumVBases()) 605234353Sdim return true; 606234353Sdim 607234353Sdim // The vbases list is uniqued and ordered by a depth-first 608234353Sdim // traversal, which is what we need here. 609234353Sdim for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(), 610234353Sdim E = RD->vbases_end(); I != E; ++I) { 611234353Sdim 612234353Sdim const CXXRecordDecl *BaseDecl = 613234353Sdim cast<CXXRecordDecl>(I->getType()->castAs<RecordType>()->getDecl()); 614234353Sdim 615234353Sdim CharUnits vbaseOffset = Layout.getVBaseClassOffset(BaseDecl); 616234353Sdim if (!LayoutVirtualBase(BaseDecl, vbaseOffset)) 617234353Sdim return false; 618234353Sdim } 619234353Sdim return true; 620234353Sdim} 621234353Sdim 622218893Sdim/// LayoutVirtualBases - layout the non-virtual bases of a record decl. 623234353Sdimbool 624218893SdimCGRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD, 625218893Sdim const ASTRecordLayout &Layout) { 626218893Sdim for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 627218893Sdim E = RD->bases_end(); I != E; ++I) { 628218893Sdim const CXXRecordDecl *BaseDecl = 629218893Sdim cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 630218893Sdim 631218893Sdim // We only want to lay out virtual bases that aren't indirect primary bases 632218893Sdim // of some other base. 633218893Sdim if (I->isVirtual() && !IndirectPrimaryBases.count(BaseDecl)) { 634218893Sdim // Only lay out the base once. 635218893Sdim if (!LaidOutVirtualBases.insert(BaseDecl)) 636218893Sdim continue; 637218893Sdim 638218893Sdim CharUnits vbaseOffset = Layout.getVBaseClassOffset(BaseDecl); 639234353Sdim if (!LayoutVirtualBase(BaseDecl, vbaseOffset)) 640234353Sdim return false; 641218893Sdim } 642218893Sdim 643218893Sdim if (!BaseDecl->getNumVBases()) { 644218893Sdim // This base isn't interesting since it doesn't have any virtual bases. 645218893Sdim continue; 646218893Sdim } 647218893Sdim 648234353Sdim if (!LayoutVirtualBases(BaseDecl, Layout)) 649234353Sdim return false; 650218893Sdim } 651234353Sdim return true; 652218893Sdim} 653218893Sdim 654234353Sdimbool 655208600SrdivackyCGRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD, 656208600Srdivacky const ASTRecordLayout &Layout) { 657208600Srdivacky const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 658208600Srdivacky 659234353Sdim // If we have a primary base, lay it out first. 660234353Sdim if (PrimaryBase) { 661234353Sdim if (!Layout.isPrimaryBaseVirtual()) { 662234353Sdim if (!LayoutNonVirtualBase(PrimaryBase, CharUnits::Zero())) 663234353Sdim return false; 664208600Srdivacky } else { 665234353Sdim if (!LayoutVirtualBase(PrimaryBase, CharUnits::Zero())) 666234353Sdim return false; 667208600Srdivacky } 668234353Sdim 669234353Sdim // Otherwise, add a vtable / vf-table if the layout says to do so. 670239462Sdim } else if (Layout.hasOwnVFPtr()) { 671234353Sdim llvm::Type *FunctionType = 672234353Sdim llvm::FunctionType::get(llvm::Type::getInt32Ty(Types.getLLVMContext()), 673234353Sdim /*isVarArg=*/true); 674234353Sdim llvm::Type *VTableTy = FunctionType->getPointerTo(); 675239462Sdim 676239462Sdim if (getTypeAlignment(VTableTy) > Alignment) { 677239462Sdim // FIXME: Should we allow this to happen in Sema? 678239462Sdim assert(!Packed && "Alignment is wrong even with packed struct!"); 679239462Sdim return false; 680239462Sdim } 681239462Sdim 682234353Sdim assert(NextFieldOffset.isZero() && 683234353Sdim "VTable pointer must come first!"); 684234353Sdim AppendField(CharUnits::Zero(), VTableTy->getPointerTo()); 685201361Srdivacky } 686208600Srdivacky 687208600Srdivacky // Layout the non-virtual bases. 688208600Srdivacky for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 689208600Srdivacky E = RD->bases_end(); I != E; ++I) { 690208600Srdivacky if (I->isVirtual()) 691208600Srdivacky continue; 692208600Srdivacky 693208600Srdivacky const CXXRecordDecl *BaseDecl = 694208600Srdivacky cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 695208600Srdivacky 696208600Srdivacky // We've already laid out the primary base. 697218893Sdim if (BaseDecl == PrimaryBase && !Layout.isPrimaryBaseVirtual()) 698208600Srdivacky continue; 699208600Srdivacky 700234353Sdim if (!LayoutNonVirtualBase(BaseDecl, Layout.getBaseClassOffset(BaseDecl))) 701234353Sdim return false; 702208600Srdivacky } 703234353Sdim 704234353Sdim // Add a vb-table pointer if the layout insists. 705234353Sdim if (Layout.getVBPtrOffset() != CharUnits::fromQuantity(-1)) { 706234353Sdim CharUnits VBPtrOffset = Layout.getVBPtrOffset(); 707234353Sdim llvm::Type *Vbptr = llvm::Type::getInt32PtrTy(Types.getLLVMContext()); 708234353Sdim AppendPadding(VBPtrOffset, getTypeAlignment(Vbptr)); 709234353Sdim AppendField(VBPtrOffset, Vbptr); 710234353Sdim } 711234353Sdim 712234353Sdim return true; 713201361Srdivacky} 714201361Srdivacky 715218893Sdimbool 716218893SdimCGRecordLayoutBuilder::ComputeNonVirtualBaseType(const CXXRecordDecl *RD) { 717218893Sdim const ASTRecordLayout &Layout = Types.getContext().getASTRecordLayout(RD); 718218893Sdim 719218893Sdim CharUnits NonVirtualSize = Layout.getNonVirtualSize(); 720218893Sdim CharUnits NonVirtualAlign = Layout.getNonVirtualAlign(); 721218893Sdim CharUnits AlignedNonVirtualTypeSize = 722218893Sdim NonVirtualSize.RoundUpToAlignment(NonVirtualAlign); 723218893Sdim 724218893Sdim // First check if we can use the same fields as for the complete class. 725218893Sdim CharUnits RecordSize = Layout.getSize(); 726218893Sdim if (AlignedNonVirtualTypeSize == RecordSize) 727218893Sdim return true; 728218893Sdim 729218893Sdim // Check if we need padding. 730218893Sdim CharUnits AlignedNextFieldOffset = 731218893Sdim NextFieldOffset.RoundUpToAlignment(getAlignmentAsLLVMStruct()); 732218893Sdim 733218893Sdim if (AlignedNextFieldOffset > AlignedNonVirtualTypeSize) { 734218893Sdim assert(!Packed && "cannot layout even as packed struct"); 735218893Sdim return false; // Needs packing. 736218893Sdim } 737218893Sdim 738218893Sdim bool needsPadding = (AlignedNonVirtualTypeSize != AlignedNextFieldOffset); 739218893Sdim if (needsPadding) { 740218893Sdim CharUnits NumBytes = AlignedNonVirtualTypeSize - AlignedNextFieldOffset; 741218893Sdim FieldTypes.push_back(getByteArrayType(NumBytes)); 742218893Sdim } 743224145Sdim 744226633Sdim BaseSubobjectType = llvm::StructType::create(Types.getLLVMContext(), 745226633Sdim FieldTypes, "", Packed); 746224145Sdim Types.addRecordTypeName(RD, BaseSubobjectType, ".base"); 747218893Sdim 748224145Sdim // Pull the padding back off. 749224145Sdim if (needsPadding) 750218893Sdim FieldTypes.pop_back(); 751218893Sdim 752218893Sdim return true; 753218893Sdim} 754218893Sdim 755198092Srdivackybool CGRecordLayoutBuilder::LayoutFields(const RecordDecl *D) { 756198092Srdivacky assert(!D->isUnion() && "Can't call LayoutFields on a union!"); 757218893Sdim assert(!Alignment.isZero() && "Did not set alignment!"); 758198092Srdivacky 759198092Srdivacky const ASTRecordLayout &Layout = Types.getContext().getASTRecordLayout(D); 760198092Srdivacky 761218893Sdim const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D); 762218893Sdim if (RD) 763234353Sdim if (!LayoutNonVirtualBases(RD, Layout)) 764234353Sdim return false; 765206084Srdivacky 766198092Srdivacky unsigned FieldNo = 0; 767221345Sdim const FieldDecl *LastFD = 0; 768221345Sdim 769249423Sdim for (RecordDecl::field_iterator FI = D->field_begin(), FE = D->field_end(); 770249423Sdim FI != FE; ++FI, ++FieldNo) { 771249423Sdim FieldDecl *FD = *FI; 772221345Sdim if (IsMsStruct) { 773221345Sdim // Zero-length bitfields following non-bitfield members are 774221345Sdim // ignored: 775223017Sdim if (Types.getContext().ZeroBitfieldFollowsNonBitfield(FD, LastFD)) { 776221345Sdim --FieldNo; 777221345Sdim continue; 778221345Sdim } 779221345Sdim LastFD = FD; 780221345Sdim } 781249423Sdim 782249423Sdim // If this field is a bitfield, layout all of the consecutive 783249423Sdim // non-zero-length bitfields and the last zero-length bitfield; these will 784249423Sdim // all share storage. 785249423Sdim if (FD->isBitField()) { 786249423Sdim // If all we have is a zero-width bitfield, skip it. 787249423Sdim if (FD->getBitWidthValue(Types.getContext()) == 0) 788249423Sdim continue; 789249423Sdim 790249423Sdim // Layout this range of bitfields. 791249423Sdim if (!LayoutBitfields(Layout, FieldNo, FI, FE)) { 792249423Sdim assert(!Packed && 793249423Sdim "Could not layout bitfields even with a packed LLVM struct!"); 794249423Sdim return false; 795249423Sdim } 796249423Sdim assert(FI != FE && "Advanced past the last bitfield"); 797249423Sdim continue; 798249423Sdim } 799249423Sdim 800249423Sdim if (!LayoutField(FD, Layout.getFieldOffset(FieldNo))) { 801198092Srdivacky assert(!Packed && 802198092Srdivacky "Could not layout fields even with a packed LLVM struct!"); 803198092Srdivacky return false; 804198092Srdivacky } 805198092Srdivacky } 806198092Srdivacky 807218893Sdim if (RD) { 808218893Sdim // We've laid out the non-virtual bases and the fields, now compute the 809218893Sdim // non-virtual base field types. 810218893Sdim if (!ComputeNonVirtualBaseType(RD)) { 811218893Sdim assert(!Packed && "Could not layout even with a packed LLVM struct!"); 812218893Sdim return false; 813218893Sdim } 814218893Sdim 815234353Sdim // Lay out the virtual bases. The MS ABI uses a different 816234353Sdim // algorithm here due to the lack of primary virtual bases. 817251662Sdim if (Types.getTarget().getCXXABI().hasPrimaryVBases()) { 818234353Sdim RD->getIndirectPrimaryBases(IndirectPrimaryBases); 819234353Sdim if (Layout.isPrimaryBaseVirtual()) 820234353Sdim IndirectPrimaryBases.insert(Layout.getPrimaryBase()); 821234353Sdim 822234353Sdim if (!LayoutVirtualBases(RD, Layout)) 823234353Sdim return false; 824234353Sdim } else { 825234353Sdim if (!MSLayoutVirtualBases(RD, Layout)) 826234353Sdim return false; 827234353Sdim } 828218893Sdim } 829218893Sdim 830198092Srdivacky // Append tail padding if necessary. 831221345Sdim AppendTailPadding(Layout.getSize()); 832198092Srdivacky 833198092Srdivacky return true; 834198092Srdivacky} 835198092Srdivacky 836221345Sdimvoid CGRecordLayoutBuilder::AppendTailPadding(CharUnits RecordSize) { 837221345Sdim ResizeLastBaseFieldIfNecessary(RecordSize); 838198092Srdivacky 839221345Sdim assert(NextFieldOffset <= RecordSize && "Size mismatch!"); 840198092Srdivacky 841218893Sdim CharUnits AlignedNextFieldOffset = 842218893Sdim NextFieldOffset.RoundUpToAlignment(getAlignmentAsLLVMStruct()); 843200583Srdivacky 844221345Sdim if (AlignedNextFieldOffset == RecordSize) { 845200583Srdivacky // We don't need any padding. 846200583Srdivacky return; 847200583Srdivacky } 848206084Srdivacky 849221345Sdim CharUnits NumPadBytes = RecordSize - NextFieldOffset; 850198092Srdivacky AppendBytes(NumPadBytes); 851198092Srdivacky} 852198092Srdivacky 853218893Sdimvoid CGRecordLayoutBuilder::AppendField(CharUnits fieldOffset, 854224145Sdim llvm::Type *fieldType) { 855218893Sdim CharUnits fieldSize = 856243830Sdim CharUnits::fromQuantity(Types.getDataLayout().getTypeAllocSize(fieldType)); 857198092Srdivacky 858218893Sdim FieldTypes.push_back(fieldType); 859198092Srdivacky 860218893Sdim NextFieldOffset = fieldOffset + fieldSize; 861198092Srdivacky} 862198092Srdivacky 863218893Sdimvoid CGRecordLayoutBuilder::AppendPadding(CharUnits fieldOffset, 864218893Sdim CharUnits fieldAlignment) { 865218893Sdim assert(NextFieldOffset <= fieldOffset && 866198092Srdivacky "Incorrect field layout!"); 867198092Srdivacky 868234353Sdim // Do nothing if we're already at the right offset. 869234353Sdim if (fieldOffset == NextFieldOffset) return; 870198092Srdivacky 871234353Sdim // If we're not emitting a packed LLVM type, try to avoid adding 872234353Sdim // unnecessary padding fields. 873234353Sdim if (!Packed) { 874234353Sdim // Round up the field offset to the alignment of the field type. 875234353Sdim CharUnits alignedNextFieldOffset = 876234353Sdim NextFieldOffset.RoundUpToAlignment(fieldAlignment); 877234353Sdim assert(alignedNextFieldOffset <= fieldOffset); 878198092Srdivacky 879234353Sdim // If that's the right offset, we're done. 880234353Sdim if (alignedNextFieldOffset == fieldOffset) return; 881198092Srdivacky } 882234353Sdim 883234353Sdim // Otherwise we need explicit padding. 884234353Sdim CharUnits padding = fieldOffset - NextFieldOffset; 885234353Sdim AppendBytes(padding); 886198092Srdivacky} 887198092Srdivacky 888221345Sdimbool CGRecordLayoutBuilder::ResizeLastBaseFieldIfNecessary(CharUnits offset) { 889221345Sdim // Check if we have a base to resize. 890221345Sdim if (!LastLaidOutBase.isValid()) 891221345Sdim return false; 892221345Sdim 893221345Sdim // This offset does not overlap with the tail padding. 894221345Sdim if (offset >= NextFieldOffset) 895221345Sdim return false; 896221345Sdim 897221345Sdim // Restore the field offset and append an i8 array instead. 898221345Sdim FieldTypes.pop_back(); 899221345Sdim NextFieldOffset = LastLaidOutBase.Offset; 900221345Sdim AppendBytes(LastLaidOutBase.NonVirtualSize); 901221345Sdim LastLaidOutBase.invalidate(); 902221345Sdim 903221345Sdim return true; 904221345Sdim} 905221345Sdim 906224145Sdimllvm::Type *CGRecordLayoutBuilder::getByteArrayType(CharUnits numBytes) { 907218893Sdim assert(!numBytes.isZero() && "Empty byte arrays aren't allowed."); 908198092Srdivacky 909224145Sdim llvm::Type *Ty = llvm::Type::getInt8Ty(Types.getLLVMContext()); 910218893Sdim if (numBytes > CharUnits::One()) 911218893Sdim Ty = llvm::ArrayType::get(Ty, numBytes.getQuantity()); 912198092Srdivacky 913218893Sdim return Ty; 914218893Sdim} 915218893Sdim 916218893Sdimvoid CGRecordLayoutBuilder::AppendBytes(CharUnits numBytes) { 917218893Sdim if (numBytes.isZero()) 918218893Sdim return; 919218893Sdim 920198092Srdivacky // Append the padding field 921218893Sdim AppendField(NextFieldOffset, getByteArrayType(numBytes)); 922198092Srdivacky} 923198092Srdivacky 924226633SdimCharUnits CGRecordLayoutBuilder::getTypeAlignment(llvm::Type *Ty) const { 925198092Srdivacky if (Packed) 926218893Sdim return CharUnits::One(); 927198092Srdivacky 928243830Sdim return CharUnits::fromQuantity(Types.getDataLayout().getABITypeAlignment(Ty)); 929198092Srdivacky} 930198092Srdivacky 931218893SdimCharUnits CGRecordLayoutBuilder::getAlignmentAsLLVMStruct() const { 932218893Sdim if (Packed) 933218893Sdim return CharUnits::One(); 934218893Sdim 935218893Sdim CharUnits maxAlignment = CharUnits::One(); 936218893Sdim for (size_t i = 0; i != FieldTypes.size(); ++i) 937218893Sdim maxAlignment = std::max(maxAlignment, getTypeAlignment(FieldTypes[i])); 938218893Sdim 939218893Sdim return maxAlignment; 940218893Sdim} 941218893Sdim 942218893Sdim/// Merge in whether a field of the given type is zero-initializable. 943212904Sdimvoid CGRecordLayoutBuilder::CheckZeroInitializable(QualType T) { 944198092Srdivacky // This record already contains a member pointer. 945218893Sdim if (!IsZeroInitializableAsBase) 946198092Srdivacky return; 947198092Srdivacky 948198092Srdivacky // Can only have member pointers if we're compiling C++. 949234353Sdim if (!Types.getContext().getLangOpts().CPlusPlus) 950198092Srdivacky return; 951198092Srdivacky 952218893Sdim const Type *elementType = T->getBaseElementTypeUnsafe(); 953198092Srdivacky 954218893Sdim if (const MemberPointerType *MPT = elementType->getAs<MemberPointerType>()) { 955212904Sdim if (!Types.getCXXABI().isZeroInitializable(MPT)) 956218893Sdim IsZeroInitializable = IsZeroInitializableAsBase = false; 957218893Sdim } else if (const RecordType *RT = elementType->getAs<RecordType>()) { 958203955Srdivacky const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 959218893Sdim const CGRecordLayout &Layout = Types.getCGRecordLayout(RD); 960218893Sdim if (!Layout.isZeroInitializable()) 961218893Sdim IsZeroInitializable = IsZeroInitializableAsBase = false; 962208600Srdivacky } 963208600Srdivacky} 964206084Srdivacky 965224145SdimCGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D, 966224145Sdim llvm::StructType *Ty) { 967206084Srdivacky CGRecordLayoutBuilder Builder(*this); 968198092Srdivacky 969198092Srdivacky Builder.Layout(D); 970198092Srdivacky 971224145Sdim Ty->setBody(Builder.FieldTypes, Builder.Packed); 972198092Srdivacky 973218893Sdim // If we're in C++, compute the base subobject type. 974224145Sdim llvm::StructType *BaseTy = 0; 975234353Sdim if (isa<CXXRecordDecl>(D) && !D->isUnion()) { 976218893Sdim BaseTy = Builder.BaseSubobjectType; 977218893Sdim if (!BaseTy) BaseTy = Ty; 978218893Sdim } 979218893Sdim 980206084Srdivacky CGRecordLayout *RL = 981218893Sdim new CGRecordLayout(Ty, BaseTy, Builder.IsZeroInitializable, 982218893Sdim Builder.IsZeroInitializableAsBase); 983206084Srdivacky 984218893Sdim RL->NonVirtualBases.swap(Builder.NonVirtualBases); 985218893Sdim RL->CompleteObjectVirtualBases.swap(Builder.VirtualBases); 986208600Srdivacky 987198092Srdivacky // Add all the field numbers. 988218893Sdim RL->FieldInfo.swap(Builder.Fields); 989198092Srdivacky 990198092Srdivacky // Add bitfield info. 991218893Sdim RL->BitFields.swap(Builder.BitFields); 992198092Srdivacky 993207619Srdivacky // Dump the layout, if requested. 994234353Sdim if (getContext().getLangOpts().DumpRecordLayouts) { 995207619Srdivacky llvm::errs() << "\n*** Dumping IRgen Record Layout\n"; 996207619Srdivacky llvm::errs() << "Record: "; 997207619Srdivacky D->dump(); 998207619Srdivacky llvm::errs() << "\nLayout: "; 999207619Srdivacky RL->dump(); 1000207619Srdivacky } 1001207619Srdivacky 1002207619Srdivacky#ifndef NDEBUG 1003207619Srdivacky // Verify that the computed LLVM struct size matches the AST layout size. 1004218893Sdim const ASTRecordLayout &Layout = getContext().getASTRecordLayout(D); 1005218893Sdim 1006218893Sdim uint64_t TypeSizeInBits = getContext().toBits(Layout.getSize()); 1007243830Sdim assert(TypeSizeInBits == getDataLayout().getTypeAllocSizeInBits(Ty) && 1008207619Srdivacky "Type size mismatch!"); 1009207619Srdivacky 1010218893Sdim if (BaseTy) { 1011218893Sdim CharUnits NonVirtualSize = Layout.getNonVirtualSize(); 1012218893Sdim CharUnits NonVirtualAlign = Layout.getNonVirtualAlign(); 1013218893Sdim CharUnits AlignedNonVirtualTypeSize = 1014218893Sdim NonVirtualSize.RoundUpToAlignment(NonVirtualAlign); 1015218893Sdim 1016218893Sdim uint64_t AlignedNonVirtualTypeSizeInBits = 1017218893Sdim getContext().toBits(AlignedNonVirtualTypeSize); 1018218893Sdim 1019218893Sdim assert(AlignedNonVirtualTypeSizeInBits == 1020243830Sdim getDataLayout().getTypeAllocSizeInBits(BaseTy) && 1021218893Sdim "Type size mismatch!"); 1022218893Sdim } 1023218893Sdim 1024207619Srdivacky // Verify that the LLVM and AST field offsets agree. 1025226633Sdim llvm::StructType *ST = 1026207619Srdivacky dyn_cast<llvm::StructType>(RL->getLLVMType()); 1027243830Sdim const llvm::StructLayout *SL = getDataLayout().getStructLayout(ST); 1028207619Srdivacky 1029207619Srdivacky const ASTRecordLayout &AST_RL = getContext().getASTRecordLayout(D); 1030207619Srdivacky RecordDecl::field_iterator it = D->field_begin(); 1031221345Sdim const FieldDecl *LastFD = 0; 1032243830Sdim bool IsMsStruct = D->isMsStruct(getContext()); 1033207619Srdivacky for (unsigned i = 0, e = AST_RL.getFieldCount(); i != e; ++i, ++it) { 1034207619Srdivacky const FieldDecl *FD = *it; 1035207619Srdivacky 1036207619Srdivacky // For non-bit-fields, just check that the LLVM struct offset matches the 1037207619Srdivacky // AST offset. 1038207619Srdivacky if (!FD->isBitField()) { 1039207619Srdivacky unsigned FieldNo = RL->getLLVMFieldNo(FD); 1040207619Srdivacky assert(AST_RL.getFieldOffset(i) == SL->getElementOffsetInBits(FieldNo) && 1041207619Srdivacky "Invalid field offset!"); 1042221345Sdim LastFD = FD; 1043207619Srdivacky continue; 1044207619Srdivacky } 1045207619Srdivacky 1046221345Sdim if (IsMsStruct) { 1047221345Sdim // Zero-length bitfields following non-bitfield members are 1048221345Sdim // ignored: 1049223017Sdim if (getContext().ZeroBitfieldFollowsNonBitfield(FD, LastFD)) { 1050221345Sdim --i; 1051221345Sdim continue; 1052221345Sdim } 1053221345Sdim LastFD = FD; 1054221345Sdim } 1055221345Sdim 1056207619Srdivacky // Ignore unnamed bit-fields. 1057221345Sdim if (!FD->getDeclName()) { 1058221345Sdim LastFD = FD; 1059207619Srdivacky continue; 1060221345Sdim } 1061249423Sdim 1062249423Sdim // Don't inspect zero-length bitfields. 1063249423Sdim if (FD->getBitWidthValue(getContext()) == 0) 1064249423Sdim continue; 1065249423Sdim 1066207619Srdivacky const CGBitFieldInfo &Info = RL->getBitFieldInfo(FD); 1067249423Sdim llvm::Type *ElementTy = ST->getTypeAtIndex(RL->getLLVMFieldNo(FD)); 1068207619Srdivacky 1069249423Sdim // Unions have overlapping elements dictating their layout, but for 1070249423Sdim // non-unions we can verify that this section of the layout is the exact 1071249423Sdim // expected size. 1072249423Sdim if (D->isUnion()) { 1073249423Sdim // For unions we verify that the start is zero and the size 1074249423Sdim // is in-bounds. However, on BE systems, the offset may be non-zero, but 1075249423Sdim // the size + offset should match the storage size in that case as it 1076249423Sdim // "starts" at the back. 1077249423Sdim if (getDataLayout().isBigEndian()) 1078249423Sdim assert(static_cast<unsigned>(Info.Offset + Info.Size) == 1079249423Sdim Info.StorageSize && 1080249423Sdim "Big endian union bitfield does not end at the back"); 1081249423Sdim else 1082249423Sdim assert(Info.Offset == 0 && 1083249423Sdim "Little endian union bitfield with a non-zero offset"); 1084249423Sdim assert(Info.StorageSize <= SL->getSizeInBits() && 1085249423Sdim "Union not large enough for bitfield storage"); 1086249423Sdim } else { 1087249423Sdim assert(Info.StorageSize == 1088249423Sdim getDataLayout().getTypeAllocSizeInBits(ElementTy) && 1089249423Sdim "Storage size does not match the element type size"); 1090207619Srdivacky } 1091249423Sdim assert(Info.Size > 0 && "Empty bitfield!"); 1092249423Sdim assert(static_cast<unsigned>(Info.Offset) + Info.Size <= Info.StorageSize && 1093249423Sdim "Bitfield outside of its allocated storage"); 1094207619Srdivacky } 1095207619Srdivacky#endif 1096207619Srdivacky 1097206084Srdivacky return RL; 1098198092Srdivacky} 1099207619Srdivacky 1100226633Sdimvoid CGRecordLayout::print(raw_ostream &OS) const { 1101207619Srdivacky OS << "<CGRecordLayout\n"; 1102218893Sdim OS << " LLVMType:" << *CompleteObjectType << "\n"; 1103218893Sdim if (BaseSubobjectType) 1104218893Sdim OS << " NonVirtualBaseLLVMType:" << *BaseSubobjectType << "\n"; 1105212904Sdim OS << " IsZeroInitializable:" << IsZeroInitializable << "\n"; 1106207619Srdivacky OS << " BitFields:[\n"; 1107207619Srdivacky 1108207619Srdivacky // Print bit-field infos in declaration order. 1109207619Srdivacky std::vector<std::pair<unsigned, const CGBitFieldInfo*> > BFIs; 1110207619Srdivacky for (llvm::DenseMap<const FieldDecl*, CGBitFieldInfo>::const_iterator 1111207619Srdivacky it = BitFields.begin(), ie = BitFields.end(); 1112207619Srdivacky it != ie; ++it) { 1113207619Srdivacky const RecordDecl *RD = it->first->getParent(); 1114207619Srdivacky unsigned Index = 0; 1115207619Srdivacky for (RecordDecl::field_iterator 1116207619Srdivacky it2 = RD->field_begin(); *it2 != it->first; ++it2) 1117207619Srdivacky ++Index; 1118207619Srdivacky BFIs.push_back(std::make_pair(Index, &it->second)); 1119207619Srdivacky } 1120207619Srdivacky llvm::array_pod_sort(BFIs.begin(), BFIs.end()); 1121207619Srdivacky for (unsigned i = 0, e = BFIs.size(); i != e; ++i) { 1122207619Srdivacky OS.indent(4); 1123207619Srdivacky BFIs[i].second->print(OS); 1124207619Srdivacky OS << "\n"; 1125207619Srdivacky } 1126207619Srdivacky 1127207619Srdivacky OS << "]>\n"; 1128207619Srdivacky} 1129207619Srdivacky 1130207619Srdivackyvoid CGRecordLayout::dump() const { 1131207619Srdivacky print(llvm::errs()); 1132207619Srdivacky} 1133207619Srdivacky 1134226633Sdimvoid CGBitFieldInfo::print(raw_ostream &OS) const { 1135249423Sdim OS << "<CGBitFieldInfo" 1136249423Sdim << " Offset:" << Offset 1137249423Sdim << " Size:" << Size 1138249423Sdim << " IsSigned:" << IsSigned 1139249423Sdim << " StorageSize:" << StorageSize 1140249423Sdim << " StorageAlignment:" << StorageAlignment << ">"; 1141207619Srdivacky} 1142207619Srdivacky 1143207619Srdivackyvoid CGBitFieldInfo::dump() const { 1144207619Srdivacky print(llvm::errs()); 1145207619Srdivacky} 1146