1206084Srdivacky//===--- CGRecordLayout.h - LLVM Record Layout Information ------*- C++ -*-===//
2206084Srdivacky//
3206084Srdivacky//                     The LLVM Compiler Infrastructure
4206084Srdivacky//
5206084Srdivacky// This file is distributed under the University of Illinois Open Source
6206084Srdivacky// License. See LICENSE.TXT for details.
7206084Srdivacky//
8206084Srdivacky//===----------------------------------------------------------------------===//
9206084Srdivacky
10206084Srdivacky#ifndef CLANG_CODEGEN_CGRECORDLAYOUT_H
11206084Srdivacky#define CLANG_CODEGEN_CGRECORDLAYOUT_H
12206084Srdivacky
13226633Sdim#include "clang/AST/CharUnits.h"
14226633Sdim#include "clang/AST/Decl.h"
15226633Sdim#include "clang/Basic/LLVM.h"
16206084Srdivacky#include "llvm/ADT/DenseMap.h"
17249423Sdim#include "llvm/IR/DerivedTypes.h"
18226633Sdim
19206084Srdivackynamespace llvm {
20218893Sdim  class StructType;
21206084Srdivacky}
22206084Srdivacky
23206084Srdivackynamespace clang {
24206084Srdivackynamespace CodeGen {
25206084Srdivacky
26249423Sdim/// \brief Structure with information about how a bitfield should be accessed.
27207619Srdivacky///
28249423Sdim/// Often we layout a sequence of bitfields as a contiguous sequence of bits.
29249423Sdim/// When the AST record layout does this, we represent it in the LLVM IR's type
30249423Sdim/// as either a sequence of i8 members or a byte array to reserve the number of
31249423Sdim/// bytes touched without forcing any particular alignment beyond the basic
32249423Sdim/// character alignment.
33249423Sdim///
34249423Sdim/// Then accessing a particular bitfield involves converting this byte array
35249423Sdim/// into a single integer of that size (i24 or i40 -- may not be power-of-two
36249423Sdim/// size), loading it, and shifting and masking to extract the particular
37249423Sdim/// subsequence of bits which make up that particular bitfield. This structure
38249423Sdim/// encodes the information used to construct the extraction code sequences.
39249423Sdim/// The CGRecordLayout also has a field index which encodes which byte-sequence
40249423Sdim/// this bitfield falls within. Let's assume the following C struct:
41249423Sdim///
42249423Sdim///   struct S {
43249423Sdim///     char a, b, c;
44249423Sdim///     unsigned bits : 3;
45249423Sdim///     unsigned more_bits : 4;
46249423Sdim///     unsigned still_more_bits : 7;
47249423Sdim///   };
48249423Sdim///
49249423Sdim/// This will end up as the following LLVM type. The first array is the
50249423Sdim/// bitfield, and the second is the padding out to a 4-byte alignmnet.
51249423Sdim///
52249423Sdim///   %t = type { i8, i8, i8, i8, i8, [3 x i8] }
53249423Sdim///
54249423Sdim/// When generating code to access more_bits, we'll generate something
55249423Sdim/// essentially like this:
56249423Sdim///
57249423Sdim///   define i32 @foo(%t* %base) {
58249423Sdim///     %0 = gep %t* %base, i32 0, i32 3
59249423Sdim///     %2 = load i8* %1
60249423Sdim///     %3 = lshr i8 %2, 3
61249423Sdim///     %4 = and i8 %3, 15
62249423Sdim///     %5 = zext i8 %4 to i32
63249423Sdim///     ret i32 %i
64249423Sdim///   }
65249423Sdim///
66249423Sdimstruct CGBitFieldInfo {
67249423Sdim  /// The offset within a contiguous run of bitfields that are represented as
68249423Sdim  /// a single "field" within the LLVM struct type. This offset is in bits.
69249423Sdim  unsigned Offset : 16;
70206275Srdivacky
71207619Srdivacky  /// The total size of the bit-field, in bits.
72249423Sdim  unsigned Size : 15;
73207619Srdivacky
74207619Srdivacky  /// Whether the bit-field is signed.
75249423Sdim  unsigned IsSigned : 1;
76207619Srdivacky
77249423Sdim  /// The storage size in bits which should be used when accessing this
78249423Sdim  /// bitfield.
79249423Sdim  unsigned StorageSize;
80207619Srdivacky
81249423Sdim  /// The alignment which should be used when accessing the bitfield.
82249423Sdim  unsigned StorageAlignment;
83207619Srdivacky
84249423Sdim  CGBitFieldInfo()
85249423Sdim      : Offset(), Size(), IsSigned(), StorageSize(), StorageAlignment() {}
86207619Srdivacky
87249423Sdim  CGBitFieldInfo(unsigned Offset, unsigned Size, bool IsSigned,
88249423Sdim                 unsigned StorageSize, unsigned StorageAlignment)
89249423Sdim      : Offset(Offset), Size(Size), IsSigned(IsSigned),
90249423Sdim        StorageSize(StorageSize), StorageAlignment(StorageAlignment) {}
91207619Srdivacky
92226633Sdim  void print(raw_ostream &OS) const;
93207619Srdivacky  void dump() const;
94212904Sdim
95212904Sdim  /// \brief Given a bit-field decl, build an appropriate helper object for
96212904Sdim  /// accessing that field (which is expected to have the given offset and
97212904Sdim  /// size).
98249423Sdim  static CGBitFieldInfo MakeInfo(class CodeGenTypes &Types,
99249423Sdim                                 const FieldDecl *FD,
100249423Sdim                                 uint64_t Offset, uint64_t Size,
101249423Sdim                                 uint64_t StorageSize,
102249423Sdim                                 uint64_t StorageAlignment);
103206275Srdivacky};
104206275Srdivacky
105206084Srdivacky/// CGRecordLayout - This class handles struct and union layout info while
106206084Srdivacky/// lowering AST types to LLVM types.
107206084Srdivacky///
108206084Srdivacky/// These layout objects are only created on demand as IR generation requires.
109206084Srdivackyclass CGRecordLayout {
110206084Srdivacky  friend class CodeGenTypes;
111206084Srdivacky
112243830Sdim  CGRecordLayout(const CGRecordLayout &) LLVM_DELETED_FUNCTION;
113243830Sdim  void operator=(const CGRecordLayout &) LLVM_DELETED_FUNCTION;
114206084Srdivacky
115206084Srdivackyprivate:
116218893Sdim  /// The LLVM type corresponding to this record layout; used when
117218893Sdim  /// laying it out as a complete object.
118224145Sdim  llvm::StructType *CompleteObjectType;
119206084Srdivacky
120218893Sdim  /// The LLVM type for the non-virtual part of this record layout;
121218893Sdim  /// used when laying it out as a base subobject.
122224145Sdim  llvm::StructType *BaseSubobjectType;
123218893Sdim
124206084Srdivacky  /// Map from (non-bit-field) struct field to the corresponding llvm struct
125206084Srdivacky  /// type field no. This info is populated by record builder.
126206084Srdivacky  llvm::DenseMap<const FieldDecl *, unsigned> FieldInfo;
127206084Srdivacky
128206084Srdivacky  /// Map from (bit-field) struct field to the corresponding llvm struct type
129206084Srdivacky  /// field no. This info is populated by record builder.
130206275Srdivacky  llvm::DenseMap<const FieldDecl *, CGBitFieldInfo> BitFields;
131206084Srdivacky
132208600Srdivacky  // FIXME: Maybe we could use a CXXBaseSpecifier as the key and use a single
133208600Srdivacky  // map for both virtual and non virtual bases.
134218893Sdim  llvm::DenseMap<const CXXRecordDecl *, unsigned> NonVirtualBases;
135208600Srdivacky
136218893Sdim  /// Map from virtual bases to their field index in the complete object.
137218893Sdim  llvm::DenseMap<const CXXRecordDecl *, unsigned> CompleteObjectVirtualBases;
138218893Sdim
139218893Sdim  /// False if any direct or indirect subobject of this class, when
140218893Sdim  /// considered as a complete object, requires a non-zero bitpattern
141218893Sdim  /// when zero-initialized.
142212904Sdim  bool IsZeroInitializable : 1;
143206084Srdivacky
144218893Sdim  /// False if any direct or indirect subobject of this class, when
145218893Sdim  /// considered as a base subobject, requires a non-zero bitpattern
146218893Sdim  /// when zero-initialized.
147218893Sdim  bool IsZeroInitializableAsBase : 1;
148218893Sdim
149206084Srdivackypublic:
150224145Sdim  CGRecordLayout(llvm::StructType *CompleteObjectType,
151224145Sdim                 llvm::StructType *BaseSubobjectType,
152218893Sdim                 bool IsZeroInitializable,
153218893Sdim                 bool IsZeroInitializableAsBase)
154218893Sdim    : CompleteObjectType(CompleteObjectType),
155218893Sdim      BaseSubobjectType(BaseSubobjectType),
156218893Sdim      IsZeroInitializable(IsZeroInitializable),
157218893Sdim      IsZeroInitializableAsBase(IsZeroInitializableAsBase) {}
158206084Srdivacky
159218893Sdim  /// \brief Return the "complete object" LLVM type associated with
160218893Sdim  /// this record.
161224145Sdim  llvm::StructType *getLLVMType() const {
162224145Sdim    return CompleteObjectType;
163206084Srdivacky  }
164206084Srdivacky
165218893Sdim  /// \brief Return the "base subobject" LLVM type associated with
166218893Sdim  /// this record.
167224145Sdim  llvm::StructType *getBaseSubobjectLLVMType() const {
168224145Sdim    return BaseSubobjectType;
169218893Sdim  }
170218893Sdim
171212904Sdim  /// \brief Check whether this struct can be C++ zero-initialized
172212904Sdim  /// with a zeroinitializer.
173212904Sdim  bool isZeroInitializable() const {
174212904Sdim    return IsZeroInitializable;
175206084Srdivacky  }
176206084Srdivacky
177218893Sdim  /// \brief Check whether this struct can be C++ zero-initialized
178218893Sdim  /// with a zeroinitializer when considered as a base subobject.
179218893Sdim  bool isZeroInitializableAsBase() const {
180218893Sdim    return IsZeroInitializableAsBase;
181218893Sdim  }
182218893Sdim
183207619Srdivacky  /// \brief Return llvm::StructType element number that corresponds to the
184207619Srdivacky  /// field FD.
185206084Srdivacky  unsigned getLLVMFieldNo(const FieldDecl *FD) const {
186206084Srdivacky    assert(FieldInfo.count(FD) && "Invalid field for record!");
187206084Srdivacky    return FieldInfo.lookup(FD);
188206084Srdivacky  }
189206084Srdivacky
190208600Srdivacky  unsigned getNonVirtualBaseLLVMFieldNo(const CXXRecordDecl *RD) const {
191218893Sdim    assert(NonVirtualBases.count(RD) && "Invalid non-virtual base!");
192218893Sdim    return NonVirtualBases.lookup(RD);
193208600Srdivacky  }
194208600Srdivacky
195218893Sdim  /// \brief Return the LLVM field index corresponding to the given
196218893Sdim  /// virtual base.  Only valid when operating on the complete object.
197218893Sdim  unsigned getVirtualBaseIndex(const CXXRecordDecl *base) const {
198218893Sdim    assert(CompleteObjectVirtualBases.count(base) && "Invalid virtual base!");
199218893Sdim    return CompleteObjectVirtualBases.lookup(base);
200218893Sdim  }
201218893Sdim
202207619Srdivacky  /// \brief Return the BitFieldInfo that corresponds to the field FD.
203206275Srdivacky  const CGBitFieldInfo &getBitFieldInfo(const FieldDecl *FD) const {
204206084Srdivacky    assert(FD->isBitField() && "Invalid call for non bit-field decl!");
205206275Srdivacky    llvm::DenseMap<const FieldDecl *, CGBitFieldInfo>::const_iterator
206206084Srdivacky      it = BitFields.find(FD);
207218893Sdim    assert(it != BitFields.end() && "Unable to find bitfield info");
208206084Srdivacky    return it->second;
209206084Srdivacky  }
210207619Srdivacky
211226633Sdim  void print(raw_ostream &OS) const;
212207619Srdivacky  void dump() const;
213206084Srdivacky};
214206084Srdivacky
215206084Srdivacky}  // end namespace CodeGen
216206084Srdivacky}  // end namespace clang
217206084Srdivacky
218206084Srdivacky#endif
219