Home | History | Annotate | Line # | Download | only in dmd
      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 
     16 class AliasThis;
     17 class Identifier;
     18 class Type;
     19 class TypeFunction;
     20 class Expression;
     21 class FuncDeclaration;
     22 class CtorDeclaration;
     23 class DtorDeclaration;
     24 class InterfaceDeclaration;
     25 class TypeInfoClassDeclaration;
     26 class VarDeclaration;
     27 
     28 enum 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 
     36 enum 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 
     44 enum class ThreeState : uint8_t
     45 {
     46     none,         // value not yet computed
     47     no,           // value is false
     48     yes,          // value is true
     49 };
     50 
     51 FuncDeclaration *search_toString(StructDeclaration *sd);
     52 
     53 enum 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 
     65 struct MangleOverride
     66 {
     67     Dsymbol *agg;
     68     Identifier *id;
     69 };
     70 
     71 class AggregateDeclaration : public ScopeDsymbol
     72 {
     73 public:
     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 
    150 struct StructFlags
    151 {
    152     enum Type
    153     {
    154         none = 0x0,
    155         hasPointers = 0x1  // NB: should use noPointers as in ClassFlags
    156     };
    157 };
    158 
    159 class StructDeclaration : public AggregateDeclaration
    160 {
    161 public:
    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 
    203 class UnionDeclaration : public StructDeclaration
    204 {
    205 public:
    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 
    213 struct 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 
    229 struct 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 
    246 class ClassDeclaration : public AggregateDeclaration
    247 {
    248 public:
    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 
    317 class InterfaceDeclaration : public ClassDeclaration
    318 {
    319 public:
    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