1
2/* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
4 * written by Walter Bright
5 * https://www.digitalmars.com
6 * Distributed under the Boost Software License, Version 1.0.
7 * https://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 "dsymbol.h"
14#include "objc.h"
15
16class AliasThis;
17class Identifier;
18class Type;
19class TypeFunction;
20class Expression;
21class FuncDeclaration;
22class CtorDeclaration;
23class DtorDeclaration;
24class InterfaceDeclaration;
25class TypeInfoClassDeclaration;
26class VarDeclaration;
27
28enum class Sizeok : uint8_t
29{
30    none,         // size of aggregate is not yet able to compute
31    fwd,          // size of aggregate is ready to compute
32    inProcess,    // in the midst of computing the size
33    done          // size of aggregate is set correctly
34};
35
36enum class Baseok : uint8_t
37{
38    none,         // base classes not computed yet
39    in,           // in process of resolving base classes
40    done,         // all base classes are resolved
41    semanticdone  // all base classes semantic done
42};
43
44enum class ThreeState : uint8_t
45{
46    none,         // value not yet computed
47    no,           // value is false
48    yes,          // value is true
49};
50
51FuncDeclaration *search_toString(StructDeclaration *sd);
52
53enum class ClassKind : uint8_t
54{
55  /// the aggregate is a d(efault) struct/class/interface
56  d,
57  /// the aggregate is a C++ struct/class/interface
58  cpp,
59  /// the aggregate is an Objective-C class/interface
60  objc,
61  /// the aggregate is a C struct
62  c,
63};
64
65struct MangleOverride
66{
67    Dsymbol *agg;
68    Identifier *id;
69};
70
71class AggregateDeclaration : public ScopeDsymbol
72{
73public:
74    Type *type;
75    StorageClass storage_class;
76    unsigned structsize;        // size of struct
77    unsigned alignsize;         // size of struct for alignment purposes
78    VarDeclarations fields;     // VarDeclaration fields
79    Dsymbol *deferred;          // any deferred semantic2() or semantic3() symbol
80
81    ClassKind classKind;        // specifies the linkage type
82    CPPMANGLE cppmangle;
83
84    // overridden symbol with pragma(mangle, "...")
85    MangleOverride *mangleOverride;
86    /* !=NULL if is nested
87     * pointing to the dsymbol that directly enclosing it.
88     * 1. The function that enclosing it (nested struct and class)
89     * 2. The class that enclosing it (nested class only)
90     * 3. If enclosing aggregate is template, its enclosing dsymbol.
91     * See AggregateDeclaraton::makeNested for the details.
92     */
93    Dsymbol *enclosing;
94    VarDeclaration *vthis;      // 'this' parameter if this aggregate is nested
95    VarDeclaration *vthis2;     // 'this' parameter if this aggregate is a template and is nested
96    // Special member functions
97    FuncDeclarations invs;              // Array of invariants
98    FuncDeclaration *inv;               // invariant
99
100    Dsymbol *ctor;                      // CtorDeclaration or TemplateDeclaration
101
102    // default constructor - should have no arguments, because
103    // it would be stored in TypeInfo_Class.defaultConstructor
104    CtorDeclaration *defaultCtor;
105
106    AliasThis *aliasthis;       // forward unresolved lookups to aliasthis
107
108    DtorDeclarations userDtors; // user-defined destructors (`~this()`) - mixins can yield multiple ones
109    DtorDeclaration *aggrDtor;  // aggregate destructor calling userDtors and fieldDtor (and base class aggregate dtor for C++ classes)
110    DtorDeclaration *dtor;      // the aggregate destructor exposed as `__xdtor` alias
111                                // (same as aggrDtor, except for C++ classes with virtual dtor on Windows)
112    DtorDeclaration *tidtor;    // aggregate destructor used in TypeInfo (must have extern(D) ABI)
113    DtorDeclaration *fieldDtor; // function destructing (non-inherited) fields
114
115    Expression *getRTInfo;      // pointer to GC info generated by object.RTInfo(this)
116
117    Visibility visibility;
118    bool noDefaultCtor;         // no default construction
119    bool disableNew;            // disallow allocations using `new`
120    Sizeok sizeok;              // set when structsize contains valid data
121
122    virtual Scope *newScope(Scope *sc);
123    void setScope(Scope *sc);
124    size_t nonHiddenFields();
125    bool determineSize(const Loc &loc);
126    virtual void finalizeSize() = 0;
127    uinteger_t size(const Loc &loc);
128    bool fill(const Loc &loc, Expressions *elements, bool ctorinit);
129    Type *getType();
130    bool isDeprecated() const;         // is aggregate deprecated?
131    void setDeprecated();
132    bool isNested() const;
133    bool isExport() const;
134    Dsymbol *searchCtor();
135
136    Visibility visible();
137
138    // 'this' type
139    Type *handleType() { return type; }
140
141    bool hasInvariant();
142
143    // Back end
144    void *sinit;
145
146    AggregateDeclaration *isAggregateDeclaration() { return this; }
147    void accept(Visitor *v) { v->visit(this); }
148};
149
150struct StructFlags
151{
152    enum Type
153    {
154        none = 0x0,
155        hasPointers = 0x1  // NB: should use noPointers as in ClassFlags
156    };
157};
158
159class StructDeclaration : public AggregateDeclaration
160{
161public:
162    bool zeroInit;              // !=0 if initialize with 0 fill
163    bool hasIdentityAssign;     // true if has identity opAssign
164    bool hasBlitAssign;         // true if opAssign is a blit
165    bool hasIdentityEquals;     // true if has identity opEquals
166    bool hasNoFields;           // has no fields
167    bool hasCopyCtor;           // copy constructor
168    // Even if struct is defined as non-root symbol, some built-in operations
169    // (e.g. TypeidExp, NewExp, ArrayLiteralExp, etc) request its TypeInfo.
170    // For those, today TypeInfo_Struct is generated in COMDAT.
171    bool requestTypeInfo;
172
173    FuncDeclarations postblits; // Array of postblit functions
174    FuncDeclaration *postblit;  // aggregate postblit
175
176    FuncDeclaration *xeq;       // TypeInfo_Struct.xopEquals
177    FuncDeclaration *xcmp;      // TypeInfo_Struct.xopCmp
178    FuncDeclaration *xhash;     // TypeInfo_Struct.xtoHash
179    static FuncDeclaration *xerreq;      // object.xopEquals
180    static FuncDeclaration *xerrcmp;     // object.xopCmp
181
182    structalign_t alignment;    // alignment applied outside of the struct
183    ThreeState ispod;           // if struct is POD
184
185    // ABI-specific type(s) if the struct can be passed in registers
186    TypeTuple *argTypes;
187
188    static StructDeclaration *create(const Loc &loc, Identifier *id, bool inObject);
189    StructDeclaration *syntaxCopy(Dsymbol *s);
190    Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
191    const char *kind() const;
192    void finalizeSize();
193    bool isPOD();
194
195    StructDeclaration *isStructDeclaration() { return this; }
196    void accept(Visitor *v) { v->visit(this); }
197
198    unsigned numArgTypes() const;
199    Type *argType(unsigned index);
200    bool hasRegularCtor(bool checkDisabled = false);
201};
202
203class UnionDeclaration : public StructDeclaration
204{
205public:
206    UnionDeclaration *syntaxCopy(Dsymbol *s);
207    const char *kind() const;
208
209    UnionDeclaration *isUnionDeclaration() { return this; }
210    void accept(Visitor *v) { v->visit(this); }
211};
212
213struct BaseClass
214{
215    Type *type;                         // (before semantic processing)
216
217    ClassDeclaration *sym;
218    unsigned offset;                    // 'this' pointer offset
219    // for interfaces: Array of FuncDeclaration's
220    // making up the vtbl[]
221    FuncDeclarations vtbl;
222
223    DArray<BaseClass> baseInterfaces;   // if BaseClass is an interface, these
224                                        // are a copy of the InterfaceDeclaration::interfaces
225
226    bool fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newinstance);
227};
228
229struct ClassFlags
230{
231    enum Type
232    {
233        none = 0x0,
234        isCOMclass = 0x1,
235        noPointers = 0x2,
236        hasOffTi = 0x4,
237        hasCtor = 0x8,
238        hasGetMembers = 0x10,
239        hasTypeInfo = 0x20,
240        isAbstract = 0x40,
241        isCPPclass = 0x80,
242        hasDtor = 0x100
243    };
244};
245
246class ClassDeclaration : public AggregateDeclaration
247{
248public:
249    static ClassDeclaration *object;
250    static ClassDeclaration *throwable;
251    static ClassDeclaration *exception;
252    static ClassDeclaration *errorException;
253    static ClassDeclaration *cpp_type_info_ptr;
254
255    ClassDeclaration *baseClass;        // NULL only if this is Object
256    FuncDeclaration *staticCtor;
257    FuncDeclaration *staticDtor;
258    Dsymbols vtbl;                      // Array of FuncDeclaration's making up the vtbl[]
259    Dsymbols vtblFinal;                 // More FuncDeclaration's that aren't in vtbl[]
260
261    BaseClasses *baseclasses;           // Array of BaseClass's; first is super,
262                                        // rest are Interface's
263
264    DArray<BaseClass*> interfaces;      // interfaces[interfaces_dim] for this class
265                                        // (does not include baseClass)
266
267    BaseClasses *vtblInterfaces;        // array of base interfaces that have
268                                        // their own vtbl[]
269
270    TypeInfoClassDeclaration *vclassinfo;       // the ClassInfo object for this ClassDeclaration
271    bool com;                           // true if this is a COM class (meaning it derives from IUnknown)
272    bool stack;                         // true if this is a scope class
273    int cppDtorVtblIndex;               // slot reserved for the virtual destructor [extern(C++)]
274    bool inuse;                         // to prevent recursive attempts
275
276    ThreeState isabstract;              // if abstract class
277    Baseok baseok;                      // set the progress of base classes resolving
278    ObjcClassDeclaration objc;          // Data for a class declaration that is needed for the Objective-C integration
279    Symbol *cpp_type_info_ptr_sym;      // cached instance of class Id.cpp_type_info_ptr
280
281    static ClassDeclaration *create(const Loc &loc, Identifier *id, BaseClasses *baseclasses, Dsymbols *members, bool inObject);
282    const char *toPrettyChars(bool QualifyTypes = false);
283    ClassDeclaration *syntaxCopy(Dsymbol *s);
284    Scope *newScope(Scope *sc);
285    bool isBaseOf2(ClassDeclaration *cd);
286
287    #define OFFSET_RUNTIME 0x76543210
288    #define OFFSET_FWDREF 0x76543211
289    virtual bool isBaseOf(ClassDeclaration *cd, int *poffset);
290
291    bool isBaseInfoComplete();
292    Dsymbol *search(const Loc &loc, Identifier *ident, int flags = SearchLocalsOnly);
293    ClassDeclaration *searchBase(Identifier *ident);
294    void finalizeSize();
295    bool hasMonitor();
296    bool isFuncHidden(FuncDeclaration *fd);
297    FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf);
298    bool isCOMclass() const;
299    virtual bool isCOMinterface() const;
300    bool isCPPclass() const;
301    virtual bool isCPPinterface() const;
302    bool isAbstract();
303    virtual int vtblOffset() const;
304    const char *kind() const;
305
306    void addLocalClass(ClassDeclarations *);
307    void addObjcSymbols(ClassDeclarations *classes, ClassDeclarations *categories);
308
309    // Back end
310    Dsymbol *vtblsym;
311    Dsymbol *vtblSymbol();
312
313    ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; }
314    void accept(Visitor *v) { v->visit(this); }
315};
316
317class InterfaceDeclaration : public ClassDeclaration
318{
319public:
320    InterfaceDeclaration *syntaxCopy(Dsymbol *s);
321    Scope *newScope(Scope *sc);
322    bool isBaseOf(ClassDeclaration *cd, int *poffset);
323    const char *kind() const;
324    int vtblOffset() const;
325    bool isCPPinterface() const;
326    bool isCOMinterface() const;
327
328    InterfaceDeclaration *isInterfaceDeclaration() { return this; }
329    void accept(Visitor *v) { v->visit(this); }
330};
331