CGRecordLayout.h revision 3d155e683a74d3783362ef1865be91544eb8a9fc
1//===--- CGRecordLayout.h - LLVM Record Layout Information ------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9
10#ifndef CLANG_CODEGEN_CGRECORDLAYOUT_H
11#define CLANG_CODEGEN_CGRECORDLAYOUT_H
12
13#include "llvm/ADT/DenseMap.h"
14#include "clang/AST/Decl.h"
15namespace llvm {
16  class raw_ostream;
17  class Type;
18}
19
20namespace clang {
21namespace CodeGen {
22
23/// \brief Helper object for describing how to generate the code for access to a
24/// bit-field.
25///
26/// This structure is intended to describe the "policy" of how the bit-field
27/// should be accessed, which may be target, language, or ABI dependent.
28class CGBitFieldInfo {
29public:
30  /// Descriptor for a single component of a bit-field access. The entire
31  /// bit-field is constituted of a bitwise OR of all of the individual
32  /// components.
33  ///
34  /// Each component describes an accessed value, which is how the component
35  /// should be transferred to/from memory, and a target placement, which is how
36  /// that component fits into the constituted bit-field. The pseudo-IR for a
37  /// load is:
38  ///
39  ///   %0 = gep %base, 0, FieldIndex
40  ///   %1 = gep (i8*) %0, FieldByteOffset
41  ///   %2 = (i(AccessWidth) *) %1
42  ///   %3 = load %2, align AccessAlignment
43  ///   %4 = shr %3, FieldBitStart
44  ///
45  /// and the composed bit-field is formed as the boolean OR of all accesses,
46  /// masked to TargetBitWidth bits and shifted to TargetBitOffset.
47  struct AccessInfo {
48    /// Offset of the field to load in the LLVM structure, if any.
49    unsigned FieldIndex;
50
51    /// Byte offset from the field address, if any. This should generally be
52    /// unused as the cleanest IR comes from having a well-constructed LLVM type
53    /// with proper GEP instructions, but sometimes its use is required, for
54    /// example if an access is intended to straddle an LLVM field boundary.
55    unsigned FieldByteOffset;
56
57    /// Bit offset in the accessed value to use. The width is implied by \see
58    /// TargetBitWidth.
59    unsigned FieldBitStart;
60
61    /// Bit width of the memory access to perform.
62    unsigned AccessWidth;
63
64    /// The alignment of the memory access, or 0 if the default alignment should
65    /// be used.
66    //
67    // FIXME: Remove use of 0 to encode default, instead have IRgen do the right
68    // thing when it generates the code, if avoiding align directives is
69    // desired.
70    unsigned AccessAlignment;
71
72    /// Offset for the target value.
73    unsigned TargetBitOffset;
74
75    /// Number of bits in the access that are destined for the bit-field.
76    unsigned TargetBitWidth;
77  };
78
79private:
80  /// The components to use to access the bit-field. We may need up to three
81  /// separate components to support up to i64 bit-field access (4 + 2 + 1 byte
82  /// accesses).
83  //
84  // FIXME: De-hardcode this, just allocate following the struct.
85  AccessInfo Components[3];
86
87  /// The total size of the bit-field, in bits.
88  unsigned Size;
89
90  /// The number of access components to use.
91  unsigned NumComponents;
92
93  /// Whether the bit-field is signed.
94  bool IsSigned : 1;
95
96public:
97  CGBitFieldInfo(unsigned Size, unsigned NumComponents, AccessInfo *_Components,
98                 bool IsSigned) : Size(Size), NumComponents(NumComponents),
99                                  IsSigned(IsSigned) {
100    assert(NumComponents <= 3 && "invalid number of components!");
101    for (unsigned i = 0; i != NumComponents; ++i)
102      Components[i] = _Components[i];
103
104    // Check some invariants.
105    unsigned AccessedSize = 0;
106    for (unsigned i = 0, e = getNumComponents(); i != e; ++i) {
107      const AccessInfo &AI = getComponent(i);
108      AccessedSize += AI.TargetBitWidth;
109
110      // We shouldn't try to load 0 bits.
111      assert(AI.TargetBitWidth > 0);
112
113      // We can't load more bits than we accessed.
114      assert(AI.FieldBitStart + AI.TargetBitWidth <= AI.AccessWidth);
115
116      // We shouldn't put any bits outside the result size.
117      assert(AI.TargetBitWidth + AI.TargetBitOffset <= Size);
118    }
119
120    // Check that the total number of target bits matches the total bit-field
121    // size.
122    assert(AccessedSize == Size && "Total size does not match accessed size!");
123  }
124
125public:
126  /// \brief Check whether this bit-field access is (i.e., should be sign
127  /// extended on loads).
128  bool isSigned() const { return IsSigned; }
129
130  /// \brief Get the size of the bit-field, in bits.
131  unsigned getSize() const { return Size; }
132
133  /// @name Component Access
134  /// @{
135
136  unsigned getNumComponents() const { return NumComponents; }
137
138  const AccessInfo &getComponent(unsigned Index) const {
139    assert(Index < getNumComponents() && "Invalid access!");
140    return Components[Index];
141  }
142
143  /// @}
144
145  void print(llvm::raw_ostream &OS) const;
146  void dump() const;
147
148  /// \brief Given a bit-field decl, build an appropriate helper object for
149  /// accessing that field (which is expected to have the given offset and
150  /// size).
151  static CGBitFieldInfo MakeInfo(class CodeGenTypes &Types, const FieldDecl *FD,
152                                 uint64_t FieldOffset, uint64_t FieldSize);
153
154  /// \brief Given a bit-field decl, build an appropriate helper object for
155  /// accessing that field (which is expected to have the given offset and
156  /// size). The field decl should be known to be contained within a type of at
157  /// least the given size and with the given alignment.
158  static CGBitFieldInfo MakeInfo(CodeGenTypes &Types, const FieldDecl *FD,
159                                 uint64_t FieldOffset, uint64_t FieldSize,
160                                 uint64_t ContainingTypeSizeInBits,
161                                 unsigned ContainingTypeAlign);
162};
163
164/// CGRecordLayout - This class handles struct and union layout info while
165/// lowering AST types to LLVM types.
166///
167/// These layout objects are only created on demand as IR generation requires.
168class CGRecordLayout {
169  friend class CodeGenTypes;
170
171  CGRecordLayout(const CGRecordLayout&); // DO NOT IMPLEMENT
172  void operator=(const CGRecordLayout&); // DO NOT IMPLEMENT
173
174private:
175  /// The LLVM type corresponding to this record layout.
176  const llvm::Type *LLVMType;
177
178  /// The LLVM type for the non-virtual part of this record layout, used for
179  /// laying out the record as a base.
180  const llvm::Type *BaseLLVMType;
181
182  /// Map from (non-bit-field) struct field to the corresponding llvm struct
183  /// type field no. This info is populated by record builder.
184  llvm::DenseMap<const FieldDecl *, unsigned> FieldInfo;
185
186  /// Map from (bit-field) struct field to the corresponding llvm struct type
187  /// field no. This info is populated by record builder.
188  llvm::DenseMap<const FieldDecl *, CGBitFieldInfo> BitFields;
189
190  // FIXME: Maybe we could use a CXXBaseSpecifier as the key and use a single
191  // map for both virtual and non virtual bases.
192  llvm::DenseMap<const CXXRecordDecl *, unsigned> NonVirtualBaseFields;
193
194  /// Whether one of the fields in this record layout is a pointer to data
195  /// member, or a struct that contains pointer to data member.
196  bool IsZeroInitializable : 1;
197
198public:
199  CGRecordLayout(const llvm::Type *LLVMType, const llvm::Type *BaseLLVMType,
200                 bool IsZeroInitializable)
201    : LLVMType(LLVMType), BaseLLVMType(BaseLLVMType),
202    IsZeroInitializable(IsZeroInitializable) {}
203
204  /// \brief Return the LLVM type associated with this record.
205  const llvm::Type *getLLVMType() const {
206    return LLVMType;
207  }
208
209  const llvm::Type *getBaseLLVMType() const {
210      return BaseLLVMType;
211  }
212
213  /// \brief Check whether this struct can be C++ zero-initialized
214  /// with a zeroinitializer.
215  bool isZeroInitializable() const {
216    return IsZeroInitializable;
217  }
218
219  /// \brief Return llvm::StructType element number that corresponds to the
220  /// field FD.
221  unsigned getLLVMFieldNo(const FieldDecl *FD) const {
222    assert(!FD->isBitField() && "Invalid call for bit-field decl!");
223    assert(FieldInfo.count(FD) && "Invalid field for record!");
224    return FieldInfo.lookup(FD);
225  }
226
227  unsigned getNonVirtualBaseLLVMFieldNo(const CXXRecordDecl *RD) const {
228    assert(NonVirtualBaseFields.count(RD) && "Invalid non-virtual base!");
229    return NonVirtualBaseFields.lookup(RD);
230  }
231
232  /// \brief Return the BitFieldInfo that corresponds to the field FD.
233  const CGBitFieldInfo &getBitFieldInfo(const FieldDecl *FD) const {
234    assert(FD->isBitField() && "Invalid call for non bit-field decl!");
235    llvm::DenseMap<const FieldDecl *, CGBitFieldInfo>::const_iterator
236      it = BitFields.find(FD);
237    assert(it != BitFields.end()  && "Unable to find bitfield info");
238    return it->second;
239  }
240
241  void print(llvm::raw_ostream &OS) const;
242  void dump() const;
243};
244
245}  // end namespace CodeGen
246}  // end namespace clang
247
248#endif
249