1//===--- CGRecordLayout.h - LLVM Record Layout Information ------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_CLANG_LIB_CODEGEN_CGRECORDLAYOUT_H
10#define LLVM_CLANG_LIB_CODEGEN_CGRECORDLAYOUT_H
11
12#include "clang/AST/CharUnits.h"
13#include "clang/AST/DeclCXX.h"
14#include "clang/Basic/LLVM.h"
15#include "llvm/ADT/DenseMap.h"
16#include "llvm/IR/DerivedTypes.h"
17
18namespace llvm {
19 class StructType;
20}
21
22namespace clang {
23namespace CodeGen {
24
25/// Structure with information about how a bitfield should be accessed.
26///
27/// Often we layout a sequence of bitfields as a contiguous sequence of bits.
28/// When the AST record layout does this, we represent it in the LLVM IR's type
29/// as either a sequence of i8 members or a byte array to reserve the number of
30/// bytes touched without forcing any particular alignment beyond the basic
31/// character alignment.
32///
33/// Then accessing a particular bitfield involves converting this byte array
34/// into a single integer of that size (i24 or i40 -- may not be power-of-two
35/// size), loading it, and shifting and masking to extract the particular
36/// subsequence of bits which make up that particular bitfield. This structure
37/// encodes the information used to construct the extraction code sequences.
38/// The CGRecordLayout also has a field index which encodes which byte-sequence
39/// this bitfield falls within. Let's assume the following C struct:
40///
41/// struct S {
42/// char a, b, c;
43/// unsigned bits : 3;
44/// unsigned more_bits : 4;
45/// unsigned still_more_bits : 7;
46/// };
47///
48/// This will end up as the following LLVM type. The first array is the
49/// bitfield, and the second is the padding out to a 4-byte alignment.
50///
51/// %t = type { i8, i8, i8, i8, i8, [3 x i8] }
52///
53/// When generating code to access more_bits, we'll generate something
54/// essentially like this:
55///
56/// define i32 @foo(%t* %base) {
57/// %0 = gep %t* %base, i32 0, i32 3
58/// %2 = load i8* %1
59/// %3 = lshr i8 %2, 3
60/// %4 = and i8 %3, 15
61/// %5 = zext i8 %4 to i32
62/// ret i32 %i
63/// }
64///
65struct CGBitFieldInfo {
66 /// The offset within a contiguous run of bitfields that are represented as
67 /// a single "field" within the LLVM struct type. This offset is in bits.
68 unsigned Offset : 16;
69
70 /// The total size of the bit-field, in bits.
71 unsigned Size : 15;
72
73 /// Whether the bit-field is signed.
74 LLVM_PREFERRED_TYPE(bool)
75 unsigned IsSigned : 1;
76
77 /// The storage size in bits which should be used when accessing this
78 /// bitfield.
79 unsigned StorageSize;
80
81 /// The offset of the bitfield storage from the start of the struct.
82 CharUnits StorageOffset;
83
84 /// The offset within a contiguous run of bitfields that are represented as a
85 /// single "field" within the LLVM struct type, taking into account the AAPCS
86 /// rules for volatile bitfields. This offset is in bits.
87 unsigned VolatileOffset : 16;
88
89 /// The storage size in bits which should be used when accessing this
90 /// bitfield.
91 unsigned VolatileStorageSize;
92
93 /// The offset of the bitfield storage from the start of the struct.
94 CharUnits VolatileStorageOffset;
95
96 CGBitFieldInfo()
97 : Offset(), Size(), IsSigned(), StorageSize(), VolatileOffset(),
98 VolatileStorageSize() {}
99
100 CGBitFieldInfo(unsigned Offset, unsigned Size, bool IsSigned,
101 unsigned StorageSize, CharUnits StorageOffset)
102 : Offset(Offset), Size(Size), IsSigned(IsSigned),
103 StorageSize(StorageSize), StorageOffset(StorageOffset) {}
104
105 void print(raw_ostream &OS) const;
106 void dump() const;
107
108 /// Given a bit-field decl, build an appropriate helper object for
109 /// accessing that field (which is expected to have the given offset and
110 /// size).
111 static CGBitFieldInfo MakeInfo(class CodeGenTypes &Types,
112 const FieldDecl *FD,
113 uint64_t Offset, uint64_t Size,
114 uint64_t StorageSize,
115 CharUnits StorageOffset);
116};
117
118/// CGRecordLayout - This class handles struct and union layout info while
119/// lowering AST types to LLVM types.
120///
121/// These layout objects are only created on demand as IR generation requires.
122class CGRecordLayout {
123 friend class CodeGenTypes;
124
125 CGRecordLayout(const CGRecordLayout &) = delete;
126 void operator=(const CGRecordLayout &) = delete;
127
128private:
129 /// The LLVM type corresponding to this record layout; used when
130 /// laying it out as a complete object.
131 llvm::StructType *CompleteObjectType;
132
133 /// The LLVM type for the non-virtual part of this record layout;
134 /// used when laying it out as a base subobject.
135 llvm::StructType *BaseSubobjectType;
136
137 /// Map from (non-bit-field) struct field to the corresponding llvm struct
138 /// type field no. This info is populated by record builder.
139 llvm::DenseMap<const FieldDecl *, unsigned> FieldInfo;
140
141 /// Map from (bit-field) struct field to the corresponding llvm struct type
142 /// field no. This info is populated by record builder.
143 llvm::DenseMap<const FieldDecl *, CGBitFieldInfo> BitFields;
144
145 // FIXME: Maybe we could use a CXXBaseSpecifier as the key and use a single
146 // map for both virtual and non-virtual bases.
147 llvm::DenseMap<const CXXRecordDecl *, unsigned> NonVirtualBases;
148
149 /// Map from virtual bases to their field index in the complete object.
150 llvm::DenseMap<const CXXRecordDecl *, unsigned> CompleteObjectVirtualBases;
151
152 /// False if any direct or indirect subobject of this class, when
153 /// considered as a complete object, requires a non-zero bitpattern
154 /// when zero-initialized.
155 bool IsZeroInitializable : 1;
156
157 /// False if any direct or indirect subobject of this class, when
158 /// considered as a base subobject, requires a non-zero bitpattern
159 /// when zero-initialized.
160 bool IsZeroInitializableAsBase : 1;
161
162public:
163 CGRecordLayout(llvm::StructType *CompleteObjectType,
164 llvm::StructType *BaseSubobjectType,
165 bool IsZeroInitializable,
166 bool IsZeroInitializableAsBase)
167 : CompleteObjectType(CompleteObjectType),
168 BaseSubobjectType(BaseSubobjectType),
169 IsZeroInitializable(IsZeroInitializable),
170 IsZeroInitializableAsBase(IsZeroInitializableAsBase) {}
171
172 /// Return the "complete object" LLVM type associated with
173 /// this record.
174 llvm::StructType *getLLVMType() const {
175 return CompleteObjectType;
176 }
177
178 /// Return the "base subobject" LLVM type associated with
179 /// this record.
180 llvm::StructType *getBaseSubobjectLLVMType() const {
181 return BaseSubobjectType;
182 }
183
184 /// Check whether this struct can be C++ zero-initialized
185 /// with a zeroinitializer.
186 bool isZeroInitializable() const {
187 return IsZeroInitializable;
188 }
189
190 /// Check whether this struct can be C++ zero-initialized
191 /// with a zeroinitializer when considered as a base subobject.
192 bool isZeroInitializableAsBase() const {
193 return IsZeroInitializableAsBase;
194 }
195
196 /// Return llvm::StructType element number that corresponds to the
197 /// field FD.
198 unsigned getLLVMFieldNo(const FieldDecl *FD) const {
199 FD = FD->getCanonicalDecl();
200 assert(FieldInfo.count(FD) && "Invalid field for record!");
201 return FieldInfo.lookup(Val: FD);
202 }
203
204 // Return whether the following non virtual base has a corresponding
205 // entry in the LLVM struct.
206 bool hasNonVirtualBaseLLVMField(const CXXRecordDecl *RD) const {
207 return NonVirtualBases.count(Val: RD);
208 }
209
210 unsigned getNonVirtualBaseLLVMFieldNo(const CXXRecordDecl *RD) const {
211 assert(NonVirtualBases.count(RD) && "Invalid non-virtual base!");
212 return NonVirtualBases.lookup(Val: RD);
213 }
214
215 /// Return the LLVM field index corresponding to the given
216 /// virtual base. Only valid when operating on the complete object.
217 unsigned getVirtualBaseIndex(const CXXRecordDecl *base) const {
218 assert(CompleteObjectVirtualBases.count(base) && "Invalid virtual base!");
219 return CompleteObjectVirtualBases.lookup(Val: base);
220 }
221
222 /// Return the BitFieldInfo that corresponds to the field FD.
223 const CGBitFieldInfo &getBitFieldInfo(const FieldDecl *FD) const {
224 FD = FD->getCanonicalDecl();
225 assert(FD->isBitField() && "Invalid call for non-bit-field decl!");
226 llvm::DenseMap<const FieldDecl *, CGBitFieldInfo>::const_iterator
227 it = BitFields.find(Val: FD);
228 assert(it != BitFields.end() && "Unable to find bitfield info");
229 return it->second;
230 }
231
232 void print(raw_ostream &OS) const;
233 void dump() const;
234};
235
236} // end namespace CodeGen
237} // end namespace clang
238
239#endif
240

source code of clang/lib/CodeGen/CGRecordLayout.h