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