CGRecordLayoutBuilder.cpp revision 219077
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"
21198092Srdivacky#include "CodeGenTypes.h"
22212904Sdim#include "CGCXXABI.h"
23207619Srdivacky#include "llvm/DerivedTypes.h"
24206084Srdivacky#include "llvm/Type.h"
25207619Srdivacky#include "llvm/Support/Debug.h"
26207619Srdivacky#include "llvm/Support/raw_ostream.h"
27198092Srdivacky#include "llvm/Target/TargetData.h"
28198092Srdivackyusing namespace clang;
29198092Srdivackyusing namespace CodeGen;
30198092Srdivacky
31218893Sdimnamespace {
32206084Srdivacky
33206084Srdivackyclass CGRecordLayoutBuilder {
34206084Srdivackypublic:
35206084Srdivacky  /// FieldTypes - Holds the LLVM types that the struct is created from.
36218893Sdim  ///
37206084Srdivacky  std::vector<const llvm::Type *> FieldTypes;
38206084Srdivacky
39218893Sdim  /// BaseSubobjectType - Holds the LLVM type for the non-virtual part
40218893Sdim  /// of the struct. For example, consider:
41218893Sdim  ///
42218893Sdim  /// struct A { int i; };
43218893Sdim  /// struct B { void *v; };
44218893Sdim  /// struct C : virtual A, B { };
45218893Sdim  ///
46218893Sdim  /// The LLVM type of C will be
47218893Sdim  /// %struct.C = type { i32 (...)**, %struct.A, i32, %struct.B }
48218893Sdim  ///
49218893Sdim  /// And the LLVM type of the non-virtual base struct will be
50218893Sdim  /// %struct.C.base = type { i32 (...)**, %struct.A, i32 }
51218893Sdim  ///
52218893Sdim  /// This only gets initialized if the base subobject type is
53218893Sdim  /// different from the complete-object type.
54218893Sdim  const llvm::StructType *BaseSubobjectType;
55206084Srdivacky
56218893Sdim  /// FieldInfo - Holds a field and its corresponding LLVM field number.
57218893Sdim  llvm::DenseMap<const FieldDecl *, unsigned> Fields;
58206084Srdivacky
59218893Sdim  /// BitFieldInfo - Holds location and size information about a bit field.
60218893Sdim  llvm::DenseMap<const FieldDecl *, CGBitFieldInfo> BitFields;
61218893Sdim
62218893Sdim  llvm::DenseMap<const CXXRecordDecl *, unsigned> NonVirtualBases;
63218893Sdim  llvm::DenseMap<const CXXRecordDecl *, unsigned> VirtualBases;
64218893Sdim
65218893Sdim  /// IndirectPrimaryBases - Virtual base classes, direct or indirect, that are
66218893Sdim  /// primary base classes for some other direct or indirect base class.
67218893Sdim  CXXIndirectPrimaryBaseSet IndirectPrimaryBases;
68218893Sdim
69218893Sdim  /// LaidOutVirtualBases - A set of all laid out virtual bases, used to avoid
70218893Sdim  /// avoid laying out virtual bases more than once.
71218893Sdim  llvm::SmallPtrSet<const CXXRecordDecl *, 4> LaidOutVirtualBases;
72208600Srdivacky
73212904Sdim  /// IsZeroInitializable - Whether this struct can be C++
74212904Sdim  /// zero-initialized with an LLVM zeroinitializer.
75212904Sdim  bool IsZeroInitializable;
76218893Sdim  bool IsZeroInitializableAsBase;
77206084Srdivacky
78206084Srdivacky  /// Packed - Whether the resulting LLVM struct will be packed or not.
79206084Srdivacky  bool Packed;
80206084Srdivacky
81206084Srdivackyprivate:
82206084Srdivacky  CodeGenTypes &Types;
83206084Srdivacky
84206084Srdivacky  /// Alignment - Contains the alignment of the RecordDecl.
85206084Srdivacky  //
86206084Srdivacky  // FIXME: This is not needed and should be removed.
87218893Sdim  CharUnits Alignment;
88206084Srdivacky
89206084Srdivacky  /// BitsAvailableInLastField - If a bit field spans only part of a LLVM field,
90206084Srdivacky  /// this will have the number of bits still available in the field.
91206084Srdivacky  char BitsAvailableInLastField;
92206084Srdivacky
93218893Sdim  /// NextFieldOffset - Holds the next field offset.
94218893Sdim  CharUnits NextFieldOffset;
95206084Srdivacky
96207619Srdivacky  /// LayoutUnionField - Will layout a field in an union and return the type
97207619Srdivacky  /// that the field will have.
98207619Srdivacky  const llvm::Type *LayoutUnionField(const FieldDecl *Field,
99207619Srdivacky                                     const ASTRecordLayout &Layout);
100207619Srdivacky
101206084Srdivacky  /// LayoutUnion - Will layout a union RecordDecl.
102206084Srdivacky  void LayoutUnion(const RecordDecl *D);
103206084Srdivacky
104206084Srdivacky  /// LayoutField - try to layout all fields in the record decl.
105206084Srdivacky  /// Returns false if the operation failed because the struct is not packed.
106206084Srdivacky  bool LayoutFields(const RecordDecl *D);
107206084Srdivacky
108218893Sdim  /// Layout a single base, virtual or non-virtual
109218893Sdim  void LayoutBase(const CXXRecordDecl *base,
110218893Sdim                  const CGRecordLayout &baseLayout,
111218893Sdim                  CharUnits baseOffset);
112218893Sdim
113218893Sdim  /// LayoutVirtualBase - layout a single virtual base.
114218893Sdim  void LayoutVirtualBase(const CXXRecordDecl *base,
115218893Sdim                         CharUnits baseOffset);
116218893Sdim
117218893Sdim  /// LayoutVirtualBases - layout the virtual bases of a record decl.
118218893Sdim  void LayoutVirtualBases(const CXXRecordDecl *RD,
119218893Sdim                          const ASTRecordLayout &Layout);
120218893Sdim
121208600Srdivacky  /// LayoutNonVirtualBase - layout a single non-virtual base.
122218893Sdim  void LayoutNonVirtualBase(const CXXRecordDecl *base,
123218893Sdim                            CharUnits baseOffset);
124208600Srdivacky
125218893Sdim  /// LayoutNonVirtualBases - layout the virtual bases of a record decl.
126208600Srdivacky  void LayoutNonVirtualBases(const CXXRecordDecl *RD,
127208600Srdivacky                             const ASTRecordLayout &Layout);
128206084Srdivacky
129218893Sdim  /// ComputeNonVirtualBaseType - Compute the non-virtual base field types.
130218893Sdim  bool ComputeNonVirtualBaseType(const CXXRecordDecl *RD);
131218893Sdim
132206084Srdivacky  /// LayoutField - layout a single field. Returns false if the operation failed
133206084Srdivacky  /// because the current struct is not packed.
134206084Srdivacky  bool LayoutField(const FieldDecl *D, uint64_t FieldOffset);
135206084Srdivacky
136206084Srdivacky  /// LayoutBitField - layout a single bit field.
137206084Srdivacky  void LayoutBitField(const FieldDecl *D, uint64_t FieldOffset);
138206084Srdivacky
139206084Srdivacky  /// AppendField - Appends a field with the given offset and type.
140218893Sdim  void AppendField(CharUnits fieldOffset, const llvm::Type *FieldTy);
141206084Srdivacky
142206084Srdivacky  /// AppendPadding - Appends enough padding bytes so that the total
143206084Srdivacky  /// struct size is a multiple of the field alignment.
144218893Sdim  void AppendPadding(CharUnits fieldOffset, CharUnits fieldAlignment);
145206084Srdivacky
146218893Sdim  /// getByteArrayType - Returns a byte array type with the given number of
147218893Sdim  /// elements.
148218893Sdim  const llvm::Type *getByteArrayType(CharUnits NumBytes);
149218893Sdim
150206084Srdivacky  /// AppendBytes - Append a given number of bytes to the record.
151218893Sdim  void AppendBytes(CharUnits numBytes);
152206084Srdivacky
153206084Srdivacky  /// AppendTailPadding - Append enough tail padding so that the type will have
154206084Srdivacky  /// the passed size.
155206084Srdivacky  void AppendTailPadding(uint64_t RecordSize);
156206084Srdivacky
157218893Sdim  CharUnits getTypeAlignment(const llvm::Type *Ty) const;
158206084Srdivacky
159218893Sdim  /// getAlignmentAsLLVMStruct - Returns the maximum alignment of all the
160218893Sdim  /// LLVM element types.
161218893Sdim  CharUnits getAlignmentAsLLVMStruct() const;
162218893Sdim
163212904Sdim  /// CheckZeroInitializable - Check if the given type contains a pointer
164206084Srdivacky  /// to data member.
165212904Sdim  void CheckZeroInitializable(QualType T);
166206084Srdivacky
167206084Srdivackypublic:
168206084Srdivacky  CGRecordLayoutBuilder(CodeGenTypes &Types)
169218893Sdim    : BaseSubobjectType(0),
170218893Sdim      IsZeroInitializable(true), IsZeroInitializableAsBase(true),
171218893Sdim      Packed(false), Types(Types), BitsAvailableInLastField(0) { }
172206084Srdivacky
173206084Srdivacky  /// Layout - Will layout a RecordDecl.
174206084Srdivacky  void Layout(const RecordDecl *D);
175206084Srdivacky};
176206084Srdivacky
177206084Srdivacky}
178206084Srdivacky
179198092Srdivackyvoid CGRecordLayoutBuilder::Layout(const RecordDecl *D) {
180218893Sdim  Alignment = Types.getContext().getASTRecordLayout(D).getAlignment();
181198092Srdivacky  Packed = D->hasAttr<PackedAttr>();
182198092Srdivacky
183198092Srdivacky  if (D->isUnion()) {
184198092Srdivacky    LayoutUnion(D);
185198092Srdivacky    return;
186198092Srdivacky  }
187198092Srdivacky
188198092Srdivacky  if (LayoutFields(D))
189198092Srdivacky    return;
190198092Srdivacky
191198092Srdivacky  // We weren't able to layout the struct. Try again with a packed struct
192198092Srdivacky  Packed = true;
193218893Sdim  NextFieldOffset = CharUnits::Zero();
194198092Srdivacky  FieldTypes.clear();
195218893Sdim  Fields.clear();
196218893Sdim  BitFields.clear();
197218893Sdim  NonVirtualBases.clear();
198218893Sdim  VirtualBases.clear();
199198092Srdivacky
200198092Srdivacky  LayoutFields(D);
201198092Srdivacky}
202198092Srdivacky
203212904SdimCGBitFieldInfo CGBitFieldInfo::MakeInfo(CodeGenTypes &Types,
204212904Sdim                               const FieldDecl *FD,
205212904Sdim                               uint64_t FieldOffset,
206212904Sdim                               uint64_t FieldSize,
207212904Sdim                               uint64_t ContainingTypeSizeInBits,
208212904Sdim                               unsigned ContainingTypeAlign) {
209207619Srdivacky  const llvm::Type *Ty = Types.ConvertTypeForMemRecursive(FD->getType());
210219077Sdim  CharUnits TypeSizeInBytes =
211219077Sdim    CharUnits::fromQuantity(Types.getTargetData().getTypeAllocSize(Ty));
212219077Sdim  uint64_t TypeSizeInBits = Types.getContext().toBits(TypeSizeInBytes);
213207619Srdivacky
214207619Srdivacky  bool IsSigned = FD->getType()->isSignedIntegerType();
215207619Srdivacky
216207619Srdivacky  if (FieldSize > TypeSizeInBits) {
217207619Srdivacky    // We have a wide bit-field. The extra bits are only used for padding, so
218207619Srdivacky    // if we have a bitfield of type T, with size N:
219207619Srdivacky    //
220207619Srdivacky    // T t : N;
221207619Srdivacky    //
222207619Srdivacky    // We can just assume that it's:
223207619Srdivacky    //
224207619Srdivacky    // T t : sizeof(T);
225207619Srdivacky    //
226207619Srdivacky    FieldSize = TypeSizeInBits;
227207619Srdivacky  }
228207619Srdivacky
229218893Sdim  // in big-endian machines the first fields are in higher bit positions,
230218893Sdim  // so revert the offset. The byte offsets are reversed(back) later.
231218893Sdim  if (Types.getTargetData().isBigEndian()) {
232218893Sdim    FieldOffset = ((ContainingTypeSizeInBits)-FieldOffset-FieldSize);
233218893Sdim  }
234218893Sdim
235207619Srdivacky  // Compute the access components. The policy we use is to start by attempting
236207619Srdivacky  // to access using the width of the bit-field type itself and to always access
237207619Srdivacky  // at aligned indices of that type. If such an access would fail because it
238207619Srdivacky  // extends past the bound of the type, then we reduce size to the next smaller
239207619Srdivacky  // power of two and retry. The current algorithm assumes pow2 sized types,
240207619Srdivacky  // although this is easy to fix.
241207619Srdivacky  //
242207619Srdivacky  assert(llvm::isPowerOf2_32(TypeSizeInBits) && "Unexpected type size!");
243207619Srdivacky  CGBitFieldInfo::AccessInfo Components[3];
244207619Srdivacky  unsigned NumComponents = 0;
245207619Srdivacky  unsigned AccessedTargetBits = 0;       // The tumber of target bits accessed.
246207619Srdivacky  unsigned AccessWidth = TypeSizeInBits; // The current access width to attempt.
247207619Srdivacky
248207619Srdivacky  // Round down from the field offset to find the first access position that is
249207619Srdivacky  // at an aligned offset of the initial access type.
250207619Srdivacky  uint64_t AccessStart = FieldOffset - (FieldOffset % AccessWidth);
251207619Srdivacky
252207619Srdivacky  // Adjust initial access size to fit within record.
253219077Sdim  while (AccessWidth > Types.getTarget().getCharWidth() &&
254207619Srdivacky         AccessStart + AccessWidth > ContainingTypeSizeInBits) {
255207619Srdivacky    AccessWidth >>= 1;
256207619Srdivacky    AccessStart = FieldOffset - (FieldOffset % AccessWidth);
257207619Srdivacky  }
258207619Srdivacky
259207619Srdivacky  while (AccessedTargetBits < FieldSize) {
260207619Srdivacky    // Check that we can access using a type of this size, without reading off
261207619Srdivacky    // the end of the structure. This can occur with packed structures and
262207619Srdivacky    // -fno-bitfield-type-align, for example.
263207619Srdivacky    if (AccessStart + AccessWidth > ContainingTypeSizeInBits) {
264207619Srdivacky      // If so, reduce access size to the next smaller power-of-two and retry.
265207619Srdivacky      AccessWidth >>= 1;
266219077Sdim      assert(AccessWidth >= Types.getTarget().getCharWidth()
267219077Sdim             && "Cannot access under byte size!");
268207619Srdivacky      continue;
269207619Srdivacky    }
270207619Srdivacky
271207619Srdivacky    // Otherwise, add an access component.
272207619Srdivacky
273207619Srdivacky    // First, compute the bits inside this access which are part of the
274207619Srdivacky    // target. We are reading bits [AccessStart, AccessStart + AccessWidth); the
275207619Srdivacky    // intersection with [FieldOffset, FieldOffset + FieldSize) gives the bits
276207619Srdivacky    // in the target that we are reading.
277207619Srdivacky    assert(FieldOffset < AccessStart + AccessWidth && "Invalid access start!");
278207619Srdivacky    assert(AccessStart < FieldOffset + FieldSize && "Invalid access start!");
279207619Srdivacky    uint64_t AccessBitsInFieldStart = std::max(AccessStart, FieldOffset);
280207619Srdivacky    uint64_t AccessBitsInFieldSize =
281207619Srdivacky      std::min(AccessWidth + AccessStart,
282207619Srdivacky               FieldOffset + FieldSize) - AccessBitsInFieldStart;
283207619Srdivacky
284207619Srdivacky    assert(NumComponents < 3 && "Unexpected number of components!");
285207619Srdivacky    CGBitFieldInfo::AccessInfo &AI = Components[NumComponents++];
286207619Srdivacky    AI.FieldIndex = 0;
287207619Srdivacky    // FIXME: We still follow the old access pattern of only using the field
288207619Srdivacky    // byte offset. We should switch this once we fix the struct layout to be
289207619Srdivacky    // pretty.
290218893Sdim
291218893Sdim    // on big-endian machines we reverted the bit offset because first fields are
292218893Sdim    // in higher bits. But this also reverts the bytes, so fix this here by reverting
293218893Sdim    // the byte offset on big-endian machines.
294218893Sdim    if (Types.getTargetData().isBigEndian()) {
295218893Sdim      AI.FieldByteOffset = (ContainingTypeSizeInBits - AccessStart - AccessWidth )/8;
296218893Sdim    } else {
297218893Sdim      AI.FieldByteOffset = AccessStart / 8;
298218893Sdim    }
299207619Srdivacky    AI.FieldBitStart = AccessBitsInFieldStart - AccessStart;
300207619Srdivacky    AI.AccessWidth = AccessWidth;
301207619Srdivacky    AI.AccessAlignment = llvm::MinAlign(ContainingTypeAlign, AccessStart) / 8;
302207619Srdivacky    AI.TargetBitOffset = AccessedTargetBits;
303207619Srdivacky    AI.TargetBitWidth = AccessBitsInFieldSize;
304207619Srdivacky
305207619Srdivacky    AccessStart += AccessWidth;
306207619Srdivacky    AccessedTargetBits += AI.TargetBitWidth;
307207619Srdivacky  }
308207619Srdivacky
309207619Srdivacky  assert(AccessedTargetBits == FieldSize && "Invalid bit-field access!");
310207619Srdivacky  return CGBitFieldInfo(FieldSize, NumComponents, Components, IsSigned);
311207619Srdivacky}
312207619Srdivacky
313212904SdimCGBitFieldInfo CGBitFieldInfo::MakeInfo(CodeGenTypes &Types,
314212904Sdim                                        const FieldDecl *FD,
315212904Sdim                                        uint64_t FieldOffset,
316212904Sdim                                        uint64_t FieldSize) {
317212904Sdim  const RecordDecl *RD = FD->getParent();
318212904Sdim  const ASTRecordLayout &RL = Types.getContext().getASTRecordLayout(RD);
319218893Sdim  uint64_t ContainingTypeSizeInBits = Types.getContext().toBits(RL.getSize());
320218893Sdim  unsigned ContainingTypeAlign = Types.getContext().toBits(RL.getAlignment());
321212904Sdim
322212904Sdim  return MakeInfo(Types, FD, FieldOffset, FieldSize, ContainingTypeSizeInBits,
323212904Sdim                  ContainingTypeAlign);
324212904Sdim}
325212904Sdim
326198092Srdivackyvoid CGRecordLayoutBuilder::LayoutBitField(const FieldDecl *D,
327218893Sdim                                           uint64_t fieldOffset) {
328218893Sdim  uint64_t fieldSize =
329198092Srdivacky    D->getBitWidth()->EvaluateAsInt(Types.getContext()).getZExtValue();
330198092Srdivacky
331218893Sdim  if (fieldSize == 0)
332198092Srdivacky    return;
333198092Srdivacky
334219077Sdim  uint64_t nextFieldOffsetInBits = Types.getContext().toBits(NextFieldOffset);
335218893Sdim  unsigned numBytesToAppend;
336198092Srdivacky
337218893Sdim  if (fieldOffset < nextFieldOffsetInBits) {
338198092Srdivacky    assert(BitsAvailableInLastField && "Bitfield size mismatch!");
339218893Sdim    assert(!NextFieldOffset.isZero() && "Must have laid out at least one byte");
340198092Srdivacky
341198092Srdivacky    // The bitfield begins in the previous bit-field.
342218893Sdim    numBytesToAppend =
343218893Sdim      llvm::RoundUpToAlignment(fieldSize - BitsAvailableInLastField, 8) / 8;
344198092Srdivacky  } else {
345218893Sdim    assert(fieldOffset % 8 == 0 && "Field offset not aligned correctly");
346198092Srdivacky
347198092Srdivacky    // Append padding if necessary.
348218893Sdim    AppendPadding(CharUnits::fromQuantity(fieldOffset / 8), CharUnits::One());
349198092Srdivacky
350218893Sdim    numBytesToAppend = llvm::RoundUpToAlignment(fieldSize, 8) / 8;
351198092Srdivacky
352218893Sdim    assert(numBytesToAppend && "No bytes to append!");
353198092Srdivacky  }
354198092Srdivacky
355207619Srdivacky  // Add the bit field info.
356218893Sdim  BitFields.insert(std::make_pair(D,
357218893Sdim                   CGBitFieldInfo::MakeInfo(Types, D, fieldOffset, fieldSize)));
358198092Srdivacky
359218893Sdim  AppendBytes(CharUnits::fromQuantity(numBytesToAppend));
360198092Srdivacky
361198092Srdivacky  BitsAvailableInLastField =
362218893Sdim    NextFieldOffset.getQuantity() * 8 - (fieldOffset + fieldSize);
363198092Srdivacky}
364198092Srdivacky
365198092Srdivackybool CGRecordLayoutBuilder::LayoutField(const FieldDecl *D,
366218893Sdim                                        uint64_t fieldOffset) {
367198092Srdivacky  // If the field is packed, then we need a packed struct.
368198092Srdivacky  if (!Packed && D->hasAttr<PackedAttr>())
369198092Srdivacky    return false;
370198092Srdivacky
371198092Srdivacky  if (D->isBitField()) {
372198092Srdivacky    // We must use packed structs for unnamed bit fields since they
373198092Srdivacky    // don't affect the struct alignment.
374198092Srdivacky    if (!Packed && !D->getDeclName())
375198092Srdivacky      return false;
376198092Srdivacky
377218893Sdim    LayoutBitField(D, fieldOffset);
378198092Srdivacky    return true;
379198092Srdivacky  }
380198092Srdivacky
381212904Sdim  CheckZeroInitializable(D->getType());
382206084Srdivacky
383219077Sdim  assert(fieldOffset % Types.getTarget().getCharWidth() == 0
384219077Sdim         && "field offset is not on a byte boundary!");
385219077Sdim  CharUnits fieldOffsetInBytes
386219077Sdim    = Types.getContext().toCharUnitsFromBits(fieldOffset);
387198092Srdivacky
388198092Srdivacky  const llvm::Type *Ty = Types.ConvertTypeForMemRecursive(D->getType());
389218893Sdim  CharUnits typeAlignment = getTypeAlignment(Ty);
390198092Srdivacky
391198092Srdivacky  // If the type alignment is larger then the struct alignment, we must use
392198092Srdivacky  // a packed struct.
393218893Sdim  if (typeAlignment > Alignment) {
394198092Srdivacky    assert(!Packed && "Alignment is wrong even with packed struct!");
395198092Srdivacky    return false;
396198092Srdivacky  }
397198092Srdivacky
398218893Sdim  if (!Packed) {
399218893Sdim    if (const RecordType *RT = D->getType()->getAs<RecordType>()) {
400218893Sdim      const RecordDecl *RD = cast<RecordDecl>(RT->getDecl());
401218893Sdim      if (const MaxFieldAlignmentAttr *MFAA =
402218893Sdim            RD->getAttr<MaxFieldAlignmentAttr>()) {
403219077Sdim        if (MFAA->getAlignment() != Types.getContext().toBits(typeAlignment))
404218893Sdim          return false;
405218893Sdim      }
406198092Srdivacky    }
407198092Srdivacky  }
408198092Srdivacky
409198092Srdivacky  // Round up the field offset to the alignment of the field type.
410218893Sdim  CharUnits alignedNextFieldOffsetInBytes =
411218893Sdim    NextFieldOffset.RoundUpToAlignment(typeAlignment);
412198092Srdivacky
413218893Sdim  if (fieldOffsetInBytes < alignedNextFieldOffsetInBytes) {
414198092Srdivacky    assert(!Packed && "Could not place field even with packed struct!");
415198092Srdivacky    return false;
416198092Srdivacky  }
417198092Srdivacky
418218893Sdim  AppendPadding(fieldOffsetInBytes, typeAlignment);
419198092Srdivacky
420198092Srdivacky  // Now append the field.
421218893Sdim  Fields[D] = FieldTypes.size();
422218893Sdim  AppendField(fieldOffsetInBytes, Ty);
423198092Srdivacky
424198092Srdivacky  return true;
425198092Srdivacky}
426198092Srdivacky
427207619Srdivackyconst llvm::Type *
428207619SrdivackyCGRecordLayoutBuilder::LayoutUnionField(const FieldDecl *Field,
429207619Srdivacky                                        const ASTRecordLayout &Layout) {
430207619Srdivacky  if (Field->isBitField()) {
431207619Srdivacky    uint64_t FieldSize =
432207619Srdivacky      Field->getBitWidth()->EvaluateAsInt(Types.getContext()).getZExtValue();
433207619Srdivacky
434207619Srdivacky    // Ignore zero sized bit fields.
435207619Srdivacky    if (FieldSize == 0)
436207619Srdivacky      return 0;
437207619Srdivacky
438207619Srdivacky    const llvm::Type *FieldTy = llvm::Type::getInt8Ty(Types.getLLVMContext());
439207619Srdivacky    unsigned NumBytesToAppend =
440207619Srdivacky      llvm::RoundUpToAlignment(FieldSize, 8) / 8;
441207619Srdivacky
442207619Srdivacky    if (NumBytesToAppend > 1)
443207619Srdivacky      FieldTy = llvm::ArrayType::get(FieldTy, NumBytesToAppend);
444207619Srdivacky
445207619Srdivacky    // Add the bit field info.
446218893Sdim    BitFields.insert(std::make_pair(Field,
447218893Sdim                         CGBitFieldInfo::MakeInfo(Types, Field, 0, FieldSize)));
448207619Srdivacky    return FieldTy;
449207619Srdivacky  }
450207619Srdivacky
451207619Srdivacky  // This is a regular union field.
452218893Sdim  Fields[Field] = 0;
453207619Srdivacky  return Types.ConvertTypeForMemRecursive(Field->getType());
454207619Srdivacky}
455207619Srdivacky
456198092Srdivackyvoid CGRecordLayoutBuilder::LayoutUnion(const RecordDecl *D) {
457198092Srdivacky  assert(D->isUnion() && "Can't call LayoutUnion on a non-union record!");
458198092Srdivacky
459218893Sdim  const ASTRecordLayout &layout = Types.getContext().getASTRecordLayout(D);
460198092Srdivacky
461218893Sdim  const llvm::Type *unionType = 0;
462218893Sdim  CharUnits unionSize = CharUnits::Zero();
463218893Sdim  CharUnits unionAlign = CharUnits::Zero();
464198092Srdivacky
465218893Sdim  bool hasOnlyZeroSizedBitFields = true;
466206084Srdivacky
467218893Sdim  unsigned fieldNo = 0;
468218893Sdim  for (RecordDecl::field_iterator field = D->field_begin(),
469218893Sdim       fieldEnd = D->field_end(); field != fieldEnd; ++field, ++fieldNo) {
470218893Sdim    assert(layout.getFieldOffset(fieldNo) == 0 &&
471198092Srdivacky          "Union field offset did not start at the beginning of record!");
472218893Sdim    const llvm::Type *fieldType = LayoutUnionField(*field, layout);
473198092Srdivacky
474218893Sdim    if (!fieldType)
475207619Srdivacky      continue;
476198092Srdivacky
477218893Sdim    hasOnlyZeroSizedBitFields = false;
478206084Srdivacky
479218893Sdim    CharUnits fieldAlign = CharUnits::fromQuantity(
480218893Sdim                          Types.getTargetData().getABITypeAlignment(fieldType));
481218893Sdim    CharUnits fieldSize = CharUnits::fromQuantity(
482218893Sdim                             Types.getTargetData().getTypeAllocSize(fieldType));
483198092Srdivacky
484218893Sdim    if (fieldAlign < unionAlign)
485198092Srdivacky      continue;
486198092Srdivacky
487218893Sdim    if (fieldAlign > unionAlign || fieldSize > unionSize) {
488218893Sdim      unionType = fieldType;
489218893Sdim      unionAlign = fieldAlign;
490218893Sdim      unionSize = fieldSize;
491198092Srdivacky    }
492198092Srdivacky  }
493198092Srdivacky
494198092Srdivacky  // Now add our field.
495218893Sdim  if (unionType) {
496218893Sdim    AppendField(CharUnits::Zero(), unionType);
497198092Srdivacky
498218893Sdim    if (getTypeAlignment(unionType) > layout.getAlignment()) {
499198092Srdivacky      // We need a packed struct.
500198092Srdivacky      Packed = true;
501218893Sdim      unionAlign = CharUnits::One();
502198092Srdivacky    }
503198092Srdivacky  }
504218893Sdim  if (unionAlign.isZero()) {
505218893Sdim    assert(hasOnlyZeroSizedBitFields &&
506203955Srdivacky           "0-align record did not have all zero-sized bit-fields!");
507218893Sdim    unionAlign = CharUnits::One();
508199482Srdivacky  }
509206084Srdivacky
510198092Srdivacky  // Append tail padding.
511218893Sdim  CharUnits recordSize = layout.getSize();
512218893Sdim  if (recordSize > unionSize)
513218893Sdim    AppendPadding(recordSize, unionAlign);
514198092Srdivacky}
515198092Srdivacky
516218893Sdimvoid CGRecordLayoutBuilder::LayoutBase(const CXXRecordDecl *base,
517218893Sdim                                       const CGRecordLayout &baseLayout,
518218893Sdim                                       CharUnits baseOffset) {
519218893Sdim  AppendPadding(baseOffset, CharUnits::One());
520208600Srdivacky
521218893Sdim  const ASTRecordLayout &baseASTLayout
522218893Sdim    = Types.getContext().getASTRecordLayout(base);
523208600Srdivacky
524218893Sdim  // Fields and bases can be laid out in the tail padding of previous
525218893Sdim  // bases.  If this happens, we need to allocate the base as an i8
526218893Sdim  // array; otherwise, we can use the subobject type.  However,
527218893Sdim  // actually doing that would require knowledge of what immediately
528218893Sdim  // follows this base in the layout, so instead we do a conservative
529218893Sdim  // approximation, which is to use the base subobject type if it
530218893Sdim  // has the same LLVM storage size as the nvsize.
531218893Sdim
532218893Sdim  // The nvsize, i.e. the unpadded size of the base class.
533218893Sdim  CharUnits nvsize = baseASTLayout.getNonVirtualSize();
534218893Sdim
535218893Sdim#if 0
536218893Sdim  const llvm::StructType *subobjectType = baseLayout.getBaseSubobjectLLVMType();
537218893Sdim  const llvm::StructLayout *baseLLVMLayout =
538218893Sdim    Types.getTargetData().getStructLayout(subobjectType);
539218893Sdim  CharUnits stsize = CharUnits::fromQuantity(baseLLVMLayout->getSizeInBytes());
540218893Sdim
541218893Sdim  if (nvsize == stsize)
542218893Sdim    AppendField(baseOffset, subobjectType);
543218893Sdim  else
544218893Sdim#endif
545218893Sdim    AppendBytes(nvsize);
546218893Sdim}
547218893Sdim
548218893Sdimvoid CGRecordLayoutBuilder::LayoutNonVirtualBase(const CXXRecordDecl *base,
549218893Sdim                                                 CharUnits baseOffset) {
550218893Sdim  // Ignore empty bases.
551218893Sdim  if (base->isEmpty()) return;
552218893Sdim
553218893Sdim  const CGRecordLayout &baseLayout = Types.getCGRecordLayout(base);
554218893Sdim  if (IsZeroInitializableAsBase) {
555218893Sdim    assert(IsZeroInitializable &&
556218893Sdim           "class zero-initializable as base but not as complete object");
557218893Sdim
558218893Sdim    IsZeroInitializable = IsZeroInitializableAsBase =
559218893Sdim      baseLayout.isZeroInitializableAsBase();
560208600Srdivacky  }
561208600Srdivacky
562218893Sdim  LayoutBase(base, baseLayout, baseOffset);
563218893Sdim  NonVirtualBases[base] = (FieldTypes.size() - 1);
564218893Sdim}
565208600Srdivacky
566218893Sdimvoid
567218893SdimCGRecordLayoutBuilder::LayoutVirtualBase(const CXXRecordDecl *base,
568218893Sdim                                         CharUnits baseOffset) {
569218893Sdim  // Ignore empty bases.
570218893Sdim  if (base->isEmpty()) return;
571208600Srdivacky
572218893Sdim  const CGRecordLayout &baseLayout = Types.getCGRecordLayout(base);
573218893Sdim  if (IsZeroInitializable)
574218893Sdim    IsZeroInitializable = baseLayout.isZeroInitializableAsBase();
575218893Sdim
576218893Sdim  LayoutBase(base, baseLayout, baseOffset);
577218893Sdim  VirtualBases[base] = (FieldTypes.size() - 1);
578208600Srdivacky}
579208600Srdivacky
580218893Sdim/// LayoutVirtualBases - layout the non-virtual bases of a record decl.
581208600Srdivackyvoid
582218893SdimCGRecordLayoutBuilder::LayoutVirtualBases(const CXXRecordDecl *RD,
583218893Sdim                                          const ASTRecordLayout &Layout) {
584218893Sdim  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
585218893Sdim       E = RD->bases_end(); I != E; ++I) {
586218893Sdim    const CXXRecordDecl *BaseDecl =
587218893Sdim      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
588218893Sdim
589218893Sdim    // We only want to lay out virtual bases that aren't indirect primary bases
590218893Sdim    // of some other base.
591218893Sdim    if (I->isVirtual() && !IndirectPrimaryBases.count(BaseDecl)) {
592218893Sdim      // Only lay out the base once.
593218893Sdim      if (!LaidOutVirtualBases.insert(BaseDecl))
594218893Sdim        continue;
595218893Sdim
596218893Sdim      CharUnits vbaseOffset = Layout.getVBaseClassOffset(BaseDecl);
597218893Sdim      LayoutVirtualBase(BaseDecl, vbaseOffset);
598218893Sdim    }
599218893Sdim
600218893Sdim    if (!BaseDecl->getNumVBases()) {
601218893Sdim      // This base isn't interesting since it doesn't have any virtual bases.
602218893Sdim      continue;
603218893Sdim    }
604218893Sdim
605218893Sdim    LayoutVirtualBases(BaseDecl, Layout);
606218893Sdim  }
607218893Sdim}
608218893Sdim
609218893Sdimvoid
610208600SrdivackyCGRecordLayoutBuilder::LayoutNonVirtualBases(const CXXRecordDecl *RD,
611208600Srdivacky                                             const ASTRecordLayout &Layout) {
612208600Srdivacky  const CXXRecordDecl *PrimaryBase = Layout.getPrimaryBase();
613208600Srdivacky
614201361Srdivacky  // Check if we need to add a vtable pointer.
615208600Srdivacky  if (RD->isDynamicClass()) {
616208600Srdivacky    if (!PrimaryBase) {
617208600Srdivacky      const llvm::Type *FunctionType =
618208600Srdivacky        llvm::FunctionType::get(llvm::Type::getInt32Ty(Types.getLLVMContext()),
619208600Srdivacky                                /*isVarArg=*/true);
620208600Srdivacky      const llvm::Type *VTableTy = FunctionType->getPointerTo();
621206084Srdivacky
622218893Sdim      assert(NextFieldOffset.isZero() &&
623208600Srdivacky             "VTable pointer must come first!");
624218893Sdim      AppendField(CharUnits::Zero(), VTableTy->getPointerTo());
625208600Srdivacky    } else {
626218893Sdim      if (!Layout.isPrimaryBaseVirtual())
627218893Sdim        LayoutNonVirtualBase(PrimaryBase, CharUnits::Zero());
628218893Sdim      else
629218893Sdim        LayoutVirtualBase(PrimaryBase, CharUnits::Zero());
630208600Srdivacky    }
631201361Srdivacky  }
632208600Srdivacky
633208600Srdivacky  // Layout the non-virtual bases.
634208600Srdivacky  for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
635208600Srdivacky       E = RD->bases_end(); I != E; ++I) {
636208600Srdivacky    if (I->isVirtual())
637208600Srdivacky      continue;
638208600Srdivacky
639208600Srdivacky    const CXXRecordDecl *BaseDecl =
640208600Srdivacky      cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
641208600Srdivacky
642208600Srdivacky    // We've already laid out the primary base.
643218893Sdim    if (BaseDecl == PrimaryBase && !Layout.isPrimaryBaseVirtual())
644208600Srdivacky      continue;
645208600Srdivacky
646208600Srdivacky    LayoutNonVirtualBase(BaseDecl, Layout.getBaseClassOffset(BaseDecl));
647208600Srdivacky  }
648201361Srdivacky}
649201361Srdivacky
650218893Sdimbool
651218893SdimCGRecordLayoutBuilder::ComputeNonVirtualBaseType(const CXXRecordDecl *RD) {
652218893Sdim  const ASTRecordLayout &Layout = Types.getContext().getASTRecordLayout(RD);
653218893Sdim
654218893Sdim  CharUnits NonVirtualSize  = Layout.getNonVirtualSize();
655218893Sdim  CharUnits NonVirtualAlign = Layout.getNonVirtualAlign();
656218893Sdim  CharUnits AlignedNonVirtualTypeSize =
657218893Sdim    NonVirtualSize.RoundUpToAlignment(NonVirtualAlign);
658218893Sdim
659218893Sdim  // First check if we can use the same fields as for the complete class.
660218893Sdim  CharUnits RecordSize = Layout.getSize();
661218893Sdim  if (AlignedNonVirtualTypeSize == RecordSize)
662218893Sdim    return true;
663218893Sdim
664218893Sdim  // Check if we need padding.
665218893Sdim  CharUnits AlignedNextFieldOffset =
666218893Sdim    NextFieldOffset.RoundUpToAlignment(getAlignmentAsLLVMStruct());
667218893Sdim
668218893Sdim  if (AlignedNextFieldOffset > AlignedNonVirtualTypeSize) {
669218893Sdim    assert(!Packed && "cannot layout even as packed struct");
670218893Sdim    return false; // Needs packing.
671218893Sdim  }
672218893Sdim
673218893Sdim  bool needsPadding = (AlignedNonVirtualTypeSize != AlignedNextFieldOffset);
674218893Sdim  if (needsPadding) {
675218893Sdim    CharUnits NumBytes = AlignedNonVirtualTypeSize - AlignedNextFieldOffset;
676218893Sdim    FieldTypes.push_back(getByteArrayType(NumBytes));
677218893Sdim  }
678218893Sdim
679218893Sdim  BaseSubobjectType = llvm::StructType::get(Types.getLLVMContext(),
680218893Sdim                                            FieldTypes, Packed);
681218893Sdim
682218893Sdim  if (needsPadding) {
683218893Sdim    // Pull the padding back off.
684218893Sdim    FieldTypes.pop_back();
685218893Sdim  }
686218893Sdim
687218893Sdim  return true;
688218893Sdim}
689218893Sdim
690198092Srdivackybool CGRecordLayoutBuilder::LayoutFields(const RecordDecl *D) {
691198092Srdivacky  assert(!D->isUnion() && "Can't call LayoutFields on a union!");
692218893Sdim  assert(!Alignment.isZero() && "Did not set alignment!");
693198092Srdivacky
694198092Srdivacky  const ASTRecordLayout &Layout = Types.getContext().getASTRecordLayout(D);
695198092Srdivacky
696218893Sdim  const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D);
697218893Sdim  if (RD)
698208600Srdivacky    LayoutNonVirtualBases(RD, Layout);
699206084Srdivacky
700198092Srdivacky  unsigned FieldNo = 0;
701198092Srdivacky
702198092Srdivacky  for (RecordDecl::field_iterator Field = D->field_begin(),
703198092Srdivacky       FieldEnd = D->field_end(); Field != FieldEnd; ++Field, ++FieldNo) {
704198092Srdivacky    if (!LayoutField(*Field, Layout.getFieldOffset(FieldNo))) {
705198092Srdivacky      assert(!Packed &&
706198092Srdivacky             "Could not layout fields even with a packed LLVM struct!");
707198092Srdivacky      return false;
708198092Srdivacky    }
709198092Srdivacky  }
710198092Srdivacky
711218893Sdim  if (RD) {
712218893Sdim    // We've laid out the non-virtual bases and the fields, now compute the
713218893Sdim    // non-virtual base field types.
714218893Sdim    if (!ComputeNonVirtualBaseType(RD)) {
715218893Sdim      assert(!Packed && "Could not layout even with a packed LLVM struct!");
716218893Sdim      return false;
717218893Sdim    }
718218893Sdim
719218893Sdim    // And lay out the virtual bases.
720218893Sdim    RD->getIndirectPrimaryBases(IndirectPrimaryBases);
721218893Sdim    if (Layout.isPrimaryBaseVirtual())
722218893Sdim      IndirectPrimaryBases.insert(Layout.getPrimaryBase());
723218893Sdim    LayoutVirtualBases(RD, Layout);
724218893Sdim  }
725218893Sdim
726198092Srdivacky  // Append tail padding if necessary.
727218893Sdim  AppendTailPadding(Types.getContext().toBits(Layout.getSize()));
728198092Srdivacky
729198092Srdivacky  return true;
730198092Srdivacky}
731198092Srdivacky
732198092Srdivackyvoid CGRecordLayoutBuilder::AppendTailPadding(uint64_t RecordSize) {
733198092Srdivacky  assert(RecordSize % 8 == 0 && "Invalid record size!");
734198092Srdivacky
735219077Sdim  CharUnits RecordSizeInBytes =
736219077Sdim    Types.getContext().toCharUnitsFromBits(RecordSize);
737218893Sdim  assert(NextFieldOffset <= RecordSizeInBytes && "Size mismatch!");
738198092Srdivacky
739218893Sdim  CharUnits AlignedNextFieldOffset =
740218893Sdim    NextFieldOffset.RoundUpToAlignment(getAlignmentAsLLVMStruct());
741200583Srdivacky
742200583Srdivacky  if (AlignedNextFieldOffset == RecordSizeInBytes) {
743200583Srdivacky    // We don't need any padding.
744200583Srdivacky    return;
745200583Srdivacky  }
746206084Srdivacky
747218893Sdim  CharUnits NumPadBytes = RecordSizeInBytes - NextFieldOffset;
748198092Srdivacky  AppendBytes(NumPadBytes);
749198092Srdivacky}
750198092Srdivacky
751218893Sdimvoid CGRecordLayoutBuilder::AppendField(CharUnits fieldOffset,
752218893Sdim                                        const llvm::Type *fieldType) {
753218893Sdim  CharUnits fieldSize =
754218893Sdim    CharUnits::fromQuantity(Types.getTargetData().getTypeAllocSize(fieldType));
755198092Srdivacky
756218893Sdim  FieldTypes.push_back(fieldType);
757198092Srdivacky
758218893Sdim  NextFieldOffset = fieldOffset + fieldSize;
759198092Srdivacky  BitsAvailableInLastField = 0;
760198092Srdivacky}
761198092Srdivacky
762218893Sdimvoid CGRecordLayoutBuilder::AppendPadding(CharUnits fieldOffset,
763218893Sdim                                          CharUnits fieldAlignment) {
764218893Sdim  assert(NextFieldOffset <= fieldOffset &&
765198092Srdivacky         "Incorrect field layout!");
766198092Srdivacky
767198092Srdivacky  // Round up the field offset to the alignment of the field type.
768218893Sdim  CharUnits alignedNextFieldOffset =
769218893Sdim    NextFieldOffset.RoundUpToAlignment(fieldAlignment);
770198092Srdivacky
771218893Sdim  if (alignedNextFieldOffset < fieldOffset) {
772198092Srdivacky    // Even with alignment, the field offset is not at the right place,
773198092Srdivacky    // insert padding.
774218893Sdim    CharUnits padding = fieldOffset - NextFieldOffset;
775198092Srdivacky
776218893Sdim    AppendBytes(padding);
777198092Srdivacky  }
778198092Srdivacky}
779198092Srdivacky
780218893Sdimconst llvm::Type *CGRecordLayoutBuilder::getByteArrayType(CharUnits numBytes) {
781218893Sdim  assert(!numBytes.isZero() && "Empty byte arrays aren't allowed.");
782198092Srdivacky
783198092Srdivacky  const llvm::Type *Ty = llvm::Type::getInt8Ty(Types.getLLVMContext());
784218893Sdim  if (numBytes > CharUnits::One())
785218893Sdim    Ty = llvm::ArrayType::get(Ty, numBytes.getQuantity());
786198092Srdivacky
787218893Sdim  return Ty;
788218893Sdim}
789218893Sdim
790218893Sdimvoid CGRecordLayoutBuilder::AppendBytes(CharUnits numBytes) {
791218893Sdim  if (numBytes.isZero())
792218893Sdim    return;
793218893Sdim
794198092Srdivacky  // Append the padding field
795218893Sdim  AppendField(NextFieldOffset, getByteArrayType(numBytes));
796198092Srdivacky}
797198092Srdivacky
798218893SdimCharUnits CGRecordLayoutBuilder::getTypeAlignment(const llvm::Type *Ty) const {
799198092Srdivacky  if (Packed)
800218893Sdim    return CharUnits::One();
801198092Srdivacky
802218893Sdim  return CharUnits::fromQuantity(Types.getTargetData().getABITypeAlignment(Ty));
803198092Srdivacky}
804198092Srdivacky
805218893SdimCharUnits CGRecordLayoutBuilder::getAlignmentAsLLVMStruct() const {
806218893Sdim  if (Packed)
807218893Sdim    return CharUnits::One();
808218893Sdim
809218893Sdim  CharUnits maxAlignment = CharUnits::One();
810218893Sdim  for (size_t i = 0; i != FieldTypes.size(); ++i)
811218893Sdim    maxAlignment = std::max(maxAlignment, getTypeAlignment(FieldTypes[i]));
812218893Sdim
813218893Sdim  return maxAlignment;
814218893Sdim}
815218893Sdim
816218893Sdim/// Merge in whether a field of the given type is zero-initializable.
817212904Sdimvoid CGRecordLayoutBuilder::CheckZeroInitializable(QualType T) {
818198092Srdivacky  // This record already contains a member pointer.
819218893Sdim  if (!IsZeroInitializableAsBase)
820198092Srdivacky    return;
821198092Srdivacky
822198092Srdivacky  // Can only have member pointers if we're compiling C++.
823198092Srdivacky  if (!Types.getContext().getLangOptions().CPlusPlus)
824198092Srdivacky    return;
825198092Srdivacky
826218893Sdim  const Type *elementType = T->getBaseElementTypeUnsafe();
827198092Srdivacky
828218893Sdim  if (const MemberPointerType *MPT = elementType->getAs<MemberPointerType>()) {
829212904Sdim    if (!Types.getCXXABI().isZeroInitializable(MPT))
830218893Sdim      IsZeroInitializable = IsZeroInitializableAsBase = false;
831218893Sdim  } else if (const RecordType *RT = elementType->getAs<RecordType>()) {
832203955Srdivacky    const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
833218893Sdim    const CGRecordLayout &Layout = Types.getCGRecordLayout(RD);
834218893Sdim    if (!Layout.isZeroInitializable())
835218893Sdim      IsZeroInitializable = IsZeroInitializableAsBase = false;
836208600Srdivacky  }
837208600Srdivacky}
838206084Srdivacky
839206084SrdivackyCGRecordLayout *CodeGenTypes::ComputeRecordLayout(const RecordDecl *D) {
840206084Srdivacky  CGRecordLayoutBuilder Builder(*this);
841198092Srdivacky
842198092Srdivacky  Builder.Layout(D);
843198092Srdivacky
844218893Sdim  const llvm::StructType *Ty = llvm::StructType::get(getLLVMContext(),
845218893Sdim                                                     Builder.FieldTypes,
846218893Sdim                                                     Builder.Packed);
847198092Srdivacky
848218893Sdim  // If we're in C++, compute the base subobject type.
849218893Sdim  const llvm::StructType *BaseTy = 0;
850218893Sdim  if (isa<CXXRecordDecl>(D)) {
851218893Sdim    BaseTy = Builder.BaseSubobjectType;
852218893Sdim    if (!BaseTy) BaseTy = Ty;
853218893Sdim  }
854218893Sdim
855206084Srdivacky  CGRecordLayout *RL =
856218893Sdim    new CGRecordLayout(Ty, BaseTy, Builder.IsZeroInitializable,
857218893Sdim                       Builder.IsZeroInitializableAsBase);
858206084Srdivacky
859218893Sdim  RL->NonVirtualBases.swap(Builder.NonVirtualBases);
860218893Sdim  RL->CompleteObjectVirtualBases.swap(Builder.VirtualBases);
861208600Srdivacky
862198092Srdivacky  // Add all the field numbers.
863218893Sdim  RL->FieldInfo.swap(Builder.Fields);
864198092Srdivacky
865198092Srdivacky  // Add bitfield info.
866218893Sdim  RL->BitFields.swap(Builder.BitFields);
867198092Srdivacky
868207619Srdivacky  // Dump the layout, if requested.
869207619Srdivacky  if (getContext().getLangOptions().DumpRecordLayouts) {
870207619Srdivacky    llvm::errs() << "\n*** Dumping IRgen Record Layout\n";
871207619Srdivacky    llvm::errs() << "Record: ";
872207619Srdivacky    D->dump();
873207619Srdivacky    llvm::errs() << "\nLayout: ";
874207619Srdivacky    RL->dump();
875207619Srdivacky  }
876207619Srdivacky
877207619Srdivacky#ifndef NDEBUG
878207619Srdivacky  // Verify that the computed LLVM struct size matches the AST layout size.
879218893Sdim  const ASTRecordLayout &Layout = getContext().getASTRecordLayout(D);
880218893Sdim
881218893Sdim  uint64_t TypeSizeInBits = getContext().toBits(Layout.getSize());
882207619Srdivacky  assert(TypeSizeInBits == getTargetData().getTypeAllocSizeInBits(Ty) &&
883207619Srdivacky         "Type size mismatch!");
884207619Srdivacky
885218893Sdim  if (BaseTy) {
886218893Sdim    CharUnits NonVirtualSize  = Layout.getNonVirtualSize();
887218893Sdim    CharUnits NonVirtualAlign = Layout.getNonVirtualAlign();
888218893Sdim    CharUnits AlignedNonVirtualTypeSize =
889218893Sdim      NonVirtualSize.RoundUpToAlignment(NonVirtualAlign);
890218893Sdim
891218893Sdim    uint64_t AlignedNonVirtualTypeSizeInBits =
892218893Sdim      getContext().toBits(AlignedNonVirtualTypeSize);
893218893Sdim
894218893Sdim    assert(AlignedNonVirtualTypeSizeInBits ==
895218893Sdim           getTargetData().getTypeAllocSizeInBits(BaseTy) &&
896218893Sdim           "Type size mismatch!");
897218893Sdim  }
898218893Sdim
899207619Srdivacky  // Verify that the LLVM and AST field offsets agree.
900207619Srdivacky  const llvm::StructType *ST =
901207619Srdivacky    dyn_cast<llvm::StructType>(RL->getLLVMType());
902207619Srdivacky  const llvm::StructLayout *SL = getTargetData().getStructLayout(ST);
903207619Srdivacky
904207619Srdivacky  const ASTRecordLayout &AST_RL = getContext().getASTRecordLayout(D);
905207619Srdivacky  RecordDecl::field_iterator it = D->field_begin();
906207619Srdivacky  for (unsigned i = 0, e = AST_RL.getFieldCount(); i != e; ++i, ++it) {
907207619Srdivacky    const FieldDecl *FD = *it;
908207619Srdivacky
909207619Srdivacky    // For non-bit-fields, just check that the LLVM struct offset matches the
910207619Srdivacky    // AST offset.
911207619Srdivacky    if (!FD->isBitField()) {
912207619Srdivacky      unsigned FieldNo = RL->getLLVMFieldNo(FD);
913207619Srdivacky      assert(AST_RL.getFieldOffset(i) == SL->getElementOffsetInBits(FieldNo) &&
914207619Srdivacky             "Invalid field offset!");
915207619Srdivacky      continue;
916207619Srdivacky    }
917207619Srdivacky
918207619Srdivacky    // Ignore unnamed bit-fields.
919207619Srdivacky    if (!FD->getDeclName())
920207619Srdivacky      continue;
921207619Srdivacky
922207619Srdivacky    const CGBitFieldInfo &Info = RL->getBitFieldInfo(FD);
923207619Srdivacky    for (unsigned i = 0, e = Info.getNumComponents(); i != e; ++i) {
924207619Srdivacky      const CGBitFieldInfo::AccessInfo &AI = Info.getComponent(i);
925207619Srdivacky
926207619Srdivacky      // Verify that every component access is within the structure.
927207619Srdivacky      uint64_t FieldOffset = SL->getElementOffsetInBits(AI.FieldIndex);
928219077Sdim      uint64_t AccessBitOffset = FieldOffset +
929219077Sdim        getContext().toBits(CharUnits::fromQuantity(AI.FieldByteOffset));
930207619Srdivacky      assert(AccessBitOffset + AI.AccessWidth <= TypeSizeInBits &&
931207619Srdivacky             "Invalid bit-field access (out of range)!");
932207619Srdivacky    }
933207619Srdivacky  }
934207619Srdivacky#endif
935207619Srdivacky
936206084Srdivacky  return RL;
937198092Srdivacky}
938207619Srdivacky
939207619Srdivackyvoid CGRecordLayout::print(llvm::raw_ostream &OS) const {
940207619Srdivacky  OS << "<CGRecordLayout\n";
941218893Sdim  OS << "  LLVMType:" << *CompleteObjectType << "\n";
942218893Sdim  if (BaseSubobjectType)
943218893Sdim    OS << "  NonVirtualBaseLLVMType:" << *BaseSubobjectType << "\n";
944212904Sdim  OS << "  IsZeroInitializable:" << IsZeroInitializable << "\n";
945207619Srdivacky  OS << "  BitFields:[\n";
946207619Srdivacky
947207619Srdivacky  // Print bit-field infos in declaration order.
948207619Srdivacky  std::vector<std::pair<unsigned, const CGBitFieldInfo*> > BFIs;
949207619Srdivacky  for (llvm::DenseMap<const FieldDecl*, CGBitFieldInfo>::const_iterator
950207619Srdivacky         it = BitFields.begin(), ie = BitFields.end();
951207619Srdivacky       it != ie; ++it) {
952207619Srdivacky    const RecordDecl *RD = it->first->getParent();
953207619Srdivacky    unsigned Index = 0;
954207619Srdivacky    for (RecordDecl::field_iterator
955207619Srdivacky           it2 = RD->field_begin(); *it2 != it->first; ++it2)
956207619Srdivacky      ++Index;
957207619Srdivacky    BFIs.push_back(std::make_pair(Index, &it->second));
958207619Srdivacky  }
959207619Srdivacky  llvm::array_pod_sort(BFIs.begin(), BFIs.end());
960207619Srdivacky  for (unsigned i = 0, e = BFIs.size(); i != e; ++i) {
961207619Srdivacky    OS.indent(4);
962207619Srdivacky    BFIs[i].second->print(OS);
963207619Srdivacky    OS << "\n";
964207619Srdivacky  }
965207619Srdivacky
966207619Srdivacky  OS << "]>\n";
967207619Srdivacky}
968207619Srdivacky
969207619Srdivackyvoid CGRecordLayout::dump() const {
970207619Srdivacky  print(llvm::errs());
971207619Srdivacky}
972207619Srdivacky
973207619Srdivackyvoid CGBitFieldInfo::print(llvm::raw_ostream &OS) const {
974207619Srdivacky  OS << "<CGBitFieldInfo";
975207619Srdivacky  OS << " Size:" << Size;
976207619Srdivacky  OS << " IsSigned:" << IsSigned << "\n";
977207619Srdivacky
978207619Srdivacky  OS.indent(4 + strlen("<CGBitFieldInfo"));
979207619Srdivacky  OS << " NumComponents:" << getNumComponents();
980207619Srdivacky  OS << " Components: [";
981207619Srdivacky  if (getNumComponents()) {
982207619Srdivacky    OS << "\n";
983207619Srdivacky    for (unsigned i = 0, e = getNumComponents(); i != e; ++i) {
984207619Srdivacky      const AccessInfo &AI = getComponent(i);
985207619Srdivacky      OS.indent(8);
986207619Srdivacky      OS << "<AccessInfo"
987207619Srdivacky         << " FieldIndex:" << AI.FieldIndex
988207619Srdivacky         << " FieldByteOffset:" << AI.FieldByteOffset
989207619Srdivacky         << " FieldBitStart:" << AI.FieldBitStart
990207619Srdivacky         << " AccessWidth:" << AI.AccessWidth << "\n";
991207619Srdivacky      OS.indent(8 + strlen("<AccessInfo"));
992207619Srdivacky      OS << " AccessAlignment:" << AI.AccessAlignment
993207619Srdivacky         << " TargetBitOffset:" << AI.TargetBitOffset
994207619Srdivacky         << " TargetBitWidth:" << AI.TargetBitWidth
995207619Srdivacky         << ">\n";
996207619Srdivacky    }
997207619Srdivacky    OS.indent(4);
998207619Srdivacky  }
999207619Srdivacky  OS << "]>";
1000207619Srdivacky}
1001207619Srdivacky
1002207619Srdivackyvoid CGBitFieldInfo::dump() const {
1003207619Srdivacky  print(llvm::errs());
1004207619Srdivacky}
1005