]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - include/clang/AST/RecordLayout.h
Vendor import of clang trunk r338150:
[FreeBSD/FreeBSD.git] / include / clang / AST / RecordLayout.h
1 //===- RecordLayout.h - Layout information for a struct/union ---*- 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 //  This file defines the RecordLayout interface.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_CLANG_AST_RECORDLAYOUT_H
15 #define LLVM_CLANG_AST_RECORDLAYOUT_H
16
17 #include "clang/AST/ASTVector.h"
18 #include "clang/AST/CharUnits.h"
19 #include "clang/AST/DeclCXX.h"
20 #include "clang/Basic/LLVM.h"
21 #include "llvm/ADT/ArrayRef.h"
22 #include "llvm/ADT/DenseMap.h"
23 #include "llvm/ADT/PointerIntPair.h"
24 #include <cassert>
25 #include <cstdint>
26
27 namespace clang {
28
29 class ASTContext;
30 class CXXRecordDecl;
31
32 /// ASTRecordLayout -
33 /// This class contains layout information for one RecordDecl,
34 /// which is a struct/union/class.  The decl represented must be a definition,
35 /// not a forward declaration.
36 /// This class is also used to contain layout information for one
37 /// ObjCInterfaceDecl. FIXME - Find appropriate name.
38 /// These objects are managed by ASTContext.
39 class ASTRecordLayout {
40 public:
41   struct VBaseInfo {
42     /// The offset to this virtual base in the complete-object layout
43     /// of this class.
44     CharUnits VBaseOffset;
45
46   private:
47     /// Whether this virtual base requires a vtordisp field in the
48     /// Microsoft ABI.  These fields are required for certain operations
49     /// in constructors and destructors.
50     bool HasVtorDisp = false;
51
52   public:
53     VBaseInfo() = default;
54     VBaseInfo(CharUnits VBaseOffset, bool hasVtorDisp)
55         : VBaseOffset(VBaseOffset), HasVtorDisp(hasVtorDisp) {}
56
57     bool hasVtorDisp() const { return HasVtorDisp; }
58   };
59
60   using VBaseOffsetsMapTy = llvm::DenseMap<const CXXRecordDecl *, VBaseInfo>;
61
62 private:
63   friend class ASTContext;
64
65   /// Size - Size of record in characters.
66   CharUnits Size;
67
68   /// DataSize - Size of record in characters without tail padding.
69   CharUnits DataSize;
70
71   // Alignment - Alignment of record in characters.
72   CharUnits Alignment;
73
74   /// RequiredAlignment - The required alignment of the object.  In the MS-ABI
75   /// the __declspec(align()) trumps #pramga pack and must always be obeyed.
76   CharUnits RequiredAlignment;
77
78   /// FieldOffsets - Array of field offsets in bits.
79   ASTVector<uint64_t> FieldOffsets;
80
81   /// CXXRecordLayoutInfo - Contains C++ specific layout information.
82   struct CXXRecordLayoutInfo {
83     /// NonVirtualSize - The non-virtual size (in chars) of an object, which is
84     /// the size of the object without virtual bases.
85     CharUnits NonVirtualSize;
86
87     /// NonVirtualAlignment - The non-virtual alignment (in chars) of an object,
88     /// which is the alignment of the object without virtual bases.
89     CharUnits NonVirtualAlignment;
90
91     /// SizeOfLargestEmptySubobject - The size of the largest empty subobject
92     /// (either a base or a member). Will be zero if the class doesn't contain
93     /// any empty subobjects.
94     CharUnits SizeOfLargestEmptySubobject;
95
96     /// VBPtrOffset - Virtual base table offset (Microsoft-only).
97     CharUnits VBPtrOffset;
98
99     /// HasOwnVFPtr - Does this class provide a virtual function table
100     /// (vtable in Itanium, vftbl in Microsoft) that is independent from
101     /// its base classes?
102     bool HasOwnVFPtr : 1;
103
104     /// HasVFPtr - Does this class have a vftable that could be extended by
105     /// a derived class.  The class may have inherited this pointer from
106     /// a primary base class.
107     bool HasExtendableVFPtr : 1;
108
109     /// EndsWithZeroSizedObject - True if this class contains a zero sized
110     /// member or base or a base with a zero sized member or base.
111     /// Only used for MS-ABI.
112     bool EndsWithZeroSizedObject : 1;
113
114     /// True if this class is zero sized or first base is zero sized or
115     /// has this property.  Only used for MS-ABI.
116     bool LeadsWithZeroSizedBase : 1;
117
118     /// PrimaryBase - The primary base info for this record.
119     llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> PrimaryBase;
120
121     /// BaseSharingVBPtr - The base we share vbptr with.
122     const CXXRecordDecl *BaseSharingVBPtr;
123     
124     /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
125     using BaseOffsetsMapTy = llvm::DenseMap<const CXXRecordDecl *, CharUnits>;
126     
127     /// BaseOffsets - Contains a map from base classes to their offset.
128     BaseOffsetsMapTy BaseOffsets;
129
130     /// VBaseOffsets - Contains a map from vbase classes to their offset.
131     VBaseOffsetsMapTy VBaseOffsets;
132   };
133
134   /// CXXInfo - If the record layout is for a C++ record, this will have
135   /// C++ specific information about the record.
136   CXXRecordLayoutInfo *CXXInfo = nullptr;
137
138   ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment,
139                   CharUnits requiredAlignment, CharUnits datasize,
140                   ArrayRef<uint64_t> fieldoffsets);
141
142   using BaseOffsetsMapTy = CXXRecordLayoutInfo::BaseOffsetsMapTy;
143
144   // Constructor for C++ records.
145   ASTRecordLayout(const ASTContext &Ctx,
146                   CharUnits size, CharUnits alignment,
147                   CharUnits requiredAlignment,
148                   bool hasOwnVFPtr, bool hasExtendableVFPtr,
149                   CharUnits vbptroffset,
150                   CharUnits datasize,
151                   ArrayRef<uint64_t> fieldoffsets,
152                   CharUnits nonvirtualsize, CharUnits nonvirtualalignment,
153                   CharUnits SizeOfLargestEmptySubobject,
154                   const CXXRecordDecl *PrimaryBase,
155                   bool IsPrimaryBaseVirtual,
156                   const CXXRecordDecl *BaseSharingVBPtr,
157                   bool EndsWithZeroSizedObject,
158                   bool LeadsWithZeroSizedBase,
159                   const BaseOffsetsMapTy& BaseOffsets,
160                   const VBaseOffsetsMapTy& VBaseOffsets);
161
162   ~ASTRecordLayout() = default;
163
164   void Destroy(ASTContext &Ctx);
165   
166 public:
167   ASTRecordLayout(const ASTRecordLayout &) = delete;
168   ASTRecordLayout &operator=(const ASTRecordLayout &) = delete;
169
170   /// getAlignment - Get the record alignment in characters.
171   CharUnits getAlignment() const { return Alignment; }
172
173   /// getSize - Get the record size in characters.
174   CharUnits getSize() const { return Size; }
175
176   /// getFieldCount - Get the number of fields in the layout.
177   unsigned getFieldCount() const { return FieldOffsets.size(); }
178
179   /// getFieldOffset - Get the offset of the given field index, in
180   /// bits.
181   uint64_t getFieldOffset(unsigned FieldNo) const {
182     return FieldOffsets[FieldNo];
183   }
184
185   /// getDataSize() - Get the record data size, which is the record size
186   /// without tail padding, in characters.
187   CharUnits getDataSize() const {
188     return DataSize;
189   }
190
191   /// getNonVirtualSize - Get the non-virtual size (in chars) of an object,
192   /// which is the size of the object without virtual bases.
193   CharUnits getNonVirtualSize() const {
194     assert(CXXInfo && "Record layout does not have C++ specific info!");
195
196     return CXXInfo->NonVirtualSize;
197   }
198
199   /// getNonVirtualSize - Get the non-virtual alignment (in chars) of an object,
200   /// which is the alignment of the object without virtual bases.
201   CharUnits getNonVirtualAlignment() const {
202     assert(CXXInfo && "Record layout does not have C++ specific info!");
203
204     return CXXInfo->NonVirtualAlignment;
205   }
206
207   /// getPrimaryBase - Get the primary base for this record.
208   const CXXRecordDecl *getPrimaryBase() const {
209     assert(CXXInfo && "Record layout does not have C++ specific info!");
210
211     return CXXInfo->PrimaryBase.getPointer();
212   }
213
214   /// isPrimaryBaseVirtual - Get whether the primary base for this record
215   /// is virtual or not.
216   bool isPrimaryBaseVirtual() const {
217     assert(CXXInfo && "Record layout does not have C++ specific info!");
218
219     return CXXInfo->PrimaryBase.getInt();
220   }
221
222   /// getBaseClassOffset - Get the offset, in chars, for the given base class.
223   CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const {
224     assert(CXXInfo && "Record layout does not have C++ specific info!");
225     assert(CXXInfo->BaseOffsets.count(Base) && "Did not find base!");
226
227     return CXXInfo->BaseOffsets[Base];
228   }
229
230   /// getVBaseClassOffset - Get the offset, in chars, for the given base class.
231   CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const {
232     assert(CXXInfo && "Record layout does not have C++ specific info!");
233     assert(CXXInfo->VBaseOffsets.count(VBase) && "Did not find base!");
234
235     return CXXInfo->VBaseOffsets[VBase].VBaseOffset;
236   }
237
238   CharUnits getSizeOfLargestEmptySubobject() const {
239     assert(CXXInfo && "Record layout does not have C++ specific info!");
240     return CXXInfo->SizeOfLargestEmptySubobject;
241   }
242
243   /// hasOwnVFPtr - Does this class provide its own virtual-function
244   /// table pointer, rather than inheriting one from a primary base
245   /// class?  If so, it is at offset zero.
246   ///
247   /// This implies that the ABI has no primary base class, meaning
248   /// that it has no base classes that are suitable under the conditions
249   /// of the ABI.
250   bool hasOwnVFPtr() const {
251     assert(CXXInfo && "Record layout does not have C++ specific info!");
252     return CXXInfo->HasOwnVFPtr;
253   }
254
255   /// hasVFPtr - Does this class have a virtual function table pointer
256   /// that can be extended by a derived class?  This is synonymous with
257   /// this class having a VFPtr at offset zero.
258   bool hasExtendableVFPtr() const {
259     assert(CXXInfo && "Record layout does not have C++ specific info!");
260     return CXXInfo->HasExtendableVFPtr;
261   }
262   
263   /// hasOwnVBPtr - Does this class provide its own virtual-base
264   /// table pointer, rather than inheriting one from a primary base
265   /// class?
266   ///
267   /// This implies that the ABI has no primary base class, meaning
268   /// that it has no base classes that are suitable under the conditions
269   /// of the ABI.
270   bool hasOwnVBPtr() const {
271     assert(CXXInfo && "Record layout does not have C++ specific info!");
272     return hasVBPtr() && !CXXInfo->BaseSharingVBPtr;
273   }
274
275   /// hasVBPtr - Does this class have a virtual function table pointer.
276   bool hasVBPtr() const {
277     assert(CXXInfo && "Record layout does not have C++ specific info!");
278     return !CXXInfo->VBPtrOffset.isNegative();
279   }
280
281   CharUnits getRequiredAlignment() const {
282     return RequiredAlignment;
283   }
284
285   bool endsWithZeroSizedObject() const {
286     return CXXInfo && CXXInfo->EndsWithZeroSizedObject;
287   }
288
289   bool leadsWithZeroSizedBase() const {
290     assert(CXXInfo && "Record layout does not have C++ specific info!");
291     return CXXInfo->LeadsWithZeroSizedBase;
292   }
293
294   /// getVBPtrOffset - Get the offset for virtual base table pointer.
295   /// This is only meaningful with the Microsoft ABI.
296   CharUnits getVBPtrOffset() const {
297     assert(CXXInfo && "Record layout does not have C++ specific info!");
298     return CXXInfo->VBPtrOffset;
299   }
300
301   const CXXRecordDecl *getBaseSharingVBPtr() const {
302     assert(CXXInfo && "Record layout does not have C++ specific info!");
303     return CXXInfo->BaseSharingVBPtr;
304   }
305
306   const VBaseOffsetsMapTy &getVBaseOffsetsMap() const {
307     assert(CXXInfo && "Record layout does not have C++ specific info!");
308     return CXXInfo->VBaseOffsets;
309   }
310 };
311
312 } // namespace clang
313
314 #endif // LLVM_CLANG_AST_RECORDLAYOUT_H