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