CGRecordLayout.h revision f56faa01936b9cf909623d7f06e3c2569ca4a78e
12924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar//===--- CGRecordLayout.h - LLVM Record Layout Information ------*- C++ -*-===//
22924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar//
32924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar//                     The LLVM Compiler Infrastructure
42924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar//
52924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar// This file is distributed under the University of Illinois Open Source
62924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar// License. See LICENSE.TXT for details.
72924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar//
82924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar//===----------------------------------------------------------------------===//
92924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar
102924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar#ifndef CLANG_CODEGEN_CGRECORDLAYOUT_H
112924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar#define CLANG_CODEGEN_CGRECORDLAYOUT_H
122924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar
1328ebde58dd94b5ed2a6d149251202ab2c602a4a6Ken Dyck#include "clang/AST/CharUnits.h"
14198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar#include "clang/AST/Decl.h"
15d47d3b0cfeb7e8564ff77f48130fe63282b6d127Chris Lattner#include "clang/Basic/LLVM.h"
16d47d3b0cfeb7e8564ff77f48130fe63282b6d127Chris Lattner#include "llvm/ADT/DenseMap.h"
17d47d3b0cfeb7e8564ff77f48130fe63282b6d127Chris Lattner#include "llvm/DerivedTypes.h"
18d47d3b0cfeb7e8564ff77f48130fe63282b6d127Chris Lattner
19270e203b50ed8791e61afd357596bcf050cf2bfdDaniel Dunbarnamespace llvm {
20ba2c2eec87d614b06e194b289627bbfe0642e4ceAnders Carlsson  class StructType;
21270e203b50ed8791e61afd357596bcf050cf2bfdDaniel Dunbar}
22270e203b50ed8791e61afd357596bcf050cf2bfdDaniel Dunbar
232924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbarnamespace clang {
242924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbarnamespace CodeGen {
252924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar
26ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar/// \brief Helper object for describing how to generate the code for access to a
2793c62967d4ac7620a8ed2c5f875daab9adb416f0Daniel Dunbar/// bit-field.
28ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar///
29ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar/// This structure is intended to describe the "policy" of how the bit-field
30ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar/// should be accessed, which may be target, language, or ABI dependent.
312eec0b2e3e931de6cefbb266a7652a0622fe95b2Daniel Dunbarclass CGBitFieldInfo {
322eec0b2e3e931de6cefbb266a7652a0622fe95b2Daniel Dunbarpublic:
33ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  /// Descriptor for a single component of a bit-field access. The entire
34ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  /// bit-field is constituted of a bitwise OR of all of the individual
35ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  /// components.
36ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  ///
37ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  /// Each component describes an accessed value, which is how the component
38ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  /// should be transferred to/from memory, and a target placement, which is how
39ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  /// that component fits into the constituted bit-field. The pseudo-IR for a
40ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  /// load is:
41ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  ///
42ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  ///   %0 = gep %base, 0, FieldIndex
43ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  ///   %1 = gep (i8*) %0, FieldByteOffset
44ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  ///   %2 = (i(AccessWidth) *) %1
45ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  ///   %3 = load %2, align AccessAlignment
46ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  ///   %4 = shr %3, FieldBitStart
47ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  ///
48ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  /// and the composed bit-field is formed as the boolean OR of all accesses,
49ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  /// masked to TargetBitWidth bits and shifted to TargetBitOffset.
50ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  struct AccessInfo {
51ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar    /// Offset of the field to load in the LLVM structure, if any.
52ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar    unsigned FieldIndex;
53ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar
54ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar    /// Byte offset from the field address, if any. This should generally be
55ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar    /// unused as the cleanest IR comes from having a well-constructed LLVM type
56ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar    /// with proper GEP instructions, but sometimes its use is required, for
57ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar    /// example if an access is intended to straddle an LLVM field boundary.
5828ebde58dd94b5ed2a6d149251202ab2c602a4a6Ken Dyck    CharUnits FieldByteOffset;
59ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar
60ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar    /// Bit offset in the accessed value to use. The width is implied by \see
61ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar    /// TargetBitWidth.
62ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar    unsigned FieldBitStart;
63ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar
64ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar    /// Bit width of the memory access to perform.
65ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar    unsigned AccessWidth;
66ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar
67f4bcfa1b1850711d5eb092f2b0639331ef9f09f1Eli Friedman    /// The alignment of the memory access, assuming the parent is aligned.
68b9e6b2c215d0a7930ad160b054bc86353da4a517Ken Dyck    CharUnits AccessAlignment;
69ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar
70ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar    /// Offset for the target value.
71ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar    unsigned TargetBitOffset;
72ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar
73ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar    /// Number of bits in the access that are destined for the bit-field.
74ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar    unsigned TargetBitWidth;
75ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  };
76ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar
77ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbarprivate:
78ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  /// The components to use to access the bit-field. We may need up to three
79ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  /// separate components to support up to i64 bit-field access (4 + 2 + 1 byte
80ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  /// accesses).
81ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  //
82ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  // FIXME: De-hardcode this, just allocate following the struct.
83ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  AccessInfo Components[3];
84ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar
857fb619500404129322af972aab66c369949a2a74Daniel Dunbar  /// The total size of the bit-field, in bits.
867fb619500404129322af972aab66c369949a2a74Daniel Dunbar  unsigned Size;
872eec0b2e3e931de6cefbb266a7652a0622fe95b2Daniel Dunbar
887fb619500404129322af972aab66c369949a2a74Daniel Dunbar  /// The number of access components to use.
897fb619500404129322af972aab66c369949a2a74Daniel Dunbar  unsigned NumComponents;
907f2896406c8f14bf123578610043a919ba1a1c8aDaniel Dunbar
917fb619500404129322af972aab66c369949a2a74Daniel Dunbar  /// Whether the bit-field is signed.
92efbf487da83883c2da81181cac6f040928aa4289Daniel Dunbar  bool IsSigned : 1;
9393c62967d4ac7620a8ed2c5f875daab9adb416f0Daniel Dunbar
94ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbarpublic:
952df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar  CGBitFieldInfo(unsigned Size, unsigned NumComponents, AccessInfo *_Components,
962df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar                 bool IsSigned) : Size(Size), NumComponents(NumComponents),
972df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar                                  IsSigned(IsSigned) {
982df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar    assert(NumComponents <= 3 && "invalid number of components!");
992df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar    for (unsigned i = 0; i != NumComponents; ++i)
1002df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar      Components[i] = _Components[i];
1012df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar
1022df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar    // Check some invariants.
1032df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar    unsigned AccessedSize = 0;
1042df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar    for (unsigned i = 0, e = getNumComponents(); i != e; ++i) {
1052df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar      const AccessInfo &AI = getComponent(i);
1062df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar      AccessedSize += AI.TargetBitWidth;
1072df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar
1082df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar      // We shouldn't try to load 0 bits.
1092df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar      assert(AI.TargetBitWidth > 0);
1102df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar
1112df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar      // We can't load more bits than we accessed.
1122df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar      assert(AI.FieldBitStart + AI.TargetBitWidth <= AI.AccessWidth);
1132df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar
1142df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar      // We shouldn't put any bits outside the result size.
1152df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar      assert(AI.TargetBitWidth + AI.TargetBitOffset <= Size);
1162df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar    }
1172df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar
1182df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar    // Check that the total number of target bits matches the total bit-field
1192df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar    // size.
1202df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar    assert(AccessedSize == Size && "Total size does not match accessed size!");
1212df2569679237b4979654a8663cd61aea67ab207Daniel Dunbar  }
1227fb619500404129322af972aab66c369949a2a74Daniel Dunbar
1237fb619500404129322af972aab66c369949a2a74Daniel Dunbarpublic:
124e792584917983edb9bbfd5751b1fa6a4136e566aDaniel Dunbar  /// \brief Check whether this bit-field access is (i.e., should be sign
125e792584917983edb9bbfd5751b1fa6a4136e566aDaniel Dunbar  /// extended on loads).
126ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  bool isSigned() const { return IsSigned; }
127ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar
128e792584917983edb9bbfd5751b1fa6a4136e566aDaniel Dunbar  /// \brief Get the size of the bit-field, in bits.
129e792584917983edb9bbfd5751b1fa6a4136e566aDaniel Dunbar  unsigned getSize() const { return Size; }
130e792584917983edb9bbfd5751b1fa6a4136e566aDaniel Dunbar
131e792584917983edb9bbfd5751b1fa6a4136e566aDaniel Dunbar  /// @name Component Access
132e792584917983edb9bbfd5751b1fa6a4136e566aDaniel Dunbar  /// @{
133e792584917983edb9bbfd5751b1fa6a4136e566aDaniel Dunbar
134ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  unsigned getNumComponents() const { return NumComponents; }
135ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar
136ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  const AccessInfo &getComponent(unsigned Index) const {
137ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar    assert(Index < getNumComponents() && "Invalid access!");
138ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar    return Components[Index];
139ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar  }
140ab970f90ce31a53fe7e6375a37536bf0832fd922Daniel Dunbar
141e792584917983edb9bbfd5751b1fa6a4136e566aDaniel Dunbar  /// @}
142e792584917983edb9bbfd5751b1fa6a4136e566aDaniel Dunbar
1438cc488fefb2fb04bc8d5398da29f0182f97934cfChris Lattner  void print(raw_ostream &OS) const;
14493c62967d4ac7620a8ed2c5f875daab9adb416f0Daniel Dunbar  void dump() const;
145e7a80bd66a80ce509de9b50f32cdd402914edd2eDaniel Dunbar
146e7a80bd66a80ce509de9b50f32cdd402914edd2eDaniel Dunbar  /// \brief Given a bit-field decl, build an appropriate helper object for
147e7a80bd66a80ce509de9b50f32cdd402914edd2eDaniel Dunbar  /// accessing that field (which is expected to have the given offset and
148e7a80bd66a80ce509de9b50f32cdd402914edd2eDaniel Dunbar  /// size).
149e7a80bd66a80ce509de9b50f32cdd402914edd2eDaniel Dunbar  static CGBitFieldInfo MakeInfo(class CodeGenTypes &Types, const FieldDecl *FD,
150e7a80bd66a80ce509de9b50f32cdd402914edd2eDaniel Dunbar                                 uint64_t FieldOffset, uint64_t FieldSize);
151e7a80bd66a80ce509de9b50f32cdd402914edd2eDaniel Dunbar
152e7a80bd66a80ce509de9b50f32cdd402914edd2eDaniel Dunbar  /// \brief Given a bit-field decl, build an appropriate helper object for
153e7a80bd66a80ce509de9b50f32cdd402914edd2eDaniel Dunbar  /// accessing that field (which is expected to have the given offset and
154e7a80bd66a80ce509de9b50f32cdd402914edd2eDaniel Dunbar  /// size). The field decl should be known to be contained within a type of at
155e7a80bd66a80ce509de9b50f32cdd402914edd2eDaniel Dunbar  /// least the given size and with the given alignment.
156e7a80bd66a80ce509de9b50f32cdd402914edd2eDaniel Dunbar  static CGBitFieldInfo MakeInfo(CodeGenTypes &Types, const FieldDecl *FD,
157e7a80bd66a80ce509de9b50f32cdd402914edd2eDaniel Dunbar                                 uint64_t FieldOffset, uint64_t FieldSize,
158e7a80bd66a80ce509de9b50f32cdd402914edd2eDaniel Dunbar                                 uint64_t ContainingTypeSizeInBits,
159e7a80bd66a80ce509de9b50f32cdd402914edd2eDaniel Dunbar                                 unsigned ContainingTypeAlign);
1602eec0b2e3e931de6cefbb266a7652a0622fe95b2Daniel Dunbar};
1612eec0b2e3e931de6cefbb266a7652a0622fe95b2Daniel Dunbar
1622924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar/// CGRecordLayout - This class handles struct and union layout info while
1632924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar/// lowering AST types to LLVM types.
164198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar///
165198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar/// These layout objects are only created on demand as IR generation requires.
1662924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbarclass CGRecordLayout {
167198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar  friend class CodeGenTypes;
168198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar
169f56faa01936b9cf909623d7f06e3c2569ca4a78eDmitri Gribenko  CGRecordLayout(const CGRecordLayout &) LLVM_DELETED_FUNCTION;
170f56faa01936b9cf909623d7f06e3c2569ca4a78eDmitri Gribenko  void operator=(const CGRecordLayout &) LLVM_DELETED_FUNCTION;
1712924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar
172198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbarprivate:
1739b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  /// The LLVM type corresponding to this record layout; used when
1749b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  /// laying it out as a complete object.
1759cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *CompleteObjectType;
1762924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar
1779b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  /// The LLVM type for the non-virtual part of this record layout;
1789b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  /// used when laying it out as a base subobject.
1799cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *BaseSubobjectType;
1803d155e683a74d3783362ef1865be91544eb8a9fcAnders Carlsson
181198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar  /// Map from (non-bit-field) struct field to the corresponding llvm struct
182198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar  /// type field no. This info is populated by record builder.
183198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar  llvm::DenseMap<const FieldDecl *, unsigned> FieldInfo;
184198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar
185198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar  /// Map from (bit-field) struct field to the corresponding llvm struct type
186198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar  /// field no. This info is populated by record builder.
1872eec0b2e3e931de6cefbb266a7652a0622fe95b2Daniel Dunbar  llvm::DenseMap<const FieldDecl *, CGBitFieldInfo> BitFields;
188198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar
189c6772ce9c80ff524c7c522b5f0b37de58786bd84Anders Carlsson  // FIXME: Maybe we could use a CXXBaseSpecifier as the key and use a single
190c6772ce9c80ff524c7c522b5f0b37de58786bd84Anders Carlsson  // map for both virtual and non virtual bases.
1919b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  llvm::DenseMap<const CXXRecordDecl *, unsigned> NonVirtualBases;
192c6772ce9c80ff524c7c522b5f0b37de58786bd84Anders Carlsson
1939b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  /// Map from virtual bases to their field index in the complete object.
1949b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  llvm::DenseMap<const CXXRecordDecl *, unsigned> CompleteObjectVirtualBases;
1959b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall
1969b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  /// False if any direct or indirect subobject of this class, when
1979b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  /// considered as a complete object, requires a non-zero bitpattern
1989b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  /// when zero-initialized.
199f16aa103d3afd42fbca2ab346f191bf745cec092John McCall  bool IsZeroInitializable : 1;
2002924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar
2019b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  /// False if any direct or indirect subobject of this class, when
2029b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  /// considered as a base subobject, requires a non-zero bitpattern
2039b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  /// when zero-initialized.
2049b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  bool IsZeroInitializableAsBase : 1;
2052924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar
2069b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCallpublic:
2079cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  CGRecordLayout(llvm::StructType *CompleteObjectType,
2089cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner                 llvm::StructType *BaseSubobjectType,
2099b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall                 bool IsZeroInitializable,
2109b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall                 bool IsZeroInitializableAsBase)
2119b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall    : CompleteObjectType(CompleteObjectType),
2129b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall      BaseSubobjectType(BaseSubobjectType),
2139b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall      IsZeroInitializable(IsZeroInitializable),
2149b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall      IsZeroInitializableAsBase(IsZeroInitializableAsBase) {}
2159b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall
2169b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  /// \brief Return the "complete object" LLVM type associated with
2179b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  /// this record.
2189cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *getLLVMType() const {
2199cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    return CompleteObjectType;
2202924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar  }
2212924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar
2229b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  /// \brief Return the "base subobject" LLVM type associated with
2239b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  /// this record.
2249cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner  llvm::StructType *getBaseSubobjectLLVMType() const {
2259cbe4f0ba01ec304e1e3d071c071f7bca33631c0Chris Lattner    return BaseSubobjectType;
2263d155e683a74d3783362ef1865be91544eb8a9fcAnders Carlsson  }
2273d155e683a74d3783362ef1865be91544eb8a9fcAnders Carlsson
228f16aa103d3afd42fbca2ab346f191bf745cec092John McCall  /// \brief Check whether this struct can be C++ zero-initialized
229f16aa103d3afd42fbca2ab346f191bf745cec092John McCall  /// with a zeroinitializer.
230f16aa103d3afd42fbca2ab346f191bf745cec092John McCall  bool isZeroInitializable() const {
231f16aa103d3afd42fbca2ab346f191bf745cec092John McCall    return IsZeroInitializable;
2322924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar  }
233198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar
2349b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  /// \brief Check whether this struct can be C++ zero-initialized
2359b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  /// with a zeroinitializer when considered as a base subobject.
2369b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  bool isZeroInitializableAsBase() const {
2379b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall    return IsZeroInitializableAsBase;
2389b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  }
2399b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall
24050810d355ab2cf3f11f4e6c478a1df7c1f9f233dDaniel Dunbar  /// \brief Return llvm::StructType element number that corresponds to the
24150810d355ab2cf3f11f4e6c478a1df7c1f9f233dDaniel Dunbar  /// field FD.
242198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar  unsigned getLLVMFieldNo(const FieldDecl *FD) const {
243198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar    assert(!FD->isBitField() && "Invalid call for bit-field decl!");
244198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar    assert(FieldInfo.count(FD) && "Invalid field for record!");
245198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar    return FieldInfo.lookup(FD);
246198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar  }
247198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar
248c6772ce9c80ff524c7c522b5f0b37de58786bd84Anders Carlsson  unsigned getNonVirtualBaseLLVMFieldNo(const CXXRecordDecl *RD) const {
2499b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall    assert(NonVirtualBases.count(RD) && "Invalid non-virtual base!");
2509b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall    return NonVirtualBases.lookup(RD);
2519b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  }
2529b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall
2539b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  /// \brief Return the LLVM field index corresponding to the given
2549b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  /// virtual base.  Only valid when operating on the complete object.
2559b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall  unsigned getVirtualBaseIndex(const CXXRecordDecl *base) const {
2569b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall    assert(CompleteObjectVirtualBases.count(base) && "Invalid virtual base!");
2579b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall    return CompleteObjectVirtualBases.lookup(base);
258c6772ce9c80ff524c7c522b5f0b37de58786bd84Anders Carlsson  }
259c6772ce9c80ff524c7c522b5f0b37de58786bd84Anders Carlsson
26050810d355ab2cf3f11f4e6c478a1df7c1f9f233dDaniel Dunbar  /// \brief Return the BitFieldInfo that corresponds to the field FD.
2612eec0b2e3e931de6cefbb266a7652a0622fe95b2Daniel Dunbar  const CGBitFieldInfo &getBitFieldInfo(const FieldDecl *FD) const {
262198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar    assert(FD->isBitField() && "Invalid call for non bit-field decl!");
2632eec0b2e3e931de6cefbb266a7652a0622fe95b2Daniel Dunbar    llvm::DenseMap<const FieldDecl *, CGBitFieldInfo>::const_iterator
264198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar      it = BitFields.find(FD);
2659b7da1c46d6d2849f9cb51328d7fcddf2c417672John McCall    assert(it != BitFields.end() && "Unable to find bitfield info");
266198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar    return it->second;
267198bcb44b6271c92fd856403f34b518828100aacDaniel Dunbar  }
26893c62967d4ac7620a8ed2c5f875daab9adb416f0Daniel Dunbar
2698cc488fefb2fb04bc8d5398da29f0182f97934cfChris Lattner  void print(raw_ostream &OS) const;
27093c62967d4ac7620a8ed2c5f875daab9adb416f0Daniel Dunbar  void dump() const;
2712924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar};
2722924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar
2732924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar}  // end namespace CodeGen
2742924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar}  // end namespace clang
2752924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar
2762924ade97ee4228fcf3518d89cd4bd1653236b48Daniel Dunbar#endif
277