1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | |
12 | |
13 | #ifndef LLVM_CLANG_AST_RECORDLAYOUT_H |
14 | #define LLVM_CLANG_AST_RECORDLAYOUT_H |
15 | |
16 | #include "clang/AST/ASTVector.h" |
17 | #include "clang/AST/CharUnits.h" |
18 | #include "clang/AST/DeclCXX.h" |
19 | #include "clang/Basic/LLVM.h" |
20 | #include "llvm/ADT/ArrayRef.h" |
21 | #include "llvm/ADT/DenseMap.h" |
22 | #include "llvm/ADT/PointerIntPair.h" |
23 | #include <cassert> |
24 | #include <cstdint> |
25 | |
26 | namespace clang { |
27 | |
28 | class ASTContext; |
29 | class CXXRecordDecl; |
30 | |
31 | |
32 | |
33 | |
34 | |
35 | |
36 | |
37 | |
38 | class ASTRecordLayout { |
39 | public: |
40 | struct VBaseInfo { |
41 | |
42 | |
43 | CharUnits VBaseOffset; |
44 | |
45 | private: |
46 | |
47 | |
48 | |
49 | bool HasVtorDisp = false; |
50 | |
51 | public: |
52 | VBaseInfo() = default; |
53 | VBaseInfo(CharUnits VBaseOffset, bool hasVtorDisp) |
54 | : VBaseOffset(VBaseOffset), HasVtorDisp(hasVtorDisp) {} |
55 | |
56 | bool hasVtorDisp() const { return HasVtorDisp; } |
57 | }; |
58 | |
59 | using VBaseOffsetsMapTy = llvm::DenseMap<const CXXRecordDecl *, VBaseInfo>; |
60 | |
61 | private: |
62 | friend class ASTContext; |
63 | |
64 | |
65 | CharUnits Size; |
66 | |
67 | |
68 | CharUnits DataSize; |
69 | |
70 | |
71 | CharUnits Alignment; |
72 | |
73 | |
74 | |
75 | CharUnits UnadjustedAlignment; |
76 | |
77 | |
78 | |
79 | CharUnits RequiredAlignment; |
80 | |
81 | |
82 | ASTVector<uint64_t> FieldOffsets; |
83 | |
84 | |
85 | struct CXXRecordLayoutInfo { |
86 | |
87 | |
88 | CharUnits NonVirtualSize; |
89 | |
90 | |
91 | |
92 | CharUnits NonVirtualAlignment; |
93 | |
94 | |
95 | |
96 | |
97 | CharUnits SizeOfLargestEmptySubobject; |
98 | |
99 | |
100 | CharUnits VBPtrOffset; |
101 | |
102 | |
103 | |
104 | |
105 | bool HasOwnVFPtr : 1; |
106 | |
107 | |
108 | |
109 | |
110 | bool HasExtendableVFPtr : 1; |
111 | |
112 | |
113 | |
114 | |
115 | bool EndsWithZeroSizedObject : 1; |
116 | |
117 | |
118 | |
119 | bool LeadsWithZeroSizedBase : 1; |
120 | |
121 | |
122 | llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> PrimaryBase; |
123 | |
124 | |
125 | const CXXRecordDecl *BaseSharingVBPtr; |
126 | |
127 | |
128 | using BaseOffsetsMapTy = llvm::DenseMap<const CXXRecordDecl *, CharUnits>; |
129 | |
130 | |
131 | BaseOffsetsMapTy BaseOffsets; |
132 | |
133 | |
134 | VBaseOffsetsMapTy VBaseOffsets; |
135 | }; |
136 | |
137 | |
138 | |
139 | CXXRecordLayoutInfo *CXXInfo = nullptr; |
140 | |
141 | ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment, |
142 | CharUnits unadjustedAlignment, |
143 | CharUnits requiredAlignment, CharUnits datasize, |
144 | ArrayRef<uint64_t> fieldoffsets); |
145 | |
146 | using BaseOffsetsMapTy = CXXRecordLayoutInfo::BaseOffsetsMapTy; |
147 | |
148 | |
149 | ASTRecordLayout(const ASTContext &Ctx, |
150 | CharUnits size, CharUnits alignment, |
151 | CharUnits unadjustedAlignment, |
152 | CharUnits requiredAlignment, |
153 | bool hasOwnVFPtr, bool hasExtendableVFPtr, |
154 | CharUnits vbptroffset, |
155 | CharUnits datasize, |
156 | ArrayRef<uint64_t> fieldoffsets, |
157 | CharUnits nonvirtualsize, CharUnits nonvirtualalignment, |
158 | CharUnits SizeOfLargestEmptySubobject, |
159 | const CXXRecordDecl *PrimaryBase, |
160 | bool IsPrimaryBaseVirtual, |
161 | const CXXRecordDecl *BaseSharingVBPtr, |
162 | bool EndsWithZeroSizedObject, |
163 | bool LeadsWithZeroSizedBase, |
164 | const BaseOffsetsMapTy& BaseOffsets, |
165 | const VBaseOffsetsMapTy& VBaseOffsets); |
166 | |
167 | ~ASTRecordLayout() = default; |
168 | |
169 | void Destroy(ASTContext &Ctx); |
170 | |
171 | public: |
172 | ASTRecordLayout(const ASTRecordLayout &) = delete; |
173 | ASTRecordLayout &operator=(const ASTRecordLayout &) = delete; |
174 | |
175 | |
176 | CharUnits getAlignment() const { return Alignment; } |
177 | |
178 | |
179 | |
180 | CharUnits getUnadjustedAlignment() const { return UnadjustedAlignment; } |
181 | |
182 | |
183 | CharUnits getSize() const { return Size; } |
184 | |
185 | |
186 | unsigned getFieldCount() const { return FieldOffsets.size(); } |
187 | |
188 | |
189 | |
190 | uint64_t getFieldOffset(unsigned FieldNo) const { |
191 | return FieldOffsets[FieldNo]; |
192 | } |
193 | |
194 | |
195 | |
196 | CharUnits getDataSize() const { |
197 | return DataSize; |
198 | } |
199 | |
200 | |
201 | |
202 | CharUnits getNonVirtualSize() const { |
203 | (0) . __assert_fail ("CXXInfo && \"Record layout does not have C++ specific info!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/RecordLayout.h", 203, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(CXXInfo && "Record layout does not have C++ specific info!"); |
204 | |
205 | return CXXInfo->NonVirtualSize; |
206 | } |
207 | |
208 | |
209 | |
210 | CharUnits getNonVirtualAlignment() const { |
211 | (0) . __assert_fail ("CXXInfo && \"Record layout does not have C++ specific info!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/RecordLayout.h", 211, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(CXXInfo && "Record layout does not have C++ specific info!"); |
212 | |
213 | return CXXInfo->NonVirtualAlignment; |
214 | } |
215 | |
216 | |
217 | const CXXRecordDecl *getPrimaryBase() const { |
218 | (0) . __assert_fail ("CXXInfo && \"Record layout does not have C++ specific info!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/RecordLayout.h", 218, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(CXXInfo && "Record layout does not have C++ specific info!"); |
219 | |
220 | return CXXInfo->PrimaryBase.getPointer(); |
221 | } |
222 | |
223 | |
224 | |
225 | bool isPrimaryBaseVirtual() const { |
226 | (0) . __assert_fail ("CXXInfo && \"Record layout does not have C++ specific info!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/RecordLayout.h", 226, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(CXXInfo && "Record layout does not have C++ specific info!"); |
227 | |
228 | return CXXInfo->PrimaryBase.getInt(); |
229 | } |
230 | |
231 | |
232 | CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const { |
233 | (0) . __assert_fail ("CXXInfo && \"Record layout does not have C++ specific info!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/RecordLayout.h", 233, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(CXXInfo && "Record layout does not have C++ specific info!"); |
234 | (0) . __assert_fail ("CXXInfo->BaseOffsets.count(Base) && \"Did not find base!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/RecordLayout.h", 234, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(CXXInfo->BaseOffsets.count(Base) && "Did not find base!"); |
235 | |
236 | return CXXInfo->BaseOffsets[Base]; |
237 | } |
238 | |
239 | |
240 | CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const { |
241 | (0) . __assert_fail ("CXXInfo && \"Record layout does not have C++ specific info!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/RecordLayout.h", 241, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(CXXInfo && "Record layout does not have C++ specific info!"); |
242 | (0) . __assert_fail ("CXXInfo->VBaseOffsets.count(VBase) && \"Did not find base!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/RecordLayout.h", 242, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(CXXInfo->VBaseOffsets.count(VBase) && "Did not find base!"); |
243 | |
244 | return CXXInfo->VBaseOffsets[VBase].VBaseOffset; |
245 | } |
246 | |
247 | CharUnits getSizeOfLargestEmptySubobject() const { |
248 | (0) . __assert_fail ("CXXInfo && \"Record layout does not have C++ specific info!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/RecordLayout.h", 248, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(CXXInfo && "Record layout does not have C++ specific info!"); |
249 | return CXXInfo->SizeOfLargestEmptySubobject; |
250 | } |
251 | |
252 | |
253 | |
254 | |
255 | |
256 | |
257 | |
258 | |
259 | bool hasOwnVFPtr() const { |
260 | (0) . __assert_fail ("CXXInfo && \"Record layout does not have C++ specific info!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/RecordLayout.h", 260, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(CXXInfo && "Record layout does not have C++ specific info!"); |
261 | return CXXInfo->HasOwnVFPtr; |
262 | } |
263 | |
264 | |
265 | |
266 | |
267 | bool hasExtendableVFPtr() const { |
268 | (0) . __assert_fail ("CXXInfo && \"Record layout does not have C++ specific info!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/RecordLayout.h", 268, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(CXXInfo && "Record layout does not have C++ specific info!"); |
269 | return CXXInfo->HasExtendableVFPtr; |
270 | } |
271 | |
272 | |
273 | |
274 | |
275 | |
276 | |
277 | |
278 | |
279 | bool hasOwnVBPtr() const { |
280 | (0) . __assert_fail ("CXXInfo && \"Record layout does not have C++ specific info!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/RecordLayout.h", 280, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(CXXInfo && "Record layout does not have C++ specific info!"); |
281 | return hasVBPtr() && !CXXInfo->BaseSharingVBPtr; |
282 | } |
283 | |
284 | |
285 | bool hasVBPtr() const { |
286 | (0) . __assert_fail ("CXXInfo && \"Record layout does not have C++ specific info!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/RecordLayout.h", 286, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(CXXInfo && "Record layout does not have C++ specific info!"); |
287 | return !CXXInfo->VBPtrOffset.isNegative(); |
288 | } |
289 | |
290 | CharUnits getRequiredAlignment() const { |
291 | return RequiredAlignment; |
292 | } |
293 | |
294 | bool endsWithZeroSizedObject() const { |
295 | return CXXInfo && CXXInfo->EndsWithZeroSizedObject; |
296 | } |
297 | |
298 | bool leadsWithZeroSizedBase() const { |
299 | (0) . __assert_fail ("CXXInfo && \"Record layout does not have C++ specific info!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/RecordLayout.h", 299, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(CXXInfo && "Record layout does not have C++ specific info!"); |
300 | return CXXInfo->LeadsWithZeroSizedBase; |
301 | } |
302 | |
303 | |
304 | |
305 | CharUnits getVBPtrOffset() const { |
306 | (0) . __assert_fail ("CXXInfo && \"Record layout does not have C++ specific info!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/RecordLayout.h", 306, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(CXXInfo && "Record layout does not have C++ specific info!"); |
307 | return CXXInfo->VBPtrOffset; |
308 | } |
309 | |
310 | const CXXRecordDecl *getBaseSharingVBPtr() const { |
311 | (0) . __assert_fail ("CXXInfo && \"Record layout does not have C++ specific info!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/RecordLayout.h", 311, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(CXXInfo && "Record layout does not have C++ specific info!"); |
312 | return CXXInfo->BaseSharingVBPtr; |
313 | } |
314 | |
315 | const VBaseOffsetsMapTy &getVBaseOffsetsMap() const { |
316 | (0) . __assert_fail ("CXXInfo && \"Record layout does not have C++ specific info!\"", "/home/seafit/code_projects/clang_source/clang/include/clang/AST/RecordLayout.h", 316, __PRETTY_FUNCTION__))" file_link="../../../../include/assert.h.html#88" macro="true">assert(CXXInfo && "Record layout does not have C++ specific info!"); |
317 | return CXXInfo->VBaseOffsets; |
318 | } |
319 | }; |
320 | |
321 | } |
322 | |
323 | #endif |
324 | |