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