clang  10.0.0svn
RecordLayout.h
Go to the documentation of this file.
1 //===- RecordLayout.h - Layout information for a struct/union ---*- 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 // This file defines the RecordLayout interface.
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 /// ASTRecordLayout -
32 /// This class contains layout information for one RecordDecl,
33 /// which is a struct/union/class. The decl represented must be a definition,
34 /// not a forward declaration.
35 /// This class is also used to contain layout information for one
36 /// ObjCInterfaceDecl. FIXME - Find appropriate name.
37 /// These objects are managed by ASTContext.
39 public:
40  struct VBaseInfo {
41  /// The offset to this virtual base in the complete-object layout
42  /// of this class.
44 
45  private:
46  /// Whether this virtual base requires a vtordisp field in the
47  /// Microsoft ABI. These fields are required for certain operations
48  /// in constructors and destructors.
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  /// Size - Size of record in characters.
65  CharUnits Size;
66 
67  /// DataSize - Size of record in characters without tail padding.
68  CharUnits DataSize;
69 
70  // Alignment - Alignment of record in characters.
71  CharUnits Alignment;
72 
73  // UnadjustedAlignment - Maximum of the alignments of the record members in
74  // characters.
75  CharUnits UnadjustedAlignment;
76 
77  /// RequiredAlignment - The required alignment of the object. In the MS-ABI
78  /// the __declspec(align()) trumps #pramga pack and must always be obeyed.
79  CharUnits RequiredAlignment;
80 
81  /// FieldOffsets - Array of field offsets in bits.
82  ASTVector<uint64_t> FieldOffsets;
83 
84  /// CXXRecordLayoutInfo - Contains C++ specific layout information.
85  struct CXXRecordLayoutInfo {
86  /// NonVirtualSize - The non-virtual size (in chars) of an object, which is
87  /// the size of the object without virtual bases.
88  CharUnits NonVirtualSize;
89 
90  /// NonVirtualAlignment - The non-virtual alignment (in chars) of an object,
91  /// which is the alignment of the object without virtual bases.
92  CharUnits NonVirtualAlignment;
93 
94  /// SizeOfLargestEmptySubobject - The size of the largest empty subobject
95  /// (either a base or a member). Will be zero if the class doesn't contain
96  /// any empty subobjects.
97  CharUnits SizeOfLargestEmptySubobject;
98 
99  /// VBPtrOffset - Virtual base table offset (Microsoft-only).
100  CharUnits VBPtrOffset;
101 
102  /// HasOwnVFPtr - Does this class provide a virtual function table
103  /// (vtable in Itanium, vftbl in Microsoft) that is independent from
104  /// its base classes?
105  bool HasOwnVFPtr : 1;
106 
107  /// HasVFPtr - Does this class have a vftable that could be extended by
108  /// a derived class. The class may have inherited this pointer from
109  /// a primary base class.
110  bool HasExtendableVFPtr : 1;
111 
112  /// EndsWithZeroSizedObject - True if this class contains a zero sized
113  /// member or base or a base with a zero sized member or base.
114  /// Only used for MS-ABI.
115  bool EndsWithZeroSizedObject : 1;
116 
117  /// True if this class is zero sized or first base is zero sized or
118  /// has this property. Only used for MS-ABI.
119  bool LeadsWithZeroSizedBase : 1;
120 
121  /// PrimaryBase - The primary base info for this record.
122  llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> PrimaryBase;
123 
124  /// BaseSharingVBPtr - The base we share vbptr with.
125  const CXXRecordDecl *BaseSharingVBPtr;
126 
127  /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
128  using BaseOffsetsMapTy = llvm::DenseMap<const CXXRecordDecl *, CharUnits>;
129 
130  /// BaseOffsets - Contains a map from base classes to their offset.
131  BaseOffsetsMapTy BaseOffsets;
132 
133  /// VBaseOffsets - Contains a map from vbase classes to their offset.
134  VBaseOffsetsMapTy VBaseOffsets;
135  };
136 
137  /// CXXInfo - If the record layout is for a C++ record, this will have
138  /// C++ specific information about the record.
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  // Constructor for C++ records.
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  /// getAlignment - Get the record alignment in characters.
176  CharUnits getAlignment() const { return Alignment; }
177 
178  /// getUnadjustedAlignment - Get the record alignment in characters, before
179  /// alignment adjustement.
180  CharUnits getUnadjustedAlignment() const { return UnadjustedAlignment; }
181 
182  /// getSize - Get the record size in characters.
183  CharUnits getSize() const { return Size; }
184 
185  /// getFieldCount - Get the number of fields in the layout.
186  unsigned getFieldCount() const { return FieldOffsets.size(); }
187 
188  /// getFieldOffset - Get the offset of the given field index, in
189  /// bits.
190  uint64_t getFieldOffset(unsigned FieldNo) const {
191  return FieldOffsets[FieldNo];
192  }
193 
194  /// getDataSize() - Get the record data size, which is the record size
195  /// without tail padding, in characters.
197  return DataSize;
198  }
199 
200  /// getNonVirtualSize - Get the non-virtual size (in chars) of an object,
201  /// which is the size of the object without virtual bases.
203  assert(CXXInfo && "Record layout does not have C++ specific info!");
204 
205  return CXXInfo->NonVirtualSize;
206  }
207 
208  /// getNonVirtualSize - Get the non-virtual alignment (in chars) of an object,
209  /// which is the alignment of the object without virtual bases.
211  assert(CXXInfo && "Record layout does not have C++ specific info!");
212 
213  return CXXInfo->NonVirtualAlignment;
214  }
215 
216  /// getPrimaryBase - Get the primary base for this record.
217  const CXXRecordDecl *getPrimaryBase() const {
218  assert(CXXInfo && "Record layout does not have C++ specific info!");
219 
220  return CXXInfo->PrimaryBase.getPointer();
221  }
222 
223  /// isPrimaryBaseVirtual - Get whether the primary base for this record
224  /// is virtual or not.
225  bool isPrimaryBaseVirtual() const {
226  assert(CXXInfo && "Record layout does not have C++ specific info!");
227 
228  return CXXInfo->PrimaryBase.getInt();
229  }
230 
231  /// getBaseClassOffset - Get the offset, in chars, for the given base class.
233  assert(CXXInfo && "Record layout does not have C++ specific info!");
234  assert(CXXInfo->BaseOffsets.count(Base) && "Did not find base!");
235 
236  return CXXInfo->BaseOffsets[Base];
237  }
238 
239  /// getVBaseClassOffset - Get the offset, in chars, for the given base class.
241  assert(CXXInfo && "Record layout does not have C++ specific info!");
242  assert(CXXInfo->VBaseOffsets.count(VBase) && "Did not find base!");
243 
244  return CXXInfo->VBaseOffsets[VBase].VBaseOffset;
245  }
246 
248  assert(CXXInfo && "Record layout does not have C++ specific info!");
249  return CXXInfo->SizeOfLargestEmptySubobject;
250  }
251 
252  /// hasOwnVFPtr - Does this class provide its own virtual-function
253  /// table pointer, rather than inheriting one from a primary base
254  /// class? If so, it is at offset zero.
255  ///
256  /// This implies that the ABI has no primary base class, meaning
257  /// that it has no base classes that are suitable under the conditions
258  /// of the ABI.
259  bool hasOwnVFPtr() const {
260  assert(CXXInfo && "Record layout does not have C++ specific info!");
261  return CXXInfo->HasOwnVFPtr;
262  }
263 
264  /// hasVFPtr - Does this class have a virtual function table pointer
265  /// that can be extended by a derived class? This is synonymous with
266  /// this class having a VFPtr at offset zero.
267  bool hasExtendableVFPtr() const {
268  assert(CXXInfo && "Record layout does not have C++ specific info!");
269  return CXXInfo->HasExtendableVFPtr;
270  }
271 
272  /// hasOwnVBPtr - Does this class provide its own virtual-base
273  /// table pointer, rather than inheriting one from a primary base
274  /// class?
275  ///
276  /// This implies that the ABI has no primary base class, meaning
277  /// that it has no base classes that are suitable under the conditions
278  /// of the ABI.
279  bool hasOwnVBPtr() const {
280  assert(CXXInfo && "Record layout does not have C++ specific info!");
281  return hasVBPtr() && !CXXInfo->BaseSharingVBPtr;
282  }
283 
284  /// hasVBPtr - Does this class have a virtual function table pointer.
285  bool hasVBPtr() const {
286  assert(CXXInfo && "Record layout does not have C++ specific info!");
287  return !CXXInfo->VBPtrOffset.isNegative();
288  }
289 
291  return RequiredAlignment;
292  }
293 
294  bool endsWithZeroSizedObject() const {
295  return CXXInfo && CXXInfo->EndsWithZeroSizedObject;
296  }
297 
298  bool leadsWithZeroSizedBase() const {
299  assert(CXXInfo && "Record layout does not have C++ specific info!");
300  return CXXInfo->LeadsWithZeroSizedBase;
301  }
302 
303  /// getVBPtrOffset - Get the offset for virtual base table pointer.
304  /// This is only meaningful with the Microsoft ABI.
306  assert(CXXInfo && "Record layout does not have C++ specific info!");
307  return CXXInfo->VBPtrOffset;
308  }
309 
311  assert(CXXInfo && "Record layout does not have C++ specific info!");
312  return CXXInfo->BaseSharingVBPtr;
313  }
314 
316  assert(CXXInfo && "Record layout does not have C++ specific info!");
317  return CXXInfo->VBaseOffsets;
318  }
319 };
320 
321 } // namespace clang
322 
323 #endif // LLVM_CLANG_AST_RECORDLAYOUT_H
bool isPrimaryBaseVirtual() const
isPrimaryBaseVirtual - Get whether the primary base for this record is virtual or not...
Definition: RecordLayout.h:225
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const
getBaseClassOffset - Get the offset, in chars, for the given base class.
Definition: RecordLayout.h:232
CharUnits getAlignment() const
getAlignment - Get the record alignment in characters.
Definition: RecordLayout.h:176
bool hasVBPtr() const
hasVBPtr - Does this class have a virtual function table pointer.
Definition: RecordLayout.h:285
bool hasOwnVFPtr() const
hasOwnVFPtr - Does this class provide its own virtual-function table pointer, rather than inheriting ...
Definition: RecordLayout.h:259
size_type size() const
Definition: ASTVector.h:109
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:160
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const
getVBaseClassOffset - Get the offset, in chars, for the given base class.
Definition: RecordLayout.h:240
CharUnits - This is an opaque type for sizes expressed in character units.
Definition: CharUnits.h:37
bool endsWithZeroSizedObject() const
Definition: RecordLayout.h:294
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
const VBaseOffsetsMapTy & getVBaseOffsetsMap() const
Definition: RecordLayout.h:315
ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...
Definition: RecordLayout.h:38
CharUnits getSizeOfLargestEmptySubobject() const
Definition: RecordLayout.h:247
const CXXRecordDecl * getPrimaryBase() const
getPrimaryBase - Get the primary base for this record.
Definition: RecordLayout.h:217
unsigned getFieldCount() const
getFieldCount - Get the number of fields in the layout.
Definition: RecordLayout.h:186
bool hasExtendableVFPtr() const
hasVFPtr - Does this class have a virtual function table pointer that can be extended by a derived cl...
Definition: RecordLayout.h:267
CharUnits getVBPtrOffset() const
getVBPtrOffset - Get the offset for virtual base table pointer.
Definition: RecordLayout.h:305
CharUnits getRequiredAlignment() const
Definition: RecordLayout.h:290
uint64_t getFieldOffset(unsigned FieldNo) const
getFieldOffset - Get the offset of the given field index, in bits.
Definition: RecordLayout.h:190
CharUnits getDataSize() const
getDataSize() - Get the record data size, which is the record size without tail padding, in characters.
Definition: RecordLayout.h:196
VBaseInfo(CharUnits VBaseOffset, bool hasVtorDisp)
Definition: RecordLayout.h:53
CharUnits getUnadjustedAlignment() const
getUnadjustedAlignment - Get the record alignment in characters, before alignment adjustement...
Definition: RecordLayout.h:180
CharUnits getNonVirtualAlignment() const
getNonVirtualSize - Get the non-virtual alignment (in chars) of an object, which is the alignment of ...
Definition: RecordLayout.h:210
Dataflow Directional Tag Classes.
CharUnits getSize() const
getSize - Get the record size in characters.
Definition: RecordLayout.h:183
const CXXRecordDecl * getBaseSharingVBPtr() const
Definition: RecordLayout.h:310
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate.h) and friends (in DeclFriend.h).
Represents a C++ struct/union/class.
Definition: DeclCXX.h:254
CharUnits getNonVirtualSize() const
getNonVirtualSize - Get the non-virtual size (in chars) of an object, which is the size of the object...
Definition: RecordLayout.h:202
llvm::DenseMap< const CXXRecordDecl *, VBaseInfo > VBaseOffsetsMapTy
Definition: RecordLayout.h:59
CharUnits VBaseOffset
The offset to this virtual base in the complete-object layout of this class.
Definition: RecordLayout.h:43
ASTRecordLayout & operator=(const ASTRecordLayout &)=delete
bool hasOwnVBPtr() const
hasOwnVBPtr - Does this class provide its own virtual-base table pointer, rather than inheriting one ...
Definition: RecordLayout.h:279
bool leadsWithZeroSizedBase() const
Definition: RecordLayout.h:298