1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
|
//===--- RecordLayout.h - Layout information for a struct/union -*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file defines the RecordLayout interface.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_LAYOUTINFO_H
#define LLVM_CLANG_AST_LAYOUTINFO_H
#include "clang/AST/CharUnits.h"
#include "clang/AST/DeclCXX.h"
#include "llvm/ADT/DenseMap.h"
namespace clang {
class ASTContext;
class FieldDecl;
class RecordDecl;
class CXXRecordDecl;
/// ASTRecordLayout -
/// This class contains layout information for one RecordDecl,
/// which is a struct/union/class. The decl represented must be a definition,
/// not a forward declaration.
/// This class is also used to contain layout information for one
/// ObjCInterfaceDecl. FIXME - Find appropriate name.
/// These objects are managed by ASTContext.
class ASTRecordLayout {
public:
struct VBaseInfo {
/// The offset to this virtual base in the complete-object layout
/// of this class.
CharUnits VBaseOffset;
private:
/// Whether this virtual base requires a vtordisp field in the
/// Microsoft ABI. These fields are required for certain operations
/// in constructors and destructors.
bool HasVtorDisp;
public:
bool hasVtorDisp() const { return HasVtorDisp; }
VBaseInfo() : HasVtorDisp(false) {}
VBaseInfo(CharUnits VBaseOffset, bool hasVtorDisp) :
VBaseOffset(VBaseOffset), HasVtorDisp(hasVtorDisp) {}
};
typedef llvm::DenseMap<const CXXRecordDecl *, VBaseInfo>
VBaseOffsetsMapTy;
private:
/// Size - Size of record in characters.
CharUnits Size;
/// DataSize - Size of record in characters without tail padding.
CharUnits DataSize;
// Alignment - Alignment of record in characters.
CharUnits Alignment;
/// FieldOffsets - Array of field offsets in bits.
uint64_t *FieldOffsets;
// FieldCount - Number of fields.
unsigned FieldCount;
/// CXXRecordLayoutInfo - Contains C++ specific layout information.
struct CXXRecordLayoutInfo {
/// NonVirtualSize - The non-virtual size (in chars) of an object, which is
/// the size of the object without virtual bases.
CharUnits NonVirtualSize;
/// NonVirtualAlign - The non-virtual alignment (in chars) of an object,
/// which is the alignment of the object without virtual bases.
CharUnits NonVirtualAlign;
/// SizeOfLargestEmptySubobject - The size of the largest empty subobject
/// (either a base or a member). Will be zero if the class doesn't contain
/// any empty subobjects.
CharUnits SizeOfLargestEmptySubobject;
/// VBPtrOffset - Virtual base table offset (Microsoft-only).
CharUnits VBPtrOffset;
/// HasOwnVFPtr - Does this class provide a virtual function table
/// (vtable in Itanium, vftbl in Microsoft) that is independent from
/// its base classes?
bool HasOwnVFPtr; // TODO: stash this somewhere more efficient
/// PrimaryBase - The primary base info for this record.
llvm::PointerIntPair<const CXXRecordDecl *, 1, bool> PrimaryBase;
/// FIXME: This should really use a SmallPtrMap, once we have one in LLVM :)
typedef llvm::DenseMap<const CXXRecordDecl *, CharUnits> BaseOffsetsMapTy;
/// BaseOffsets - Contains a map from base classes to their offset.
BaseOffsetsMapTy BaseOffsets;
/// VBaseOffsets - Contains a map from vbase classes to their offset.
VBaseOffsetsMapTy VBaseOffsets;
};
/// CXXInfo - If the record layout is for a C++ record, this will have
/// C++ specific information about the record.
CXXRecordLayoutInfo *CXXInfo;
friend class ASTContext;
ASTRecordLayout(const ASTContext &Ctx, CharUnits size, CharUnits alignment,
CharUnits datasize, const uint64_t *fieldoffsets,
unsigned fieldcount);
// Constructor for C++ records.
typedef CXXRecordLayoutInfo::BaseOffsetsMapTy BaseOffsetsMapTy;
ASTRecordLayout(const ASTContext &Ctx,
CharUnits size, CharUnits alignment,
bool hasOwnVFPtr, CharUnits vbptroffset,
CharUnits datasize,
const uint64_t *fieldoffsets, unsigned fieldcount,
CharUnits nonvirtualsize, CharUnits nonvirtualalign,
CharUnits SizeOfLargestEmptySubobject,
const CXXRecordDecl *PrimaryBase,
bool IsPrimaryBaseVirtual,
const BaseOffsetsMapTy& BaseOffsets,
const VBaseOffsetsMapTy& VBaseOffsets);
~ASTRecordLayout() {}
void Destroy(ASTContext &Ctx);
ASTRecordLayout(const ASTRecordLayout &) LLVM_DELETED_FUNCTION;
void operator=(const ASTRecordLayout &) LLVM_DELETED_FUNCTION;
public:
/// getAlignment - Get the record alignment in characters.
CharUnits getAlignment() const { return Alignment; }
/// getSize - Get the record size in characters.
CharUnits getSize() const { return Size; }
/// getFieldCount - Get the number of fields in the layout.
unsigned getFieldCount() const { return FieldCount; }
/// getFieldOffset - Get the offset of the given field index, in
/// bits.
uint64_t getFieldOffset(unsigned FieldNo) const {
assert (FieldNo < FieldCount && "Invalid Field No");
return FieldOffsets[FieldNo];
}
/// getDataSize() - Get the record data size, which is the record size
/// without tail padding, in characters.
CharUnits getDataSize() const {
return DataSize;
}
/// getNonVirtualSize - Get the non-virtual size (in chars) of an object,
/// which is the size of the object without virtual bases.
CharUnits getNonVirtualSize() const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
return CXXInfo->NonVirtualSize;
}
/// getNonVirtualSize - Get the non-virtual alignment (in chars) of an object,
/// which is the alignment of the object without virtual bases.
CharUnits getNonVirtualAlign() const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
return CXXInfo->NonVirtualAlign;
}
/// getPrimaryBase - Get the primary base for this record.
const CXXRecordDecl *getPrimaryBase() const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
return CXXInfo->PrimaryBase.getPointer();
}
/// isPrimaryBaseVirtual - Get whether the primary base for this record
/// is virtual or not.
bool isPrimaryBaseVirtual() const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
return CXXInfo->PrimaryBase.getInt();
}
/// getBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
assert(CXXInfo->BaseOffsets.count(Base) && "Did not find base!");
return CXXInfo->BaseOffsets[Base];
}
/// getVBaseClassOffset - Get the offset, in chars, for the given base class.
CharUnits getVBaseClassOffset(const CXXRecordDecl *VBase) const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
assert(CXXInfo->VBaseOffsets.count(VBase) && "Did not find base!");
return CXXInfo->VBaseOffsets[VBase].VBaseOffset;
}
CharUnits getSizeOfLargestEmptySubobject() const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
return CXXInfo->SizeOfLargestEmptySubobject;
}
/// hasOwnVFPtr - Does this class provide its own virtual-function
/// table pointer, rather than inheriting one from a primary base
/// class? If so, it is at offset zero.
///
/// This implies that the ABI has no primary base class, meaning
/// that it has no base classes that are suitable under the conditions
/// of the ABI.
bool hasOwnVFPtr() const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
return CXXInfo->HasOwnVFPtr;
}
/// getVBPtrOffset - Get the offset for virtual base table pointer.
/// This is only meaningful with the Microsoft ABI.
CharUnits getVBPtrOffset() const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
return CXXInfo->VBPtrOffset;
}
const VBaseOffsetsMapTy &getVBaseOffsetsMap() const {
assert(CXXInfo && "Record layout does not have C++ specific info!");
return CXXInfo->VBaseOffsets;
}
};
} // end namespace clang
#endif
|