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