/
aggregate.h
332 lines (279 loc) · 11.2 KB
/
aggregate.h
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
331
332
/* Compiler implementation of the D programming language
* Copyright (c) 1999-2016 by Digital Mars
* All Rights Reserved
* written by Walter Bright
* http://www.digitalmars.com
* Distributed under the Boost Software License, Version 1.0.
* http://www.boost.org/LICENSE_1_0.txt
* https://github.com/dlang/dmd/blob/master/src/aggregate.h
*/
#ifndef DMD_AGGREGATE_H
#define DMD_AGGREGATE_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "root.h"
#include "dsymbol.h"
#include "declaration.h"
#include "objc.h"
class Identifier;
class Type;
class TypeFunction;
class Expression;
class FuncDeclaration;
class CtorDeclaration;
class DtorDeclaration;
class InvariantDeclaration;
class NewDeclaration;
class DeleteDeclaration;
class InterfaceDeclaration;
class TypeInfoClassDeclaration;
class VarDeclaration;
enum Sizeok
{
SIZEOKnone, // size of aggregate is not yet able to compute
SIZEOKfwd, // size of aggregate is ready to compute
SIZEOKdone, // size of aggregate is set correctly
};
enum Baseok
{
BASEOKnone, // base classes not computed yet
BASEOKin, // in process of resolving base classes
BASEOKdone, // all base classes are resolved
BASEOKsemanticdone, // all base classes semantic done
};
enum StructPOD
{
ISPODno, // struct is not POD
ISPODyes, // struct is POD
ISPODfwd, // POD not yet computed
};
FuncDeclaration *hasIdentityOpAssign(AggregateDeclaration *ad, Scope *sc);
FuncDeclaration *buildOpAssign(StructDeclaration *sd, Scope *sc);
bool needOpEquals(StructDeclaration *sd);
FuncDeclaration *buildOpEquals(StructDeclaration *sd, Scope *sc);
FuncDeclaration *buildXopEquals(StructDeclaration *sd, Scope *sc);
FuncDeclaration *buildXopCmp(StructDeclaration *sd, Scope *sc);
FuncDeclaration *buildXtoHash(StructDeclaration *ad, Scope *sc);
FuncDeclaration *buildPostBlit(StructDeclaration *sd, Scope *sc);
FuncDeclaration *buildDtor(AggregateDeclaration *ad, Scope *sc);
FuncDeclaration *buildInv(AggregateDeclaration *ad, Scope *sc);
class AggregateDeclaration : public ScopeDsymbol
{
public:
Type *type;
StorageClass storage_class;
Prot protection;
unsigned structsize; // size of struct
unsigned alignsize; // size of struct for alignment purposes
VarDeclarations fields; // VarDeclaration fields
Sizeok sizeok; // set when structsize contains valid data
Dsymbol *deferred; // any deferred semantic2() or semantic3() symbol
bool isdeprecated; // true if deprecated
/* !=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
// Special member functions
FuncDeclarations invs; // Array of invariants
FuncDeclaration *inv; // invariant
NewDeclaration *aggNew; // allocator
DeleteDeclaration *aggDelete; // deallocator
Dsymbol *ctor; // CtorDeclaration or TemplateDeclaration
// default constructor - should have no arguments, because
// it would be stored in TypeInfo_Class.defaultConstructor
CtorDeclaration *defaultCtor;
Dsymbol *aliasthis; // forward unresolved lookups to aliasthis
bool noDefaultCtor; // no default construction
FuncDeclarations dtors; // Array of destructors
FuncDeclaration *dtor; // aggregate destructor
Expression *getRTInfo; // pointer to GC info generated by object.RTInfo(this)
AggregateDeclaration(Loc loc, Identifier *id);
void setScope(Scope *sc);
void semantic2(Scope *sc);
void semantic3(Scope *sc);
bool determineFields();
bool determineSize(Loc loc);
virtual void finalizeSize() = 0;
unsigned size(Loc loc);
bool checkOverlappedFields();
bool fill(Loc loc, Expressions *elements, bool ctorinit);
static void alignmember(structalign_t salign, unsigned size, unsigned *poffset);
static unsigned placeField(unsigned *nextoffset,
unsigned memsize, unsigned memalignsize, structalign_t memalign,
unsigned *paggsize, unsigned *paggalignsize, bool isunion);
Type *getType();
bool isDeprecated(); // is aggregate deprecated?
bool isNested();
void makeNested();
bool isExport();
Dsymbol *searchCtor();
Prot prot();
// 'this' type
Type *handleType() { return type; }
// Back end
Symbol *stag; // tag symbol for debug data
Symbol *sinit;
AggregateDeclaration *isAggregateDeclaration() { return this; }
void accept(Visitor *v) { v->visit(this); }
};
struct StructFlags
{
typedef unsigned Type;
enum Enum
{
hasPointers = 0x1, // NB: should use noPointers as in ClassFlags
};
};
class StructDeclaration : public AggregateDeclaration
{
public:
int zeroInit; // !=0 if initialize with 0 fill
bool hasIdentityAssign; // true if has identity opAssign
bool hasIdentityEquals; // true if has identity opEquals
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
StructPOD ispod; // if struct is POD
// For 64 bit Efl function call/return ABI
Type *arg1type;
Type *arg2type;
// 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;
StructDeclaration(Loc loc, Identifier *id);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
void semanticTypeInfoMembers();
Dsymbol *search(Loc, Identifier *ident, int flags = SearchLocalsOnly);
const char *kind();
void finalizeSize();
bool fit(Loc loc, Scope *sc, Expressions *elements, Type *stype);
bool isPOD();
StructDeclaration *isStructDeclaration() { return this; }
void accept(Visitor *v) { v->visit(this); }
};
class UnionDeclaration : public StructDeclaration
{
public:
UnionDeclaration(Loc loc, Identifier *id);
Dsymbol *syntaxCopy(Dsymbol *s);
const char *kind();
UnionDeclaration *isUnionDeclaration() { return this; }
void accept(Visitor *v) { 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;
size_t baseInterfaces_dim;
// if BaseClass is an interface, these
// are a copy of the InterfaceDeclaration::interfaces
BaseClass *baseInterfaces;
BaseClass();
BaseClass(Type *type);
bool fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newinstance);
void copyBaseInterfaces(BaseClasses *);
};
struct ClassFlags
{
typedef unsigned Type;
enum Enum
{
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 cpp; // true if this is a C++ interface
bool isscope; // true if this is a scope class
int isabstract; // 0: fwdref, 1: is abstract class, 2: not abstract
int inuse; // to prevent recursive attempts
Baseok baseok; // set the progress of base classes resolving
Objc_ClassDeclaration objc;
Symbol *cpp_type_info_ptr_sym; // cached instance of class Id.cpp_type_info_ptr
ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses, bool inObject = false);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
bool isBaseOf2(ClassDeclaration *cd);
#define OFFSET_RUNTIME 0x76543210
virtual bool isBaseOf(ClassDeclaration *cd, int *poffset);
bool isBaseInfoComplete();
Dsymbol *search(Loc, Identifier *ident, int flags = SearchLocalsOnly);
ClassDeclaration *searchBase(Loc, Identifier *ident);
void finalizeSize();
bool isFuncHidden(FuncDeclaration *fd);
FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf);
void interfaceSemantic(Scope *sc);
unsigned setBaseInterfaceOffsets(unsigned baseOffset);
bool isCOMclass() const;
virtual bool isCOMinterface() const;
bool isCPPclass() const;
virtual bool isCPPinterface() const;
bool isAbstract();
virtual int vtblOffset() const;
const char *kind();
void addLocalClass(ClassDeclarations *);
// Back end
Symbol *vtblsym;
ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; }
void accept(Visitor *v) { v->visit(this); }
};
class InterfaceDeclaration : public ClassDeclaration
{
public:
InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
bool isBaseOf(ClassDeclaration *cd, int *poffset);
bool isBaseOf(BaseClass *bc, int *poffset);
const char *kind();
int vtblOffset() const;
bool isCPPinterface() const;
bool isCOMinterface() const;
InterfaceDeclaration *isInterfaceDeclaration() { return this; }
void accept(Visitor *v) { v->visit(this); }
};
#endif /* DMD_AGGREGATE_H */