"Fossies" - the Fresh Open Source Software Archive

Member "dmd2/src/dmd/dmd/expression.h" (20 Nov 2020, 33955 Bytes) of package /linux/misc/dmd.2.094.2.linux.tar.xz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file.

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