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