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()
dyncast()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);
implicitCastTo(Scope * sc,Type * t)164     Expression *implicitCastTo(Scope *sc, Type *t)
165     {
166         return ::implicitCastTo(this, sc, t);
167     }
implicitConvTo(Type * t)168     MATCH implicitConvTo(Type *t)
169     {
170         return ::implicitConvTo(this, t);
171     }
castTo(Scope * sc,Type * t)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
ctfeInterpret()204     Expression *ctfeInterpret()
205     {
206         return ::ctfeInterpret(this);
207     }
208 
isConst()209     int isConst() { return ::isConst(this); }
210     virtual bool isBool(bool result);
op_overload(Scope * sc)211     Expression *op_overload(Scope *sc)
212     {
213         return ::op_overload(this, sc);
214     }
215 
hasCode()216     virtual bool hasCode()
217     {
218         return true;
219     }
220 
accept(Visitor * v)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);
accept(Visitor * v)239     void accept(Visitor *v) { v->visit(this); }
getInteger()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);
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)298     void accept(Visitor *v) { v->visit(this); }
299 };
300 
301 class DollarExp : public IdentifierExp
302 {
303 public:
304     DollarExp(Loc loc);
accept(Visitor * v)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);
accept(Visitor * v)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 
accept(Visitor * v)330     void accept(Visitor *v) { v->visit(this); }
331 };
332 
333 class SuperExp : public ThisExp
334 {
335 public:
336     SuperExp(Loc loc);
337 
accept(Visitor * v)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();
accept(Visitor * v)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;
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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();
accept(Visitor * v)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();
accept(Visitor * v)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();
accept(Visitor * v)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 
accept(Visitor * v)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();
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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);
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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();
accept(Visitor * v)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();
accept(Visitor * v)684     void accept(Visitor *v) { v->visit(this); }
685 };
686 
687 class HaltExp : public Expression
688 {
689 public:
690     HaltExp(Loc loc);
691 
accept(Visitor * v)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();
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)771     void accept(Visitor *v) { v->visit(this); }
772 };
773 
774 class ImportExp : public UnaExp
775 {
776 public:
777     ImportExp(Loc loc, Expression *e);
accept(Visitor * v)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 
accept(Visitor * v)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);
accept(Visitor * v)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();
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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 
accept(Visitor * v)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);
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)928     void accept(Visitor *v) { v->visit(this); }
929 };
930 
931 class NotExp : public UnaExp
932 {
933 public:
934     NotExp(Loc loc, Expression *e);
accept(Visitor * v)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);
accept(Visitor * v)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 
accept(Visitor * v)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();
accept(Visitor * v)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);
accept(Visitor * v)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 
accept(Visitor * v)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);
accept(Visitor * v)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();
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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 
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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 
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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 
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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 
accept(Visitor * v)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 
accept(Visitor * v)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);
accept(Visitor * v)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 
accept(Visitor * v)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);
accept(Visitor * v)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 
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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);
accept(Visitor * v)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 {
UnionExpUnionExp1491     UnionExp() { }  // yes, default constructor does nothing
1492 
UnionExpUnionExp1493     UnionExp(Expression *e)
1494     {
1495         memcpy(this, (void *)e, e->size);
1496     }
1497 
1498     /* Extract pointer to Expression
1499      */
expUnionExp1500     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