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/expression.h
       9   */
      10  
      11  #pragma once
      12  
      13  #include "ast_node.h"
      14  #include "globals.h"
      15  #include "arraytypes.h"
      16  #include "visitor.h"
      17  #include "tokens.h"
      18  
      19  #include "root/complex_t.h"
      20  #include "root/dcompat.h"
      21  #include "root/optional.h"
      22  
      23  class Type;
      24  class TypeVector;
      25  struct Scope;
      26  class TupleDeclaration;
      27  class VarDeclaration;
      28  class FuncDeclaration;
      29  class FuncLiteralDeclaration;
      30  class CtorDeclaration;
      31  class Dsymbol;
      32  class ScopeDsymbol;
      33  class Expression;
      34  class Declaration;
      35  class StructDeclaration;
      36  class TemplateInstance;
      37  class TemplateDeclaration;
      38  class ClassDeclaration;
      39  class OverloadSet;
      40  class StringExp;
      41  struct UnionExp;
      42  #ifdef IN_GCC
      43  typedef union tree_node Symbol;
      44  #else
      45  struct Symbol;          // back end symbol
      46  #endif
      47  
      48  void expandTuples(Expressions *exps, Identifiers *names = nullptr);
      49  bool isTrivialExp(Expression *e);
      50  bool hasSideEffect(Expression *e, bool assumeImpureCalls = false);
      51  
      52  enum BE : int32_t;
      53  BE canThrow(Expression *e, FuncDeclaration *func, bool mustNotThrow);
      54  
      55  typedef unsigned char OwnedBy;
      56  enum
      57  {
      58      OWNEDcode,      // normal code expression in AST
      59      OWNEDctfe,      // value expression for CTFE
      60      OWNEDcache      // constant value cached for CTFE
      61  };
      62  
      63  #define WANTvalue  0 // default
      64  #define WANTexpand 1 // expand const/immutable variables if possible
      65  
      66  /**
      67   * Specifies how the checkModify deals with certain situations
      68   */
      69  enum class ModifyFlags
      70  {
      71      /// Issue error messages on invalid modifications of the variable
      72      none,
      73      /// No errors are emitted for invalid modifications
      74      noError = 0x1,
      75      /// The modification occurs for a subfield of the current variable
      76      fieldAssign = 0x2,
      77  };
      78  
      79  class Expression : public ASTNode
      80  {
      81  public:
      82      EXP op;                     // to minimize use of dynamic_cast
      83      unsigned char size;         // # of bytes in Expression so we can copy() it
      84      d_bool parens;                // if this is a parenthesized expression
      85      Type *type;                 // !=NULL means that semantic() has been run
      86      Loc loc;                    // file location
      87  
      88      static void _init();
      89      Expression *copy();
      90      virtual Expression *syntaxCopy();
      91  
      92      // kludge for template.isExpression()
      93      DYNCAST dyncast() const override final { return DYNCAST_EXPRESSION; }
      94  
      95      const char *toChars() const override;
      96      void error(const char *format, ...) const;
      97      void warning(const char *format, ...) const;
      98      void deprecation(const char *format, ...) const;
      99  
     100      virtual dinteger_t toInteger();
     101      virtual uinteger_t toUInteger();
     102      virtual real_t toReal();
     103      virtual real_t toImaginary();
     104      virtual complex_t toComplex();
     105      virtual StringExp *toStringExp();
     106      virtual bool isLvalue();
     107      virtual Expression *toLvalue(Scope *sc, Expression *e);
     108      virtual Expression *modifiableLvalue(Scope *sc, Expression *e);
     109      Expression *implicitCastTo(Scope *sc, Type *t);
     110      MATCH implicitConvTo(Type *t);
     111      Expression *castTo(Scope *sc, Type *t);
     112      virtual Expression *resolveLoc(const Loc &loc, Scope *sc);
     113      virtual bool checkType();
     114      virtual bool checkValue();
     115      bool checkDeprecated(Scope *sc, Dsymbol *s);
     116      virtual Expression *addDtorHook(Scope *sc);
     117      Expression *addressOf();
     118      Expression *deref();
     119  
     120      Expression *optimize(int result, bool keepLvalue = false);
     121  
     122      // Entry point for CTFE.
     123      // A compile-time result is required. Give an error if not possible
     124      Expression *ctfeInterpret();
     125      int isConst();
     126      virtual bool isIdentical(const Expression *e) const;
     127      virtual Optional<bool> toBool();
     128      virtual bool hasCode()
     129      {
     130          return true;
     131      }
     132  
     133      IntegerExp* isIntegerExp();
     134      ErrorExp* isErrorExp();
     135      VoidInitExp* isVoidInitExp();
     136      RealExp* isRealExp();
     137      ComplexExp* isComplexExp();
     138      IdentifierExp* isIdentifierExp();
     139      DollarExp* isDollarExp();
     140      DsymbolExp* isDsymbolExp();
     141      ThisExp* isThisExp();
     142      SuperExp* isSuperExp();
     143      NullExp* isNullExp();
     144      StringExp* isStringExp();
     145      TupleExp* isTupleExp();
     146      ArrayLiteralExp* isArrayLiteralExp();
     147      AssocArrayLiteralExp* isAssocArrayLiteralExp();
     148      StructLiteralExp* isStructLiteralExp();
     149      TypeExp* isTypeExp();
     150      ScopeExp* isScopeExp();
     151      TemplateExp* isTemplateExp();
     152      NewExp* isNewExp();
     153      NewAnonClassExp* isNewAnonClassExp();
     154      SymOffExp* isSymOffExp();
     155      VarExp* isVarExp();
     156      OverExp* isOverExp();
     157      FuncExp* isFuncExp();
     158      DeclarationExp* isDeclarationExp();
     159      TypeidExp* isTypeidExp();
     160      TraitsExp* isTraitsExp();
     161      HaltExp* isHaltExp();
     162      IsExp* isExp();
     163      MixinExp* isMixinExp();
     164      ImportExp* isImportExp();
     165      AssertExp* isAssertExp();
     166      DotIdExp* isDotIdExp();
     167      DotTemplateExp* isDotTemplateExp();
     168      DotVarExp* isDotVarExp();
     169      DotTemplateInstanceExp* isDotTemplateInstanceExp();
     170      DelegateExp* isDelegateExp();
     171      DotTypeExp* isDotTypeExp();
     172      CallExp* isCallExp();
     173      AddrExp* isAddrExp();
     174      PtrExp* isPtrExp();
     175      NegExp* isNegExp();
     176      UAddExp* isUAddExp();
     177      ComExp* isComExp();
     178      NotExp* isNotExp();
     179      DeleteExp* isDeleteExp();
     180      CastExp* isCastExp();
     181      VectorExp* isVectorExp();
     182      VectorArrayExp* isVectorArrayExp();
     183      SliceExp* isSliceExp();
     184      ArrayLengthExp* isArrayLengthExp();
     185      ArrayExp* isArrayExp();
     186      DotExp* isDotExp();
     187      CommaExp* isCommaExp();
     188      IntervalExp* isIntervalExp();
     189      DelegatePtrExp* isDelegatePtrExp();
     190      DelegateFuncptrExp* isDelegateFuncptrExp();
     191      IndexExp* isIndexExp();
     192      PostExp* isPostExp();
     193      PreExp* isPreExp();
     194      AssignExp* isAssignExp();
     195      ConstructExp* isConstructExp();
     196      BlitExp* isBlitExp();
     197      AddAssignExp* isAddAssignExp();
     198      MinAssignExp* isMinAssignExp();
     199      MulAssignExp* isMulAssignExp();
     200      DivAssignExp* isDivAssignExp();
     201      ModAssignExp* isModAssignExp();
     202      AndAssignExp* isAndAssignExp();
     203      OrAssignExp* isOrAssignExp();
     204      XorAssignExp* isXorAssignExp();
     205      PowAssignExp* isPowAssignExp();
     206      ShlAssignExp* isShlAssignExp();
     207      ShrAssignExp* isShrAssignExp();
     208      UshrAssignExp* isUshrAssignExp();
     209      CatAssignExp* isCatAssignExp();
     210      CatElemAssignExp* isCatElemAssignExp();
     211      CatDcharAssignExp* isCatDcharAssignExp();
     212      AddExp* isAddExp();
     213      MinExp* isMinExp();
     214      CatExp* isCatExp();
     215      MulExp* isMulExp();
     216      DivExp* isDivExp();
     217      ModExp* isModExp();
     218      PowExp* isPowExp();
     219      ShlExp* isShlExp();
     220      ShrExp* isShrExp();
     221      UshrExp* isUshrExp();
     222      AndExp* isAndExp();
     223      OrExp* isOrExp();
     224      XorExp* isXorExp();
     225      LogicalExp* isLogicalExp();
     226      InExp* isInExp();
     227      RemoveExp* isRemoveExp();
     228      EqualExp* isEqualExp();
     229      IdentityExp* isIdentityExp();
     230      CondExp* isCondExp();
     231      GenericExp* isGenericExp();
     232      DefaultInitExp* isDefaultInitExp();
     233      FileInitExp* isFileInitExp();
     234      LineInitExp* isLineInitExp();
     235      ModuleInitExp* isModuleInitExp();
     236      FuncInitExp* isFuncInitExp();
     237      PrettyFuncInitExp* isPrettyFuncInitExp();
     238      ClassReferenceExp* isClassReferenceExp();
     239      ThrownExceptionExp* isThrownExceptionExp();
     240      UnaExp* isUnaExp();
     241      BinExp* isBinExp();
     242      BinAssignExp* isBinAssignExp();
     243  
     244      void accept(Visitor *v) override { v->visit(this); }
     245  };
     246  
     247  class IntegerExp final : public Expression
     248  {
     249  public:
     250      dinteger_t value;
     251  
     252      static IntegerExp *create(const Loc &loc, dinteger_t value, Type *type);
     253      static void emplace(UnionExp *pue, const Loc &loc, dinteger_t value, Type *type);
     254      bool equals(const RootObject * const o) const override;
     255      dinteger_t toInteger() override;
     256      real_t toReal() override;
     257      real_t toImaginary() override;
     258      complex_t toComplex() override;
     259      Optional<bool> toBool() override;
     260      Expression *toLvalue(Scope *sc, Expression *e) override;
     261      void accept(Visitor *v) override { v->visit(this); }
     262      dinteger_t getInteger() { return value; }
     263      void setInteger(dinteger_t value);
     264      template<int v>
     265      static IntegerExp literal();
     266  };
     267  
     268  class ErrorExp final : public Expression
     269  {
     270  public:
     271      Expression *toLvalue(Scope *sc, Expression *e) override;
     272      void accept(Visitor *v) override { v->visit(this); }
     273  
     274      static ErrorExp *errorexp; // handy shared value
     275  };
     276  
     277  class RealExp final : public Expression
     278  {
     279  public:
     280      real_t value;
     281  
     282      static RealExp *create(const Loc &loc, real_t value, Type *type);
     283      static void emplace(UnionExp *pue, const Loc &loc, real_t value, Type *type);
     284      bool equals(const RootObject * const o) const override;
     285      bool isIdentical(const Expression *e) const override;
     286      dinteger_t toInteger() override;
     287      uinteger_t toUInteger() override;
     288      real_t toReal() override;
     289      real_t toImaginary() override;
     290      complex_t toComplex() override;
     291      Optional<bool> toBool() override;
     292      void accept(Visitor *v) override { v->visit(this); }
     293  };
     294  
     295  class ComplexExp final : public Expression
     296  {
     297  public:
     298      complex_t value;
     299  
     300      static ComplexExp *create(const Loc &loc, complex_t value, Type *type);
     301      static void emplace(UnionExp *pue, const Loc &loc, complex_t value, Type *type);
     302      bool equals(const RootObject * const o) const override;
     303      bool isIdentical(const Expression *e) const override;
     304      dinteger_t toInteger() override;
     305      uinteger_t toUInteger() override;
     306      real_t toReal() override;
     307      real_t toImaginary() override;
     308      complex_t toComplex() override;
     309      Optional<bool> toBool() override;
     310      void accept(Visitor *v) override { v->visit(this); }
     311  };
     312  
     313  class IdentifierExp : public Expression
     314  {
     315  public:
     316      Identifier *ident;
     317  
     318      static IdentifierExp *create(const Loc &loc, Identifier *ident);
     319      bool isLvalue() override final;
     320      Expression *toLvalue(Scope *sc, Expression *e) override final;
     321      void accept(Visitor *v) override { v->visit(this); }
     322  };
     323  
     324  class DollarExp final : public IdentifierExp
     325  {
     326  public:
     327      void accept(Visitor *v) override { v->visit(this); }
     328  };
     329  
     330  class DsymbolExp final : public Expression
     331  {
     332  public:
     333      Dsymbol *s;
     334      d_bool hasOverloads;
     335  
     336      DsymbolExp *syntaxCopy() override;
     337      bool isLvalue() override;
     338      Expression *toLvalue(Scope *sc, Expression *e) override;
     339      void accept(Visitor *v) override { v->visit(this); }
     340  };
     341  
     342  class ThisExp : public Expression
     343  {
     344  public:
     345      VarDeclaration *var;
     346  
     347      ThisExp *syntaxCopy() override;
     348      Optional<bool> toBool() override;
     349      bool isLvalue() override final;
     350      Expression *toLvalue(Scope *sc, Expression *e) override final;
     351  
     352      void accept(Visitor *v) override { v->visit(this); }
     353  };
     354  
     355  class SuperExp final : public ThisExp
     356  {
     357  public:
     358      void accept(Visitor *v) override { v->visit(this); }
     359  };
     360  
     361  class NullExp final : public Expression
     362  {
     363  public:
     364      bool equals(const RootObject * const o) const override;
     365      Optional<bool> toBool() override;
     366      StringExp *toStringExp() override;
     367      void accept(Visitor *v) override { v->visit(this); }
     368  };
     369  
     370  class StringExp final : public Expression
     371  {
     372  public:
     373      void *string;       // char, wchar, or dchar data
     374      size_t len;         // number of chars, wchars, or dchars
     375      unsigned char sz;   // 1: char, 2: wchar, 4: dchar
     376      unsigned char committed;    // !=0 if type is committed
     377      utf8_t postfix;      // 'c', 'w', 'd'
     378      OwnedBy ownedByCtfe;
     379  
     380      static StringExp *create(const Loc &loc, const char *s);
     381      static StringExp *create(const Loc &loc, const void *s, d_size_t len);
     382      static void emplace(UnionExp *pue, const Loc &loc, const char *s);
     383      bool equals(const RootObject * const o) const override;
     384      char32_t getCodeUnit(d_size_t i) const;
     385      void setCodeUnit(d_size_t i, char32_t c);
     386      StringExp *toStringExp() override;
     387      StringExp *toUTF8(Scope *sc);
     388      Optional<bool> toBool() override;
     389      bool isLvalue() override;
     390      Expression *toLvalue(Scope *sc, Expression *e) override;
     391      Expression *modifiableLvalue(Scope *sc, Expression *e) override;
     392      void accept(Visitor *v) override { v->visit(this); }
     393      size_t numberOfCodeUnits(int tynto = 0) const;
     394      void writeTo(void* dest, bool zero, int tyto = 0) const;
     395  };
     396  
     397  // Tuple
     398  
     399  class TupleExp final : public Expression
     400  {
     401  public:
     402      Expression *e0;     // side-effect part
     403      /* Tuple-field access may need to take out its side effect part.
     404       * For example:
     405       *      foo().tupleof
     406       * is rewritten as:
     407       *      (ref __tup = foo(); tuple(__tup.field0, __tup.field1, ...))
     408       * The declaration of temporary variable __tup will be stored in TupleExp::e0.
     409       */
     410      Expressions *exps;
     411  
     412      static TupleExp *create(const Loc &loc, Expressions *exps);
     413      TupleExp *syntaxCopy() override;
     414      bool equals(const RootObject * const o) const override;
     415  
     416      void accept(Visitor *v) override { v->visit(this); }
     417  };
     418  
     419  class ArrayLiteralExp final : public Expression
     420  {
     421  public:
     422      Expression *basis;
     423      Expressions *elements;
     424      OwnedBy ownedByCtfe;
     425      d_bool onstack;
     426  
     427      static ArrayLiteralExp *create(const Loc &loc, Expressions *elements);
     428      static void emplace(UnionExp *pue, const Loc &loc, Expressions *elements);
     429      ArrayLiteralExp *syntaxCopy() override;
     430      bool equals(const RootObject * const o) const override;
     431      Expression *getElement(d_size_t i); // use opIndex instead
     432      Expression *opIndex(d_size_t i);
     433      Optional<bool> toBool() override;
     434      StringExp *toStringExp() override;
     435  
     436      void accept(Visitor *v) override { v->visit(this); }
     437  };
     438  
     439  class AssocArrayLiteralExp final : public Expression
     440  {
     441  public:
     442      Expressions *keys;
     443      Expressions *values;
     444      OwnedBy ownedByCtfe;
     445  
     446      bool equals(const RootObject * const o) const override;
     447      AssocArrayLiteralExp *syntaxCopy() override;
     448      Optional<bool> toBool() override;
     449  
     450      void accept(Visitor *v) override { v->visit(this); }
     451  };
     452  
     453  class StructLiteralExp final : public Expression
     454  {
     455  public:
     456      StructDeclaration *sd;      // which aggregate this is for
     457      Expressions *elements;      // parallels sd->fields[] with NULL entries for fields to skip
     458      Type *stype;                // final type of result (can be different from sd's type)
     459  
     460      Symbol *sym;                // back end symbol to initialize with literal
     461  
     462      /** pointer to the origin instance of the expression.
     463       * once a new expression is created, origin is set to 'this'.
     464       * anytime when an expression copy is created, 'origin' pointer is set to
     465       * 'origin' pointer value of the original expression.
     466       */
     467      StructLiteralExp *origin;
     468  
     469      // those fields need to prevent a infinite recursion when one field of struct initialized with 'this' pointer.
     470      StructLiteralExp *inlinecopy;
     471  
     472      /** anytime when recursive function is calling, 'stageflags' marks with bit flag of
     473       * current stage and unmarks before return from this function.
     474       * 'inlinecopy' uses similar 'stageflags' and from multiple evaluation 'doInline'
     475       * (with infinite recursion) of this expression.
     476       */
     477      int stageflags;
     478  
     479      d_bool useStaticInit;         // if this is true, use the StructDeclaration's init symbol
     480      d_bool isOriginal;            // used when moving instances to indicate `this is this.origin`
     481      OwnedBy ownedByCtfe;
     482  
     483      static StructLiteralExp *create(const Loc &loc, StructDeclaration *sd, void *elements, Type *stype = NULL);
     484      bool equals(const RootObject * const o) const override;
     485      StructLiteralExp *syntaxCopy() override;
     486      Expression *getField(Type *type, unsigned offset);
     487      int getFieldIndex(Type *type, unsigned offset);
     488      Expression *addDtorHook(Scope *sc) override;
     489      Expression *toLvalue(Scope *sc, Expression *e) override;
     490  
     491      void accept(Visitor *v) override { v->visit(this); }
     492  };
     493  
     494  class TypeExp final : public Expression
     495  {
     496  public:
     497      TypeExp *syntaxCopy() override;
     498      bool checkType() override;
     499      bool checkValue() override;
     500      void accept(Visitor *v) override { v->visit(this); }
     501  };
     502  
     503  class ScopeExp final : public Expression
     504  {
     505  public:
     506      ScopeDsymbol *sds;
     507  
     508      ScopeExp *syntaxCopy() override;
     509      bool checkType() override;
     510      bool checkValue() override;
     511      void accept(Visitor *v) override { v->visit(this); }
     512  };
     513  
     514  class TemplateExp final : public Expression
     515  {
     516  public:
     517      TemplateDeclaration *td;
     518      FuncDeclaration *fd;
     519  
     520      bool isLvalue() override;
     521      Expression *toLvalue(Scope *sc, Expression *e) override;
     522      bool checkType() override;
     523      bool checkValue() override;
     524      void accept(Visitor *v) override { v->visit(this); }
     525  };
     526  
     527  class NewExp final : public Expression
     528  {
     529  public:
     530      /* newtype(arguments)
     531       */
     532      Expression *thisexp;        // if !NULL, 'this' for class being allocated
     533      Type *newtype;
     534      Expressions *arguments;     // Array of Expression's
     535      Identifiers *names;         // Array of names corresponding to expressions
     536  
     537      Expression *argprefix;      // expression to be evaluated just before arguments[]
     538  
     539      CtorDeclaration *member;    // constructor function
     540      d_bool onstack;               // allocate on stack
     541      d_bool thrownew;              // this NewExp is the expression of a ThrowStatement
     542  
     543      Expression *lowering;       // lowered druntime hook: `_d_newclass`
     544  
     545      static NewExp *create(const Loc &loc, Expression *thisexp, Type *newtype, Expressions *arguments);
     546      NewExp *syntaxCopy() override;
     547  
     548      void accept(Visitor *v) override { v->visit(this); }
     549  };
     550  
     551  class NewAnonClassExp final : public Expression
     552  {
     553  public:
     554      /* class baseclasses { } (arguments)
     555       */
     556      Expression *thisexp;        // if !NULL, 'this' for class being allocated
     557      ClassDeclaration *cd;       // class being instantiated
     558      Expressions *arguments;     // Array of Expression's to call class constructor
     559  
     560      NewAnonClassExp *syntaxCopy() override;
     561      void accept(Visitor *v) override { v->visit(this); }
     562  };
     563  
     564  class SymbolExp : public Expression
     565  {
     566  public:
     567      Declaration *var;
     568      Dsymbol *originalScope;
     569      d_bool hasOverloads;
     570  
     571      void accept(Visitor *v) override { v->visit(this); }
     572  };
     573  
     574  // Offset from symbol
     575  
     576  class SymOffExp final : public SymbolExp
     577  {
     578  public:
     579      dinteger_t offset;
     580  
     581      Optional<bool> toBool() override;
     582  
     583      void accept(Visitor *v) override { v->visit(this); }
     584  };
     585  
     586  // Variable
     587  
     588  class VarExp final : public SymbolExp
     589  {
     590  public:
     591      d_bool delegateWasExtracted;
     592      static VarExp *create(const Loc &loc, Declaration *var, bool hasOverloads = true);
     593      bool equals(const RootObject * const o) const override;
     594      bool isLvalue() override;
     595      Expression *toLvalue(Scope *sc, Expression *e) override;
     596      Expression *modifiableLvalue(Scope *sc, Expression *e) override;
     597  
     598      void accept(Visitor *v) override { v->visit(this); }
     599  };
     600  
     601  // Overload Set
     602  
     603  class OverExp final : public Expression
     604  {
     605  public:
     606      OverloadSet *vars;
     607  
     608      bool isLvalue() override;
     609      Expression *toLvalue(Scope *sc, Expression *e) override;
     610      void accept(Visitor *v) override { v->visit(this); }
     611  };
     612  
     613  // Function/Delegate literal
     614  
     615  class FuncExp final : public Expression
     616  {
     617  public:
     618      FuncLiteralDeclaration *fd;
     619      TemplateDeclaration *td;
     620      TOK tok;
     621  
     622      bool equals(const RootObject * const o) const override;
     623      FuncExp *syntaxCopy() override;
     624      const char *toChars() const override;
     625      bool checkType() override;
     626      bool checkValue() override;
     627  
     628      void accept(Visitor *v) override { v->visit(this); }
     629  };
     630  
     631  // Declaration of a symbol
     632  
     633  // D grammar allows declarations only as statements. However in AST representation
     634  // it can be part of any expression. This is used, for example, during internal
     635  // syntax re-writes to inject hidden symbols.
     636  class DeclarationExp final : public Expression
     637  {
     638  public:
     639      Dsymbol *declaration;
     640  
     641      DeclarationExp *syntaxCopy() override;
     642  
     643      bool hasCode() override;
     644  
     645      void accept(Visitor *v) override { v->visit(this); }
     646  };
     647  
     648  class TypeidExp final : public Expression
     649  {
     650  public:
     651      RootObject *obj;
     652  
     653      TypeidExp *syntaxCopy() override;
     654      void accept(Visitor *v) override { v->visit(this); }
     655  };
     656  
     657  class TraitsExp final : public Expression
     658  {
     659  public:
     660      Identifier *ident;
     661      Objects *args;
     662  
     663      TraitsExp *syntaxCopy() override;
     664      void accept(Visitor *v) override { v->visit(this); }
     665  };
     666  
     667  class HaltExp final : public Expression
     668  {
     669  public:
     670      void accept(Visitor *v) override { v->visit(this); }
     671  };
     672  
     673  class IsExp final : public Expression
     674  {
     675  public:
     676      /* is(targ id tok tspec)
     677       * is(targ id == tok2)
     678       */
     679      Type *targ;
     680      Identifier *id;     // can be NULL
     681      Type *tspec;        // can be NULL
     682      TemplateParameters *parameters;
     683      TOK tok;       // ':' or '=='
     684      TOK tok2;      // 'struct', 'union', etc.
     685  
     686      IsExp *syntaxCopy() override;
     687      void accept(Visitor *v) override { v->visit(this); }
     688  };
     689  
     690  /****************************************************************/
     691  
     692  class UnaExp : public Expression
     693  {
     694  public:
     695      Expression *e1;
     696      Type *att1; // Save alias this type to detect recursion
     697  
     698      UnaExp *syntaxCopy() override;
     699      Expression *incompatibleTypes();
     700      Expression *resolveLoc(const Loc &loc, Scope *sc) override final;
     701  
     702      void accept(Visitor *v) override { v->visit(this); }
     703  };
     704  
     705  class BinExp : public Expression
     706  {
     707  public:
     708      Expression *e1;
     709      Expression *e2;
     710  
     711      Type *att1; // Save alias this type to detect recursion
     712      Type *att2; // Save alias this type to detect recursion
     713  
     714      BinExp *syntaxCopy() override;
     715      Expression *incompatibleTypes();
     716  
     717      Expression *reorderSettingAAElem(Scope *sc);
     718  
     719      void accept(Visitor *v) override { v->visit(this); }
     720  };
     721  
     722  class BinAssignExp : public BinExp
     723  {
     724  public:
     725      bool isLvalue() override final;
     726      Expression *toLvalue(Scope *sc, Expression *ex) override final;
     727      Expression *modifiableLvalue(Scope *sc, Expression *e) override final;
     728      void accept(Visitor *v) override { v->visit(this); }
     729  };
     730  
     731  /****************************************************************/
     732  
     733  class MixinExp final : public UnaExp
     734  {
     735  public:
     736      void accept(Visitor *v) override { v->visit(this); }
     737  };
     738  
     739  class ImportExp final : public UnaExp
     740  {
     741  public:
     742      void accept(Visitor *v) override { v->visit(this); }
     743  };
     744  
     745  class AssertExp final : public UnaExp
     746  {
     747  public:
     748      Expression *msg;
     749  
     750      AssertExp *syntaxCopy() override;
     751  
     752      void accept(Visitor *v) override { v->visit(this); }
     753  };
     754  
     755  class ThrowExp final : public UnaExp
     756  {
     757  public:
     758      ThrowExp *syntaxCopy() override;
     759  
     760      void accept(Visitor *v) override { v->visit(this); }
     761  };
     762  
     763  class DotIdExp final : public UnaExp
     764  {
     765  public:
     766      Identifier *ident;
     767      d_bool noderef;       // true if the result of the expression will never be dereferenced
     768      d_bool wantsym;       // do not replace Symbol with its initializer during semantic()
     769      d_bool arrow;         // ImportC: if -> instead of .
     770  
     771      static DotIdExp *create(const Loc &loc, Expression *e, Identifier *ident);
     772      void accept(Visitor *v) override { v->visit(this); }
     773  };
     774  
     775  class DotTemplateExp final : public UnaExp
     776  {
     777  public:
     778      TemplateDeclaration *td;
     779  
     780      bool checkType() override;
     781      bool checkValue() override;
     782      void accept(Visitor *v) override { v->visit(this); }
     783  };
     784  
     785  class DotVarExp final : public UnaExp
     786  {
     787  public:
     788      Declaration *var;
     789      d_bool hasOverloads;
     790  
     791      bool isLvalue() override;
     792      Expression *toLvalue(Scope *sc, Expression *e) override;
     793      Expression *modifiableLvalue(Scope *sc, Expression *e) override;
     794      void accept(Visitor *v) override { v->visit(this); }
     795  };
     796  
     797  class DotTemplateInstanceExp final : public UnaExp
     798  {
     799  public:
     800      TemplateInstance *ti;
     801  
     802      DotTemplateInstanceExp *syntaxCopy() override;
     803      bool findTempDecl(Scope *sc);
     804      bool checkType() override;
     805      bool checkValue() override;
     806      void accept(Visitor *v) override { v->visit(this); }
     807  };
     808  
     809  class DelegateExp final : public UnaExp
     810  {
     811  public:
     812      FuncDeclaration *func;
     813      d_bool hasOverloads;
     814      VarDeclaration *vthis2;  // container for multi-context
     815  
     816  
     817      void accept(Visitor *v) override { v->visit(this); }
     818  };
     819  
     820  class DotTypeExp final : public UnaExp
     821  {
     822  public:
     823      Dsymbol *sym;               // symbol that represents a type
     824  
     825      void accept(Visitor *v) override { v->visit(this); }
     826  };
     827  
     828  class CallExp final : public UnaExp
     829  {
     830  public:
     831      Expressions *arguments;     // function arguments
     832      Identifiers *names;
     833      FuncDeclaration *f;         // symbol to call
     834      d_bool directcall;            // true if a virtual call is devirtualized
     835      d_bool inDebugStatement;      // true if this was in a debug statement
     836      d_bool ignoreAttributes;      // don't enforce attributes (e.g. call @gc function in @nogc code)
     837      VarDeclaration *vthis2;     // container for multi-context
     838  
     839      static CallExp *create(const Loc &loc, Expression *e, Expressions *exps);
     840      static CallExp *create(const Loc &loc, Expression *e);
     841      static CallExp *create(const Loc &loc, Expression *e, Expression *earg1);
     842      static CallExp *create(const Loc &loc, FuncDeclaration *fd, Expression *earg1);
     843  
     844      CallExp *syntaxCopy() override;
     845      bool isLvalue() override;
     846      Expression *toLvalue(Scope *sc, Expression *e) override;
     847      Expression *addDtorHook(Scope *sc) override;
     848  
     849      void accept(Visitor *v) override { v->visit(this); }
     850  };
     851  
     852  class AddrExp final : public UnaExp
     853  {
     854  public:
     855      void accept(Visitor *v) override { v->visit(this); }
     856  };
     857  
     858  class PtrExp final : public UnaExp
     859  {
     860  public:
     861      bool isLvalue() override;
     862      Expression *toLvalue(Scope *sc, Expression *e) override;
     863      Expression *modifiableLvalue(Scope *sc, Expression *e) override;
     864  
     865      void accept(Visitor *v) override { v->visit(this); }
     866  };
     867  
     868  class NegExp final : public UnaExp
     869  {
     870  public:
     871      void accept(Visitor *v) override { v->visit(this); }
     872  };
     873  
     874  class UAddExp final : public UnaExp
     875  {
     876  public:
     877      void accept(Visitor *v) override { v->visit(this); }
     878  };
     879  
     880  class ComExp final : public UnaExp
     881  {
     882  public:
     883      void accept(Visitor *v) override { v->visit(this); }
     884  };
     885  
     886  class NotExp final : public UnaExp
     887  {
     888  public:
     889      void accept(Visitor *v) override { v->visit(this); }
     890  };
     891  
     892  class DeleteExp final : public UnaExp
     893  {
     894  public:
     895      d_bool isRAII;
     896      void accept(Visitor *v) override { v->visit(this); }
     897  };
     898  
     899  class CastExp final : public UnaExp
     900  {
     901  public:
     902      // Possible to cast to one type while painting to another type
     903      Type *to;                   // type to cast to
     904      unsigned char mod;          // MODxxxxx
     905  
     906      CastExp *syntaxCopy() override;
     907      bool isLvalue() override;
     908      Expression *toLvalue(Scope *sc, Expression *e) override;
     909  
     910      void accept(Visitor *v) override { v->visit(this); }
     911  };
     912  
     913  class VectorExp final : public UnaExp
     914  {
     915  public:
     916      TypeVector *to;             // the target vector type before semantic()
     917      unsigned dim;               // number of elements in the vector
     918      OwnedBy ownedByCtfe;
     919  
     920      static VectorExp *create(const Loc &loc, Expression *e, Type *t);
     921      static void emplace(UnionExp *pue, const Loc &loc, Expression *e, Type *t);
     922      VectorExp *syntaxCopy() override;
     923      void accept(Visitor *v) override { v->visit(this); }
     924  };
     925  
     926  class VectorArrayExp final : public UnaExp
     927  {
     928  public:
     929      bool isLvalue() override;
     930      Expression *toLvalue(Scope *sc, Expression *e) override;
     931      void accept(Visitor *v) override { v->visit(this); }
     932  };
     933  
     934  class SliceExp final : public UnaExp
     935  {
     936  public:
     937      Expression *upr;            // NULL if implicit 0
     938      Expression *lwr;            // NULL if implicit [length - 1]
     939      VarDeclaration *lengthVar;
     940      d_bool upperIsInBounds;       // true if upr <= e1.length
     941      d_bool lowerIsLessThanUpper;  // true if lwr <= upr
     942      d_bool arrayop;               // an array operation, rather than a slice
     943  
     944      SliceExp *syntaxCopy() override;
     945      bool isLvalue() override;
     946      Expression *toLvalue(Scope *sc, Expression *e) override;
     947      Expression *modifiableLvalue(Scope *sc, Expression *e) override;
     948      Optional<bool> toBool() override;
     949  
     950      void accept(Visitor *v) override { v->visit(this); }
     951  };
     952  
     953  class ArrayLengthExp final : public UnaExp
     954  {
     955  public:
     956      void accept(Visitor *v) override { v->visit(this); }
     957  };
     958  
     959  class IntervalExp final : public Expression
     960  {
     961  public:
     962      Expression *lwr;
     963      Expression *upr;
     964  
     965      IntervalExp *syntaxCopy() override;
     966      void accept(Visitor *v) override { v->visit(this); }
     967  };
     968  
     969  class DelegatePtrExp final : public UnaExp
     970  {
     971  public:
     972      bool isLvalue() override;
     973      Expression *toLvalue(Scope *sc, Expression *e) override;
     974      Expression *modifiableLvalue(Scope *sc, Expression *e) override;
     975      void accept(Visitor *v) override { v->visit(this); }
     976  };
     977  
     978  class DelegateFuncptrExp final : public UnaExp
     979  {
     980  public:
     981      bool isLvalue() override;
     982      Expression *toLvalue(Scope *sc, Expression *e) override;
     983      Expression *modifiableLvalue(Scope *sc, Expression *e) override;
     984      void accept(Visitor *v) override { v->visit(this); }
     985  };
     986  
     987  // e1[a0,a1,a2,a3,...]
     988  
     989  class ArrayExp final : public UnaExp
     990  {
     991  public:
     992      Expressions *arguments;             // Array of Expression's
     993      size_t currentDimension;            // for opDollar
     994      VarDeclaration *lengthVar;
     995  
     996      ArrayExp *syntaxCopy() override;
     997      bool isLvalue() override;
     998      Expression *toLvalue(Scope *sc, Expression *e) override;
     999  
    1000      void accept(Visitor *v) override { v->visit(this); }
    1001  };
    1002  
    1003  /****************************************************************/
    1004  
    1005  class DotExp final : public BinExp
    1006  {
    1007  public:
    1008      void accept(Visitor *v) override { v->visit(this); }
    1009  };
    1010  
    1011  class CommaExp final : public BinExp
    1012  {
    1013  public:
    1014      d_bool isGenerated;
    1015      d_bool allowCommaExp;
    1016      bool isLvalue() override;
    1017      Expression *toLvalue(Scope *sc, Expression *e) override;
    1018      Expression *modifiableLvalue(Scope *sc, Expression *e) override;
    1019      Optional<bool> toBool() override;
    1020      Expression *addDtorHook(Scope *sc) override;
    1021      void accept(Visitor *v) override { v->visit(this); }
    1022  };
    1023  
    1024  class IndexExp final : public BinExp
    1025  {
    1026  public:
    1027      VarDeclaration *lengthVar;
    1028      d_bool modifiable;
    1029      d_bool indexIsInBounds;       // true if 0 <= e2 && e2 <= e1.length - 1
    1030  
    1031      IndexExp *syntaxCopy() override;
    1032      bool isLvalue() override;
    1033      Expression *toLvalue(Scope *sc, Expression *e) override;
    1034      Expression *modifiableLvalue(Scope *sc, Expression *e) override;
    1035  
    1036      void accept(Visitor *v) override { v->visit(this); }
    1037  };
    1038  
    1039  /* For both i++ and i--
    1040   */
    1041  class PostExp final : public BinExp
    1042  {
    1043  public:
    1044      void accept(Visitor *v) override { v->visit(this); }
    1045  };
    1046  
    1047  /* For both ++i and --i
    1048   */
    1049  class PreExp final : public UnaExp
    1050  {
    1051  public:
    1052      void accept(Visitor *v) override { v->visit(this); }
    1053  };
    1054  
    1055  enum class MemorySet
    1056  {
    1057      none            = 0,    // simple assignment
    1058      blockAssign     = 1,    // setting the contents of an array
    1059      referenceInit   = 2     // setting the reference of STCref variable
    1060  };
    1061  
    1062  class AssignExp : public BinExp
    1063  {
    1064  public:
    1065      MemorySet memset;
    1066  
    1067      bool isLvalue() override final;
    1068      Expression *toLvalue(Scope *sc, Expression *ex) override final;
    1069  
    1070      void accept(Visitor *v) override { v->visit(this); }
    1071  };
    1072  
    1073  class ConstructExp final : public AssignExp
    1074  {
    1075  public:
    1076      void accept(Visitor *v) override { v->visit(this); }
    1077  };
    1078  
    1079  class BlitExp final : public AssignExp
    1080  {
    1081  public:
    1082      void accept(Visitor *v) override { v->visit(this); }
    1083  };
    1084  
    1085  class AddAssignExp final : public BinAssignExp
    1086  {
    1087  public:
    1088      void accept(Visitor *v) override { v->visit(this); }
    1089  };
    1090  
    1091  class MinAssignExp final : public BinAssignExp
    1092  {
    1093  public:
    1094      void accept(Visitor *v) override { v->visit(this); }
    1095  };
    1096  
    1097  class MulAssignExp final : public BinAssignExp
    1098  {
    1099  public:
    1100      void accept(Visitor *v) override { v->visit(this); }
    1101  };
    1102  
    1103  class DivAssignExp final : public BinAssignExp
    1104  {
    1105  public:
    1106      void accept(Visitor *v) override { v->visit(this); }
    1107  };
    1108  
    1109  class ModAssignExp final : public BinAssignExp
    1110  {
    1111  public:
    1112      void accept(Visitor *v) override { v->visit(this); }
    1113  };
    1114  
    1115  class AndAssignExp final : public BinAssignExp
    1116  {
    1117  public:
    1118      void accept(Visitor *v) override { v->visit(this); }
    1119  };
    1120  
    1121  class OrAssignExp final : public BinAssignExp
    1122  {
    1123  public:
    1124      void accept(Visitor *v) override { v->visit(this); }
    1125  };
    1126  
    1127  class XorAssignExp final : public BinAssignExp
    1128  {
    1129  public:
    1130      void accept(Visitor *v) override { v->visit(this); }
    1131  };
    1132  
    1133  class PowAssignExp final : public BinAssignExp
    1134  {
    1135  public:
    1136      void accept(Visitor *v) override { v->visit(this); }
    1137  };
    1138  
    1139  class ShlAssignExp final : public BinAssignExp
    1140  {
    1141  public:
    1142      void accept(Visitor *v) override { v->visit(this); }
    1143  };
    1144  
    1145  class ShrAssignExp final : public BinAssignExp
    1146  {
    1147  public:
    1148      void accept(Visitor *v) override { v->visit(this); }
    1149  };
    1150  
    1151  class UshrAssignExp final : public BinAssignExp
    1152  {
    1153  public:
    1154      void accept(Visitor *v) override { v->visit(this); }
    1155  };
    1156  
    1157  class CatAssignExp : public BinAssignExp
    1158  {
    1159  public:
    1160      void accept(Visitor *v) override { v->visit(this); }
    1161  };
    1162  
    1163  class CatElemAssignExp final : public CatAssignExp
    1164  {
    1165  public:
    1166      void accept(Visitor *v) override { v->visit(this); }
    1167  };
    1168  
    1169  class CatDcharAssignExp final : public CatAssignExp
    1170  {
    1171  public:
    1172      void accept(Visitor *v) override { v->visit(this); }
    1173  };
    1174  
    1175  class AddExp final : public BinExp
    1176  {
    1177  public:
    1178      void accept(Visitor *v) override { v->visit(this); }
    1179  };
    1180  
    1181  class MinExp final : public BinExp
    1182  {
    1183  public:
    1184      void accept(Visitor *v) override { v->visit(this); }
    1185  };
    1186  
    1187  class CatExp final : public BinExp
    1188  {
    1189  public:
    1190      void accept(Visitor *v) override { v->visit(this); }
    1191  };
    1192  
    1193  class MulExp final : public BinExp
    1194  {
    1195  public:
    1196      void accept(Visitor *v) override { v->visit(this); }
    1197  };
    1198  
    1199  class DivExp final : public BinExp
    1200  {
    1201  public:
    1202      void accept(Visitor *v) override { v->visit(this); }
    1203  };
    1204  
    1205  class ModExp final : public BinExp
    1206  {
    1207  public:
    1208      void accept(Visitor *v) override { v->visit(this); }
    1209  };
    1210  
    1211  class PowExp final : public BinExp
    1212  {
    1213  public:
    1214      void accept(Visitor *v) override { v->visit(this); }
    1215  };
    1216  
    1217  class ShlExp final : public BinExp
    1218  {
    1219  public:
    1220      void accept(Visitor *v) override { v->visit(this); }
    1221  };
    1222  
    1223  class ShrExp final : public BinExp
    1224  {
    1225  public:
    1226      void accept(Visitor *v) override { v->visit(this); }
    1227  };
    1228  
    1229  class UshrExp final : public BinExp
    1230  {
    1231  public:
    1232      void accept(Visitor *v) override { v->visit(this); }
    1233  };
    1234  
    1235  class AndExp final : public BinExp
    1236  {
    1237  public:
    1238      void accept(Visitor *v) override { v->visit(this); }
    1239  };
    1240  
    1241  class OrExp final : public BinExp
    1242  {
    1243  public:
    1244      void accept(Visitor *v) override { v->visit(this); }
    1245  };
    1246  
    1247  class XorExp final : public BinExp
    1248  {
    1249  public:
    1250      void accept(Visitor *v) override { v->visit(this); }
    1251  };
    1252  
    1253  class LogicalExp final : public BinExp
    1254  {
    1255  public:
    1256      void accept(Visitor *v) override { v->visit(this); }
    1257  };
    1258  
    1259  class CmpExp final : public BinExp
    1260  {
    1261  public:
    1262      void accept(Visitor *v) override { v->visit(this); }
    1263  };
    1264  
    1265  class InExp final : public BinExp
    1266  {
    1267  public:
    1268      void accept(Visitor *v) override { v->visit(this); }
    1269  };
    1270  
    1271  class RemoveExp final : public BinExp
    1272  {
    1273  public:
    1274      void accept(Visitor *v) override { v->visit(this); }
    1275  };
    1276  
    1277  // == and !=
    1278  
    1279  class EqualExp final : public BinExp
    1280  {
    1281  public:
    1282      void accept(Visitor *v) override { v->visit(this); }
    1283  };
    1284  
    1285  // is and !is
    1286  
    1287  class IdentityExp final : public BinExp
    1288  {
    1289  public:
    1290      void accept(Visitor *v) override { v->visit(this); }
    1291  };
    1292  
    1293  /****************************************************************/
    1294  
    1295  class CondExp final : public BinExp
    1296  {
    1297  public:
    1298      Expression *econd;
    1299  
    1300      CondExp *syntaxCopy() override;
    1301      bool isLvalue() override;
    1302      Expression *toLvalue(Scope *sc, Expression *e) override;
    1303      Expression *modifiableLvalue(Scope *sc, Expression *e) override;
    1304      void hookDtors(Scope *sc);
    1305  
    1306      void accept(Visitor *v) override { v->visit(this); }
    1307  };
    1308  
    1309  class GenericExp final : Expression
    1310  {
    1311      Expression *cntlExp;
    1312      Types *types;
    1313      Expressions *exps;
    1314  
    1315      GenericExp *syntaxCopy() override;
    1316  
    1317      void accept(Visitor *v) override { v->visit(this); }
    1318  };
    1319  
    1320  /****************************************************************/
    1321  
    1322  class DefaultInitExp : public Expression
    1323  {
    1324  public:
    1325      void accept(Visitor *v) override { v->visit(this); }
    1326  };
    1327  
    1328  class FileInitExp final : public DefaultInitExp
    1329  {
    1330  public:
    1331      Expression *resolveLoc(const Loc &loc, Scope *sc) override;
    1332      void accept(Visitor *v) override { v->visit(this); }
    1333  };
    1334  
    1335  class LineInitExp final : public DefaultInitExp
    1336  {
    1337  public:
    1338      Expression *resolveLoc(const Loc &loc, Scope *sc) override;
    1339      void accept(Visitor *v) override { v->visit(this); }
    1340  };
    1341  
    1342  class ModuleInitExp final : public DefaultInitExp
    1343  {
    1344  public:
    1345      Expression *resolveLoc(const Loc &loc, Scope *sc) override;
    1346      void accept(Visitor *v) override { v->visit(this); }
    1347  };
    1348  
    1349  class FuncInitExp final : public DefaultInitExp
    1350  {
    1351  public:
    1352      Expression *resolveLoc(const Loc &loc, Scope *sc) override;
    1353      void accept(Visitor *v) override { v->visit(this); }
    1354  };
    1355  
    1356  class PrettyFuncInitExp final : public DefaultInitExp
    1357  {
    1358  public:
    1359      Expression *resolveLoc(const Loc &loc, Scope *sc) override;
    1360      void accept(Visitor *v) override { v->visit(this); }
    1361  };
    1362  
    1363  /****************************************************************/
    1364  
    1365  /* A type meant as a union of all the Expression types,
    1366   * to serve essentially as a Variant that will sit on the stack
    1367   * during CTFE to reduce memory consumption.
    1368   */
    1369  struct UnionExp
    1370  {
    1371      UnionExp() { }  // yes, default constructor does nothing
    1372  
    1373      UnionExp(Expression *e)
    1374      {
    1375          memcpy(this, (void *)e, e->size);
    1376      }
    1377  
    1378      /* Extract pointer to Expression
    1379       */
    1380      Expression *exp() { return (Expression *)&u; }
    1381  
    1382      /* Convert to an allocated Expression
    1383       */
    1384      Expression *copy();
    1385  
    1386  private:
    1387      // Ensure that the union is suitably aligned.
    1388  #if defined(__GNUC__) || defined(__clang__)
    1389      __attribute__((aligned(8)))
    1390  #elif defined(_MSC_VER)
    1391      __declspec(align(8))
    1392  #elif defined(__DMC__)
    1393      #pragma pack(8)
    1394  #endif
    1395      union
    1396      {
    1397          char exp       [sizeof(Expression)];
    1398          char integerexp[sizeof(IntegerExp)];
    1399          char errorexp  [sizeof(ErrorExp)];
    1400          char realexp   [sizeof(RealExp)];
    1401          char complexexp[sizeof(ComplexExp)];
    1402          char symoffexp [sizeof(SymOffExp)];
    1403          char stringexp [sizeof(StringExp)];
    1404          char arrayliteralexp [sizeof(ArrayLiteralExp)];
    1405          char assocarrayliteralexp [sizeof(AssocArrayLiteralExp)];
    1406          char structliteralexp [sizeof(StructLiteralExp)];
    1407          char nullexp   [sizeof(NullExp)];
    1408          char dotvarexp [sizeof(DotVarExp)];
    1409          char addrexp   [sizeof(AddrExp)];
    1410          char indexexp  [sizeof(IndexExp)];
    1411          char sliceexp  [sizeof(SliceExp)];
    1412          char vectorexp [sizeof(VectorExp)];
    1413      } u;
    1414  #if defined(__DMC__)
    1415      #pragma pack()
    1416  #endif
    1417  };
    1418  
    1419  /****************************************************************/
    1420  
    1421  class ObjcClassReferenceExp final : public Expression
    1422  {
    1423  public:
    1424      ClassDeclaration* classDeclaration;
    1425  
    1426      void accept(Visitor *v) override { v->visit(this); }
    1427  };