Coverage Report

Created: 2018-09-21 05:35

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/include/clang/AST/RecordLayout.h
Line
Count
Source (jump to first uncovered line)
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
0
    VBaseInfo() = default;
54
    VBaseInfo(CharUnits VBaseOffset, bool hasVtorDisp)
55
2.37k
        : VBaseOffset(VBaseOffset), HasVtorDisp(hasVtorDisp) {}
56
57
3.50k
    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
  // UnadjustedAlignment - Maximum of the alignments of the record members in
75
  // characters.
76
  CharUnits UnadjustedAlignment;
77
78
  /// RequiredAlignment - The required alignment of the object.  In the MS-ABI
79
  /// the __declspec(align()) trumps #pramga pack and must always be obeyed.
80
  CharUnits RequiredAlignment;
81
82
  /// FieldOffsets - Array of field offsets in bits.
83
  ASTVector<uint64_t> FieldOffsets;
84
85
  /// CXXRecordLayoutInfo - Contains C++ specific layout information.
86
  struct CXXRecordLayoutInfo {
87
    /// NonVirtualSize - The non-virtual size (in chars) of an object, which is
88
    /// the size of the object without virtual bases.
89
    CharUnits NonVirtualSize;
90
91
    /// NonVirtualAlignment - The non-virtual alignment (in chars) of an object,
92
    /// which is the alignment of the object without virtual bases.
93
    CharUnits NonVirtualAlignment;
94
95
    /// SizeOfLargestEmptySubobject - The size of the largest empty subobject
96
    /// (either a base or a member). Will be zero if the class doesn't contain
97
    /// any empty subobjects.
98
    CharUnits SizeOfLargestEmptySubobject;
99
100
    /// VBPtrOffset - Virtual base table offset (Microsoft-only).
101
    CharUnits VBPtrOffset;
102
103
    /// HasOwnVFPtr - Does this class provide a virtual function table
104
    /// (vtable in Itanium, vftbl in Microsoft) that is independent from
105
    /// its base classes?
106
    bool HasOwnVFPtr : 1;
107
108
    /// HasVFPtr - Does this class have a vftable that could be extended by
109
    /// a derived class.  The class may have inherited this pointer from
110
    /// a primary base class.
111
    bool HasExtendableVFPtr : 1;
112
113
    /// EndsWithZeroSizedObject - True if this class contains a zero sized
114
    /// member or base or a base with a zero sized member or base.
115
    /// Only used for MS-ABI.
116
    bool EndsWithZeroSizedObject : 1;
117
118
    /// True if this class is zero sized or first base is zero sized or
119
    /// has this property.  Only used for MS-ABI.
120
    bool LeadsWithZeroSizedBase : 1;
121
122
    /// PrimaryBase - The primary base info for this record.
123
    llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> PrimaryBase;
124
125
    /// BaseSharingVBPtr - The base we share vbptr with.
126
    const CXXRecordDecl *BaseSharingVBPtr;
127
128
    /// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
129
    using BaseOffsetsMapTy = llvm::DenseMap<const CXXRecordDecl *, CharUnits>;
130
131
    /// BaseOffsets - Contains a map from base classes to their offset.
132
    BaseOffsetsMapTy BaseOffsets;
133
134
    /// VBaseOffsets - Contains a map from vbase classes to their offset.
135
    VBaseOffsetsMapTy VBaseOffsets;
136
  };
137
138
  /// CXXInfo - If the record layout is for a C++ record, this will have
139
  /// C++ specific information about the record.
140
  CXXRecordLayoutInfo *CXXInfo = nullptr;
141
142
  ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment,
143
                  CharUnits unadjustedAlignment,
144
                  CharUnits requiredAlignment, CharUnits datasize,
145
                  ArrayRef<uint64_t> fieldoffsets);
146
147
  using BaseOffsetsMapTy = CXXRecordLayoutInfo::BaseOffsetsMapTy;
148
149
  // Constructor for C++ records.
150
  ASTRecordLayout(const ASTContext &Ctx,
151
                  CharUnits size, CharUnits alignment,
152
                  CharUnits unadjustedAlignment,
153
                  CharUnits requiredAlignment,
154
                  bool hasOwnVFPtr, bool hasExtendableVFPtr,
155
                  CharUnits vbptroffset,
156
                  CharUnits datasize,
157
                  ArrayRef<uint64_t> fieldoffsets,
158
                  CharUnits nonvirtualsize, CharUnits nonvirtualalignment,
159
                  CharUnits SizeOfLargestEmptySubobject,
160
                  const CXXRecordDecl *PrimaryBase,
161
                  bool IsPrimaryBaseVirtual,
162
                  const CXXRecordDecl *BaseSharingVBPtr,
163
                  bool EndsWithZeroSizedObject,
164
                  bool LeadsWithZeroSizedBase,
165
                  const BaseOffsetsMapTy& BaseOffsets,
166
                  const VBaseOffsetsMapTy& VBaseOffsets);
167
168
39.5k
  ~ASTRecordLayout() = default;
169
170
  void Destroy(ASTContext &Ctx);
171
172
public:
173
  ASTRecordLayout(const ASTRecordLayout &) = delete;
174
  ASTRecordLayout &operator=(const ASTRecordLayout &) = delete;
175
176
  /// getAlignment - Get the record alignment in characters.
177
307k
  CharUnits getAlignment() const { return Alignment; }
178
179
  /// getUnadjustedAlignment - Get the record alignment in characters, before
180
  /// alignment adjustement.
181
170
  CharUnits getUnadjustedAlignment() const { return UnadjustedAlignment; }
182
183
  /// getSize - Get the record size in characters.
184
402k
  CharUnits getSize() const { return Size; }
185
186
  /// getFieldCount - Get the number of fields in the layout.
187
1.02k
  unsigned getFieldCount() const { return FieldOffsets.size(); }
188
189
  /// getFieldOffset - Get the offset of the given field index, in
190
  /// bits.
191
2.07M
  uint64_t getFieldOffset(unsigned FieldNo) const {
192
2.07M
    return FieldOffsets[FieldNo];
193
2.07M
  }
194
195
  /// getDataSize() - Get the record data size, which is the record size
196
  /// without tail padding, in characters.
197
11.3k
  CharUnits getDataSize() const {
198
11.3k
    return DataSize;
199
11.3k
  }
200
201
  /// getNonVirtualSize - Get the non-virtual size (in chars) of an object,
202
  /// which is the size of the object without virtual bases.
203
315k
  CharUnits getNonVirtualSize() const {
204
315k
    assert(CXXInfo && "Record layout does not have C++ specific info!");
205
315k
206
315k
    return CXXInfo->NonVirtualSize;
207
315k
  }
208
209
  /// getNonVirtualSize - Get the non-virtual alignment (in chars) of an object,
210
  /// which is the alignment of the object without virtual bases.
211
747k
  CharUnits getNonVirtualAlignment() const {
212
747k
    assert(CXXInfo && "Record layout does not have C++ specific info!");
213
747k
214
747k
    return CXXInfo->NonVirtualAlignment;
215
747k
  }
216
217
  /// getPrimaryBase - Get the primary base for this record.
218
98.0k
  const CXXRecordDecl *getPrimaryBase() const {
219
98.0k
    assert(CXXInfo && "Record layout does not have C++ specific info!");
220
98.0k
221
98.0k
    return CXXInfo->PrimaryBase.getPointer();
222
98.0k
  }
223
224
  /// isPrimaryBaseVirtual - Get whether the primary base for this record
225
  /// is virtual or not.
226
140k
  bool isPrimaryBaseVirtual() const {
227
140k
    assert(CXXInfo && "Record layout does not have C++ specific info!");
228
140k
229
140k
    return CXXInfo->PrimaryBase.getInt();
230
140k
  }
231
232
  /// getBaseClassOffset - Get the offset, in chars, for the given base class.
233
1.33M
  CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const {
234
1.33M
    assert(CXXInfo && "Record layout does not have C++ specific info!");
235
1.33M
    assert(CXXInfo->BaseOffsets.count(Base) && "Did not find base!");
236
1.33M
237
1.33M
    return CXXInfo->BaseOffsets[Base];
238
1.33M
  }
239
240
  /// getVBaseClassOffset - Get the offset, in chars, for the given base class.
241
23.1k
  CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const {
242
23.1k
    assert(CXXInfo && "Record layout does not have C++ specific info!");
243
23.1k
    assert(CXXInfo->VBaseOffsets.count(VBase) && "Did not find base!");
244
23.1k
245
23.1k
    return CXXInfo->VBaseOffsets[VBase].VBaseOffset;
246
23.1k
  }
247
248
70.6k
  CharUnits getSizeOfLargestEmptySubobject() const {
249
70.6k
    assert(CXXInfo && "Record layout does not have C++ specific info!");
250
70.6k
    return CXXInfo->SizeOfLargestEmptySubobject;
251
70.6k
  }
252
253
  /// hasOwnVFPtr - Does this class provide its own virtual-function
254
  /// table pointer, rather than inheriting one from a primary base
255
  /// class?  If so, it is at offset zero.
256
  ///
257
  /// This implies that the ABI has no primary base class, meaning
258
  /// that it has no base classes that are suitable under the conditions
259
  /// of the ABI.
260
105k
  bool hasOwnVFPtr() const {
261
105k
    assert(CXXInfo && "Record layout does not have C++ specific info!");
262
105k
    return CXXInfo->HasOwnVFPtr;
263
105k
  }
264
265
  /// hasVFPtr - Does this class have a virtual function table pointer
266
  /// that can be extended by a derived class?  This is synonymous with
267
  /// this class having a VFPtr at offset zero.
268
3.05k
  bool hasExtendableVFPtr() const {
269
3.05k
    assert(CXXInfo && "Record layout does not have C++ specific info!");
270
3.05k
    return CXXInfo->HasExtendableVFPtr;
271
3.05k
  }
272
273
  /// hasOwnVBPtr - Does this class provide its own virtual-base
274
  /// table pointer, rather than inheriting one from a primary base
275
  /// class?
276
  ///
277
  /// This implies that the ABI has no primary base class, meaning
278
  /// that it has no base classes that are suitable under the conditions
279
  /// of the ABI.
280
104k
  bool hasOwnVBPtr() const {
281
104k
    assert(CXXInfo && "Record layout does not have C++ specific info!");
282
104k
    return hasVBPtr() && 
!CXXInfo->BaseSharingVBPtr1.78k
;
283
104k
  }
284
285
  /// hasVBPtr - Does this class have a virtual function table pointer.
286
105k
  bool hasVBPtr() const {
287
105k
    assert(CXXInfo && "Record layout does not have C++ specific info!");
288
105k
    return !CXXInfo->VBPtrOffset.isNegative();
289
105k
  }
290
291
6.77k
  CharUnits getRequiredAlignment() const {
292
6.77k
    return RequiredAlignment;
293
6.77k
  }
294
295
3.75k
  bool endsWithZeroSizedObject() const {
296
3.75k
    return CXXInfo && 
CXXInfo->EndsWithZeroSizedObject3.74k
;
297
3.75k
  }
298
299
1.26k
  bool leadsWithZeroSizedBase() const {
300
1.26k
    assert(CXXInfo && "Record layout does not have C++ specific info!");
301
1.26k
    return CXXInfo->LeadsWithZeroSizedBase;
302
1.26k
  }
303
304
  /// getVBPtrOffset - Get the offset for virtual base table pointer.
305
  /// This is only meaningful with the Microsoft ABI.
306
3.02k
  CharUnits getVBPtrOffset() const {
307
3.02k
    assert(CXXInfo && "Record layout does not have C++ specific info!");
308
3.02k
    return CXXInfo->VBPtrOffset;
309
3.02k
  }
310
311
884
  const CXXRecordDecl *getBaseSharingVBPtr() const {
312
884
    assert(CXXInfo && "Record layout does not have C++ specific info!");
313
884
    return CXXInfo->BaseSharingVBPtr;
314
884
  }
315
316
4.74k
  const VBaseOffsetsMapTy &getVBaseOffsetsMap() const {
317
4.74k
    assert(CXXInfo && "Record layout does not have C++ specific info!");
318
4.74k
    return CXXInfo->VBaseOffsets;
319
4.74k
  }
320
};
321
322
} // namespace clang
323
324
#endif // LLVM_CLANG_AST_RECORDLAYOUT_H