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
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
|
/* Compiler implementation of the D programming language
* Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
* written by Walter Bright
* https://www.digitalmars.com
* Distributed under the Boost Software License, Version 1.0.
* https://www.boost.org/LICENSE_1_0.txt
* https://github.com/dlang/dmd/blob/master/src/dmd/aggregate.h
*/
#pragma once
#include "dsymbol.h"
#include "objc.h"
class AliasThis;
class Identifier;
class Type;
class TypeFunction;
class Expression;
class FuncDeclaration;
class CtorDeclaration;
class DtorDeclaration;
class InterfaceDeclaration;
class TypeInfoClassDeclaration;
class VarDeclaration;
enum class Sizeok : uint8_t
{
none, // size of aggregate is not yet able to compute
fwd, // size of aggregate is ready to compute
inProcess, // in the midst of computing the size
done // size of aggregate is set correctly
};
enum class Baseok : uint8_t
{
none, // base classes not computed yet
in, // in process of resolving base classes
done, // all base classes are resolved
semanticdone // all base classes semantic done
};
enum class ThreeState : uint8_t
{
none, // value not yet computed
no, // value is false
yes, // value is true
};
FuncDeclaration *search_toString(StructDeclaration *sd);
enum class ClassKind : uint8_t
{
/// the aggregate is a d(efault) struct/class/interface
d,
/// the aggregate is a C++ struct/class/interface
cpp,
/// the aggregate is an Objective-C class/interface
objc,
/// the aggregate is a C struct
c,
};
struct MangleOverride
{
Dsymbol *agg;
Identifier *id;
};
class AggregateDeclaration : public ScopeDsymbol
{
public:
Type *type;
StorageClass storage_class;
unsigned structsize; // size of struct
unsigned alignsize; // size of struct for alignment purposes
VarDeclarations fields; // VarDeclaration fields
Dsymbol *deferred; // any deferred semantic2() or semantic3() symbol
ClassKind classKind; // specifies the linkage type
CPPMANGLE cppmangle;
// overridden symbol with pragma(mangle, "...")
MangleOverride *mangleOverride;
/* !=NULL if is nested
* pointing to the dsymbol that directly enclosing it.
* 1. The function that enclosing it (nested struct and class)
* 2. The class that enclosing it (nested class only)
* 3. If enclosing aggregate is template, its enclosing dsymbol.
* See AggregateDeclaraton::makeNested for the details.
*/
Dsymbol *enclosing;
VarDeclaration *vthis; // 'this' parameter if this aggregate is nested
VarDeclaration *vthis2; // 'this' parameter if this aggregate is a template and is nested
// Special member functions
FuncDeclarations invs; // Array of invariants
FuncDeclaration *inv; // invariant
Dsymbol *ctor; // CtorDeclaration or TemplateDeclaration
// default constructor - should have no arguments, because
// it would be stored in TypeInfo_Class.defaultConstructor
CtorDeclaration *defaultCtor;
AliasThis *aliasthis; // forward unresolved lookups to aliasthis
DtorDeclarations userDtors; // user-defined destructors (`~this()`) - mixins can yield multiple ones
DtorDeclaration *aggrDtor; // aggregate destructor calling userDtors and fieldDtor (and base class aggregate dtor for C++ classes)
DtorDeclaration *dtor; // the aggregate destructor exposed as `__xdtor` alias
// (same as aggrDtor, except for C++ classes with virtual dtor on Windows)
DtorDeclaration *tidtor; // aggregate destructor used in TypeInfo (must have extern(D) ABI)
DtorDeclaration *fieldDtor; // function destructing (non-inherited) fields
Expression *getRTInfo; // pointer to GC info generated by object.RTInfo(this)
Visibility visibility;
bool noDefaultCtor; // no default construction
bool disableNew; // disallow allocations using `new`
Sizeok sizeok; // set when structsize contains valid data
virtual Scope *newScope(Scope *sc);
void setScope(Scope *sc) override final;
size_t nonHiddenFields();
bool determineSize(const Loc &loc);
virtual void finalizeSize() = 0;
uinteger_t size(const Loc &loc) override final;
bool fill(const Loc &loc, Expressions *elements, bool ctorinit);
Type *getType() override final;
bool isDeprecated() const override final; // is aggregate deprecated?
void setDeprecated();
bool isNested() const;
bool isExport() const override final;
Dsymbol *searchCtor();
Visibility visible() override final;
// 'this' type
Type *handleType() { return type; }
bool hasInvariant();
// Back end
void *sinit;
AggregateDeclaration *isAggregateDeclaration() override final { return this; }
void accept(Visitor *v) override { v->visit(this); }
};
struct StructFlags
{
enum Type
{
none = 0x0,
hasPointers = 0x1 // NB: should use noPointers as in ClassFlags
};
};
class StructDeclaration : public AggregateDeclaration
{
public:
bool zeroInit; // !=0 if initialize with 0 fill
bool hasIdentityAssign; // true if has identity opAssign
bool hasBlitAssign; // true if opAssign is a blit
bool hasIdentityEquals; // true if has identity opEquals
bool hasNoFields; // has no fields
bool hasCopyCtor; // copy constructor
// Even if struct is defined as non-root symbol, some built-in operations
// (e.g. TypeidExp, NewExp, ArrayLiteralExp, etc) request its TypeInfo.
// For those, today TypeInfo_Struct is generated in COMDAT.
bool requestTypeInfo;
FuncDeclarations postblits; // Array of postblit functions
FuncDeclaration *postblit; // aggregate postblit
FuncDeclaration *xeq; // TypeInfo_Struct.xopEquals
FuncDeclaration *xcmp; // TypeInfo_Struct.xopCmp
FuncDeclaration *xhash; // TypeInfo_Struct.xtoHash
static FuncDeclaration *xerreq; // object.xopEquals
static FuncDeclaration *xerrcmp; // object.xopCmp
structalign_t alignment; // alignment applied outside of the struct
ThreeState ispod; // if struct is POD
// ABI-specific type(s) if the struct can be passed in registers
TypeTuple *argTypes;
static StructDeclaration *create(const Loc &loc, Identifier *id, bool inObject);
StructDeclaration *syntaxCopy(Dsymbol *s) override;
Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override final;
const char *kind() const override;
void finalizeSize() override final;
bool isPOD();
StructDeclaration *isStructDeclaration() override final { return this; }
void accept(Visitor *v) override { v->visit(this); }
unsigned numArgTypes() const;
Type *argType(unsigned index);
bool hasRegularCtor(bool checkDisabled = false);
};
class UnionDeclaration final : public StructDeclaration
{
public:
UnionDeclaration *syntaxCopy(Dsymbol *s) override;
const char *kind() const override;
UnionDeclaration *isUnionDeclaration() override { return this; }
void accept(Visitor *v) override { v->visit(this); }
};
struct BaseClass
{
Type *type; // (before semantic processing)
ClassDeclaration *sym;
unsigned offset; // 'this' pointer offset
// for interfaces: Array of FuncDeclaration's
// making up the vtbl[]
FuncDeclarations vtbl;
DArray<BaseClass> baseInterfaces; // if BaseClass is an interface, these
// are a copy of the InterfaceDeclaration::interfaces
bool fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newinstance);
};
struct ClassFlags
{
enum Type
{
none = 0x0,
isCOMclass = 0x1,
noPointers = 0x2,
hasOffTi = 0x4,
hasCtor = 0x8,
hasGetMembers = 0x10,
hasTypeInfo = 0x20,
isAbstract = 0x40,
isCPPclass = 0x80,
hasDtor = 0x100
};
};
class ClassDeclaration : public AggregateDeclaration
{
public:
static ClassDeclaration *object;
static ClassDeclaration *throwable;
static ClassDeclaration *exception;
static ClassDeclaration *errorException;
static ClassDeclaration *cpp_type_info_ptr;
ClassDeclaration *baseClass; // NULL only if this is Object
FuncDeclaration *staticCtor;
FuncDeclaration *staticDtor;
Dsymbols vtbl; // Array of FuncDeclaration's making up the vtbl[]
Dsymbols vtblFinal; // More FuncDeclaration's that aren't in vtbl[]
BaseClasses *baseclasses; // Array of BaseClass's; first is super,
// rest are Interface's
DArray<BaseClass*> interfaces; // interfaces[interfaces_dim] for this class
// (does not include baseClass)
BaseClasses *vtblInterfaces; // array of base interfaces that have
// their own vtbl[]
TypeInfoClassDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration
bool com; // true if this is a COM class (meaning it derives from IUnknown)
bool stack; // true if this is a scope class
int cppDtorVtblIndex; // slot reserved for the virtual destructor [extern(C++)]
bool inuse; // to prevent recursive attempts
ThreeState isabstract; // if abstract class
Baseok baseok; // set the progress of base classes resolving
ObjcClassDeclaration objc; // Data for a class declaration that is needed for the Objective-C integration
Symbol *cpp_type_info_ptr_sym; // cached instance of class Id.cpp_type_info_ptr
static ClassDeclaration *create(const Loc &loc, Identifier *id, BaseClasses *baseclasses, Dsymbols *members, bool inObject);
const char *toPrettyChars(bool QualifyTypes = false) override;
ClassDeclaration *syntaxCopy(Dsymbol *s) override;
Scope *newScope(Scope *sc) override;
bool isBaseOf2(ClassDeclaration *cd);
#define OFFSET_RUNTIME 0x76543210
#define OFFSET_FWDREF 0x76543211
virtual bool isBaseOf(ClassDeclaration *cd, int *poffset);
bool isBaseInfoComplete();
Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly) override final;
ClassDeclaration *searchBase(Identifier *ident);
void finalizeSize() override;
bool hasMonitor();
bool isFuncHidden(FuncDeclaration *fd);
FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf);
bool isCOMclass() const;
virtual bool isCOMinterface() const;
bool isCPPclass() const;
virtual bool isCPPinterface() const;
bool isAbstract();
virtual int vtblOffset() const;
const char *kind() const override;
void addLocalClass(ClassDeclarations *) override final;
void addObjcSymbols(ClassDeclarations *classes, ClassDeclarations *categories) override final;
// Back end
Dsymbol *vtblsym;
Dsymbol *vtblSymbol();
ClassDeclaration *isClassDeclaration() override final { return (ClassDeclaration *)this; }
void accept(Visitor *v) override { v->visit(this); }
};
class InterfaceDeclaration final : public ClassDeclaration
{
public:
InterfaceDeclaration *syntaxCopy(Dsymbol *s) override;
Scope *newScope(Scope *sc) override;
bool isBaseOf(ClassDeclaration *cd, int *poffset) override;
const char *kind() const override;
int vtblOffset() const override;
bool isCPPinterface() const override;
bool isCOMinterface() const override;
InterfaceDeclaration *isInterfaceDeclaration() override { return this; }
void accept(Visitor *v) override { v->visit(this); }
};
|