(root)/
gcc-13.2.0/
gcc/
d/
dmd/
mtype.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/mtype.h
       9   */
      10  
      11  #pragma once
      12  
      13  #include "root/dcompat.h" // for d_size_t
      14  
      15  #include "arraytypes.h"
      16  #include "ast_node.h"
      17  #include "globals.h"
      18  #include "visitor.h"
      19  
      20  struct Scope;
      21  class AggregateDeclaration;
      22  class Identifier;
      23  class Expression;
      24  class StructDeclaration;
      25  class ClassDeclaration;
      26  class EnumDeclaration;
      27  class TypeInfoDeclaration;
      28  class Dsymbol;
      29  class TemplateInstance;
      30  class TemplateDeclaration;
      31  
      32  class TypeBasic;
      33  class Parameter;
      34  
      35  // Back end
      36  #ifdef IN_GCC
      37  typedef union tree_node type;
      38  #else
      39  typedef struct TYPE type;
      40  #endif
      41  
      42  void semanticTypeInfo(Scope *sc, Type *t);
      43  
      44  Type *typeSemantic(Type *t, const Loc &loc, Scope *sc);
      45  Type *merge(Type *type);
      46  
      47  enum class TY : uint8_t
      48  {
      49      Tarray,             // slice array, aka T[]
      50      Tsarray,            // static array, aka T[dimension]
      51      Taarray,            // associative array, aka T[type]
      52      Tpointer,
      53      Treference,
      54      Tfunction,
      55      Tident,
      56      Tclass,
      57      Tstruct,
      58      Tenum,
      59  
      60      Tdelegate,
      61      Tnone,
      62      Tvoid,
      63      Tint8,
      64      Tuns8,
      65      Tint16,
      66      Tuns16,
      67      Tint32,
      68      Tuns32,
      69      Tint64,
      70  
      71      Tuns64,
      72      Tfloat32,
      73      Tfloat64,
      74      Tfloat80,
      75      Timaginary32,
      76      Timaginary64,
      77      Timaginary80,
      78      Tcomplex32,
      79      Tcomplex64,
      80      Tcomplex80,
      81  
      82      Tbool,
      83      Tchar,
      84      Twchar,
      85      Tdchar,
      86      Terror,
      87      Tinstance,
      88      Ttypeof,
      89      Ttuple,
      90      Tslice,
      91      Treturn,
      92  
      93      Tnull,
      94      Tvector,
      95      Tint128,
      96      Tuns128,
      97      Ttraits,
      98      Tmixin,
      99      Tnoreturn,
     100      TMAX
     101  };
     102  
     103  #define SIZE_INVALID (~(uinteger_t)0)   // error return from size() functions
     104  
     105  
     106  /**
     107   * type modifiers
     108   * pick this order of numbers so switch statements work better
     109   */
     110  enum MODFlags
     111  {
     112      MODnone      = 0, // default (mutable)
     113      MODconst     = 1, // type is const
     114      MODimmutable = 4, // type is immutable
     115      MODshared    = 2, // type is shared
     116      MODwild      = 8, // type is wild
     117      MODwildconst = (MODwild | MODconst), // type is wild const
     118      MODmutable   = 0x10       // type is mutable (only used in wildcard matching)
     119  };
     120  typedef unsigned char MOD;
     121  
     122  enum VarArgValues
     123  {
     124      VARARGnone     = 0,  /// fixed number of arguments
     125      VARARGvariadic = 1,  /// T t, ...)  can be C-style (core.stdc.stdarg) or D-style (core.vararg)
     126      VARARGtypesafe = 2   /// T t ...) typesafe https://dlang.org/spec/function.html#typesafe_variadic_functions
     127                           ///   or https://dlang.org/spec/function.html#typesafe_variadic_functions
     128  };
     129  typedef unsigned char VarArg;
     130  
     131  enum class Covariant
     132  {
     133      distinct = 0, /// types are distinct
     134      yes = 1,      /// types are covariant
     135      no = 2,       /// arguments match as far as overloading goes, but types are not covariant
     136      fwdref = 3,   /// cannot determine covariance because of forward references
     137  };
     138  
     139  class Type : public ASTNode
     140  {
     141  public:
     142      TY ty;
     143      MOD mod;  // modifiers MODxxxx
     144      char *deco;
     145  
     146  private:
     147      void* mcache;
     148  
     149  public:
     150      Type *pto;          // merged pointer to this type
     151      Type *rto;          // reference to this type
     152      Type *arrayof;      // array of this type
     153      TypeInfoDeclaration *vtinfo;        // TypeInfo object for this Type
     154  
     155      type *ctype;        // for back end
     156  
     157      static Type *tvoid;
     158      static Type *tint8;
     159      static Type *tuns8;
     160      static Type *tint16;
     161      static Type *tuns16;
     162      static Type *tint32;
     163      static Type *tuns32;
     164      static Type *tint64;
     165      static Type *tuns64;
     166      static Type *tint128;
     167      static Type *tuns128;
     168      static Type *tfloat32;
     169      static Type *tfloat64;
     170      static Type *tfloat80;
     171  
     172      static Type *timaginary32;
     173      static Type *timaginary64;
     174      static Type *timaginary80;
     175  
     176      static Type *tcomplex32;
     177      static Type *tcomplex64;
     178      static Type *tcomplex80;
     179  
     180      static Type *tbool;
     181      static Type *tchar;
     182      static Type *twchar;
     183      static Type *tdchar;
     184  
     185      // Some special types
     186      static Type *tshiftcnt;
     187      static Type *tvoidptr;              // void*
     188      static Type *tstring;               // immutable(char)[]
     189      static Type *twstring;              // immutable(wchar)[]
     190      static Type *tdstring;              // immutable(dchar)[]
     191      static Type *terror;                // for error recovery
     192      static Type *tnull;                 // for null type
     193      static Type *tnoreturn;             // for bottom type typeof(*null)
     194  
     195      static Type *tsize_t;               // matches size_t alias
     196      static Type *tptrdiff_t;            // matches ptrdiff_t alias
     197      static Type *thash_t;               // matches hash_t alias
     198  
     199      static ClassDeclaration *dtypeinfo;
     200      static ClassDeclaration *typeinfoclass;
     201      static ClassDeclaration *typeinfointerface;
     202      static ClassDeclaration *typeinfostruct;
     203      static ClassDeclaration *typeinfopointer;
     204      static ClassDeclaration *typeinfoarray;
     205      static ClassDeclaration *typeinfostaticarray;
     206      static ClassDeclaration *typeinfoassociativearray;
     207      static ClassDeclaration *typeinfovector;
     208      static ClassDeclaration *typeinfoenum;
     209      static ClassDeclaration *typeinfofunction;
     210      static ClassDeclaration *typeinfodelegate;
     211      static ClassDeclaration *typeinfotypelist;
     212      static ClassDeclaration *typeinfoconst;
     213      static ClassDeclaration *typeinfoinvariant;
     214      static ClassDeclaration *typeinfoshared;
     215      static ClassDeclaration *typeinfowild;
     216  
     217      static TemplateDeclaration *rtinfo;
     218  
     219      static Type *basic[(int)TY::TMAX];
     220  
     221      virtual const char *kind();
     222      Type *copy() const;
     223      virtual Type *syntaxCopy();
     224      bool equals(const RootObject * const o) const override;
     225      bool equivalent(Type *t);
     226      // kludge for template.isType()
     227      DYNCAST dyncast() const override final { return DYNCAST_TYPE; }
     228      size_t getUniqueID() const;
     229      Covariant covariant(Type *, StorageClass * = NULL, bool = false);
     230      const char *toChars() const override;
     231      char *toPrettyChars(bool QualifyTypes = false);
     232      static void _init();
     233  
     234      uinteger_t size();
     235      virtual uinteger_t size(const Loc &loc);
     236      virtual unsigned alignsize();
     237      Type *trySemantic(const Loc &loc, Scope *sc);
     238      Type *merge2();
     239      void modToBuffer(OutBuffer *buf) const;
     240      char *modToChars() const;
     241  
     242      virtual bool isintegral();
     243      virtual bool isfloating();   // real, imaginary, or complex
     244      virtual bool isreal();
     245      virtual bool isimaginary();
     246      virtual bool iscomplex();
     247      virtual bool isscalar();
     248      virtual bool isunsigned();
     249      virtual bool isscope();
     250      virtual bool isString();
     251      virtual bool isAssignable();
     252      virtual bool isBoolean();
     253      virtual void checkDeprecated(const Loc &loc, Scope *sc);
     254      bool isConst() const       { return (mod & MODconst) != 0; }
     255      bool isImmutable() const   { return (mod & MODimmutable) != 0; }
     256      bool isMutable() const     { return (mod & (MODconst | MODimmutable | MODwild)) == 0; }
     257      bool isShared() const      { return (mod & MODshared) != 0; }
     258      bool isSharedConst() const { return (mod & (MODshared | MODconst)) == (MODshared | MODconst); }
     259      bool isWild() const        { return (mod & MODwild) != 0; }
     260      bool isWildConst() const   { return (mod & MODwildconst) == MODwildconst; }
     261      bool isSharedWild() const  { return (mod & (MODshared | MODwild)) == (MODshared | MODwild); }
     262      bool isNaked() const       { return mod == 0; }
     263      Type *nullAttributes() const;
     264      Type *constOf();
     265      Type *immutableOf();
     266      Type *mutableOf();
     267      Type *sharedOf();
     268      Type *sharedConstOf();
     269      Type *unSharedOf();
     270      Type *wildOf();
     271      Type *wildConstOf();
     272      Type *sharedWildOf();
     273      Type *sharedWildConstOf();
     274      void fixTo(Type *t);
     275      void check();
     276      Type *addSTC(StorageClass stc);
     277      Type *castMod(MOD mod);
     278      Type *addMod(MOD mod);
     279      virtual Type *addStorageClass(StorageClass stc);
     280      Type *pointerTo();
     281      Type *referenceTo();
     282      Type *arrayOf();
     283      Type *sarrayOf(dinteger_t dim);
     284      bool hasDeprecatedAliasThis();
     285      Type *aliasthisOf();
     286      virtual Type *makeConst();
     287      virtual Type *makeImmutable();
     288      virtual Type *makeShared();
     289      virtual Type *makeSharedConst();
     290      virtual Type *makeWild();
     291      virtual Type *makeWildConst();
     292      virtual Type *makeSharedWild();
     293      virtual Type *makeSharedWildConst();
     294      virtual Type *makeMutable();
     295      virtual Dsymbol *toDsymbol(Scope *sc);
     296      Type *toBasetype();
     297      virtual bool isBaseOf(Type *t, int *poffset);
     298      virtual MATCH implicitConvTo(Type *to);
     299      virtual MATCH constConv(Type *to);
     300      virtual unsigned char deduceWild(Type *t, bool isRef);
     301      virtual Type *substWildTo(unsigned mod);
     302  
     303      Type *unqualify(unsigned m);
     304  
     305      virtual Type *toHeadMutable();
     306      virtual ClassDeclaration *isClassHandle();
     307      virtual structalign_t alignment();
     308      virtual Expression *defaultInitLiteral(const Loc &loc);
     309      virtual bool isZeroInit(const Loc &loc = Loc()); // if initializer is 0
     310      Identifier *getTypeInfoIdent();
     311      virtual int hasWild() const;
     312      virtual bool hasPointers();
     313      virtual bool hasVoidInitPointers();
     314      virtual bool hasSystemFields();
     315      virtual bool hasInvariant();
     316      virtual Type *nextOf();
     317      Type *baseElemOf();
     318      uinteger_t sizemask();
     319      virtual bool needsDestruction();
     320      virtual bool needsCopyOrPostblit();
     321      virtual bool needsNested();
     322  
     323      TypeFunction *toTypeFunction();
     324  
     325      // For eliminating dynamic_cast
     326      virtual TypeBasic *isTypeBasic();
     327      TypeFunction *isPtrToFunction();
     328      TypeFunction *isFunction_Delegate_PtrToFunction();
     329      TypeError *isTypeError();
     330      TypeVector *isTypeVector();
     331      TypeSArray *isTypeSArray();
     332      TypeDArray *isTypeDArray();
     333      TypeAArray *isTypeAArray();
     334      TypePointer *isTypePointer();
     335      TypeReference *isTypeReference();
     336      TypeFunction *isTypeFunction();
     337      TypeDelegate *isTypeDelegate();
     338      TypeIdentifier *isTypeIdentifier();
     339      TypeInstance *isTypeInstance();
     340      TypeTypeof *isTypeTypeof();
     341      TypeReturn *isTypeReturn();
     342      TypeStruct *isTypeStruct();
     343      TypeEnum *isTypeEnum();
     344      TypeClass *isTypeClass();
     345      TypeTuple *isTypeTuple();
     346      TypeSlice *isTypeSlice();
     347      TypeNull *isTypeNull();
     348      TypeMixin *isTypeMixin();
     349      TypeTraits *isTypeTraits();
     350      TypeNoreturn *isTypeNoreturn();
     351      TypeTag *isTypeTag();
     352  
     353      void accept(Visitor *v) override { v->visit(this); }
     354  };
     355  
     356  class TypeError final : public Type
     357  {
     358  public:
     359      const char *kind() override;
     360      TypeError *syntaxCopy() override;
     361  
     362      uinteger_t size(const Loc &loc) override;
     363      Expression *defaultInitLiteral(const Loc &loc) override;
     364      void accept(Visitor *v) override { v->visit(this); }
     365  };
     366  
     367  class TypeNext : public Type
     368  {
     369  public:
     370      Type *next;
     371  
     372      void checkDeprecated(const Loc &loc, Scope *sc) override final;
     373      int hasWild() const override final;
     374      Type *nextOf() override final;
     375      Type *makeConst() override final;
     376      Type *makeImmutable() override final;
     377      Type *makeShared() override final;
     378      Type *makeSharedConst() override final;
     379      Type *makeWild() override final;
     380      Type *makeWildConst() override final;
     381      Type *makeSharedWild() override final;
     382      Type *makeSharedWildConst() override final;
     383      Type *makeMutable() override final;
     384      MATCH constConv(Type *to) override;
     385      unsigned char deduceWild(Type *t, bool isRef) override final;
     386      void transitive();
     387      void accept(Visitor *v) override { v->visit(this); }
     388  };
     389  
     390  class TypeBasic final : public Type
     391  {
     392  public:
     393      const char *dstring;
     394      unsigned flags;
     395  
     396      const char *kind() override;
     397      TypeBasic *syntaxCopy() override;
     398      uinteger_t size(const Loc &loc) override;
     399      unsigned alignsize() override;
     400      bool isintegral() override;
     401      bool isfloating() override;
     402      bool isreal() override;
     403      bool isimaginary() override;
     404      bool iscomplex() override;
     405      bool isscalar() override;
     406      bool isunsigned() override;
     407      MATCH implicitConvTo(Type *to) override;
     408      bool isZeroInit(const Loc &loc) override;
     409  
     410      // For eliminating dynamic_cast
     411      TypeBasic *isTypeBasic() override;
     412      void accept(Visitor *v) override { v->visit(this); }
     413  };
     414  
     415  class TypeVector final : public Type
     416  {
     417  public:
     418      Type *basetype;
     419  
     420      static TypeVector *create(Type *basetype);
     421      const char *kind() override;
     422      TypeVector *syntaxCopy() override;
     423      uinteger_t size(const Loc &loc) override;
     424      unsigned alignsize() override;
     425      bool isintegral() override;
     426      bool isfloating() override;
     427      bool isscalar() override;
     428      bool isunsigned() override;
     429      bool isBoolean() override;
     430      MATCH implicitConvTo(Type *to) override;
     431      Expression *defaultInitLiteral(const Loc &loc) override;
     432      TypeBasic *elementType();
     433      bool isZeroInit(const Loc &loc) override;
     434  
     435      void accept(Visitor *v) override { v->visit(this); }
     436  };
     437  
     438  class TypeArray : public TypeNext
     439  {
     440  public:
     441      void accept(Visitor *v) override { v->visit(this); }
     442  };
     443  
     444  // Static array, one with a fixed dimension
     445  class TypeSArray final : public TypeArray
     446  {
     447  public:
     448      Expression *dim;
     449  
     450      const char *kind() override;
     451      TypeSArray *syntaxCopy() override;
     452      bool isIncomplete();
     453      uinteger_t size(const Loc &loc) override;
     454      unsigned alignsize() override;
     455      bool isString() override;
     456      bool isZeroInit(const Loc &loc) override;
     457      structalign_t alignment() override;
     458      MATCH constConv(Type *to) override;
     459      MATCH implicitConvTo(Type *to) override;
     460      Expression *defaultInitLiteral(const Loc &loc) override;
     461      bool hasPointers() override;
     462      bool hasSystemFields() override;
     463      bool hasVoidInitPointers() override;
     464      bool hasInvariant() override;
     465      bool needsDestruction() override;
     466      bool needsCopyOrPostblit() override;
     467      bool needsNested() override;
     468  
     469      void accept(Visitor *v) override { v->visit(this); }
     470  };
     471  
     472  // Dynamic array, no dimension
     473  class TypeDArray final : public TypeArray
     474  {
     475  public:
     476      const char *kind() override;
     477      TypeDArray *syntaxCopy() override;
     478      uinteger_t size(const Loc &loc) override;
     479      unsigned alignsize() override;
     480      bool isString() override;
     481      bool isZeroInit(const Loc &loc) override;
     482      bool isBoolean() override;
     483      MATCH implicitConvTo(Type *to) override;
     484      bool hasPointers() override;
     485  
     486      void accept(Visitor *v) override { v->visit(this); }
     487  };
     488  
     489  class TypeAArray final : public TypeArray
     490  {
     491  public:
     492      Type *index;                // key type
     493      Loc loc;
     494  
     495      static TypeAArray *create(Type *t, Type *index);
     496      const char *kind() override;
     497      TypeAArray *syntaxCopy() override;
     498      uinteger_t size(const Loc &loc) override;
     499      bool isZeroInit(const Loc &loc) override;
     500      bool isBoolean() override;
     501      bool hasPointers() override;
     502      MATCH implicitConvTo(Type *to) override;
     503      MATCH constConv(Type *to) override;
     504  
     505      void accept(Visitor *v) override { v->visit(this); }
     506  };
     507  
     508  class TypePointer final : public TypeNext
     509  {
     510  public:
     511      static TypePointer *create(Type *t);
     512      const char *kind() override;
     513      TypePointer *syntaxCopy() override;
     514      uinteger_t size(const Loc &loc) override;
     515      MATCH implicitConvTo(Type *to) override;
     516      MATCH constConv(Type *to) override;
     517      bool isscalar() override;
     518      bool isZeroInit(const Loc &loc) override;
     519      bool hasPointers() override;
     520  
     521      void accept(Visitor *v) override { v->visit(this); }
     522  };
     523  
     524  class TypeReference final : public TypeNext
     525  {
     526  public:
     527      const char *kind() override;
     528      TypeReference *syntaxCopy() override;
     529      uinteger_t size(const Loc &loc) override;
     530      bool isZeroInit(const Loc &loc) override;
     531      void accept(Visitor *v) override { v->visit(this); }
     532  };
     533  
     534  enum RET
     535  {
     536      RETregs     = 1,    // returned in registers
     537      RETstack    = 2     // returned on stack
     538  };
     539  
     540  enum class TRUST : unsigned char
     541  {
     542      default_ = 0,
     543      system = 1,    // @system (same as TRUSTdefault)
     544      trusted = 2,   // @trusted
     545      safe = 3       // @safe
     546  };
     547  
     548  enum TRUSTformat
     549  {
     550      TRUSTformatDefault,  // do not emit @system when trust == TRUSTdefault
     551      TRUSTformatSystem    // emit @system when trust == TRUSTdefault
     552  };
     553  
     554  enum class PURE : unsigned char
     555  {
     556      impure = 0,     // not pure at all
     557      fwdref = 1,     // it's pure, but not known which level yet
     558      weak = 2,       // no mutable globals are read or written
     559      const_ = 3,     // parameters are values or const
     560  };
     561  
     562  class Parameter final : public ASTNode
     563  {
     564  public:
     565      StorageClass storageClass;
     566      Type *type;
     567      Identifier *ident;
     568      Expression *defaultArg;
     569      UserAttributeDeclaration *userAttribDecl;   // user defined attributes
     570  
     571      static Parameter *create(StorageClass storageClass, Type *type, Identifier *ident,
     572                               Expression *defaultArg, UserAttributeDeclaration *userAttribDecl);
     573      Parameter *syntaxCopy();
     574      Type *isLazyArray();
     575      bool isLazy() const;
     576      bool isReference() const;
     577      // kludge for template.isType()
     578      DYNCAST dyncast() const override { return DYNCAST_PARAMETER; }
     579      void accept(Visitor *v) override { v->visit(this); }
     580  
     581      static size_t dim(Parameters *parameters);
     582      static Parameter *getNth(Parameters *parameters, d_size_t nth);
     583      const char *toChars() const override;
     584      bool isCovariant(bool returnByRef, const Parameter *p, bool previewIn) const;
     585  };
     586  
     587  struct ParameterList
     588  {
     589      Parameters* parameters;
     590      StorageClass stc;
     591      VarArg varargs;
     592      d_bool hasIdentifierList; // true if C identifier-list style
     593  
     594      size_t length();
     595      Parameter *operator[](size_t i) { return Parameter::getNth(parameters, i); }
     596  };
     597  
     598  class TypeFunction final : public TypeNext
     599  {
     600  public:
     601      // .next is the return type
     602  
     603      ParameterList parameterList; // function parameters
     604      uint16_t bitFields;
     605      LINK linkage;                // calling convention
     606      TRUST trust;                 // level of trust
     607      PURE purity;                 // PURExxxx
     608      char inuse;
     609      Expressions *fargs;          // function arguments
     610  
     611      static TypeFunction *create(Parameters *parameters, Type *treturn, VarArg varargs, LINK linkage, StorageClass stc = 0);
     612      const char *kind() override;
     613      TypeFunction *syntaxCopy() override;
     614      void purityLevel();
     615      bool hasLazyParameters();
     616      bool isDstyleVariadic() const;
     617      StorageClass parameterStorageClass(Parameter *p);
     618      Type *addStorageClass(StorageClass stc) override;
     619  
     620      Type *substWildTo(unsigned mod) override;
     621      MATCH constConv(Type *to) override;
     622  
     623      bool isnothrow() const;
     624      void isnothrow(bool v);
     625      bool isnogc() const;
     626      void isnogc(bool v);
     627      bool isproperty() const;
     628      void isproperty(bool v);
     629      bool isref() const;
     630      void isref(bool v);
     631      bool isreturn() const;
     632      void isreturn(bool v);
     633      bool isreturnscope() const;
     634      void isreturnscope(bool v);
     635      bool isScopeQual() const;
     636      void isScopeQual(bool v);
     637      bool isreturninferred() const;
     638      void isreturninferred(bool v);
     639      bool isscopeinferred() const;
     640      void isscopeinferred(bool v);
     641      bool islive() const;
     642      void islive(bool v);
     643      bool incomplete() const;
     644      void incomplete(bool v);
     645      bool isInOutParam() const;
     646      void isInOutParam(bool v);
     647      bool isInOutQual() const;
     648      void isInOutQual(bool v);
     649      bool iswild() const;
     650  
     651      void accept(Visitor *v) override { v->visit(this); }
     652  };
     653  
     654  class TypeDelegate final : public TypeNext
     655  {
     656  public:
     657      // .next is a TypeFunction
     658  
     659      static TypeDelegate *create(TypeFunction *t);
     660      const char *kind() override;
     661      TypeDelegate *syntaxCopy() override;
     662      Type *addStorageClass(StorageClass stc) override;
     663      uinteger_t size(const Loc &loc) override;
     664      unsigned alignsize() override;
     665      MATCH implicitConvTo(Type *to) override;
     666      bool isZeroInit(const Loc &loc) override;
     667      bool isBoolean() override;
     668      bool hasPointers() override;
     669  
     670      void accept(Visitor *v) override { v->visit(this); }
     671  };
     672  
     673  class TypeTraits final : public Type
     674  {
     675      Loc loc;
     676      /// The expression to resolve as type or symbol.
     677      TraitsExp *exp;
     678      /// Cached type/symbol after semantic analysis.
     679      RootObject *obj;
     680  
     681      const char *kind() override;
     682      TypeTraits *syntaxCopy() override;
     683      uinteger_t size(const Loc &loc) override;
     684      Dsymbol *toDsymbol(Scope *sc) override;
     685      void accept(Visitor *v) override { v->visit(this); }
     686  };
     687  
     688  class TypeMixin final : public Type
     689  {
     690      Loc loc;
     691      Expressions *exps;
     692      RootObject *obj;
     693  
     694      const char *kind() override;
     695      TypeMixin *syntaxCopy() override;
     696      Dsymbol *toDsymbol(Scope *sc) override;
     697      void accept(Visitor *v) override { v->visit(this); }
     698  };
     699  
     700  class TypeQualified : public Type
     701  {
     702  public:
     703      Loc loc;
     704      // array of Identifier and TypeInstance,
     705      // representing ident.ident!tiargs.ident. ... etc.
     706      Objects idents;
     707  
     708      void syntaxCopyHelper(TypeQualified *t);
     709      void addIdent(Identifier *ident);
     710      void addInst(TemplateInstance *inst);
     711      void addIndex(RootObject *expr);
     712      uinteger_t size(const Loc &loc) override;
     713  
     714      void accept(Visitor *v) override { v->visit(this); }
     715  };
     716  
     717  class TypeIdentifier final : public TypeQualified
     718  {
     719  public:
     720      Identifier *ident;
     721      Dsymbol *originalSymbol; // The symbol representing this identifier, before alias resolution
     722  
     723      static TypeIdentifier *create(const Loc &loc, Identifier *ident);
     724      const char *kind() override;
     725      TypeIdentifier *syntaxCopy() override;
     726      Dsymbol *toDsymbol(Scope *sc) override;
     727      void accept(Visitor *v) override { v->visit(this); }
     728  };
     729  
     730  /* Similar to TypeIdentifier, but with a TemplateInstance as the root
     731   */
     732  class TypeInstance final : public TypeQualified
     733  {
     734  public:
     735      TemplateInstance *tempinst;
     736  
     737      const char *kind() override;
     738      TypeInstance *syntaxCopy() override;
     739      Dsymbol *toDsymbol(Scope *sc) override;
     740      void accept(Visitor *v) override { v->visit(this); }
     741  };
     742  
     743  class TypeTypeof final : public TypeQualified
     744  {
     745  public:
     746      Expression *exp;
     747      int inuse;
     748  
     749      const char *kind() override;
     750      TypeTypeof *syntaxCopy() override;
     751      Dsymbol *toDsymbol(Scope *sc) override;
     752      uinteger_t size(const Loc &loc) override;
     753      void accept(Visitor *v) override { v->visit(this); }
     754  };
     755  
     756  class TypeReturn final : public TypeQualified
     757  {
     758  public:
     759      const char *kind() override;
     760      TypeReturn *syntaxCopy() override;
     761      Dsymbol *toDsymbol(Scope *sc) override;
     762      void accept(Visitor *v) override { v->visit(this); }
     763  };
     764  
     765  // Whether alias this dependency is recursive or not.
     766  enum AliasThisRec
     767  {
     768      RECno = 0,      // no alias this recursion
     769      RECyes = 1,     // alias this has recursive dependency
     770      RECfwdref = 2,  // not yet known
     771      RECtypeMask = 3,// mask to read no/yes/fwdref
     772  
     773      RECtracing = 0x4, // mark in progress of implicitConvTo/deduceWild
     774      RECtracingDT = 0x8  // mark in progress of deduceType
     775  };
     776  
     777  class TypeStruct final : public Type
     778  {
     779  public:
     780      StructDeclaration *sym;
     781      AliasThisRec att;
     782      d_bool inuse;
     783  
     784      static TypeStruct *create(StructDeclaration *sym);
     785      const char *kind() override;
     786      uinteger_t size(const Loc &loc) override;
     787      unsigned alignsize() override;
     788      TypeStruct *syntaxCopy() override;
     789      Dsymbol *toDsymbol(Scope *sc) override;
     790      structalign_t alignment() override;
     791      Expression *defaultInitLiteral(const Loc &loc) override;
     792      bool isZeroInit(const Loc &loc) override;
     793      bool isAssignable() override;
     794      bool isBoolean() override;
     795      bool needsDestruction() override;
     796      bool needsCopyOrPostblit() override;
     797      bool needsNested() override;
     798      bool hasPointers() override;
     799      bool hasVoidInitPointers() override;
     800      bool hasSystemFields() override;
     801      bool hasInvariant() override;
     802      MATCH implicitConvTo(Type *to) override;
     803      MATCH constConv(Type *to) override;
     804      unsigned char deduceWild(Type *t, bool isRef) override;
     805      Type *toHeadMutable() override;
     806  
     807      void accept(Visitor *v) override { v->visit(this); }
     808  };
     809  
     810  class TypeEnum final : public Type
     811  {
     812  public:
     813      EnumDeclaration *sym;
     814  
     815      const char *kind() override;
     816      TypeEnum *syntaxCopy() override;
     817      uinteger_t size(const Loc &loc) override;
     818      unsigned alignsize() override;
     819      Type *memType(const Loc &loc = Loc());
     820      Dsymbol *toDsymbol(Scope *sc) override;
     821      bool isintegral() override;
     822      bool isfloating() override;
     823      bool isreal() override;
     824      bool isimaginary() override;
     825      bool iscomplex() override;
     826      bool isscalar() override;
     827      bool isunsigned() override;
     828      bool isBoolean() override;
     829      bool isString() override;
     830      bool isAssignable() override;
     831      bool needsDestruction() override;
     832      bool needsCopyOrPostblit() override;
     833      bool needsNested() override;
     834      MATCH implicitConvTo(Type *to) override;
     835      MATCH constConv(Type *to) override;
     836      bool isZeroInit(const Loc &loc) override;
     837      bool hasPointers() override;
     838      bool hasVoidInitPointers() override;
     839      bool hasSystemFields() override;
     840      bool hasInvariant() override;
     841      Type *nextOf() override;
     842  
     843      void accept(Visitor *v) override { v->visit(this); }
     844  };
     845  
     846  class TypeClass final : public Type
     847  {
     848  public:
     849      ClassDeclaration *sym;
     850      AliasThisRec att;
     851      CPPMANGLE cppmangle;
     852  
     853      const char *kind() override;
     854      uinteger_t size(const Loc &loc) override;
     855      TypeClass *syntaxCopy() override;
     856      Dsymbol *toDsymbol(Scope *sc) override;
     857      ClassDeclaration *isClassHandle() override;
     858      bool isBaseOf(Type *t, int *poffset) override;
     859      MATCH implicitConvTo(Type *to) override;
     860      MATCH constConv(Type *to) override;
     861      unsigned char deduceWild(Type *t, bool isRef) override;
     862      Type *toHeadMutable() override;
     863      bool isZeroInit(const Loc &loc) override;
     864      bool isscope() override;
     865      bool isBoolean() override;
     866      bool hasPointers() override;
     867  
     868      void accept(Visitor *v) override { v->visit(this); }
     869  };
     870  
     871  class TypeTuple final : public Type
     872  {
     873  public:
     874      // 'logically immutable' cached global - don't modify (neither pointer nor pointee)!
     875      static TypeTuple *empty;
     876  
     877      Parameters *arguments;      // types making up the tuple
     878  
     879      static TypeTuple *create(Parameters *arguments);
     880      static TypeTuple *create();
     881      static TypeTuple *create(Type *t1);
     882      static TypeTuple *create(Type *t1, Type *t2);
     883      const char *kind() override;
     884      TypeTuple *syntaxCopy() override;
     885      bool equals(const RootObject * const o) const override;
     886      void accept(Visitor *v) override { v->visit(this); }
     887  };
     888  
     889  class TypeSlice final : public TypeNext
     890  {
     891  public:
     892      Expression *lwr;
     893      Expression *upr;
     894  
     895      const char *kind() override;
     896      TypeSlice *syntaxCopy() override;
     897      void accept(Visitor *v) override { v->visit(this); }
     898  };
     899  
     900  class TypeNull final : public Type
     901  {
     902  public:
     903      const char *kind() override;
     904  
     905      TypeNull *syntaxCopy() override;
     906      MATCH implicitConvTo(Type *to) override;
     907      bool hasPointers() override;
     908      bool isBoolean() override;
     909  
     910      uinteger_t size(const Loc &loc) override;
     911      void accept(Visitor *v) override { v->visit(this); }
     912  };
     913  
     914  class TypeNoreturn final : public Type
     915  {
     916  public:
     917      const char *kind() override;
     918      TypeNoreturn *syntaxCopy() override;
     919      MATCH implicitConvTo(Type* to) override;
     920      MATCH constConv(Type* to) override;
     921      bool isBoolean() override;
     922      uinteger_t size(const Loc& loc) override;
     923      unsigned alignsize() override;
     924  
     925      void accept(Visitor *v) override { v->visit(this); }
     926  };
     927  
     928  class TypeTag final : public Type
     929  {
     930  public:
     931      TypeTag *syntaxCopy() override;
     932  
     933      void accept(Visitor *v) override { v->visit(this); }
     934  };
     935  
     936  /**************************************************************/
     937  
     938  bool arrayTypeCompatibleWithoutCasting(Type *t1, Type *t2);
     939  
     940  // If the type is a class or struct, returns the symbol for it, else null.
     941  AggregateDeclaration *isAggregate(Type *t);