CGRecordLayoutBuilder.cpp revision 224145
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" 15198092Srdivacky#include "clang/AST/ASTContext.h" 16198092Srdivacky#include "clang/AST/Attr.h" 17218893Sdim#include "clang/AST/CXXInheritance.h" 18198092Srdivacky#include "clang/AST/DeclCXX.h" 19198092Srdivacky#include "clang/AST/Expr.h" 20198092Srdivacky#include "clang/AST/RecordLayout.h" 21224145Sdim#include "clang/Frontend/CodeGenOptions.h" 22198092Srdivacky#include "CodeGenTypes.h" 23212904Sdim#include "CGCXXABI.h" 24207619Srdivacky#include "llvm/DerivedTypes.h" 25206084Srdivacky#include "llvm/Type.h" 26207619Srdivacky#include "llvm/Support/Debug.h" 27207619Srdivacky#include "llvm/Support/raw_ostream.h" 28198092Srdivacky#include "llvm/Target/TargetData.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 /// 38224145Sdim llvm::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 103206084Srdivacky /// BitsAvailableInLastField - If a bit field spans only part of a LLVM field, 104206084Srdivacky /// this will have the number of bits still available in the field. 105206084Srdivacky char BitsAvailableInLastField; 106206084Srdivacky 107218893Sdim /// NextFieldOffset - Holds the next field offset. 108218893Sdim CharUnits NextFieldOffset; 109206084Srdivacky 110207619Srdivacky /// LayoutUnionField - Will layout a field in an union and return the type 111207619Srdivacky /// that the field will have. 112224145Sdim llvm::Type *LayoutUnionField(const FieldDecl *Field, 113224145Sdim const ASTRecordLayout &Layout); 114207619Srdivacky 115206084Srdivacky /// LayoutUnion - Will layout a union RecordDecl. 116206084Srdivacky void LayoutUnion(const RecordDecl *D); 117206084Srdivacky 118206084Srdivacky /// LayoutField - try to layout all fields in the record decl. 119206084Srdivacky /// Returns false if the operation failed because the struct is not packed. 120206084Srdivacky bool LayoutFields(const RecordDecl *D); 121206084Srdivacky 122218893Sdim /// Layout a single base, virtual or non-virtual 123218893Sdim void LayoutBase(const CXXRecordDecl *base, 124218893Sdim const CGRecordLayout &baseLayout, 125218893Sdim CharUnits baseOffset); 126218893Sdim 127218893Sdim /// LayoutVirtualBase - layout a single virtual base. 128218893Sdim void LayoutVirtualBase(const CXXRecordDecl *base, 129218893Sdim CharUnits baseOffset); 130218893Sdim 131218893Sdim /// LayoutVirtualBases - layout the virtual bases of a record decl. 132218893Sdim void LayoutVirtualBases(const CXXRecordDecl *RD, 133218893Sdim const ASTRecordLayout &Layout); 134218893Sdim 135208600Srdivacky /// LayoutNonVirtualBase - layout a single non-virtual base. 136218893Sdim void LayoutNonVirtualBase(const CXXRecordDecl *base, 137218893Sdim CharUnits baseOffset); 138208600Srdivacky 139218893Sdim /// LayoutNonVirtualBases - layout the virtual bases of a record decl. 140208600Srdivacky void LayoutNonVirtualBases(const CXXRecordDecl *RD, 141208600Srdivacky const ASTRecordLayout &Layout); 142206084Srdivacky 143218893Sdim /// ComputeNonVirtualBaseType - Compute the non-virtual base field types. 144218893Sdim bool ComputeNonVirtualBaseType(const CXXRecordDecl *RD); 145218893Sdim 146206084Srdivacky /// LayoutField - layout a single field. Returns false if the operation failed 147206084Srdivacky /// because the current struct is not packed. 148206084Srdivacky bool LayoutField(const FieldDecl *D, uint64_t FieldOffset); 149206084Srdivacky 150206084Srdivacky /// LayoutBitField - layout a single bit field. 151206084Srdivacky void LayoutBitField(const FieldDecl *D, uint64_t FieldOffset); 152206084Srdivacky 153206084Srdivacky /// AppendField - Appends a field with the given offset and type. 154224145Sdim void AppendField(CharUnits fieldOffset, llvm::Type *FieldTy); 155206084Srdivacky 156206084Srdivacky /// AppendPadding - Appends enough padding bytes so that the total 157206084Srdivacky /// struct size is a multiple of the field alignment. 158218893Sdim void AppendPadding(CharUnits fieldOffset, CharUnits fieldAlignment); 159206084Srdivacky 160221345Sdim /// ResizeLastBaseFieldIfNecessary - Fields and bases can be laid out in the 161221345Sdim /// tail padding of a previous base. If this happens, the type of the previous 162221345Sdim /// base needs to be changed to an array of i8. Returns true if the last 163221345Sdim /// laid out base was resized. 164221345Sdim bool ResizeLastBaseFieldIfNecessary(CharUnits offset); 165221345Sdim 166218893Sdim /// getByteArrayType - Returns a byte array type with the given number of 167218893Sdim /// elements. 168224145Sdim llvm::Type *getByteArrayType(CharUnits NumBytes); 169218893Sdim 170206084Srdivacky /// AppendBytes - Append a given number of bytes to the record. 171218893Sdim void AppendBytes(CharUnits numBytes); 172206084Srdivacky 173206084Srdivacky /// AppendTailPadding - Append enough tail padding so that the type will have 174206084Srdivacky /// the passed size. 175221345Sdim void AppendTailPadding(CharUnits RecordSize); 176206084Srdivacky 177218893Sdim CharUnits getTypeAlignment(const llvm::Type *Ty) const; 178206084Srdivacky 179218893Sdim /// getAlignmentAsLLVMStruct - Returns the maximum alignment of all the 180218893Sdim /// LLVM element types. 181218893Sdim CharUnits getAlignmentAsLLVMStruct() const; 182218893Sdim 183212904Sdim /// CheckZeroInitializable - Check if the given type contains a pointer 184206084Srdivacky /// to data member. 185212904Sdim void CheckZeroInitializable(QualType T); 186206084Srdivacky 187206084Srdivackypublic: 188206084Srdivacky CGRecordLayoutBuilder(CodeGenTypes &Types) 189218893Sdim : BaseSubobjectType(0), 190218893Sdim IsZeroInitializable(true), IsZeroInitializableAsBase(true), 191221345Sdim Packed(false), IsMsStruct(false), 192221345Sdim Types(Types), BitsAvailableInLastField(0) { } 193206084Srdivacky 194206084Srdivacky /// Layout - Will layout a RecordDecl. 195206084Srdivacky void Layout(const RecordDecl *D); 196206084Srdivacky}; 197206084Srdivacky 198206084Srdivacky} 199206084Srdivacky 200198092Srdivackyvoid CGRecordLayoutBuilder::Layout(const RecordDecl *D) { 201218893Sdim Alignment = Types.getContext().getASTRecordLayout(D).getAlignment(); 202198092Srdivacky Packed = D->hasAttr<PackedAttr>(); 203221345Sdim 204221345Sdim IsMsStruct = D->hasAttr<MsStructAttr>(); 205198092Srdivacky 206198092Srdivacky if (D->isUnion()) { 207198092Srdivacky LayoutUnion(D); 208198092Srdivacky return; 209198092Srdivacky } 210198092Srdivacky 211198092Srdivacky if (LayoutFields(D)) 212198092Srdivacky return; 213198092Srdivacky 214198092Srdivacky // We weren't able to layout the struct. Try again with a packed struct 215198092Srdivacky Packed = true; 216221345Sdim LastLaidOutBase.invalidate(); 217218893Sdim NextFieldOffset = CharUnits::Zero(); 218198092Srdivacky FieldTypes.clear(); 219218893Sdim Fields.clear(); 220218893Sdim BitFields.clear(); 221218893Sdim NonVirtualBases.clear(); 222218893Sdim VirtualBases.clear(); 223198092Srdivacky 224198092Srdivacky LayoutFields(D); 225198092Srdivacky} 226198092Srdivacky 227212904SdimCGBitFieldInfo CGBitFieldInfo::MakeInfo(CodeGenTypes &Types, 228212904Sdim const FieldDecl *FD, 229212904Sdim uint64_t FieldOffset, 230212904Sdim uint64_t FieldSize, 231212904Sdim uint64_t ContainingTypeSizeInBits, 232212904Sdim unsigned ContainingTypeAlign) { 233224145Sdim const llvm::Type *Ty = Types.ConvertTypeForMem(FD->getType()); 234219077Sdim CharUnits TypeSizeInBytes = 235219077Sdim CharUnits::fromQuantity(Types.getTargetData().getTypeAllocSize(Ty)); 236219077Sdim uint64_t TypeSizeInBits = Types.getContext().toBits(TypeSizeInBytes); 237207619Srdivacky 238223017Sdim bool IsSigned = FD->getType()->isSignedIntegerOrEnumerationType(); 239207619Srdivacky 240207619Srdivacky if (FieldSize > TypeSizeInBits) { 241207619Srdivacky // We have a wide bit-field. The extra bits are only used for padding, so 242207619Srdivacky // if we have a bitfield of type T, with size N: 243207619Srdivacky // 244207619Srdivacky // T t : N; 245207619Srdivacky // 246207619Srdivacky // We can just assume that it's: 247207619Srdivacky // 248207619Srdivacky // T t : sizeof(T); 249207619Srdivacky // 250207619Srdivacky FieldSize = TypeSizeInBits; 251207619Srdivacky } 252207619Srdivacky 253218893Sdim // in big-endian machines the first fields are in higher bit positions, 254218893Sdim // so revert the offset. The byte offsets are reversed(back) later. 255218893Sdim if (Types.getTargetData().isBigEndian()) { 256218893Sdim FieldOffset = ((ContainingTypeSizeInBits)-FieldOffset-FieldSize); 257218893Sdim } 258218893Sdim 259207619Srdivacky // Compute the access components. The policy we use is to start by attempting 260207619Srdivacky // to access using the width of the bit-field type itself and to always access 261207619Srdivacky // at aligned indices of that type. If such an access would fail because it 262207619Srdivacky // extends past the bound of the type, then we reduce size to the next smaller 263207619Srdivacky // power of two and retry. The current algorithm assumes pow2 sized types, 264207619Srdivacky // although this is easy to fix. 265207619Srdivacky // 266207619Srdivacky assert(llvm::isPowerOf2_32(TypeSizeInBits) && "Unexpected type size!"); 267207619Srdivacky CGBitFieldInfo::AccessInfo Components[3]; 268207619Srdivacky unsigned NumComponents = 0; 269221345Sdim unsigned AccessedTargetBits = 0; // The number of target bits accessed. 270207619Srdivacky unsigned AccessWidth = TypeSizeInBits; // The current access width to attempt. 271207619Srdivacky 272224145Sdim // If requested, widen the initial bit-field access to be register sized. The 273224145Sdim // theory is that this is most likely to allow multiple accesses into the same 274224145Sdim // structure to be coalesced, and that the backend should be smart enough to 275224145Sdim // narrow the store if no coalescing is ever done. 276224145Sdim // 277224145Sdim // The subsequent code will handle align these access to common boundaries and 278224145Sdim // guaranteeing that we do not access past the end of the structure. 279224145Sdim if (Types.getCodeGenOpts().UseRegisterSizedBitfieldAccess) { 280224145Sdim if (AccessWidth < Types.getTarget().getRegisterWidth()) 281224145Sdim AccessWidth = Types.getTarget().getRegisterWidth(); 282224145Sdim } 283224145Sdim 284207619Srdivacky // Round down from the field offset to find the first access position that is 285207619Srdivacky // at an aligned offset of the initial access type. 286207619Srdivacky uint64_t AccessStart = FieldOffset - (FieldOffset % AccessWidth); 287207619Srdivacky 288207619Srdivacky // Adjust initial access size to fit within record. 289219077Sdim while (AccessWidth > Types.getTarget().getCharWidth() && 290207619Srdivacky AccessStart + AccessWidth > ContainingTypeSizeInBits) { 291207619Srdivacky AccessWidth >>= 1; 292207619Srdivacky AccessStart = FieldOffset - (FieldOffset % AccessWidth); 293207619Srdivacky } 294207619Srdivacky 295207619Srdivacky while (AccessedTargetBits < FieldSize) { 296207619Srdivacky // Check that we can access using a type of this size, without reading off 297207619Srdivacky // the end of the structure. This can occur with packed structures and 298207619Srdivacky // -fno-bitfield-type-align, for example. 299207619Srdivacky if (AccessStart + AccessWidth > ContainingTypeSizeInBits) { 300207619Srdivacky // If so, reduce access size to the next smaller power-of-two and retry. 301207619Srdivacky AccessWidth >>= 1; 302219077Sdim assert(AccessWidth >= Types.getTarget().getCharWidth() 303219077Sdim && "Cannot access under byte size!"); 304207619Srdivacky continue; 305207619Srdivacky } 306207619Srdivacky 307207619Srdivacky // Otherwise, add an access component. 308207619Srdivacky 309207619Srdivacky // First, compute the bits inside this access which are part of the 310207619Srdivacky // target. We are reading bits [AccessStart, AccessStart + AccessWidth); the 311207619Srdivacky // intersection with [FieldOffset, FieldOffset + FieldSize) gives the bits 312207619Srdivacky // in the target that we are reading. 313207619Srdivacky assert(FieldOffset < AccessStart + AccessWidth && "Invalid access start!"); 314207619Srdivacky assert(AccessStart < FieldOffset + FieldSize && "Invalid access start!"); 315207619Srdivacky uint64_t AccessBitsInFieldStart = std::max(AccessStart, FieldOffset); 316207619Srdivacky uint64_t AccessBitsInFieldSize = 317207619Srdivacky std::min(AccessWidth + AccessStart, 318207619Srdivacky FieldOffset + FieldSize) - AccessBitsInFieldStart; 319207619Srdivacky 320207619Srdivacky assert(NumComponents < 3 && "Unexpected number of components!"); 321207619Srdivacky CGBitFieldInfo::AccessInfo &AI = Components[NumComponents++]; 322207619Srdivacky AI.FieldIndex = 0; 323207619Srdivacky // FIXME: We still follow the old access pattern of only using the field 324207619Srdivacky // byte offset. We should switch this once we fix the struct layout to be 325207619Srdivacky // pretty. 326218893Sdim 327218893Sdim // on big-endian machines we reverted the bit offset because first fields are 328218893Sdim // in higher bits. But this also reverts the bytes, so fix this here by reverting 329218893Sdim // the byte offset on big-endian machines. 330218893Sdim if (Types.getTargetData().isBigEndian()) { 331221345Sdim AI.FieldByteOffset = Types.getContext().toCharUnitsFromBits( 332221345Sdim ContainingTypeSizeInBits - AccessStart - AccessWidth); 333218893Sdim } else { 334221345Sdim AI.FieldByteOffset = Types.getContext().toCharUnitsFromBits(AccessStart); 335218893Sdim } 336207619Srdivacky AI.FieldBitStart = AccessBitsInFieldStart - AccessStart; 337207619Srdivacky AI.AccessWidth = AccessWidth; 338221345Sdim AI.AccessAlignment = Types.getContext().toCharUnitsFromBits( 339221345Sdim llvm::MinAlign(ContainingTypeAlign, AccessStart)); 340207619Srdivacky AI.TargetBitOffset = AccessedTargetBits; 341207619Srdivacky AI.TargetBitWidth = AccessBitsInFieldSize; 342207619Srdivacky 343207619Srdivacky AccessStart += AccessWidth; 344207619Srdivacky AccessedTargetBits += AI.TargetBitWidth; 345207619Srdivacky } 346207619Srdivacky 347207619Srdivacky assert(AccessedTargetBits == FieldSize && "Invalid bit-field access!"); 348207619Srdivacky return CGBitFieldInfo(FieldSize, NumComponents, Components, IsSigned); 349207619Srdivacky} 350207619Srdivacky 351212904SdimCGBitFieldInfo CGBitFieldInfo::MakeInfo(CodeGenTypes &Types, 352212904Sdim const FieldDecl *FD, 353212904Sdim uint64_t FieldOffset, 354212904Sdim uint64_t FieldSize) { 355212904Sdim const RecordDecl *RD = FD->getParent(); 356212904Sdim const ASTRecordLayout &RL = Types.getContext().getASTRecordLayout(RD); 357218893Sdim uint64_t ContainingTypeSizeInBits = Types.getContext().toBits(RL.getSize()); 358218893Sdim unsigned ContainingTypeAlign = Types.getContext().toBits(RL.getAlignment()); 359212904Sdim 360212904Sdim return MakeInfo(Types, FD, FieldOffset, FieldSize, ContainingTypeSizeInBits, 361212904Sdim ContainingTypeAlign); 362212904Sdim} 363212904Sdim 364198092Srdivackyvoid CGRecordLayoutBuilder::LayoutBitField(const FieldDecl *D, 365218893Sdim uint64_t fieldOffset) { 366218893Sdim uint64_t fieldSize = 367198092Srdivacky D->getBitWidth()->EvaluateAsInt(Types.getContext()).getZExtValue(); 368198092Srdivacky 369218893Sdim if (fieldSize == 0) 370198092Srdivacky return; 371198092Srdivacky 372219077Sdim uint64_t nextFieldOffsetInBits = Types.getContext().toBits(NextFieldOffset); 373221345Sdim CharUnits numBytesToAppend; 374221345Sdim unsigned charAlign = Types.getContext().Target.getCharAlign(); 375198092Srdivacky 376221345Sdim if (fieldOffset < nextFieldOffsetInBits && !BitsAvailableInLastField) { 377221345Sdim assert(fieldOffset % charAlign == 0 && 378221345Sdim "Field offset not aligned correctly"); 379221345Sdim 380221345Sdim CharUnits fieldOffsetInCharUnits = 381221345Sdim Types.getContext().toCharUnitsFromBits(fieldOffset); 382221345Sdim 383221345Sdim // Try to resize the last base field. 384221345Sdim if (ResizeLastBaseFieldIfNecessary(fieldOffsetInCharUnits)) 385221345Sdim nextFieldOffsetInBits = Types.getContext().toBits(NextFieldOffset); 386221345Sdim } 387221345Sdim 388218893Sdim if (fieldOffset < nextFieldOffsetInBits) { 389198092Srdivacky assert(BitsAvailableInLastField && "Bitfield size mismatch!"); 390218893Sdim assert(!NextFieldOffset.isZero() && "Must have laid out at least one byte"); 391198092Srdivacky 392198092Srdivacky // The bitfield begins in the previous bit-field. 393221345Sdim numBytesToAppend = Types.getContext().toCharUnitsFromBits( 394221345Sdim llvm::RoundUpToAlignment(fieldSize - BitsAvailableInLastField, 395221345Sdim charAlign)); 396198092Srdivacky } else { 397221345Sdim assert(fieldOffset % charAlign == 0 && 398221345Sdim "Field offset not aligned correctly"); 399198092Srdivacky 400198092Srdivacky // Append padding if necessary. 401221345Sdim AppendPadding(Types.getContext().toCharUnitsFromBits(fieldOffset), 402221345Sdim CharUnits::One()); 403198092Srdivacky 404221345Sdim numBytesToAppend = Types.getContext().toCharUnitsFromBits( 405221345Sdim llvm::RoundUpToAlignment(fieldSize, charAlign)); 406198092Srdivacky 407221345Sdim assert(!numBytesToAppend.isZero() && "No bytes to append!"); 408198092Srdivacky } 409198092Srdivacky 410207619Srdivacky // Add the bit field info. 411218893Sdim BitFields.insert(std::make_pair(D, 412218893Sdim CGBitFieldInfo::MakeInfo(Types, D, fieldOffset, fieldSize))); 413198092Srdivacky 414221345Sdim AppendBytes(numBytesToAppend); 415198092Srdivacky 416198092Srdivacky BitsAvailableInLastField = 417221345Sdim Types.getContext().toBits(NextFieldOffset) - (fieldOffset + fieldSize); 418198092Srdivacky} 419198092Srdivacky 420198092Srdivackybool CGRecordLayoutBuilder::LayoutField(const FieldDecl *D, 421218893Sdim uint64_t fieldOffset) { 422198092Srdivacky // If the field is packed, then we need a packed struct. 423198092Srdivacky if (!Packed && D->hasAttr<PackedAttr>()) 424198092Srdivacky return false; 425198092Srdivacky 426198092Srdivacky if (D->isBitField()) { 427198092Srdivacky // We must use packed structs for unnamed bit fields since they 428198092Srdivacky // don't affect the struct alignment. 429198092Srdivacky if (!Packed && !D->getDeclName()) 430198092Srdivacky return false; 431198092Srdivacky 432218893Sdim LayoutBitField(D, fieldOffset); 433198092Srdivacky return true; 434198092Srdivacky } 435198092Srdivacky 436212904Sdim CheckZeroInitializable(D->getType()); 437206084Srdivacky 438219077Sdim assert(fieldOffset % Types.getTarget().getCharWidth() == 0 439219077Sdim && "field offset is not on a byte boundary!"); 440219077Sdim CharUnits fieldOffsetInBytes 441219077Sdim = Types.getContext().toCharUnitsFromBits(fieldOffset); 442198092Srdivacky 443224145Sdim llvm::Type *Ty = Types.ConvertTypeForMem(D->getType()); 444218893Sdim CharUnits typeAlignment = getTypeAlignment(Ty); 445198092Srdivacky 446198092Srdivacky // If the type alignment is larger then the struct alignment, we must use 447198092Srdivacky // a packed struct. 448218893Sdim if (typeAlignment > Alignment) { 449198092Srdivacky assert(!Packed && "Alignment is wrong even with packed struct!"); 450198092Srdivacky return false; 451198092Srdivacky } 452198092Srdivacky 453218893Sdim if (!Packed) { 454218893Sdim if (const RecordType *RT = D->getType()->getAs<RecordType>()) { 455218893Sdim const RecordDecl *RD = cast<RecordDecl>(RT->getDecl()); 456218893Sdim if (const MaxFieldAlignmentAttr *MFAA = 457218893Sdim RD->getAttr<MaxFieldAlignmentAttr>()) { 458219077Sdim if (MFAA->getAlignment() != Types.getContext().toBits(typeAlignment)) 459218893Sdim return false; 460218893Sdim } 461198092Srdivacky } 462198092Srdivacky } 463198092Srdivacky 464198092Srdivacky // Round up the field offset to the alignment of the field type. 465218893Sdim CharUnits alignedNextFieldOffsetInBytes = 466218893Sdim NextFieldOffset.RoundUpToAlignment(typeAlignment); 467198092Srdivacky 468218893Sdim if (fieldOffsetInBytes < alignedNextFieldOffsetInBytes) { 469221345Sdim // Try to resize the last base field. 470221345Sdim if (ResizeLastBaseFieldIfNecessary(fieldOffsetInBytes)) { 471221345Sdim alignedNextFieldOffsetInBytes = 472221345Sdim NextFieldOffset.RoundUpToAlignment(typeAlignment); 473221345Sdim } 474221345Sdim } 475221345Sdim 476221345Sdim if (fieldOffsetInBytes < alignedNextFieldOffsetInBytes) { 477198092Srdivacky assert(!Packed && "Could not place field even with packed struct!"); 478198092Srdivacky return false; 479198092Srdivacky } 480198092Srdivacky 481218893Sdim AppendPadding(fieldOffsetInBytes, typeAlignment); 482198092Srdivacky 483198092Srdivacky // Now append the field. 484218893Sdim Fields[D] = FieldTypes.size(); 485218893Sdim AppendField(fieldOffsetInBytes, Ty); 486198092Srdivacky 487221345Sdim LastLaidOutBase.invalidate(); 488198092Srdivacky return true; 489198092Srdivacky} 490198092Srdivacky 491224145Sdimllvm::Type * 492207619SrdivackyCGRecordLayoutBuilder::LayoutUnionField(const FieldDecl *Field, 493207619Srdivacky const ASTRecordLayout &Layout) { 494207619Srdivacky if (Field->isBitField()) { 495207619Srdivacky uint64_t FieldSize = 496207619Srdivacky Field->getBitWidth()->EvaluateAsInt(Types.getContext()).getZExtValue(); 497207619Srdivacky 498207619Srdivacky // Ignore zero sized bit fields. 499207619Srdivacky if (FieldSize == 0) 500207619Srdivacky return 0; 501207619Srdivacky 502224145Sdim llvm::Type *FieldTy = llvm::Type::getInt8Ty(Types.getLLVMContext()); 503221345Sdim CharUnits NumBytesToAppend = Types.getContext().toCharUnitsFromBits( 504221345Sdim llvm::RoundUpToAlignment(FieldSize, 505221345Sdim Types.getContext().Target.getCharAlign())); 506207619Srdivacky 507221345Sdim if (NumBytesToAppend > CharUnits::One()) 508221345Sdim FieldTy = llvm::ArrayType::get(FieldTy, NumBytesToAppend.getQuantity()); 509207619Srdivacky 510207619Srdivacky // Add the bit field info. 511218893Sdim BitFields.insert(std::make_pair(Field, 512218893Sdim CGBitFieldInfo::MakeInfo(Types, Field, 0, FieldSize))); 513207619Srdivacky return FieldTy; 514207619Srdivacky } 515207619Srdivacky 516207619Srdivacky // This is a regular union field. 517218893Sdim Fields[Field] = 0; 518224145Sdim return Types.ConvertTypeForMem(Field->getType()); 519207619Srdivacky} 520207619Srdivacky 521198092Srdivackyvoid CGRecordLayoutBuilder::LayoutUnion(const RecordDecl *D) { 522198092Srdivacky assert(D->isUnion() && "Can't call LayoutUnion on a non-union record!"); 523198092Srdivacky 524218893Sdim const ASTRecordLayout &layout = Types.getContext().getASTRecordLayout(D); 525198092Srdivacky 526224145Sdim llvm::Type *unionType = 0; 527218893Sdim CharUnits unionSize = CharUnits::Zero(); 528218893Sdim CharUnits unionAlign = CharUnits::Zero(); 529198092Srdivacky 530218893Sdim bool hasOnlyZeroSizedBitFields = true; 531206084Srdivacky 532218893Sdim unsigned fieldNo = 0; 533218893Sdim for (RecordDecl::field_iterator field = D->field_begin(), 534218893Sdim fieldEnd = D->field_end(); field != fieldEnd; ++field, ++fieldNo) { 535218893Sdim assert(layout.getFieldOffset(fieldNo) == 0 && 536198092Srdivacky "Union field offset did not start at the beginning of record!"); 537224145Sdim llvm::Type *fieldType = LayoutUnionField(*field, layout); 538198092Srdivacky 539218893Sdim if (!fieldType) 540207619Srdivacky continue; 541198092Srdivacky 542218893Sdim hasOnlyZeroSizedBitFields = false; 543206084Srdivacky 544218893Sdim CharUnits fieldAlign = CharUnits::fromQuantity( 545218893Sdim Types.getTargetData().getABITypeAlignment(fieldType)); 546218893Sdim CharUnits fieldSize = CharUnits::fromQuantity( 547218893Sdim Types.getTargetData().getTypeAllocSize(fieldType)); 548198092Srdivacky 549218893Sdim if (fieldAlign < unionAlign) 550198092Srdivacky continue; 551198092Srdivacky 552218893Sdim if (fieldAlign > unionAlign || fieldSize > unionSize) { 553218893Sdim unionType = fieldType; 554218893Sdim unionAlign = fieldAlign; 555218893Sdim unionSize = fieldSize; 556198092Srdivacky } 557198092Srdivacky } 558198092Srdivacky 559198092Srdivacky // Now add our field. 560218893Sdim if (unionType) { 561218893Sdim AppendField(CharUnits::Zero(), unionType); 562198092Srdivacky 563218893Sdim if (getTypeAlignment(unionType) > layout.getAlignment()) { 564198092Srdivacky // We need a packed struct. 565198092Srdivacky Packed = true; 566218893Sdim unionAlign = CharUnits::One(); 567198092Srdivacky } 568198092Srdivacky } 569218893Sdim if (unionAlign.isZero()) { 570218893Sdim assert(hasOnlyZeroSizedBitFields && 571203955Srdivacky "0-align record did not have all zero-sized bit-fields!"); 572218893Sdim unionAlign = CharUnits::One(); 573199482Srdivacky } 574206084Srdivacky 575198092Srdivacky // Append tail padding. 576218893Sdim CharUnits recordSize = layout.getSize(); 577218893Sdim if (recordSize > unionSize) 578218893Sdim AppendPadding(recordSize, unionAlign); 579198092Srdivacky} 580198092Srdivacky 581218893Sdimvoid CGRecordLayoutBuilder::LayoutBase(const CXXRecordDecl *base, 582218893Sdim const CGRecordLayout &baseLayout, 583218893Sdim CharUnits baseOffset) { 584221345Sdim ResizeLastBaseFieldIfNecessary(baseOffset); 585221345Sdim 586218893Sdim AppendPadding(baseOffset, CharUnits::One()); 587208600Srdivacky 588218893Sdim const ASTRecordLayout &baseASTLayout 589218893Sdim = Types.getContext().getASTRecordLayout(base); 590208600Srdivacky 591221345Sdim LastLaidOutBase.Offset = NextFieldOffset; 592221345Sdim LastLaidOutBase.NonVirtualSize = baseASTLayout.getNonVirtualSize(); 593221345Sdim 594218893Sdim // Fields and bases can be laid out in the tail padding of previous 595218893Sdim // bases. If this happens, we need to allocate the base as an i8 596218893Sdim // array; otherwise, we can use the subobject type. However, 597218893Sdim // actually doing that would require knowledge of what immediately 598218893Sdim // follows this base in the layout, so instead we do a conservative 599218893Sdim // approximation, which is to use the base subobject type if it 600218893Sdim // has the same LLVM storage size as the nvsize. 601218893Sdim 602224145Sdim llvm::StructType *subobjectType = baseLayout.getBaseSubobjectLLVMType(); 603221345Sdim AppendField(baseOffset, subobjectType); 604218893Sdim} 605218893Sdim 606218893Sdimvoid CGRecordLayoutBuilder::LayoutNonVirtualBase(const CXXRecordDecl *base, 607218893Sdim CharUnits baseOffset) { 608218893Sdim // Ignore empty bases. 609218893Sdim if (base->isEmpty()) return; 610218893Sdim 611218893Sdim const CGRecordLayout &baseLayout = Types.getCGRecordLayout(base); 612218893Sdim if (IsZeroInitializableAsBase) { 613218893Sdim assert(IsZeroInitializable && 614218893Sdim "class zero-initializable as base but not as complete object"); 615218893Sdim 616218893Sdim IsZeroInitializable = IsZeroInitializableAsBase = 617218893Sdim baseLayout.isZeroInitializableAsBase(); 618208600Srdivacky } 619208600Srdivacky 620218893Sdim LayoutBase(base, baseLayout, baseOffset); 621218893Sdim NonVirtualBases[base] = (FieldTypes.size() - 1); 622218893Sdim} 623208600Srdivacky 624218893Sdimvoid 625218893SdimCGRecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *base, 626218893Sdim CharUnits baseOffset) { 627218893Sdim // Ignore empty bases. 628218893Sdim if (base->isEmpty()) return; 629208600Srdivacky 630218893Sdim const CGRecordLayout &baseLayout = Types.getCGRecordLayout(base); 631218893Sdim if (IsZeroInitializable) 632218893Sdim IsZeroInitializable = baseLayout.isZeroInitializableAsBase(); 633218893Sdim 634218893Sdim LayoutBase(base, baseLayout, baseOffset); 635218893Sdim VirtualBases[base] = (FieldTypes.size() - 1); 636208600Srdivacky} 637208600Srdivacky 638218893Sdim/// LayoutVirtualBases - layout the non-virtual bases of a record decl. 639208600Srdivackyvoid 640218893SdimCGRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD, 641218893Sdim const ASTRecordLayout &Layout) { 642218893Sdim for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 643218893Sdim E = RD->bases_end(); I != E; ++I) { 644218893Sdim const CXXRecordDecl *BaseDecl = 645218893Sdim cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 646218893Sdim 647218893Sdim // We only want to lay out virtual bases that aren't indirect primary bases 648218893Sdim // of some other base. 649218893Sdim if (I->isVirtual() && !IndirectPrimaryBases.count(BaseDecl)) { 650218893Sdim // Only lay out the base once. 651218893Sdim if (!LaidOutVirtualBases.insert(BaseDecl)) 652218893Sdim continue; 653218893Sdim 654218893Sdim CharUnits vbaseOffset = Layout.getVBaseClassOffset(BaseDecl); 655218893Sdim LayoutVirtualBase(BaseDecl, vbaseOffset); 656218893Sdim } 657218893Sdim 658218893Sdim if (!BaseDecl->getNumVBases()) { 659218893Sdim // This base isn't interesting since it doesn't have any virtual bases. 660218893Sdim continue; 661218893Sdim } 662218893Sdim 663218893Sdim LayoutVirtualBases(BaseDecl, Layout); 664218893Sdim } 665218893Sdim} 666218893Sdim 667218893Sdimvoid 668208600SrdivackyCGRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD, 669208600Srdivacky const ASTRecordLayout &Layout) { 670208600Srdivacky const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase(); 671208600Srdivacky 672201361Srdivacky // Check if we need to add a vtable pointer. 673208600Srdivacky if (RD->isDynamicClass()) { 674208600Srdivacky if (!PrimaryBase) { 675208600Srdivacky const llvm::Type *FunctionType = 676208600Srdivacky llvm::FunctionType::get(llvm::Type::getInt32Ty(Types.getLLVMContext()), 677208600Srdivacky /*isVarArg=*/true); 678208600Srdivacky const llvm::Type *VTableTy = FunctionType->getPointerTo(); 679206084Srdivacky 680218893Sdim assert(NextFieldOffset.isZero() && 681208600Srdivacky "VTable pointer must come first!"); 682218893Sdim AppendField(CharUnits::Zero(), VTableTy->getPointerTo()); 683208600Srdivacky } else { 684218893Sdim if (!Layout.isPrimaryBaseVirtual()) 685218893Sdim LayoutNonVirtualBase(PrimaryBase, CharUnits::Zero()); 686218893Sdim else 687218893Sdim LayoutVirtualBase(PrimaryBase, CharUnits::Zero()); 688208600Srdivacky } 689201361Srdivacky } 690208600Srdivacky 691208600Srdivacky // Layout the non-virtual bases. 692208600Srdivacky for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(), 693208600Srdivacky E = RD->bases_end(); I != E; ++I) { 694208600Srdivacky if (I->isVirtual()) 695208600Srdivacky continue; 696208600Srdivacky 697208600Srdivacky const CXXRecordDecl *BaseDecl = 698208600Srdivacky cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl()); 699208600Srdivacky 700208600Srdivacky // We've already laid out the primary base. 701218893Sdim if (BaseDecl == PrimaryBase && !Layout.isPrimaryBaseVirtual()) 702208600Srdivacky continue; 703208600Srdivacky 704208600Srdivacky LayoutNonVirtualBase(BaseDecl, Layout.getBaseClassOffset(BaseDecl)); 705208600Srdivacky } 706201361Srdivacky} 707201361Srdivacky 708218893Sdimbool 709218893SdimCGRecordLayoutBuilder::ComputeNonVirtualBaseType(const CXXRecordDecl *RD) { 710218893Sdim const ASTRecordLayout &Layout = Types.getContext().getASTRecordLayout(RD); 711218893Sdim 712218893Sdim CharUnits NonVirtualSize = Layout.getNonVirtualSize(); 713218893Sdim CharUnits NonVirtualAlign = Layout.getNonVirtualAlign(); 714218893Sdim CharUnits AlignedNonVirtualTypeSize = 715218893Sdim NonVirtualSize.RoundUpToAlignment(NonVirtualAlign); 716218893Sdim 717218893Sdim // First check if we can use the same fields as for the complete class. 718218893Sdim CharUnits RecordSize = Layout.getSize(); 719218893Sdim if (AlignedNonVirtualTypeSize == RecordSize) 720218893Sdim return true; 721218893Sdim 722218893Sdim // Check if we need padding. 723218893Sdim CharUnits AlignedNextFieldOffset = 724218893Sdim NextFieldOffset.RoundUpToAlignment(getAlignmentAsLLVMStruct()); 725218893Sdim 726218893Sdim if (AlignedNextFieldOffset > AlignedNonVirtualTypeSize) { 727218893Sdim assert(!Packed && "cannot layout even as packed struct"); 728218893Sdim return false; // Needs packing. 729218893Sdim } 730218893Sdim 731218893Sdim bool needsPadding = (AlignedNonVirtualTypeSize != AlignedNextFieldOffset); 732218893Sdim if (needsPadding) { 733218893Sdim CharUnits NumBytes = AlignedNonVirtualTypeSize - AlignedNextFieldOffset; 734218893Sdim FieldTypes.push_back(getByteArrayType(NumBytes)); 735218893Sdim } 736218893Sdim 737224145Sdim 738224145Sdim BaseSubobjectType = llvm::StructType::createNamed(Types.getLLVMContext(), "", 739224145Sdim FieldTypes, Packed); 740224145Sdim Types.addRecordTypeName(RD, BaseSubobjectType, ".base"); 741218893Sdim 742224145Sdim // Pull the padding back off. 743224145Sdim if (needsPadding) 744218893Sdim FieldTypes.pop_back(); 745218893Sdim 746218893Sdim return true; 747218893Sdim} 748218893Sdim 749198092Srdivackybool CGRecordLayoutBuilder::LayoutFields(const RecordDecl *D) { 750198092Srdivacky assert(!D->isUnion() && "Can't call LayoutFields on a union!"); 751218893Sdim assert(!Alignment.isZero() && "Did not set alignment!"); 752198092Srdivacky 753198092Srdivacky const ASTRecordLayout &Layout = Types.getContext().getASTRecordLayout(D); 754198092Srdivacky 755218893Sdim const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D); 756218893Sdim if (RD) 757208600Srdivacky LayoutNonVirtualBases(RD, Layout); 758206084Srdivacky 759198092Srdivacky unsigned FieldNo = 0; 760221345Sdim const FieldDecl *LastFD = 0; 761221345Sdim 762198092Srdivacky for (RecordDecl::field_iterator Field = D->field_begin(), 763198092Srdivacky FieldEnd = D->field_end(); Field != FieldEnd; ++Field, ++FieldNo) { 764221345Sdim if (IsMsStruct) { 765221345Sdim // Zero-length bitfields following non-bitfield members are 766221345Sdim // ignored: 767221345Sdim const FieldDecl *FD = (*Field); 768223017Sdim if (Types.getContext().ZeroBitfieldFollowsNonBitfield(FD, LastFD)) { 769221345Sdim --FieldNo; 770221345Sdim continue; 771221345Sdim } 772221345Sdim LastFD = FD; 773221345Sdim } 774221345Sdim 775198092Srdivacky if (!LayoutField(*Field, Layout.getFieldOffset(FieldNo))) { 776198092Srdivacky assert(!Packed && 777198092Srdivacky "Could not layout fields even with a packed LLVM struct!"); 778198092Srdivacky return false; 779198092Srdivacky } 780198092Srdivacky } 781198092Srdivacky 782218893Sdim if (RD) { 783218893Sdim // We've laid out the non-virtual bases and the fields, now compute the 784218893Sdim // non-virtual base field types. 785218893Sdim if (!ComputeNonVirtualBaseType(RD)) { 786218893Sdim assert(!Packed && "Could not layout even with a packed LLVM struct!"); 787218893Sdim return false; 788218893Sdim } 789218893Sdim 790218893Sdim // And lay out the virtual bases. 791218893Sdim RD->getIndirectPrimaryBases(IndirectPrimaryBases); 792218893Sdim if (Layout.isPrimaryBaseVirtual()) 793218893Sdim IndirectPrimaryBases.insert(Layout.getPrimaryBase()); 794218893Sdim LayoutVirtualBases(RD, Layout); 795218893Sdim } 796218893Sdim 797198092Srdivacky // Append tail padding if necessary. 798221345Sdim AppendTailPadding(Layout.getSize()); 799198092Srdivacky 800198092Srdivacky return true; 801198092Srdivacky} 802198092Srdivacky 803221345Sdimvoid CGRecordLayoutBuilder::AppendTailPadding(CharUnits RecordSize) { 804221345Sdim ResizeLastBaseFieldIfNecessary(RecordSize); 805198092Srdivacky 806221345Sdim assert(NextFieldOffset <= RecordSize && "Size mismatch!"); 807198092Srdivacky 808218893Sdim CharUnits AlignedNextFieldOffset = 809218893Sdim NextFieldOffset.RoundUpToAlignment(getAlignmentAsLLVMStruct()); 810200583Srdivacky 811221345Sdim if (AlignedNextFieldOffset == RecordSize) { 812200583Srdivacky // We don't need any padding. 813200583Srdivacky return; 814200583Srdivacky } 815206084Srdivacky 816221345Sdim CharUnits NumPadBytes = RecordSize - NextFieldOffset; 817198092Srdivacky AppendBytes(NumPadBytes); 818198092Srdivacky} 819198092Srdivacky 820218893Sdimvoid CGRecordLayoutBuilder::AppendField(CharUnits fieldOffset, 821224145Sdim llvm::Type *fieldType) { 822218893Sdim CharUnits fieldSize = 823218893Sdim CharUnits::fromQuantity(Types.getTargetData().getTypeAllocSize(fieldType)); 824198092Srdivacky 825218893Sdim FieldTypes.push_back(fieldType); 826198092Srdivacky 827218893Sdim NextFieldOffset = fieldOffset + fieldSize; 828198092Srdivacky BitsAvailableInLastField = 0; 829198092Srdivacky} 830198092Srdivacky 831218893Sdimvoid CGRecordLayoutBuilder::AppendPadding(CharUnits fieldOffset, 832218893Sdim CharUnits fieldAlignment) { 833218893Sdim assert(NextFieldOffset <= fieldOffset && 834198092Srdivacky "Incorrect field layout!"); 835198092Srdivacky 836198092Srdivacky // Round up the field offset to the alignment of the field type. 837218893Sdim CharUnits alignedNextFieldOffset = 838218893Sdim NextFieldOffset.RoundUpToAlignment(fieldAlignment); 839198092Srdivacky 840218893Sdim if (alignedNextFieldOffset < fieldOffset) { 841198092Srdivacky // Even with alignment, the field offset is not at the right place, 842198092Srdivacky // insert padding. 843218893Sdim CharUnits padding = fieldOffset - NextFieldOffset; 844198092Srdivacky 845218893Sdim AppendBytes(padding); 846198092Srdivacky } 847198092Srdivacky} 848198092Srdivacky 849221345Sdimbool CGRecordLayoutBuilder::ResizeLastBaseFieldIfNecessary(CharUnits offset) { 850221345Sdim // Check if we have a base to resize. 851221345Sdim if (!LastLaidOutBase.isValid()) 852221345Sdim return false; 853221345Sdim 854221345Sdim // This offset does not overlap with the tail padding. 855221345Sdim if (offset >= NextFieldOffset) 856221345Sdim return false; 857221345Sdim 858221345Sdim // Restore the field offset and append an i8 array instead. 859221345Sdim FieldTypes.pop_back(); 860221345Sdim NextFieldOffset = LastLaidOutBase.Offset; 861221345Sdim AppendBytes(LastLaidOutBase.NonVirtualSize); 862221345Sdim LastLaidOutBase.invalidate(); 863221345Sdim 864221345Sdim return true; 865221345Sdim} 866221345Sdim 867224145Sdimllvm::Type *CGRecordLayoutBuilder::getByteArrayType(CharUnits numBytes) { 868218893Sdim assert(!numBytes.isZero() && "Empty byte arrays aren't allowed."); 869198092Srdivacky 870224145Sdim llvm::Type *Ty = llvm::Type::getInt8Ty(Types.getLLVMContext()); 871218893Sdim if (numBytes > CharUnits::One()) 872218893Sdim Ty = llvm::ArrayType::get(Ty, numBytes.getQuantity()); 873198092Srdivacky 874218893Sdim return Ty; 875218893Sdim} 876218893Sdim 877218893Sdimvoid CGRecordLayoutBuilder::AppendBytes(CharUnits numBytes) { 878218893Sdim if (numBytes.isZero()) 879218893Sdim return; 880218893Sdim 881198092Srdivacky // Append the padding field 882218893Sdim AppendField(NextFieldOffset, getByteArrayType(numBytes)); 883198092Srdivacky} 884198092Srdivacky 885218893SdimCharUnits CGRecordLayoutBuilder::getTypeAlignment(const llvm::Type *Ty) const { 886198092Srdivacky if (Packed) 887218893Sdim return CharUnits::One(); 888198092Srdivacky 889218893Sdim return CharUnits::fromQuantity(Types.getTargetData().getABITypeAlignment(Ty)); 890198092Srdivacky} 891198092Srdivacky 892218893SdimCharUnits CGRecordLayoutBuilder::getAlignmentAsLLVMStruct() const { 893218893Sdim if (Packed) 894218893Sdim return CharUnits::One(); 895218893Sdim 896218893Sdim CharUnits maxAlignment = CharUnits::One(); 897218893Sdim for (size_t i = 0; i != FieldTypes.size(); ++i) 898218893Sdim maxAlignment = std::max(maxAlignment, getTypeAlignment(FieldTypes[i])); 899218893Sdim 900218893Sdim return maxAlignment; 901218893Sdim} 902218893Sdim 903218893Sdim/// Merge in whether a field of the given type is zero-initializable. 904212904Sdimvoid CGRecordLayoutBuilder::CheckZeroInitializable(QualType T) { 905198092Srdivacky // This record already contains a member pointer. 906218893Sdim if (!IsZeroInitializableAsBase) 907198092Srdivacky return; 908198092Srdivacky 909198092Srdivacky // Can only have member pointers if we're compiling C++. 910198092Srdivacky if (!Types.getContext().getLangOptions().CPlusPlus) 911198092Srdivacky return; 912198092Srdivacky 913218893Sdim const Type *elementType = T->getBaseElementTypeUnsafe(); 914198092Srdivacky 915218893Sdim if (const MemberPointerType *MPT = elementType->getAs<MemberPointerType>()) { 916212904Sdim if (!Types.getCXXABI().isZeroInitializable(MPT)) 917218893Sdim IsZeroInitializable = IsZeroInitializableAsBase = false; 918218893Sdim } else if (const RecordType *RT = elementType->getAs<RecordType>()) { 919203955Srdivacky const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl()); 920218893Sdim const CGRecordLayout &Layout = Types.getCGRecordLayout(RD); 921218893Sdim if (!Layout.isZeroInitializable()) 922218893Sdim IsZeroInitializable = IsZeroInitializableAsBase = false; 923208600Srdivacky } 924208600Srdivacky} 925206084Srdivacky 926224145SdimCGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D, 927224145Sdim llvm::StructType *Ty) { 928206084Srdivacky CGRecordLayoutBuilder Builder(*this); 929198092Srdivacky 930198092Srdivacky Builder.Layout(D); 931198092Srdivacky 932224145Sdim Ty->setBody(Builder.FieldTypes, Builder.Packed); 933198092Srdivacky 934218893Sdim // If we're in C++, compute the base subobject type. 935224145Sdim llvm::StructType *BaseTy = 0; 936218893Sdim if (isa<CXXRecordDecl>(D)) { 937218893Sdim BaseTy = Builder.BaseSubobjectType; 938218893Sdim if (!BaseTy) BaseTy = Ty; 939218893Sdim } 940218893Sdim 941206084Srdivacky CGRecordLayout *RL = 942218893Sdim new CGRecordLayout(Ty, BaseTy, Builder.IsZeroInitializable, 943218893Sdim Builder.IsZeroInitializableAsBase); 944206084Srdivacky 945218893Sdim RL->NonVirtualBases.swap(Builder.NonVirtualBases); 946218893Sdim RL->CompleteObjectVirtualBases.swap(Builder.VirtualBases); 947208600Srdivacky 948198092Srdivacky // Add all the field numbers. 949218893Sdim RL->FieldInfo.swap(Builder.Fields); 950198092Srdivacky 951198092Srdivacky // Add bitfield info. 952218893Sdim RL->BitFields.swap(Builder.BitFields); 953198092Srdivacky 954207619Srdivacky // Dump the layout, if requested. 955207619Srdivacky if (getContext().getLangOptions().DumpRecordLayouts) { 956207619Srdivacky llvm::errs() << "\n*** Dumping IRgen Record Layout\n"; 957207619Srdivacky llvm::errs() << "Record: "; 958207619Srdivacky D->dump(); 959207619Srdivacky llvm::errs() << "\nLayout: "; 960207619Srdivacky RL->dump(); 961207619Srdivacky } 962207619Srdivacky 963207619Srdivacky#ifndef NDEBUG 964207619Srdivacky // Verify that the computed LLVM struct size matches the AST layout size. 965218893Sdim const ASTRecordLayout &Layout = getContext().getASTRecordLayout(D); 966218893Sdim 967218893Sdim uint64_t TypeSizeInBits = getContext().toBits(Layout.getSize()); 968207619Srdivacky assert(TypeSizeInBits == getTargetData().getTypeAllocSizeInBits(Ty) && 969207619Srdivacky "Type size mismatch!"); 970207619Srdivacky 971218893Sdim if (BaseTy) { 972218893Sdim CharUnits NonVirtualSize = Layout.getNonVirtualSize(); 973218893Sdim CharUnits NonVirtualAlign = Layout.getNonVirtualAlign(); 974218893Sdim CharUnits AlignedNonVirtualTypeSize = 975218893Sdim NonVirtualSize.RoundUpToAlignment(NonVirtualAlign); 976218893Sdim 977218893Sdim uint64_t AlignedNonVirtualTypeSizeInBits = 978218893Sdim getContext().toBits(AlignedNonVirtualTypeSize); 979218893Sdim 980218893Sdim assert(AlignedNonVirtualTypeSizeInBits == 981218893Sdim getTargetData().getTypeAllocSizeInBits(BaseTy) && 982218893Sdim "Type size mismatch!"); 983218893Sdim } 984218893Sdim 985207619Srdivacky // Verify that the LLVM and AST field offsets agree. 986207619Srdivacky const llvm::StructType *ST = 987207619Srdivacky dyn_cast<llvm::StructType>(RL->getLLVMType()); 988207619Srdivacky const llvm::StructLayout *SL = getTargetData().getStructLayout(ST); 989207619Srdivacky 990207619Srdivacky const ASTRecordLayout &AST_RL = getContext().getASTRecordLayout(D); 991207619Srdivacky RecordDecl::field_iterator it = D->field_begin(); 992221345Sdim const FieldDecl *LastFD = 0; 993221345Sdim bool IsMsStruct = D->hasAttr<MsStructAttr>(); 994207619Srdivacky for (unsigned i = 0, e = AST_RL.getFieldCount(); i != e; ++i, ++it) { 995207619Srdivacky const FieldDecl *FD = *it; 996207619Srdivacky 997207619Srdivacky // For non-bit-fields, just check that the LLVM struct offset matches the 998207619Srdivacky // AST offset. 999207619Srdivacky if (!FD->isBitField()) { 1000207619Srdivacky unsigned FieldNo = RL->getLLVMFieldNo(FD); 1001207619Srdivacky assert(AST_RL.getFieldOffset(i) == SL->getElementOffsetInBits(FieldNo) && 1002207619Srdivacky "Invalid field offset!"); 1003221345Sdim LastFD = FD; 1004207619Srdivacky continue; 1005207619Srdivacky } 1006207619Srdivacky 1007221345Sdim if (IsMsStruct) { 1008221345Sdim // Zero-length bitfields following non-bitfield members are 1009221345Sdim // ignored: 1010223017Sdim if (getContext().ZeroBitfieldFollowsNonBitfield(FD, LastFD)) { 1011221345Sdim --i; 1012221345Sdim continue; 1013221345Sdim } 1014221345Sdim LastFD = FD; 1015221345Sdim } 1016221345Sdim 1017207619Srdivacky // Ignore unnamed bit-fields. 1018221345Sdim if (!FD->getDeclName()) { 1019221345Sdim LastFD = FD; 1020207619Srdivacky continue; 1021221345Sdim } 1022221345Sdim 1023207619Srdivacky const CGBitFieldInfo &Info = RL->getBitFieldInfo(FD); 1024207619Srdivacky for (unsigned i = 0, e = Info.getNumComponents(); i != e; ++i) { 1025207619Srdivacky const CGBitFieldInfo::AccessInfo &AI = Info.getComponent(i); 1026207619Srdivacky 1027207619Srdivacky // Verify that every component access is within the structure. 1028207619Srdivacky uint64_t FieldOffset = SL->getElementOffsetInBits(AI.FieldIndex); 1029219077Sdim uint64_t AccessBitOffset = FieldOffset + 1030221345Sdim getContext().toBits(AI.FieldByteOffset); 1031207619Srdivacky assert(AccessBitOffset + AI.AccessWidth <= TypeSizeInBits && 1032207619Srdivacky "Invalid bit-field access (out of range)!"); 1033207619Srdivacky } 1034207619Srdivacky } 1035207619Srdivacky#endif 1036207619Srdivacky 1037206084Srdivacky return RL; 1038198092Srdivacky} 1039207619Srdivacky 1040207619Srdivackyvoid CGRecordLayout::print(llvm::raw_ostream &OS) const { 1041207619Srdivacky OS << "<CGRecordLayout\n"; 1042218893Sdim OS << " LLVMType:" << *CompleteObjectType << "\n"; 1043218893Sdim if (BaseSubobjectType) 1044218893Sdim OS << " NonVirtualBaseLLVMType:" << *BaseSubobjectType << "\n"; 1045212904Sdim OS << " IsZeroInitializable:" << IsZeroInitializable << "\n"; 1046207619Srdivacky OS << " BitFields:[\n"; 1047207619Srdivacky 1048207619Srdivacky // Print bit-field infos in declaration order. 1049207619Srdivacky std::vector<std::pair<unsigned, const CGBitFieldInfo*> > BFIs; 1050207619Srdivacky for (llvm::DenseMap<const FieldDecl*, CGBitFieldInfo>::const_iterator 1051207619Srdivacky it = BitFields.begin(), ie = BitFields.end(); 1052207619Srdivacky it != ie; ++it) { 1053207619Srdivacky const RecordDecl *RD = it->first->getParent(); 1054207619Srdivacky unsigned Index = 0; 1055207619Srdivacky for (RecordDecl::field_iterator 1056207619Srdivacky it2 = RD->field_begin(); *it2 != it->first; ++it2) 1057207619Srdivacky ++Index; 1058207619Srdivacky BFIs.push_back(std::make_pair(Index, &it->second)); 1059207619Srdivacky } 1060207619Srdivacky llvm::array_pod_sort(BFIs.begin(), BFIs.end()); 1061207619Srdivacky for (unsigned i = 0, e = BFIs.size(); i != e; ++i) { 1062207619Srdivacky OS.indent(4); 1063207619Srdivacky BFIs[i].second->print(OS); 1064207619Srdivacky OS << "\n"; 1065207619Srdivacky } 1066207619Srdivacky 1067207619Srdivacky OS << "]>\n"; 1068207619Srdivacky} 1069207619Srdivacky 1070207619Srdivackyvoid CGRecordLayout::dump() const { 1071207619Srdivacky print(llvm::errs()); 1072207619Srdivacky} 1073207619Srdivacky 1074207619Srdivackyvoid CGBitFieldInfo::print(llvm::raw_ostream &OS) const { 1075207619Srdivacky OS << "<CGBitFieldInfo"; 1076207619Srdivacky OS << " Size:" << Size; 1077207619Srdivacky OS << " IsSigned:" << IsSigned << "\n"; 1078207619Srdivacky 1079207619Srdivacky OS.indent(4 + strlen("<CGBitFieldInfo")); 1080207619Srdivacky OS << " NumComponents:" << getNumComponents(); 1081207619Srdivacky OS << " Components: ["; 1082207619Srdivacky if (getNumComponents()) { 1083207619Srdivacky OS << "\n"; 1084207619Srdivacky for (unsigned i = 0, e = getNumComponents(); i != e; ++i) { 1085207619Srdivacky const AccessInfo &AI = getComponent(i); 1086207619Srdivacky OS.indent(8); 1087207619Srdivacky OS << "<AccessInfo" 1088207619Srdivacky << " FieldIndex:" << AI.FieldIndex 1089221345Sdim << " FieldByteOffset:" << AI.FieldByteOffset.getQuantity() 1090207619Srdivacky << " FieldBitStart:" << AI.FieldBitStart 1091207619Srdivacky << " AccessWidth:" << AI.AccessWidth << "\n"; 1092207619Srdivacky OS.indent(8 + strlen("<AccessInfo")); 1093221345Sdim OS << " AccessAlignment:" << AI.AccessAlignment.getQuantity() 1094207619Srdivacky << " TargetBitOffset:" << AI.TargetBitOffset 1095207619Srdivacky << " TargetBitWidth:" << AI.TargetBitWidth 1096207619Srdivacky << ">\n"; 1097207619Srdivacky } 1098207619Srdivacky OS.indent(4); 1099207619Srdivacky } 1100207619Srdivacky OS << "]>"; 1101207619Srdivacky} 1102207619Srdivacky 1103207619Srdivackyvoid CGBitFieldInfo::dump() const { 1104207619Srdivacky print(llvm::errs()); 1105207619Srdivacky} 1106