Home | History | Annotate | Line # | Download | only in dmd
expression.h revision 1.1.1.1
      1 
      2 /* Compiler implementation of the D programming language
      3  * Copyright (C) 1999-2019 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 "complex_t.h"
     14 #include "globals.h"
     15 #include "identifier.h"
     16 #include "arraytypes.h"
     17 #include "intrange.h"
     18 #include "visitor.h"
     19 #include "tokens.h"
     20 
     21 #include "root/rmem.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 Declaration;
     31 class CtorDeclaration;
     32 class NewDeclaration;
     33 class Dsymbol;
     34 class Import;
     35 class Module;
     36 class ScopeDsymbol;
     37 class Expression;
     38 class Declaration;
     39 class AggregateDeclaration;
     40 class StructDeclaration;
     41 class TemplateInstance;
     42 class TemplateDeclaration;
     43 class ClassDeclaration;
     44 class BinExp;
     45 class OverloadSet;
     46 class Initializer;
     47 class StringExp;
     48 class ArrayExp;
     49 class SliceExp;
     50 struct UnionExp;
     51 #ifdef IN_GCC
     52 typedef union tree_node Symbol;
     53 #else
     54 struct Symbol;          // back end symbol
     55 #endif
     56 
     57 Expression *resolveProperties(Scope *sc, Expression *e);
     58 Expression *resolvePropertiesOnly(Scope *sc, Expression *e1);
     59 bool checkAccess(Loc loc, Scope *sc, Expression *e, Declaration *d);
     60 bool checkAccess(Loc loc, Scope *sc, Package *p);
     61 Expression *build_overload(Loc loc, Scope *sc, Expression *ethis, Expression *earg, Dsymbol *d);
     62 Dsymbol *search_function(ScopeDsymbol *ad, Identifier *funcid);
     63 void expandTuples(Expressions *exps);
     64 TupleDeclaration *isAliasThisTuple(Expression *e);
     65 int expandAliasThisTuples(Expressions *exps, size_t starti = 0);
     66 FuncDeclaration *hasThis(Scope *sc);
     67 Expression *fromConstInitializer(int result, Expression *e);
     68 bool arrayExpressionSemantic(Expressions *exps, Scope *sc, bool preserveErrors = false);
     69 TemplateDeclaration *getFuncTemplateDecl(Dsymbol *s);
     70 Expression *valueNoDtor(Expression *e);
     71 int modifyFieldVar(Loc loc, Scope *sc, VarDeclaration *var, Expression *e1);
     72 Expression *resolveAliasThis(Scope *sc, Expression *e, bool gag = false);
     73 Expression *doCopyOrMove(Scope *sc, Expression *e);
     74 Expression *resolveOpDollar(Scope *sc, ArrayExp *ae, Expression **pe0);
     75 Expression *resolveOpDollar(Scope *sc, ArrayExp *ae, IntervalExp *ie, Expression **pe0);
     76 Expression *integralPromotions(Expression *e, Scope *sc);
     77 bool discardValue(Expression *e);
     78 bool isTrivialExp(Expression *e);
     79 
     80 int isConst(Expression *e);
     81 Expression *toDelegate(Expression *e, Type* t, Scope *sc);
     82 AggregateDeclaration *isAggregate(Type *t);
     83 IntRange getIntRange(Expression *e);
     84 bool checkNonAssignmentArrayOp(Expression *e, bool suggestion = false);
     85 bool isUnaArrayOp(TOK op);
     86 bool isBinArrayOp(TOK op);
     87 bool isBinAssignArrayOp(TOK op);
     88 bool isArrayOpOperand(Expression *e);
     89 Expression *arrayOp(BinExp *e, Scope *sc);
     90 Expression *arrayOp(BinAssignExp *e, Scope *sc);
     91 bool hasSideEffect(Expression *e);
     92 bool canThrow(Expression *e, FuncDeclaration *func, bool mustNotThrow);
     93 Expression *Expression_optimize(Expression *e, int result, bool keepLvalue);
     94 MATCH implicitConvTo(Expression *e, Type *t);
     95 Expression *implicitCastTo(Expression *e, Scope *sc, Type *t);
     96 Expression *castTo(Expression *e, Scope *sc, Type *t);
     97 Expression *ctfeInterpret(Expression *);
     98 Expression *inlineCopy(Expression *e, Scope *sc);
     99 Expression *op_overload(Expression *e, Scope *sc);
    100 Type *toStaticArrayType(SliceExp *e);
    101 Expression *scaleFactor(BinExp *be, Scope *sc);
    102 Expression *typeCombine(BinExp *be, Scope *sc);
    103 Expression *inferType(Expression *e, Type *t, int flag = 0);
    104 Expression *semanticTraits(TraitsExp *e, Scope *sc);
    105 Type *getIndirection(Type *t);
    106 
    107 Expression *checkGC(Scope *sc, Expression *e);
    108 
    109 /* Run CTFE on the expression, but allow the expression to be a TypeExp
    110  * or a tuple containing a TypeExp. (This is required by pragma(msg)).
    111  */
    112 Expression *ctfeInterpretForPragmaMsg(Expression *e);
    113 
    114 enum OwnedBy
    115 {
    116     OWNEDcode,      // normal code expression in AST
    117     OWNEDctfe,      // value expression for CTFE
    118     OWNEDcache      // constant value cached for CTFE
    119 };
    120 
    121 #define WANTvalue   0   // default
    122 #define WANTexpand  1   // expand const/immutable variables if possible
    123 
    124 class Expression : public RootObject
    125 {
    126 public:
    127     Loc loc;                    // file location
    128     Type *type;                 // !=NULL means that semantic() has been run
    129     TOK op;                     // to minimize use of dynamic_cast
    130     unsigned char size;         // # of bytes in Expression so we can copy() it
    131     unsigned char parens;       // if this is a parenthesized expression
    132 
    133     Expression(Loc loc, TOK op, int size);
    134     static void _init();
    135     Expression *copy();
    136     virtual Expression *syntaxCopy();
    137 
    138     // kludge for template.isExpression()
    139     int dyncast() const { return DYNCAST_EXPRESSION; }
    140 
    141     void print();
    142     const char *toChars();
    143     void error(const char *format, ...) const;
    144     void warning(const char *format, ...) const;
    145     void deprecation(const char *format, ...) const;
    146 
    147     // creates a single expression which is effectively (e1, e2)
    148     // this new expression does not necessarily need to have valid D source code representation,
    149     // for example, it may include declaration expressions
    150     static Expression *combine(Expression *e1, Expression *e2);
    151     static Expression *extractLast(Expression *e, Expression **pe0);
    152     static Expressions *arraySyntaxCopy(Expressions *exps);
    153 
    154     virtual dinteger_t toInteger();
    155     virtual uinteger_t toUInteger();
    156     virtual real_t toReal();
    157     virtual real_t toImaginary();
    158     virtual complex_t toComplex();
    159     virtual StringExp *toStringExp();
    160     virtual bool isLvalue();
    161     virtual Expression *toLvalue(Scope *sc, Expression *e);
    162     virtual Expression *modifiableLvalue(Scope *sc, Expression *e);
    163     Expression *implicitCastTo(Scope *sc, Type *t)
    164     {
    165         return ::implicitCastTo(this, sc, t);
    166     }
    167     MATCH implicitConvTo(Type *t)
    168     {
    169         return ::implicitConvTo(this, t);
    170     }
    171     Expression *castTo(Scope *sc, Type *t)
    172     {
    173         return ::castTo(this, sc, t);
    174     }
    175     virtual Expression *resolveLoc(Loc loc, Scope *sc);
    176     virtual bool checkType();
    177     virtual bool checkValue();
    178     bool checkScalar();
    179     bool checkNoBool();
    180     bool checkIntegral();
    181     bool checkArithmetic();
    182     void checkDeprecated(Scope *sc, Dsymbol *s);
    183     bool checkPurity(Scope *sc, FuncDeclaration *f);
    184     bool checkPurity(Scope *sc, VarDeclaration *v);
    185     bool checkSafety(Scope *sc, FuncDeclaration *f);
    186     bool checkNogc(Scope *sc, FuncDeclaration *f);
    187     bool checkPostblit(Scope *sc, Type *t);
    188     bool checkRightThis(Scope *sc);
    189     bool checkReadModifyWrite(TOK rmwOp, Expression *ex = NULL);
    190     virtual int checkModifiable(Scope *sc, int flag = 0);
    191     virtual Expression *toBoolean(Scope *sc);
    192     virtual Expression *addDtorHook(Scope *sc);
    193     Expression *addressOf();
    194     Expression *deref();
    195 
    196     Expression *optimize(int result, bool keepLvalue = false)
    197     {
    198         return Expression_optimize(this, result, keepLvalue);
    199     }
    200 
    201     // Entry point for CTFE.
    202     // A compile-time result is required. Give an error if not possible
    203     Expression *ctfeInterpret()
    204     {
    205         return ::ctfeInterpret(this);
    206     }
    207 
    208     int isConst() { return ::isConst(this); }
    209     virtual bool isBool(bool result);
    210     Expression *op_overload(Scope *sc)
    211     {
    212         return ::op_overload(this, sc);
    213     }
    214 
    215     virtual bool hasCode()
    216     {
    217         return true;
    218     }
    219 
    220     virtual void accept(Visitor *v) { v->visit(this); }
    221 };
    222 
    223 class IntegerExp : public Expression
    224 {
    225 public:
    226     dinteger_t value;
    227 
    228     IntegerExp(Loc loc, dinteger_t value, Type *type);
    229     IntegerExp(dinteger_t value);
    230     static IntegerExp *create(Loc loc, dinteger_t value, Type *type);
    231     bool equals(RootObject *o);
    232     dinteger_t toInteger();
    233     real_t toReal();
    234     real_t toImaginary();
    235     complex_t toComplex();
    236     bool isBool(bool result);
    237     Expression *toLvalue(Scope *sc, Expression *e);
    238     void accept(Visitor *v) { v->visit(this); }
    239     dinteger_t getInteger() { return value; }
    240     void setInteger(dinteger_t value);
    241     void normalize();
    242 };
    243 
    244 class ErrorExp : public Expression
    245 {
    246 public:
    247     ErrorExp();
    248     Expression *toLvalue(Scope *sc, Expression *e);
    249     void accept(Visitor *v) { v->visit(this); }
    250 
    251     static ErrorExp *errorexp; // handy shared value
    252 };
    253 
    254 class RealExp : public Expression
    255 {
    256 public:
    257     real_t value;
    258 
    259     RealExp(Loc loc, real_t value, Type *type);
    260     static RealExp *create(Loc loc, real_t value, Type *type);
    261     bool equals(RootObject *o);
    262     dinteger_t toInteger();
    263     uinteger_t toUInteger();
    264     real_t toReal();
    265     real_t toImaginary();
    266     complex_t toComplex();
    267     bool isBool(bool result);
    268     void accept(Visitor *v) { v->visit(this); }
    269 };
    270 
    271 class ComplexExp : public Expression
    272 {
    273 public:
    274     complex_t value;
    275 
    276     ComplexExp(Loc loc, complex_t value, Type *type);
    277     static ComplexExp *create(Loc loc, complex_t value, Type *type);
    278     bool equals(RootObject *o);
    279     dinteger_t toInteger();
    280     uinteger_t toUInteger();
    281     real_t toReal();
    282     real_t toImaginary();
    283     complex_t toComplex();
    284     bool isBool(bool result);
    285     void accept(Visitor *v) { v->visit(this); }
    286 };
    287 
    288 class IdentifierExp : public Expression
    289 {
    290 public:
    291     Identifier *ident;
    292 
    293     IdentifierExp(Loc loc, Identifier *ident);
    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     DollarExp(Loc loc);
    304     void accept(Visitor *v) { v->visit(this); }
    305 };
    306 
    307 class DsymbolExp : public Expression
    308 {
    309 public:
    310     Dsymbol *s;
    311     bool hasOverloads;
    312 
    313     DsymbolExp(Loc loc, Dsymbol *s, bool hasOverloads = true);
    314     bool isLvalue();
    315     Expression *toLvalue(Scope *sc, Expression *e);
    316     void accept(Visitor *v) { v->visit(this); }
    317 };
    318 
    319 class ThisExp : public Expression
    320 {
    321 public:
    322     VarDeclaration *var;
    323 
    324     ThisExp(Loc loc);
    325     bool isBool(bool result);
    326     bool isLvalue();
    327     Expression *toLvalue(Scope *sc, Expression *e);
    328 
    329     void accept(Visitor *v) { v->visit(this); }
    330 };
    331 
    332 class SuperExp : public ThisExp
    333 {
    334 public:
    335     SuperExp(Loc loc);
    336 
    337     void accept(Visitor *v) { v->visit(this); }
    338 };
    339 
    340 class NullExp : public Expression
    341 {
    342 public:
    343     unsigned char committed;    // !=0 if type is committed
    344 
    345     NullExp(Loc loc, Type *t = NULL);
    346     bool equals(RootObject *o);
    347     bool isBool(bool result);
    348     StringExp *toStringExp();
    349     void accept(Visitor *v) { v->visit(this); }
    350 };
    351 
    352 class StringExp : public Expression
    353 {
    354 public:
    355     void *string;       // char, wchar, or dchar data
    356     size_t len;         // number of chars, wchars, or dchars
    357     unsigned char sz;   // 1: char, 2: wchar, 4: dchar
    358     unsigned char committed;    // !=0 if type is committed
    359     utf8_t postfix;      // 'c', 'w', 'd'
    360     OwnedBy ownedByCtfe;
    361 
    362     StringExp(Loc loc, char *s);
    363     StringExp(Loc loc, void *s, size_t len);
    364     StringExp(Loc loc, void *s, size_t len, utf8_t postfix);
    365     static StringExp *create(Loc loc, char *s);
    366     static StringExp *create(Loc loc, void *s, size_t len);
    367     bool equals(RootObject *o);
    368     StringExp *toStringExp();
    369     StringExp *toUTF8(Scope *sc);
    370     int compare(RootObject *obj);
    371     bool isBool(bool result);
    372     bool isLvalue();
    373     Expression *toLvalue(Scope *sc, Expression *e);
    374     Expression *modifiableLvalue(Scope *sc, Expression *e);
    375     unsigned charAt(uinteger_t i) const;
    376     void accept(Visitor *v) { v->visit(this); }
    377     size_t numberOfCodeUnits(int tynto = 0) const;
    378     void writeTo(void* dest, bool zero, int tyto = 0) const;
    379     char *toPtr();
    380 };
    381 
    382 // Tuple
    383 
    384 class TupleExp : public Expression
    385 {
    386 public:
    387     Expression *e0;     // side-effect part
    388     /* Tuple-field access may need to take out its side effect part.
    389      * For example:
    390      *      foo().tupleof
    391      * is rewritten as:
    392      *      (ref __tup = foo(); tuple(__tup.field0, __tup.field1, ...))
    393      * The declaration of temporary variable __tup will be stored in TupleExp::e0.
    394      */
    395     Expressions *exps;
    396 
    397     TupleExp(Loc loc, Expression *e0, Expressions *exps);
    398     TupleExp(Loc loc, Expressions *exps);
    399     TupleExp(Loc loc, TupleDeclaration *tup);
    400     Expression *syntaxCopy();
    401     bool equals(RootObject *o);
    402 
    403     void accept(Visitor *v) { v->visit(this); }
    404 };
    405 
    406 class ArrayLiteralExp : public Expression
    407 {
    408 public:
    409     Expression *basis;
    410     Expressions *elements;
    411     OwnedBy ownedByCtfe;
    412 
    413     ArrayLiteralExp(Loc loc, Type *type, Expressions *elements);
    414     ArrayLiteralExp(Loc loc, Type *type, Expression *e);
    415     ArrayLiteralExp(Loc loc, Type *type, Expression *basis, Expressions *elements);
    416     static ArrayLiteralExp *create(Loc loc, Expressions *elements);
    417     Expression *syntaxCopy();
    418     bool equals(RootObject *o);
    419     Expression *getElement(d_size_t i);
    420     static Expressions* copyElements(Expression *e1, Expression *e2 = NULL);
    421     bool isBool(bool result);
    422     StringExp *toStringExp();
    423 
    424     void accept(Visitor *v) { v->visit(this); }
    425 };
    426 
    427 class AssocArrayLiteralExp : public Expression
    428 {
    429 public:
    430     Expressions *keys;
    431     Expressions *values;
    432     OwnedBy ownedByCtfe;
    433 
    434     AssocArrayLiteralExp(Loc loc, Expressions *keys, Expressions *values);
    435     bool equals(RootObject *o);
    436     Expression *syntaxCopy();
    437     bool isBool(bool result);
    438 
    439     void accept(Visitor *v) { v->visit(this); }
    440 };
    441 
    442 // scrubReturnValue is running
    443 #define stageScrub          0x1
    444 // hasNonConstPointers is running
    445 #define stageSearchPointers 0x2
    446 // optimize is running
    447 #define stageOptimize       0x4
    448 // apply is running
    449 #define stageApply          0x8
    450 //inlineScan is running
    451 #define stageInlineScan     0x10
    452 // toCBuffer is running
    453 #define stageToCBuffer      0x20
    454 
    455 class StructLiteralExp : public Expression
    456 {
    457 public:
    458     StructDeclaration *sd;      // which aggregate this is for
    459     Expressions *elements;      // parallels sd->fields[] with NULL entries for fields to skip
    460     Type *stype;                // final type of result (can be different from sd's type)
    461 
    462     bool useStaticInit;         // if this is true, use the StructDeclaration's init symbol
    463     Symbol *sym;                // back end symbol to initialize with literal
    464 
    465     OwnedBy ownedByCtfe;
    466 
    467     // pointer to the origin instance of the expression.
    468     // once a new expression is created, origin is set to 'this'.
    469     // anytime when an expression copy is created, 'origin' pointer is set to
    470     // 'origin' pointer value of the original expression.
    471     StructLiteralExp *origin;
    472 
    473     // those fields need to prevent a infinite recursion when one field of struct initialized with 'this' pointer.
    474     StructLiteralExp *inlinecopy;
    475 
    476     // anytime when recursive function is calling, 'stageflags' marks with bit flag of
    477     // current stage and unmarks before return from this function.
    478     // 'inlinecopy' uses similar 'stageflags' and from multiple evaluation 'doInline'
    479     // (with infinite recursion) of this expression.
    480     int stageflags;
    481 
    482     StructLiteralExp(Loc loc, StructDeclaration *sd, Expressions *elements, Type *stype = NULL);
    483     static StructLiteralExp *create(Loc loc, StructDeclaration *sd, void *elements, Type *stype = NULL);
    484     bool equals(RootObject *o);
    485     Expression *syntaxCopy();
    486     Expression *getField(Type *type, unsigned offset);
    487     int getFieldIndex(Type *type, unsigned offset);
    488     Expression *addDtorHook(Scope *sc);
    489 
    490     void accept(Visitor *v) { v->visit(this); }
    491 };
    492 
    493 class DotIdExp;
    494 DotIdExp *typeDotIdExp(Loc loc, Type *type, Identifier *ident);
    495 
    496 class TypeExp : public Expression
    497 {
    498 public:
    499     TypeExp(Loc loc, Type *type);
    500     Expression *syntaxCopy();
    501     bool checkType();
    502     bool checkValue();
    503     void accept(Visitor *v) { v->visit(this); }
    504 };
    505 
    506 class ScopeExp : public Expression
    507 {
    508 public:
    509     ScopeDsymbol *sds;
    510 
    511     ScopeExp(Loc loc, ScopeDsymbol *sds);
    512     Expression *syntaxCopy();
    513     bool checkType();
    514     bool checkValue();
    515     void accept(Visitor *v) { v->visit(this); }
    516 };
    517 
    518 class TemplateExp : public Expression
    519 {
    520 public:
    521     TemplateDeclaration *td;
    522     FuncDeclaration *fd;
    523 
    524     TemplateExp(Loc loc, TemplateDeclaration *td, FuncDeclaration *fd = NULL);
    525     bool isLvalue();
    526     Expression *toLvalue(Scope *sc, Expression *e);
    527     bool checkType();
    528     bool checkValue();
    529     void accept(Visitor *v) { v->visit(this); }
    530 };
    531 
    532 class NewExp : public Expression
    533 {
    534 public:
    535     /* thisexp.new(newargs) newtype(arguments)
    536      */
    537     Expression *thisexp;        // if !NULL, 'this' for class being allocated
    538     Expressions *newargs;       // Array of Expression's to call new operator
    539     Type *newtype;
    540     Expressions *arguments;     // Array of Expression's
    541 
    542     Expression *argprefix;      // expression to be evaluated just before arguments[]
    543 
    544     CtorDeclaration *member;    // constructor function
    545     NewDeclaration *allocator;  // allocator function
    546     int onstack;                // allocate on stack
    547 
    548     NewExp(Loc loc, Expression *thisexp, Expressions *newargs,
    549         Type *newtype, Expressions *arguments);
    550     static NewExp *create(Loc loc, Expression *thisexp, Expressions *newargs, Type *newtype, Expressions *arguments);
    551     Expression *syntaxCopy();
    552 
    553     void accept(Visitor *v) { v->visit(this); }
    554 };
    555 
    556 class NewAnonClassExp : public Expression
    557 {
    558 public:
    559     /* thisexp.new(newargs) class baseclasses { } (arguments)
    560      */
    561     Expression *thisexp;        // if !NULL, 'this' for class being allocated
    562     Expressions *newargs;       // Array of Expression's to call new operator
    563     ClassDeclaration *cd;       // class being instantiated
    564     Expressions *arguments;     // Array of Expression's to call class constructor
    565 
    566     NewAnonClassExp(Loc loc, Expression *thisexp, Expressions *newargs,
    567         ClassDeclaration *cd, Expressions *arguments);
    568     Expression *syntaxCopy();
    569     void accept(Visitor *v) { v->visit(this); }
    570 };
    571 
    572 class SymbolExp : public Expression
    573 {
    574 public:
    575     Declaration *var;
    576     bool hasOverloads;
    577     SymbolExp(Loc loc, TOK op, int size, Declaration *var, bool hasOverloads);
    578 
    579     void accept(Visitor *v) { v->visit(this); }
    580 };
    581 
    582 // Offset from symbol
    583 
    584 class SymOffExp : public SymbolExp
    585 {
    586 public:
    587     dinteger_t offset;
    588 
    589     SymOffExp(Loc loc, Declaration *var, dinteger_t offset, bool hasOverloads = true);
    590     bool isBool(bool result);
    591 
    592     void accept(Visitor *v) { v->visit(this); }
    593 };
    594 
    595 // Variable
    596 
    597 class VarExp : public SymbolExp
    598 {
    599 public:
    600     VarExp(Loc loc, Declaration *var, bool hasOverloads = true);
    601     static VarExp *create(Loc loc, Declaration *var, bool hasOverloads = true);
    602     bool equals(RootObject *o);
    603     int checkModifiable(Scope *sc, int flag);
    604     bool checkReadModifyWrite();
    605     bool isLvalue();
    606     Expression *toLvalue(Scope *sc, Expression *e);
    607     Expression *modifiableLvalue(Scope *sc, Expression *e);
    608 
    609     void accept(Visitor *v) { v->visit(this); }
    610 };
    611 
    612 // Overload Set
    613 
    614 class OverExp : public Expression
    615 {
    616 public:
    617     OverloadSet *vars;
    618 
    619     OverExp(Loc loc, OverloadSet *s);
    620     bool isLvalue();
    621     Expression *toLvalue(Scope *sc, Expression *e);
    622     void accept(Visitor *v) { v->visit(this); }
    623 };
    624 
    625 // Function/Delegate literal
    626 
    627 class FuncExp : public Expression
    628 {
    629 public:
    630     FuncLiteralDeclaration *fd;
    631     TemplateDeclaration *td;
    632     TOK tok;
    633 
    634     FuncExp(Loc loc, Dsymbol *s);
    635     bool equals(RootObject *o);
    636     void genIdent(Scope *sc);
    637     Expression *syntaxCopy();
    638     MATCH matchType(Type *to, Scope *sc, FuncExp **pfe, int flag = 0);
    639     const char *toChars();
    640     bool checkType();
    641     bool checkValue();
    642 
    643     void accept(Visitor *v) { v->visit(this); }
    644 };
    645 
    646 // Declaration of a symbol
    647 
    648 // D grammar allows declarations only as statements. However in AST representation
    649 // it can be part of any expression. This is used, for example, during internal
    650 // syntax re-writes to inject hidden symbols.
    651 class DeclarationExp : public Expression
    652 {
    653 public:
    654     Dsymbol *declaration;
    655 
    656     DeclarationExp(Loc loc, Dsymbol *declaration);
    657     Expression *syntaxCopy();
    658 
    659     bool hasCode();
    660 
    661     void accept(Visitor *v) { v->visit(this); }
    662 };
    663 
    664 class TypeidExp : public Expression
    665 {
    666 public:
    667     RootObject *obj;
    668 
    669     TypeidExp(Loc loc, RootObject *obj);
    670     Expression *syntaxCopy();
    671     void accept(Visitor *v) { v->visit(this); }
    672 };
    673 
    674 class TraitsExp : public Expression
    675 {
    676 public:
    677     Identifier *ident;
    678     Objects *args;
    679 
    680     TraitsExp(Loc loc, Identifier *ident, Objects *args);
    681     Expression *syntaxCopy();
    682     void accept(Visitor *v) { v->visit(this); }
    683 };
    684 
    685 class HaltExp : public Expression
    686 {
    687 public:
    688     HaltExp(Loc loc);
    689 
    690     void accept(Visitor *v) { v->visit(this); }
    691 };
    692 
    693 class IsExp : public Expression
    694 {
    695 public:
    696     /* is(targ id tok tspec)
    697      * is(targ id == tok2)
    698      */
    699     Type *targ;
    700     Identifier *id;     // can be NULL
    701     TOK tok;       // ':' or '=='
    702     Type *tspec;        // can be NULL
    703     TOK tok2;      // 'struct', 'union', etc.
    704     TemplateParameters *parameters;
    705 
    706     IsExp(Loc loc, Type *targ, Identifier *id, TOK tok, Type *tspec,
    707         TOK tok2, TemplateParameters *parameters);
    708     Expression *syntaxCopy();
    709     void accept(Visitor *v) { v->visit(this); }
    710 };
    711 
    712 /****************************************************************/
    713 
    714 class UnaExp : public Expression
    715 {
    716 public:
    717     Expression *e1;
    718     Type *att1; // Save alias this type to detect recursion
    719 
    720     UnaExp(Loc loc, TOK op, int size, Expression *e1);
    721     Expression *syntaxCopy();
    722     Expression *incompatibleTypes();
    723     Expression *resolveLoc(Loc loc, Scope *sc);
    724 
    725     void accept(Visitor *v) { v->visit(this); }
    726 };
    727 
    728 typedef UnionExp (*fp_t)(Loc loc, Type *, Expression *, Expression *);
    729 typedef int (*fp2_t)(Loc loc, TOK, Expression *, Expression *);
    730 
    731 class BinExp : public Expression
    732 {
    733 public:
    734     Expression *e1;
    735     Expression *e2;
    736 
    737     Type *att1; // Save alias this type to detect recursion
    738     Type *att2; // Save alias this type to detect recursion
    739 
    740     BinExp(Loc loc, TOK op, int size, Expression *e1, Expression *e2);
    741     Expression *syntaxCopy();
    742     Expression *incompatibleTypes();
    743     Expression *checkOpAssignTypes(Scope *sc);
    744     bool checkIntegralBin();
    745     bool checkArithmeticBin();
    746 
    747     Expression *reorderSettingAAElem(Scope *sc);
    748 
    749     void accept(Visitor *v) { v->visit(this); }
    750 };
    751 
    752 class BinAssignExp : public BinExp
    753 {
    754 public:
    755     BinAssignExp(Loc loc, TOK op, int size, Expression *e1, Expression *e2);
    756 
    757     bool isLvalue();
    758     Expression *toLvalue(Scope *sc, Expression *ex);
    759     Expression *modifiableLvalue(Scope *sc, Expression *e);
    760     void accept(Visitor *v) { v->visit(this); }
    761 };
    762 
    763 /****************************************************************/
    764 
    765 class CompileExp : public UnaExp
    766 {
    767 public:
    768     CompileExp(Loc loc, Expression *e);
    769     void accept(Visitor *v) { v->visit(this); }
    770 };
    771 
    772 class ImportExp : public UnaExp
    773 {
    774 public:
    775     ImportExp(Loc loc, Expression *e);
    776     void accept(Visitor *v) { v->visit(this); }
    777 };
    778 
    779 class AssertExp : public UnaExp
    780 {
    781 public:
    782     Expression *msg;
    783 
    784     AssertExp(Loc loc, Expression *e, Expression *msg = NULL);
    785     Expression *syntaxCopy();
    786 
    787     void accept(Visitor *v) { v->visit(this); }
    788 };
    789 
    790 class DotIdExp : public UnaExp
    791 {
    792 public:
    793     Identifier *ident;
    794     bool noderef;       // true if the result of the expression will never be dereferenced
    795     bool wantsym;       // do not replace Symbol with its initializer during semantic()
    796 
    797     DotIdExp(Loc loc, Expression *e, Identifier *ident);
    798     static DotIdExp *create(Loc loc, Expression *e, Identifier *ident);
    799     void accept(Visitor *v) { v->visit(this); }
    800 };
    801 
    802 class DotTemplateExp : public UnaExp
    803 {
    804 public:
    805     TemplateDeclaration *td;
    806 
    807     DotTemplateExp(Loc loc, Expression *e, TemplateDeclaration *td);
    808     void accept(Visitor *v) { v->visit(this); }
    809 };
    810 
    811 class DotVarExp : public UnaExp
    812 {
    813 public:
    814     Declaration *var;
    815     bool hasOverloads;
    816 
    817     DotVarExp(Loc loc, Expression *e, Declaration *var, bool hasOverloads = true);
    818     int checkModifiable(Scope *sc, int flag);
    819     bool checkReadModifyWrite();
    820     bool isLvalue();
    821     Expression *toLvalue(Scope *sc, Expression *e);
    822     Expression *modifiableLvalue(Scope *sc, Expression *e);
    823     void accept(Visitor *v) { v->visit(this); }
    824 };
    825 
    826 class DotTemplateInstanceExp : public UnaExp
    827 {
    828 public:
    829     TemplateInstance *ti;
    830 
    831     DotTemplateInstanceExp(Loc loc, Expression *e, Identifier *name, Objects *tiargs);
    832     DotTemplateInstanceExp(Loc loc, Expression *e, TemplateInstance *ti);
    833     Expression *syntaxCopy();
    834     bool findTempDecl(Scope *sc);
    835     void accept(Visitor *v) { v->visit(this); }
    836 };
    837 
    838 class DelegateExp : public UnaExp
    839 {
    840 public:
    841     FuncDeclaration *func;
    842     bool hasOverloads;
    843 
    844     DelegateExp(Loc loc, Expression *e, FuncDeclaration *func, bool hasOverloads = true);
    845 
    846     void accept(Visitor *v) { v->visit(this); }
    847 };
    848 
    849 class DotTypeExp : public UnaExp
    850 {
    851 public:
    852     Dsymbol *sym;               // symbol that represents a type
    853 
    854     DotTypeExp(Loc loc, Expression *e, Dsymbol *sym);
    855     void accept(Visitor *v) { v->visit(this); }
    856 };
    857 
    858 class CallExp : public UnaExp
    859 {
    860 public:
    861     Expressions *arguments;     // function arguments
    862     FuncDeclaration *f;         // symbol to call
    863     bool directcall;            // true if a virtual call is devirtualized
    864     CallExp(Loc loc, Expression *e, Expressions *exps);
    865     CallExp(Loc loc, Expression *e);
    866     CallExp(Loc loc, Expression *e, Expression *earg1);
    867     CallExp(Loc loc, Expression *e, Expression *earg1, Expression *earg2);
    868 
    869     static CallExp *create(Loc loc, Expression *e, Expressions *exps);
    870     static CallExp *create(Loc loc, Expression *e);
    871     static CallExp *create(Loc loc, Expression *e, Expression *earg1);
    872 
    873     Expression *syntaxCopy();
    874     bool isLvalue();
    875     Expression *toLvalue(Scope *sc, Expression *e);
    876     Expression *addDtorHook(Scope *sc);
    877 
    878     void accept(Visitor *v) { v->visit(this); }
    879 };
    880 
    881 class AddrExp : public UnaExp
    882 {
    883 public:
    884     AddrExp(Loc loc, Expression *e);
    885     AddrExp(Loc loc, Expression *e, Type *t);
    886 
    887     void accept(Visitor *v) { v->visit(this); }
    888 };
    889 
    890 class PtrExp : public UnaExp
    891 {
    892 public:
    893     PtrExp(Loc loc, Expression *e);
    894     PtrExp(Loc loc, Expression *e, Type *t);
    895     int checkModifiable(Scope *sc, int flag);
    896     bool isLvalue();
    897     Expression *toLvalue(Scope *sc, Expression *e);
    898     Expression *modifiableLvalue(Scope *sc, Expression *e);
    899 
    900     void accept(Visitor *v) { v->visit(this); }
    901 };
    902 
    903 class NegExp : public UnaExp
    904 {
    905 public:
    906     NegExp(Loc loc, Expression *e);
    907 
    908     void accept(Visitor *v) { v->visit(this); }
    909 };
    910 
    911 class UAddExp : public UnaExp
    912 {
    913 public:
    914     UAddExp(Loc loc, Expression *e);
    915 
    916     void accept(Visitor *v) { v->visit(this); }
    917 };
    918 
    919 class ComExp : public UnaExp
    920 {
    921 public:
    922     ComExp(Loc loc, Expression *e);
    923 
    924     void accept(Visitor *v) { v->visit(this); }
    925 };
    926 
    927 class NotExp : public UnaExp
    928 {
    929 public:
    930     NotExp(Loc loc, Expression *e);
    931     void accept(Visitor *v) { v->visit(this); }
    932 };
    933 
    934 class DeleteExp : public UnaExp
    935 {
    936 public:
    937     bool isRAII;
    938     DeleteExp(Loc loc, Expression *e, bool isRAII);
    939     Expression *toBoolean(Scope *sc);
    940     void accept(Visitor *v) { v->visit(this); }
    941 };
    942 
    943 class CastExp : public UnaExp
    944 {
    945 public:
    946     // Possible to cast to one type while painting to another type
    947     Type *to;                   // type to cast to
    948     unsigned char mod;          // MODxxxxx
    949 
    950     CastExp(Loc loc, Expression *e, Type *t);
    951     CastExp(Loc loc, Expression *e, unsigned char mod);
    952     Expression *syntaxCopy();
    953 
    954     void accept(Visitor *v) { v->visit(this); }
    955 };
    956 
    957 class VectorExp : public UnaExp
    958 {
    959 public:
    960     TypeVector *to;             // the target vector type before semantic()
    961     unsigned dim;               // number of elements in the vector
    962     OwnedBy ownedByCtfe;
    963 
    964     VectorExp(Loc loc, Expression *e, Type *t);
    965     static VectorExp *create(Loc loc, Expression *e, Type *t);
    966     Expression *syntaxCopy();
    967     void accept(Visitor *v) { v->visit(this); }
    968 };
    969 
    970 class VectorArrayExp : public UnaExp
    971 {
    972 public:
    973     VectorArrayExp(Loc loc, Expression *e1);
    974     bool isLvalue();
    975     Expression *toLvalue(Scope *sc, Expression *e);
    976     void accept(Visitor *v) { v->visit(this); }
    977 };
    978 
    979 class SliceExp : public UnaExp
    980 {
    981 public:
    982     Expression *upr;            // NULL if implicit 0
    983     Expression *lwr;            // NULL if implicit [length - 1]
    984     VarDeclaration *lengthVar;
    985     bool upperIsInBounds;       // true if upr <= e1.length
    986     bool lowerIsLessThanUpper;  // true if lwr <= upr
    987     bool arrayop;               // an array operation, rather than a slice
    988 
    989     SliceExp(Loc loc, Expression *e1, IntervalExp *ie);
    990     SliceExp(Loc loc, Expression *e1, Expression *lwr, Expression *upr);
    991     Expression *syntaxCopy();
    992     int checkModifiable(Scope *sc, int flag);
    993     bool isLvalue();
    994     Expression *toLvalue(Scope *sc, Expression *e);
    995     Expression *modifiableLvalue(Scope *sc, Expression *e);
    996     bool isBool(bool result);
    997 
    998     void accept(Visitor *v) { v->visit(this); }
    999 };
   1000 
   1001 class ArrayLengthExp : public UnaExp
   1002 {
   1003 public:
   1004     ArrayLengthExp(Loc loc, Expression *e1);
   1005 
   1006     static Expression *rewriteOpAssign(BinExp *exp);
   1007     void accept(Visitor *v) { v->visit(this); }
   1008 };
   1009 
   1010 class IntervalExp : public Expression
   1011 {
   1012 public:
   1013     Expression *lwr;
   1014     Expression *upr;
   1015 
   1016     IntervalExp(Loc loc, Expression *lwr, Expression *upr);
   1017     Expression *syntaxCopy();
   1018     void accept(Visitor *v) { v->visit(this); }
   1019 };
   1020 
   1021 class DelegatePtrExp : public UnaExp
   1022 {
   1023 public:
   1024     DelegatePtrExp(Loc loc, Expression *e1);
   1025     bool isLvalue();
   1026     Expression *toLvalue(Scope *sc, Expression *e);
   1027     Expression *modifiableLvalue(Scope *sc, Expression *e);
   1028     void accept(Visitor *v) { v->visit(this); }
   1029 };
   1030 
   1031 class DelegateFuncptrExp : public UnaExp
   1032 {
   1033 public:
   1034     DelegateFuncptrExp(Loc loc, Expression *e1);
   1035     bool isLvalue();
   1036     Expression *toLvalue(Scope *sc, Expression *e);
   1037     Expression *modifiableLvalue(Scope *sc, Expression *e);
   1038     void accept(Visitor *v) { v->visit(this); }
   1039 };
   1040 
   1041 // e1[a0,a1,a2,a3,...]
   1042 
   1043 class ArrayExp : public UnaExp
   1044 {
   1045 public:
   1046     Expressions *arguments;             // Array of Expression's
   1047     size_t currentDimension;            // for opDollar
   1048     VarDeclaration *lengthVar;
   1049 
   1050     ArrayExp(Loc loc, Expression *e1, Expression *index = NULL);
   1051     ArrayExp(Loc loc, Expression *e1, Expressions *args);
   1052     Expression *syntaxCopy();
   1053     bool isLvalue();
   1054     Expression *toLvalue(Scope *sc, Expression *e);
   1055 
   1056     void accept(Visitor *v) { v->visit(this); }
   1057 };
   1058 
   1059 /****************************************************************/
   1060 
   1061 class DotExp : public BinExp
   1062 {
   1063 public:
   1064     DotExp(Loc loc, Expression *e1, Expression *e2);
   1065     void accept(Visitor *v) { v->visit(this); }
   1066 };
   1067 
   1068 class CommaExp : public BinExp
   1069 {
   1070 public:
   1071     bool isGenerated;
   1072     bool allowCommaExp;
   1073     CommaExp(Loc loc, Expression *e1, Expression *e2, bool generated = true);
   1074     int checkModifiable(Scope *sc, int flag);
   1075     bool isLvalue();
   1076     Expression *toLvalue(Scope *sc, Expression *e);
   1077     Expression *modifiableLvalue(Scope *sc, Expression *e);
   1078     bool isBool(bool result);
   1079     Expression *toBoolean(Scope *sc);
   1080     Expression *addDtorHook(Scope *sc);
   1081     void accept(Visitor *v) { v->visit(this); }
   1082 };
   1083 
   1084 class IndexExp : public BinExp
   1085 {
   1086 public:
   1087     VarDeclaration *lengthVar;
   1088     bool modifiable;
   1089     bool indexIsInBounds;       // true if 0 <= e2 && e2 <= e1.length - 1
   1090 
   1091     IndexExp(Loc loc, Expression *e1, Expression *e2);
   1092     Expression *syntaxCopy();
   1093     int checkModifiable(Scope *sc, int flag);
   1094     bool isLvalue();
   1095     Expression *toLvalue(Scope *sc, Expression *e);
   1096     Expression *modifiableLvalue(Scope *sc, Expression *e);
   1097 
   1098     Expression *markSettingAAElem();
   1099 
   1100     void accept(Visitor *v) { v->visit(this); }
   1101 };
   1102 
   1103 /* For both i++ and i--
   1104  */
   1105 class PostExp : public BinExp
   1106 {
   1107 public:
   1108     PostExp(TOK op, Loc loc, Expression *e);
   1109     void accept(Visitor *v) { v->visit(this); }
   1110 };
   1111 
   1112 /* For both ++i and --i
   1113  */
   1114 class PreExp : public UnaExp
   1115 {
   1116 public:
   1117     PreExp(TOK op, Loc loc, Expression *e);
   1118     void accept(Visitor *v) { v->visit(this); }
   1119 };
   1120 
   1121 enum MemorySet
   1122 {
   1123     blockAssign     = 1,    // setting the contents of an array
   1124     referenceInit   = 2     // setting the reference of STCref variable
   1125 };
   1126 
   1127 class AssignExp : public BinExp
   1128 {
   1129 public:
   1130     int memset;         // combination of MemorySet flags
   1131 
   1132     AssignExp(Loc loc, Expression *e1, Expression *e2);
   1133     bool isLvalue();
   1134     Expression *toLvalue(Scope *sc, Expression *ex);
   1135     Expression *toBoolean(Scope *sc);
   1136 
   1137     void accept(Visitor *v) { v->visit(this); }
   1138 };
   1139 
   1140 class ConstructExp : public AssignExp
   1141 {
   1142 public:
   1143     ConstructExp(Loc loc, Expression *e1, Expression *e2);
   1144     ConstructExp(Loc loc, VarDeclaration *v, Expression *e2);
   1145     void accept(Visitor *v) { v->visit(this); }
   1146 };
   1147 
   1148 class BlitExp : public AssignExp
   1149 {
   1150 public:
   1151     BlitExp(Loc loc, Expression *e1, Expression *e2);
   1152     BlitExp(Loc loc, VarDeclaration *v, Expression *e2);
   1153     void accept(Visitor *v) { v->visit(this); }
   1154 };
   1155 
   1156 class AddAssignExp : public BinAssignExp
   1157 {
   1158 public:
   1159     AddAssignExp(Loc loc, Expression *e1, Expression *e2);
   1160     void accept(Visitor *v) { v->visit(this); }
   1161 };
   1162 
   1163 class MinAssignExp : public BinAssignExp
   1164 {
   1165 public:
   1166     MinAssignExp(Loc loc, Expression *e1, Expression *e2);
   1167     void accept(Visitor *v) { v->visit(this); }
   1168 };
   1169 
   1170 class MulAssignExp : public BinAssignExp
   1171 {
   1172 public:
   1173     MulAssignExp(Loc loc, Expression *e1, Expression *e2);
   1174     void accept(Visitor *v) { v->visit(this); }
   1175 };
   1176 
   1177 class DivAssignExp : public BinAssignExp
   1178 {
   1179 public:
   1180     DivAssignExp(Loc loc, Expression *e1, Expression *e2);
   1181     void accept(Visitor *v) { v->visit(this); }
   1182 };
   1183 
   1184 class ModAssignExp : public BinAssignExp
   1185 {
   1186 public:
   1187     ModAssignExp(Loc loc, Expression *e1, Expression *e2);
   1188     void accept(Visitor *v) { v->visit(this); }
   1189 };
   1190 
   1191 class AndAssignExp : public BinAssignExp
   1192 {
   1193 public:
   1194     AndAssignExp(Loc loc, Expression *e1, Expression *e2);
   1195     void accept(Visitor *v) { v->visit(this); }
   1196 };
   1197 
   1198 class OrAssignExp : public BinAssignExp
   1199 {
   1200 public:
   1201     OrAssignExp(Loc loc, Expression *e1, Expression *e2);
   1202     void accept(Visitor *v) { v->visit(this); }
   1203 };
   1204 
   1205 class XorAssignExp : public BinAssignExp
   1206 {
   1207 public:
   1208     XorAssignExp(Loc loc, Expression *e1, Expression *e2);
   1209     void accept(Visitor *v) { v->visit(this); }
   1210 };
   1211 
   1212 class PowAssignExp : public BinAssignExp
   1213 {
   1214 public:
   1215     PowAssignExp(Loc loc, Expression *e1, Expression *e2);
   1216     void accept(Visitor *v) { v->visit(this); }
   1217 };
   1218 
   1219 class ShlAssignExp : public BinAssignExp
   1220 {
   1221 public:
   1222     ShlAssignExp(Loc loc, Expression *e1, Expression *e2);
   1223     void accept(Visitor *v) { v->visit(this); }
   1224 };
   1225 
   1226 class ShrAssignExp : public BinAssignExp
   1227 {
   1228 public:
   1229     ShrAssignExp(Loc loc, Expression *e1, Expression *e2);
   1230     void accept(Visitor *v) { v->visit(this); }
   1231 };
   1232 
   1233 class UshrAssignExp : public BinAssignExp
   1234 {
   1235 public:
   1236     UshrAssignExp(Loc loc, Expression *e1, Expression *e2);
   1237     void accept(Visitor *v) { v->visit(this); }
   1238 };
   1239 
   1240 class CatAssignExp : public BinAssignExp
   1241 {
   1242 public:
   1243     CatAssignExp(Loc loc, Expression *e1, Expression *e2);
   1244     void accept(Visitor *v) { v->visit(this); }
   1245 };
   1246 
   1247 class AddExp : public BinExp
   1248 {
   1249 public:
   1250     AddExp(Loc loc, Expression *e1, Expression *e2);
   1251 
   1252     void accept(Visitor *v) { v->visit(this); }
   1253 };
   1254 
   1255 class MinExp : public BinExp
   1256 {
   1257 public:
   1258     MinExp(Loc loc, Expression *e1, Expression *e2);
   1259 
   1260     void accept(Visitor *v) { v->visit(this); }
   1261 };
   1262 
   1263 class CatExp : public BinExp
   1264 {
   1265 public:
   1266     CatExp(Loc loc, Expression *e1, Expression *e2);
   1267 
   1268     void accept(Visitor *v) { v->visit(this); }
   1269 };
   1270 
   1271 class MulExp : public BinExp
   1272 {
   1273 public:
   1274     MulExp(Loc loc, Expression *e1, Expression *e2);
   1275 
   1276     void accept(Visitor *v) { v->visit(this); }
   1277 };
   1278 
   1279 class DivExp : public BinExp
   1280 {
   1281 public:
   1282     DivExp(Loc loc, Expression *e1, Expression *e2);
   1283 
   1284     void accept(Visitor *v) { v->visit(this); }
   1285 };
   1286 
   1287 class ModExp : public BinExp
   1288 {
   1289 public:
   1290     ModExp(Loc loc, Expression *e1, Expression *e2);
   1291 
   1292     void accept(Visitor *v) { v->visit(this); }
   1293 };
   1294 
   1295 class PowExp : public BinExp
   1296 {
   1297 public:
   1298     PowExp(Loc loc, Expression *e1, Expression *e2);
   1299 
   1300     void accept(Visitor *v) { v->visit(this); }
   1301 };
   1302 
   1303 class ShlExp : public BinExp
   1304 {
   1305 public:
   1306     ShlExp(Loc loc, Expression *e1, Expression *e2);
   1307 
   1308     void accept(Visitor *v) { v->visit(this); }
   1309 };
   1310 
   1311 class ShrExp : public BinExp
   1312 {
   1313 public:
   1314     ShrExp(Loc loc, Expression *e1, Expression *e2);
   1315 
   1316     void accept(Visitor *v) { v->visit(this); }
   1317 };
   1318 
   1319 class UshrExp : public BinExp
   1320 {
   1321 public:
   1322     UshrExp(Loc loc, Expression *e1, Expression *e2);
   1323 
   1324     void accept(Visitor *v) { v->visit(this); }
   1325 };
   1326 
   1327 class AndExp : public BinExp
   1328 {
   1329 public:
   1330     AndExp(Loc loc, Expression *e1, Expression *e2);
   1331 
   1332     void accept(Visitor *v) { v->visit(this); }
   1333 };
   1334 
   1335 class OrExp : public BinExp
   1336 {
   1337 public:
   1338     OrExp(Loc loc, Expression *e1, Expression *e2);
   1339 
   1340     void accept(Visitor *v) { v->visit(this); }
   1341 };
   1342 
   1343 class XorExp : public BinExp
   1344 {
   1345 public:
   1346     XorExp(Loc loc, Expression *e1, Expression *e2);
   1347 
   1348     void accept(Visitor *v) { v->visit(this); }
   1349 };
   1350 
   1351 class OrOrExp : public BinExp
   1352 {
   1353 public:
   1354     OrOrExp(Loc loc, Expression *e1, Expression *e2);
   1355     Expression *toBoolean(Scope *sc);
   1356     void accept(Visitor *v) { v->visit(this); }
   1357 };
   1358 
   1359 class AndAndExp : public BinExp
   1360 {
   1361 public:
   1362     AndAndExp(Loc loc, Expression *e1, Expression *e2);
   1363     Expression *toBoolean(Scope *sc);
   1364     void accept(Visitor *v) { v->visit(this); }
   1365 };
   1366 
   1367 class CmpExp : public BinExp
   1368 {
   1369 public:
   1370     CmpExp(TOK op, Loc loc, Expression *e1, Expression *e2);
   1371 
   1372     void accept(Visitor *v) { v->visit(this); }
   1373 };
   1374 
   1375 class InExp : public BinExp
   1376 {
   1377 public:
   1378     InExp(Loc loc, Expression *e1, Expression *e2);
   1379 
   1380     void accept(Visitor *v) { v->visit(this); }
   1381 };
   1382 
   1383 class RemoveExp : public BinExp
   1384 {
   1385 public:
   1386     RemoveExp(Loc loc, Expression *e1, Expression *e2);
   1387     void accept(Visitor *v) { v->visit(this); }
   1388 };
   1389 
   1390 // == and !=
   1391 
   1392 class EqualExp : public BinExp
   1393 {
   1394 public:
   1395     EqualExp(TOK op, Loc loc, Expression *e1, Expression *e2);
   1396 
   1397     void accept(Visitor *v) { v->visit(this); }
   1398 };
   1399 
   1400 // is and !is
   1401 
   1402 class IdentityExp : public BinExp
   1403 {
   1404 public:
   1405     IdentityExp(TOK op, Loc loc, Expression *e1, Expression *e2);
   1406     void accept(Visitor *v) { v->visit(this); }
   1407 };
   1408 
   1409 /****************************************************************/
   1410 
   1411 class CondExp : public BinExp
   1412 {
   1413 public:
   1414     Expression *econd;
   1415 
   1416     CondExp(Loc loc, Expression *econd, Expression *e1, Expression *e2);
   1417     Expression *syntaxCopy();
   1418     int checkModifiable(Scope *sc, int flag);
   1419     bool isLvalue();
   1420     Expression *toLvalue(Scope *sc, Expression *e);
   1421     Expression *modifiableLvalue(Scope *sc, Expression *e);
   1422     Expression *toBoolean(Scope *sc);
   1423     void hookDtors(Scope *sc);
   1424 
   1425     void accept(Visitor *v) { v->visit(this); }
   1426 };
   1427 
   1428 /****************************************************************/
   1429 
   1430 class DefaultInitExp : public Expression
   1431 {
   1432 public:
   1433     TOK subop;             // which of the derived classes this is
   1434 
   1435     DefaultInitExp(Loc loc, TOK subop, int size);
   1436     void accept(Visitor *v) { v->visit(this); }
   1437 };
   1438 
   1439 class FileInitExp : public DefaultInitExp
   1440 {
   1441 public:
   1442     FileInitExp(Loc loc, TOK tok);
   1443     Expression *resolveLoc(Loc loc, Scope *sc);
   1444     void accept(Visitor *v) { v->visit(this); }
   1445 };
   1446 
   1447 class LineInitExp : public DefaultInitExp
   1448 {
   1449 public:
   1450     LineInitExp(Loc loc);
   1451     Expression *resolveLoc(Loc loc, Scope *sc);
   1452     void accept(Visitor *v) { v->visit(this); }
   1453 };
   1454 
   1455 class ModuleInitExp : public DefaultInitExp
   1456 {
   1457 public:
   1458     ModuleInitExp(Loc loc);
   1459     Expression *resolveLoc(Loc loc, Scope *sc);
   1460     void accept(Visitor *v) { v->visit(this); }
   1461 };
   1462 
   1463 class FuncInitExp : public DefaultInitExp
   1464 {
   1465 public:
   1466     FuncInitExp(Loc loc);
   1467     Expression *resolveLoc(Loc loc, Scope *sc);
   1468     void accept(Visitor *v) { v->visit(this); }
   1469 };
   1470 
   1471 class PrettyFuncInitExp : public DefaultInitExp
   1472 {
   1473 public:
   1474     PrettyFuncInitExp(Loc loc);
   1475     Expression *resolveLoc(Loc loc, Scope *sc);
   1476     void accept(Visitor *v) { v->visit(this); }
   1477 };
   1478 
   1479 /****************************************************************/
   1480 
   1481 /* A type meant as a union of all the Expression types,
   1482  * to serve essentially as a Variant that will sit on the stack
   1483  * during CTFE to reduce memory consumption.
   1484  */
   1485 struct UnionExp
   1486 {
   1487     UnionExp() { }  // yes, default constructor does nothing
   1488 
   1489     UnionExp(Expression *e)
   1490     {
   1491         memcpy(this, (void *)e, e->size);
   1492     }
   1493 
   1494     /* Extract pointer to Expression
   1495      */
   1496     Expression *exp() { return (Expression *)&u; }
   1497 
   1498     /* Convert to an allocated Expression
   1499      */
   1500     Expression *copy();
   1501 
   1502 private:
   1503     // Ensure that the union is suitably aligned.
   1504 #if defined(__GNUC__) || defined(__clang__)
   1505     __attribute__((aligned(8)))
   1506 #elif defined(_MSC_VER)
   1507     __declspec(align(8))
   1508 #elif defined(__DMC__)
   1509     #pragma pack(8)
   1510 #endif
   1511     union
   1512     {
   1513         char exp       [sizeof(Expression)];
   1514         char integerexp[sizeof(IntegerExp)];
   1515         char errorexp  [sizeof(ErrorExp)];
   1516         char realexp   [sizeof(RealExp)];
   1517         char complexexp[sizeof(ComplexExp)];
   1518         char symoffexp [sizeof(SymOffExp)];
   1519         char stringexp [sizeof(StringExp)];
   1520         char arrayliteralexp [sizeof(ArrayLiteralExp)];
   1521         char assocarrayliteralexp [sizeof(AssocArrayLiteralExp)];
   1522         char structliteralexp [sizeof(StructLiteralExp)];
   1523         char nullexp   [sizeof(NullExp)];
   1524         char dotvarexp [sizeof(DotVarExp)];
   1525         char addrexp   [sizeof(AddrExp)];
   1526         char indexexp  [sizeof(IndexExp)];
   1527         char sliceexp  [sizeof(SliceExp)];
   1528         char vectorexp [sizeof(VectorExp)];
   1529     } u;
   1530 #if defined(__DMC__)
   1531     #pragma pack()
   1532 #endif
   1533 };
   1534 
   1535 /****************************************************************/
   1536 
   1537 /* Special values used by the interpreter
   1538  */
   1539 
   1540 Expression *expType(Type *type, Expression *e);
   1541 
   1542 UnionExp Neg(Type *type, Expression *e1);
   1543 UnionExp Com(Type *type, Expression *e1);
   1544 UnionExp Not(Type *type, Expression *e1);
   1545 UnionExp Bool(Type *type, Expression *e1);
   1546 UnionExp Cast(Loc loc, Type *type, Type *to, Expression *e1);
   1547 UnionExp ArrayLength(Type *type, Expression *e1);
   1548 UnionExp Ptr(Type *type, Expression *e1);
   1549 
   1550 UnionExp Add(Loc loc, Type *type, Expression *e1, Expression *e2);
   1551 UnionExp Min(Loc loc, Type *type, Expression *e1, Expression *e2);
   1552 UnionExp Mul(Loc loc, Type *type, Expression *e1, Expression *e2);
   1553 UnionExp Div(Loc loc, Type *type, Expression *e1, Expression *e2);
   1554 UnionExp Mod(Loc loc, Type *type, Expression *e1, Expression *e2);
   1555 UnionExp Pow(Loc loc, Type *type, Expression *e1, Expression *e2);
   1556 UnionExp Shl(Loc loc, Type *type, Expression *e1, Expression *e2);
   1557 UnionExp Shr(Loc loc, Type *type, Expression *e1, Expression *e2);
   1558 UnionExp Ushr(Loc loc, Type *type, Expression *e1, Expression *e2);
   1559 UnionExp And(Loc loc, Type *type, Expression *e1, Expression *e2);
   1560 UnionExp Or(Loc loc, Type *type, Expression *e1, Expression *e2);
   1561 UnionExp Xor(Loc loc, Type *type, Expression *e1, Expression *e2);
   1562 UnionExp Index(Type *type, Expression *e1, Expression *e2);
   1563 UnionExp Cat(Type *type, Expression *e1, Expression *e2);
   1564 
   1565 UnionExp Equal(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2);
   1566 UnionExp Cmp(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2);
   1567 UnionExp Identity(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2);
   1568 
   1569 UnionExp Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr);
   1570 
   1571 // Const-folding functions used by CTFE
   1572 
   1573 void sliceAssignArrayLiteralFromString(ArrayLiteralExp *existingAE, StringExp *newval, size_t firstIndex);
   1574 void sliceAssignStringFromArrayLiteral(StringExp *existingSE, ArrayLiteralExp *newae, size_t firstIndex);
   1575 void sliceAssignStringFromString(StringExp *existingSE, StringExp *newstr, size_t firstIndex);
   1576 
   1577 int sliceCmpStringWithString(StringExp *se1, StringExp *se2, size_t lo1, size_t lo2, size_t len);
   1578 int sliceCmpStringWithArray(StringExp *se1, ArrayLiteralExp *ae2, size_t lo1, size_t lo2, size_t len);
   1579