xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/d/dmd/aggregate.h (revision 4c3eb207d36f67d31994830c0a694161fc1ca39b)
1 
2 /* Compiler implementation of the D programming language
3  * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
4  * written by Walter Bright
5  * http://www.digitalmars.com
6  * Distributed under the Boost Software License, Version 1.0.
7  * http://www.boost.org/LICENSE_1_0.txt
8  * https://github.com/dlang/dmd/blob/master/src/dmd/aggregate.h
9  */
10 
11 #pragma once
12 
13 #include "root/root.h"
14 
15 #include "dsymbol.h"
16 #include "declaration.h"
17 #include "objc.h"
18 
19 class Identifier;
20 class Type;
21 class TypeFunction;
22 class Expression;
23 class FuncDeclaration;
24 class CtorDeclaration;
25 class DtorDeclaration;
26 class InvariantDeclaration;
27 class NewDeclaration;
28 class DeleteDeclaration;
29 class InterfaceDeclaration;
30 class TypeInfoClassDeclaration;
31 class VarDeclaration;
32 
33 enum Sizeok
34 {
35     SIZEOKnone,         // size of aggregate is not yet able to compute
36     SIZEOKfwd,          // size of aggregate is ready to compute
37     SIZEOKdone          // size of aggregate is set correctly
38 };
39 
40 enum Baseok
41 {
42     BASEOKnone,         // base classes not computed yet
43     BASEOKin,           // in process of resolving base classes
44     BASEOKdone,         // all base classes are resolved
45     BASEOKsemanticdone  // all base classes semantic done
46 };
47 
48 enum StructPOD
49 {
50     ISPODno,            // struct is not POD
51     ISPODyes,           // struct is POD
52     ISPODfwd            // POD not yet computed
53 };
54 
55 enum Abstract
56 {
57     ABSfwdref = 0,      // whether an abstract class is not yet computed
58     ABSyes,             // is abstract class
59     ABSno               // is not abstract class
60 };
61 
62 FuncDeclaration *hasIdentityOpAssign(AggregateDeclaration *ad, Scope *sc);
63 FuncDeclaration *buildOpAssign(StructDeclaration *sd, Scope *sc);
64 bool needOpEquals(StructDeclaration *sd);
65 FuncDeclaration *buildOpEquals(StructDeclaration *sd, Scope *sc);
66 FuncDeclaration *buildXopEquals(StructDeclaration *sd, Scope *sc);
67 FuncDeclaration *buildXopCmp(StructDeclaration *sd, Scope *sc);
68 FuncDeclaration *buildXtoHash(StructDeclaration *ad, Scope *sc);
69 FuncDeclaration *buildPostBlit(StructDeclaration *sd, Scope *sc);
70 FuncDeclaration *buildDtor(AggregateDeclaration *ad, Scope *sc);
71 FuncDeclaration *buildInv(AggregateDeclaration *ad, Scope *sc);
72 FuncDeclaration *search_toString(StructDeclaration *sd);
73 
74 struct ClassKind
75 {
76     enum Type
77     {
78         /// the class is a d(efault) class
79         d,
80         /// the class is a C++ interface
81         cpp,
82         /// the class is an Objective-C class/interface
83         objc,
84     };
85 };
86 
87 class AggregateDeclaration : public ScopeDsymbol
88 {
89 public:
90     Type *type;
91     StorageClass storage_class;
92     Prot protection;
93     unsigned structsize;        // size of struct
94     unsigned alignsize;         // size of struct for alignment purposes
95     VarDeclarations fields;     // VarDeclaration fields
96     Sizeok sizeok;              // set when structsize contains valid data
97     Dsymbol *deferred;          // any deferred semantic2() or semantic3() symbol
98     bool isdeprecated;          // true if deprecated
99 
100     ClassKind::Type classKind;  // specifies the linkage type
101 
102     /* !=NULL if is nested
103      * pointing to the dsymbol that directly enclosing it.
104      * 1. The function that enclosing it (nested struct and class)
105      * 2. The class that enclosing it (nested class only)
106      * 3. If enclosing aggregate is template, its enclosing dsymbol.
107      * See AggregateDeclaraton::makeNested for the details.
108      */
109     Dsymbol *enclosing;
110     VarDeclaration *vthis;      // 'this' parameter if this aggregate is nested
111     // Special member functions
112     FuncDeclarations invs;              // Array of invariants
113     FuncDeclaration *inv;               // invariant
114     NewDeclaration *aggNew;             // allocator
115     DeleteDeclaration *aggDelete;       // deallocator
116 
117     Dsymbol *ctor;                      // CtorDeclaration or TemplateDeclaration
118 
119     // default constructor - should have no arguments, because
120     // it would be stored in TypeInfo_Class.defaultConstructor
121     CtorDeclaration *defaultCtor;
122 
123     Dsymbol *aliasthis;         // forward unresolved lookups to aliasthis
124     bool noDefaultCtor;         // no default construction
125 
126     FuncDeclarations dtors;     // Array of destructors
127     FuncDeclaration *dtor;      // aggregate destructor
128 
129     Expression *getRTInfo;      // pointer to GC info generated by object.RTInfo(this)
130 
131     AggregateDeclaration(Loc loc, Identifier *id);
132     virtual Scope *newScope(Scope *sc);
133     void setScope(Scope *sc);
134     void semantic2(Scope *sc);
135     void semantic3(Scope *sc);
136     bool determineFields();
137     bool determineSize(Loc loc);
138     virtual void finalizeSize() = 0;
139     d_uns64 size(Loc loc);
140     bool checkOverlappedFields();
141     bool fill(Loc loc, Expressions *elements, bool ctorinit);
142     static void alignmember(structalign_t salign, unsigned size, unsigned *poffset);
143     static unsigned placeField(unsigned *nextoffset,
144         unsigned memsize, unsigned memalignsize, structalign_t memalign,
145         unsigned *paggsize, unsigned *paggalignsize, bool isunion);
146     Type *getType();
147     bool isDeprecated();         // is aggregate deprecated?
148     bool isNested();
149     void makeNested();
150     bool isExport() const;
151     Dsymbol *searchCtor();
152 
153     Prot prot();
154 
155     // 'this' type
handleType()156     Type *handleType() { return type; }
157 
158     // Back end
159     Symbol *stag;               // tag symbol for debug data
160     Symbol *sinit;
161 
isAggregateDeclaration()162     AggregateDeclaration *isAggregateDeclaration() { return this; }
accept(Visitor * v)163     void accept(Visitor *v) { v->visit(this); }
164 };
165 
166 struct StructFlags
167 {
168     typedef unsigned Type;
169     enum Enum
170     {
171         none = 0x0,
172         hasPointers = 0x1  // NB: should use noPointers as in ClassFlags
173     };
174 };
175 
176 class StructDeclaration : public AggregateDeclaration
177 {
178 public:
179     int zeroInit;               // !=0 if initialize with 0 fill
180     bool hasIdentityAssign;     // true if has identity opAssign
181     bool hasIdentityEquals;     // true if has identity opEquals
182     FuncDeclarations postblits; // Array of postblit functions
183     FuncDeclaration *postblit;  // aggregate postblit
184 
185     FuncDeclaration *xeq;       // TypeInfo_Struct.xopEquals
186     FuncDeclaration *xcmp;      // TypeInfo_Struct.xopCmp
187     FuncDeclaration *xhash;     // TypeInfo_Struct.xtoHash
188     static FuncDeclaration *xerreq;      // object.xopEquals
189     static FuncDeclaration *xerrcmp;     // object.xopCmp
190 
191     structalign_t alignment;    // alignment applied outside of the struct
192     StructPOD ispod;            // if struct is POD
193 
194     // For 64 bit Efl function call/return ABI
195     Type *arg1type;
196     Type *arg2type;
197 
198     // Even if struct is defined as non-root symbol, some built-in operations
199     // (e.g. TypeidExp, NewExp, ArrayLiteralExp, etc) request its TypeInfo.
200     // For those, today TypeInfo_Struct is generated in COMDAT.
201     bool requestTypeInfo;
202 
203     StructDeclaration(Loc loc, Identifier *id, bool inObject);
204     static StructDeclaration *create(Loc loc, Identifier *id, bool inObject);
205     Dsymbol *syntaxCopy(Dsymbol *s);
206     void semantic(Scope *sc);
207     void semanticTypeInfoMembers();
208     Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
209     const char *kind() const;
210     void finalizeSize();
211     bool fit(Loc loc, Scope *sc, Expressions *elements, Type *stype);
212     bool isPOD();
213 
isStructDeclaration()214     StructDeclaration *isStructDeclaration() { return this; }
accept(Visitor * v)215     void accept(Visitor *v) { v->visit(this); }
216 };
217 
218 class UnionDeclaration : public StructDeclaration
219 {
220 public:
221     UnionDeclaration(Loc loc, Identifier *id);
222     Dsymbol *syntaxCopy(Dsymbol *s);
223     const char *kind() const;
224 
isUnionDeclaration()225     UnionDeclaration *isUnionDeclaration() { return this; }
accept(Visitor * v)226     void accept(Visitor *v) { v->visit(this); }
227 };
228 
229 struct BaseClass
230 {
231     Type *type;                         // (before semantic processing)
232 
233     ClassDeclaration *sym;
234     unsigned offset;                    // 'this' pointer offset
235     // for interfaces: Array of FuncDeclaration's
236     // making up the vtbl[]
237     FuncDeclarations vtbl;
238 
239     DArray<BaseClass> baseInterfaces;   // if BaseClass is an interface, these
240                                         // are a copy of the InterfaceDeclaration::interfaces
241 
242     BaseClass();
243     BaseClass(Type *type);
244 
245     bool fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newinstance);
246     void copyBaseInterfaces(BaseClasses *);
247 };
248 
249 struct ClassFlags
250 {
251     typedef unsigned Type;
252     enum Enum
253     {
254         isCOMclass = 0x1,
255         noPointers = 0x2,
256         hasOffTi = 0x4,
257         hasCtor = 0x8,
258         hasGetMembers = 0x10,
259         hasTypeInfo = 0x20,
260         isAbstract = 0x40,
261         isCPPclass = 0x80,
262         hasDtor = 0x100
263     };
264 };
265 
266 class ClassDeclaration : public AggregateDeclaration
267 {
268 public:
269     static ClassDeclaration *object;
270     static ClassDeclaration *throwable;
271     static ClassDeclaration *exception;
272     static ClassDeclaration *errorException;
273     static ClassDeclaration *cpp_type_info_ptr;
274 
275     ClassDeclaration *baseClass;        // NULL only if this is Object
276     FuncDeclaration *staticCtor;
277     FuncDeclaration *staticDtor;
278     Dsymbols vtbl;                      // Array of FuncDeclaration's making up the vtbl[]
279     Dsymbols vtblFinal;                 // More FuncDeclaration's that aren't in vtbl[]
280 
281     BaseClasses *baseclasses;           // Array of BaseClass's; first is super,
282                                         // rest are Interface's
283 
284     DArray<BaseClass*> interfaces;      // interfaces[interfaces_dim] for this class
285                                         // (does not include baseClass)
286 
287     BaseClasses *vtblInterfaces;        // array of base interfaces that have
288                                         // their own vtbl[]
289 
290     TypeInfoClassDeclaration *vclassinfo;       // the ClassInfo object for this ClassDeclaration
291     bool com;                           // true if this is a COM class (meaning it derives from IUnknown)
292     bool isscope;                       // true if this is a scope class
293     Abstract isabstract;                // 0: fwdref, 1: is abstract class, 2: not abstract
294     int inuse;                          // to prevent recursive attempts
295     Baseok baseok;                      // set the progress of base classes resolving
296     Symbol *cpp_type_info_ptr_sym;      // cached instance of class Id.cpp_type_info_ptr
297 
298     ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses, Dsymbols *members, bool inObject = false);
299     static ClassDeclaration *create(Loc loc, Identifier *id, BaseClasses *baseclasses, Dsymbols *members, bool inObject);
300     Dsymbol *syntaxCopy(Dsymbol *s);
301     Scope *newScope(Scope *sc);
302     void semantic(Scope *sc);
303     bool isBaseOf2(ClassDeclaration *cd);
304 
305     #define OFFSET_RUNTIME 0x76543210
306     #define OFFSET_FWDREF 0x76543211
307     virtual bool isBaseOf(ClassDeclaration *cd, int *poffset);
308 
309     bool isBaseInfoComplete();
310     Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
311     ClassDeclaration *searchBase(Identifier *ident);
312     void finalizeSize();
313     bool isFuncHidden(FuncDeclaration *fd);
314     FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf);
315     void interfaceSemantic(Scope *sc);
316     bool isCOMclass() const;
317     virtual bool isCOMinterface() const;
318     bool isCPPclass() const;
319     virtual bool isCPPinterface() const;
320     bool isAbstract();
321     virtual int vtblOffset() const;
322     const char *kind() const;
323 
324     void addLocalClass(ClassDeclarations *);
325 
326     // Back end
327     Symbol *vtblsym;
328 
isClassDeclaration()329     ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; }
accept(Visitor * v)330     void accept(Visitor *v) { v->visit(this); }
331 };
332 
333 class InterfaceDeclaration : public ClassDeclaration
334 {
335 public:
336     InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses);
337     Dsymbol *syntaxCopy(Dsymbol *s);
338     Scope *newScope(Scope *sc);
339     void semantic(Scope *sc);
340     bool isBaseOf(ClassDeclaration *cd, int *poffset);
341     bool isBaseOf(BaseClass *bc, int *poffset);
342     const char *kind() const;
343     int vtblOffset() const;
344     bool isCPPinterface() const;
345     bool isCOMinterface() const;
346 
isInterfaceDeclaration()347     InterfaceDeclaration *isInterfaceDeclaration() { return this; }
accept(Visitor * v)348     void accept(Visitor *v) { v->visit(this); }
349 };
350