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);
accept(Visitor * v)810     void accept(Visitor *v) { v->visit(this); }
811 };
812 
813 class DotVarExp : public UnaExp
814 {
815 public:
816     Declaration *var;
817     bool hasOverloads;
818 
819     DotVarExp(Loc loc, Expression *e, Declaration *var, bool hasOverloads = true);
820     int checkModifiable(Scope *sc, int flag);
821     bool checkReadModifyWrite();
822     bool isLvalue();
823     Expression *toLvalue(Scope *sc, Expression *e);
824     Expression *modifiableLvalue(Scope *sc, Expression *e);
accept(Visitor * v)825     void accept(Visitor *v) { v->visit(this); }
826 };
827 
828 class DotTemplateInstanceExp : public UnaExp
829 {
830 public:
831     TemplateInstance *ti;
832 
833     DotTemplateInstanceExp(Loc loc, Expression *e, Identifier *name, Objects *tiargs);
834     DotTemplateInstanceExp(Loc loc, Expression *e, TemplateInstance *ti);
835     Expression *syntaxCopy();
836     bool findTempDecl(Scope *sc);
accept(Visitor * v)837     void accept(Visitor *v) { v->visit(this); }
838 };
839 
840 class DelegateExp : public UnaExp
841 {
842 public:
843     FuncDeclaration *func;
844     bool hasOverloads;
845 
846     DelegateExp(Loc loc, Expression *e, FuncDeclaration *func, bool hasOverloads = true);
847 
accept(Visitor * v)848     void accept(Visitor *v) { v->visit(this); }
849 };
850 
851 class DotTypeExp : public UnaExp
852 {
853 public:
854     Dsymbol *sym;               // symbol that represents a type
855 
856     DotTypeExp(Loc loc, Expression *e, Dsymbol *sym);
accept(Visitor * v)857     void accept(Visitor *v) { v->visit(this); }
858 };
859 
860 class CallExp : public UnaExp
861 {
862 public:
863     Expressions *arguments;     // function arguments
864     FuncDeclaration *f;         // symbol to call
865     bool directcall;            // true if a virtual call is devirtualized
866     CallExp(Loc loc, Expression *e, Expressions *exps);
867     CallExp(Loc loc, Expression *e);
868     CallExp(Loc loc, Expression *e, Expression *earg1);
869     CallExp(Loc loc, Expression *e, Expression *earg1, Expression *earg2);
870 
871     static CallExp *create(Loc loc, Expression *e, Expressions *exps);
872     static CallExp *create(Loc loc, Expression *e);
873     static CallExp *create(Loc loc, Expression *e, Expression *earg1);
874 
875     Expression *syntaxCopy();
876     bool isLvalue();
877     Expression *toLvalue(Scope *sc, Expression *e);
878     Expression *addDtorHook(Scope *sc);
879 
accept(Visitor * v)880     void accept(Visitor *v) { v->visit(this); }
881 };
882 
883 class AddrExp : public UnaExp
884 {
885 public:
886     AddrExp(Loc loc, Expression *e);
887     AddrExp(Loc loc, Expression *e, Type *t);
888 
accept(Visitor * v)889     void accept(Visitor *v) { v->visit(this); }
890 };
891 
892 class PtrExp : public UnaExp
893 {
894 public:
895     PtrExp(Loc loc, Expression *e);
896     PtrExp(Loc loc, Expression *e, Type *t);
897     int checkModifiable(Scope *sc, int flag);
898     bool isLvalue();
899     Expression *toLvalue(Scope *sc, Expression *e);
900     Expression *modifiableLvalue(Scope *sc, Expression *e);
901 
accept(Visitor * v)902     void accept(Visitor *v) { v->visit(this); }
903 };
904 
905 class NegExp : public UnaExp
906 {
907 public:
908     NegExp(Loc loc, Expression *e);
909 
accept(Visitor * v)910     void accept(Visitor *v) { v->visit(this); }
911 };
912 
913 class UAddExp : public UnaExp
914 {
915 public:
916     UAddExp(Loc loc, Expression *e);
917 
accept(Visitor * v)918     void accept(Visitor *v) { v->visit(this); }
919 };
920 
921 class ComExp : public UnaExp
922 {
923 public:
924     ComExp(Loc loc, Expression *e);
925 
accept(Visitor * v)926     void accept(Visitor *v) { v->visit(this); }
927 };
928 
929 class NotExp : public UnaExp
930 {
931 public:
932     NotExp(Loc loc, Expression *e);
accept(Visitor * v)933     void accept(Visitor *v) { v->visit(this); }
934 };
935 
936 class DeleteExp : public UnaExp
937 {
938 public:
939     bool isRAII;
940     DeleteExp(Loc loc, Expression *e, bool isRAII);
941     Expression *toBoolean(Scope *sc);
accept(Visitor * v)942     void accept(Visitor *v) { v->visit(this); }
943 };
944 
945 class CastExp : public UnaExp
946 {
947 public:
948     // Possible to cast to one type while painting to another type
949     Type *to;                   // type to cast to
950     unsigned char mod;          // MODxxxxx
951 
952     CastExp(Loc loc, Expression *e, Type *t);
953     CastExp(Loc loc, Expression *e, unsigned char mod);
954     Expression *syntaxCopy();
955 
accept(Visitor * v)956     void accept(Visitor *v) { v->visit(this); }
957 };
958 
959 class VectorExp : public UnaExp
960 {
961 public:
962     TypeVector *to;             // the target vector type before semantic()
963     unsigned dim;               // number of elements in the vector
964     OwnedBy ownedByCtfe;
965 
966     VectorExp(Loc loc, Expression *e, Type *t);
967     static VectorExp *create(Loc loc, Expression *e, Type *t);
968     Expression *syntaxCopy();
accept(Visitor * v)969     void accept(Visitor *v) { v->visit(this); }
970 };
971 
972 class VectorArrayExp : public UnaExp
973 {
974 public:
975     VectorArrayExp(Loc loc, Expression *e1);
976     bool isLvalue();
977     Expression *toLvalue(Scope *sc, Expression *e);
accept(Visitor * v)978     void accept(Visitor *v) { v->visit(this); }
979 };
980 
981 class SliceExp : public UnaExp
982 {
983 public:
984     Expression *upr;            // NULL if implicit 0
985     Expression *lwr;            // NULL if implicit [length - 1]
986     VarDeclaration *lengthVar;
987     bool upperIsInBounds;       // true if upr <= e1.length
988     bool lowerIsLessThanUpper;  // true if lwr <= upr
989     bool arrayop;               // an array operation, rather than a slice
990 
991     SliceExp(Loc loc, Expression *e1, IntervalExp *ie);
992     SliceExp(Loc loc, Expression *e1, Expression *lwr, Expression *upr);
993     Expression *syntaxCopy();
994     int checkModifiable(Scope *sc, int flag);
995     bool isLvalue();
996     Expression *toLvalue(Scope *sc, Expression *e);
997     Expression *modifiableLvalue(Scope *sc, Expression *e);
998     bool isBool(bool result);
999 
accept(Visitor * v)1000     void accept(Visitor *v) { v->visit(this); }
1001 };
1002 
1003 class ArrayLengthExp : public UnaExp
1004 {
1005 public:
1006     ArrayLengthExp(Loc loc, Expression *e1);
1007 
1008     static Expression *rewriteOpAssign(BinExp *exp);
accept(Visitor * v)1009     void accept(Visitor *v) { v->visit(this); }
1010 };
1011 
1012 class IntervalExp : public Expression
1013 {
1014 public:
1015     Expression *lwr;
1016     Expression *upr;
1017 
1018     IntervalExp(Loc loc, Expression *lwr, Expression *upr);
1019     Expression *syntaxCopy();
accept(Visitor * v)1020     void accept(Visitor *v) { v->visit(this); }
1021 };
1022 
1023 class DelegatePtrExp : public UnaExp
1024 {
1025 public:
1026     DelegatePtrExp(Loc loc, Expression *e1);
1027     bool isLvalue();
1028     Expression *toLvalue(Scope *sc, Expression *e);
1029     Expression *modifiableLvalue(Scope *sc, Expression *e);
accept(Visitor * v)1030     void accept(Visitor *v) { v->visit(this); }
1031 };
1032 
1033 class DelegateFuncptrExp : public UnaExp
1034 {
1035 public:
1036     DelegateFuncptrExp(Loc loc, Expression *e1);
1037     bool isLvalue();
1038     Expression *toLvalue(Scope *sc, Expression *e);
1039     Expression *modifiableLvalue(Scope *sc, Expression *e);
accept(Visitor * v)1040     void accept(Visitor *v) { v->visit(this); }
1041 };
1042 
1043 // e1[a0,a1,a2,a3,...]
1044 
1045 class ArrayExp : public UnaExp
1046 {
1047 public:
1048     Expressions *arguments;             // Array of Expression's
1049     size_t currentDimension;            // for opDollar
1050     VarDeclaration *lengthVar;
1051 
1052     ArrayExp(Loc loc, Expression *e1, Expression *index = NULL);
1053     ArrayExp(Loc loc, Expression *e1, Expressions *args);
1054     Expression *syntaxCopy();
1055     bool isLvalue();
1056     Expression *toLvalue(Scope *sc, Expression *e);
1057 
accept(Visitor * v)1058     void accept(Visitor *v) { v->visit(this); }
1059 };
1060 
1061 /****************************************************************/
1062 
1063 class DotExp : public BinExp
1064 {
1065 public:
1066     DotExp(Loc loc, Expression *e1, Expression *e2);
accept(Visitor * v)1067     void accept(Visitor *v) { v->visit(this); }
1068 };
1069 
1070 class CommaExp : public BinExp
1071 {
1072 public:
1073     bool isGenerated;
1074     bool allowCommaExp;
1075     CommaExp(Loc loc, Expression *e1, Expression *e2, bool generated = true);
1076     int checkModifiable(Scope *sc, int flag);
1077     bool isLvalue();
1078     Expression *toLvalue(Scope *sc, Expression *e);
1079     Expression *modifiableLvalue(Scope *sc, Expression *e);
1080     bool isBool(bool result);
1081     Expression *toBoolean(Scope *sc);
1082     Expression *addDtorHook(Scope *sc);
accept(Visitor * v)1083     void accept(Visitor *v) { v->visit(this); }
1084 };
1085 
1086 class IndexExp : public BinExp
1087 {
1088 public:
1089     VarDeclaration *lengthVar;
1090     bool modifiable;
1091     bool indexIsInBounds;       // true if 0 <= e2 && e2 <= e1.length - 1
1092 
1093     IndexExp(Loc loc, Expression *e1, Expression *e2);
1094     Expression *syntaxCopy();
1095     int checkModifiable(Scope *sc, int flag);
1096     bool isLvalue();
1097     Expression *toLvalue(Scope *sc, Expression *e);
1098     Expression *modifiableLvalue(Scope *sc, Expression *e);
1099 
1100     Expression *markSettingAAElem();
1101 
accept(Visitor * v)1102     void accept(Visitor *v) { v->visit(this); }
1103 };
1104 
1105 /* For both i++ and i--
1106  */
1107 class PostExp : public BinExp
1108 {
1109 public:
1110     PostExp(TOK op, Loc loc, Expression *e);
accept(Visitor * v)1111     void accept(Visitor *v) { v->visit(this); }
1112 };
1113 
1114 /* For both ++i and --i
1115  */
1116 class PreExp : public UnaExp
1117 {
1118 public:
1119     PreExp(TOK op, Loc loc, Expression *e);
accept(Visitor * v)1120     void accept(Visitor *v) { v->visit(this); }
1121 };
1122 
1123 enum MemorySet
1124 {
1125     blockAssign     = 1,    // setting the contents of an array
1126     referenceInit   = 2     // setting the reference of STCref variable
1127 };
1128 
1129 class AssignExp : public BinExp
1130 {
1131 public:
1132     int memset;         // combination of MemorySet flags
1133 
1134     AssignExp(Loc loc, Expression *e1, Expression *e2);
1135     bool isLvalue();
1136     Expression *toLvalue(Scope *sc, Expression *ex);
1137     Expression *toBoolean(Scope *sc);
1138 
accept(Visitor * v)1139     void accept(Visitor *v) { v->visit(this); }
1140 };
1141 
1142 class ConstructExp : public AssignExp
1143 {
1144 public:
1145     ConstructExp(Loc loc, Expression *e1, Expression *e2);
1146     ConstructExp(Loc loc, VarDeclaration *v, Expression *e2);
accept(Visitor * v)1147     void accept(Visitor *v) { v->visit(this); }
1148 };
1149 
1150 class BlitExp : public AssignExp
1151 {
1152 public:
1153     BlitExp(Loc loc, Expression *e1, Expression *e2);
1154     BlitExp(Loc loc, VarDeclaration *v, Expression *e2);
accept(Visitor * v)1155     void accept(Visitor *v) { v->visit(this); }
1156 };
1157 
1158 class AddAssignExp : public BinAssignExp
1159 {
1160 public:
1161     AddAssignExp(Loc loc, Expression *e1, Expression *e2);
accept(Visitor * v)1162     void accept(Visitor *v) { v->visit(this); }
1163 };
1164 
1165 class MinAssignExp : public BinAssignExp
1166 {
1167 public:
1168     MinAssignExp(Loc loc, Expression *e1, Expression *e2);
accept(Visitor * v)1169     void accept(Visitor *v) { v->visit(this); }
1170 };
1171 
1172 class MulAssignExp : public BinAssignExp
1173 {
1174 public:
1175     MulAssignExp(Loc loc, Expression *e1, Expression *e2);
accept(Visitor * v)1176     void accept(Visitor *v) { v->visit(this); }
1177 };
1178 
1179 class DivAssignExp : public BinAssignExp
1180 {
1181 public:
1182     DivAssignExp(Loc loc, Expression *e1, Expression *e2);
accept(Visitor * v)1183     void accept(Visitor *v) { v->visit(this); }
1184 };
1185 
1186 class ModAssignExp : public BinAssignExp
1187 {
1188 public:
1189     ModAssignExp(Loc loc, Expression *e1, Expression *e2);
accept(Visitor * v)1190     void accept(Visitor *v) { v->visit(this); }
1191 };
1192 
1193 class AndAssignExp : public BinAssignExp
1194 {
1195 public:
1196     AndAssignExp(Loc loc, Expression *e1, Expression *e2);
accept(Visitor * v)1197     void accept(Visitor *v) { v->visit(this); }
1198 };
1199 
1200 class OrAssignExp : public BinAssignExp
1201 {
1202 public:
1203     OrAssignExp(Loc loc, Expression *e1, Expression *e2);
accept(Visitor * v)1204     void accept(Visitor *v) { v->visit(this); }
1205 };
1206 
1207 class XorAssignExp : public BinAssignExp
1208 {
1209 public:
1210     XorAssignExp(Loc loc, Expression *e1, Expression *e2);
accept(Visitor * v)1211     void accept(Visitor *v) { v->visit(this); }
1212 };
1213 
1214 class PowAssignExp : public BinAssignExp
1215 {
1216 public:
1217     PowAssignExp(Loc loc, Expression *e1, Expression *e2);
accept(Visitor * v)1218     void accept(Visitor *v) { v->visit(this); }
1219 };
1220 
1221 class ShlAssignExp : public BinAssignExp
1222 {
1223 public:
1224     ShlAssignExp(Loc loc, Expression *e1, Expression *e2);
accept(Visitor * v)1225     void accept(Visitor *v) { v->visit(this); }
1226 };
1227 
1228 class ShrAssignExp : public BinAssignExp
1229 {
1230 public:
1231     ShrAssignExp(Loc loc, Expression *e1, Expression *e2);
accept(Visitor * v)1232     void accept(Visitor *v) { v->visit(this); }
1233 };
1234 
1235 class UshrAssignExp : public BinAssignExp
1236 {
1237 public:
1238     UshrAssignExp(Loc loc, Expression *e1, Expression *e2);
accept(Visitor * v)1239     void accept(Visitor *v) { v->visit(this); }
1240 };
1241 
1242 class CatAssignExp : public BinAssignExp
1243 {
1244 public:
1245     CatAssignExp(Loc loc, Expression *e1, Expression *e2);
accept(Visitor * v)1246     void accept(Visitor *v) { v->visit(this); }
1247 };
1248 
1249 class AddExp : public BinExp
1250 {
1251 public:
1252     AddExp(Loc loc, Expression *e1, Expression *e2);
1253 
accept(Visitor * v)1254     void accept(Visitor *v) { v->visit(this); }
1255 };
1256 
1257 class MinExp : public BinExp
1258 {
1259 public:
1260     MinExp(Loc loc, Expression *e1, Expression *e2);
1261 
accept(Visitor * v)1262     void accept(Visitor *v) { v->visit(this); }
1263 };
1264 
1265 class CatExp : public BinExp
1266 {
1267 public:
1268     CatExp(Loc loc, Expression *e1, Expression *e2);
1269 
accept(Visitor * v)1270     void accept(Visitor *v) { v->visit(this); }
1271 };
1272 
1273 class MulExp : public BinExp
1274 {
1275 public:
1276     MulExp(Loc loc, Expression *e1, Expression *e2);
1277 
accept(Visitor * v)1278     void accept(Visitor *v) { v->visit(this); }
1279 };
1280 
1281 class DivExp : public BinExp
1282 {
1283 public:
1284     DivExp(Loc loc, Expression *e1, Expression *e2);
1285 
accept(Visitor * v)1286     void accept(Visitor *v) { v->visit(this); }
1287 };
1288 
1289 class ModExp : public BinExp
1290 {
1291 public:
1292     ModExp(Loc loc, Expression *e1, Expression *e2);
1293 
accept(Visitor * v)1294     void accept(Visitor *v) { v->visit(this); }
1295 };
1296 
1297 class PowExp : public BinExp
1298 {
1299 public:
1300     PowExp(Loc loc, Expression *e1, Expression *e2);
1301 
accept(Visitor * v)1302     void accept(Visitor *v) { v->visit(this); }
1303 };
1304 
1305 class ShlExp : public BinExp
1306 {
1307 public:
1308     ShlExp(Loc loc, Expression *e1, Expression *e2);
1309 
accept(Visitor * v)1310     void accept(Visitor *v) { v->visit(this); }
1311 };
1312 
1313 class ShrExp : public BinExp
1314 {
1315 public:
1316     ShrExp(Loc loc, Expression *e1, Expression *e2);
1317 
accept(Visitor * v)1318     void accept(Visitor *v) { v->visit(this); }
1319 };
1320 
1321 class UshrExp : public BinExp
1322 {
1323 public:
1324     UshrExp(Loc loc, Expression *e1, Expression *e2);
1325 
accept(Visitor * v)1326     void accept(Visitor *v) { v->visit(this); }
1327 };
1328 
1329 class AndExp : public BinExp
1330 {
1331 public:
1332     AndExp(Loc loc, Expression *e1, Expression *e2);
1333 
accept(Visitor * v)1334     void accept(Visitor *v) { v->visit(this); }
1335 };
1336 
1337 class OrExp : public BinExp
1338 {
1339 public:
1340     OrExp(Loc loc, Expression *e1, Expression *e2);
1341 
accept(Visitor * v)1342     void accept(Visitor *v) { v->visit(this); }
1343 };
1344 
1345 class XorExp : public BinExp
1346 {
1347 public:
1348     XorExp(Loc loc, Expression *e1, Expression *e2);
1349 
accept(Visitor * v)1350     void accept(Visitor *v) { v->visit(this); }
1351 };
1352 
1353 class OrOrExp : public BinExp
1354 {
1355 public:
1356     OrOrExp(Loc loc, Expression *e1, Expression *e2);
1357     Expression *toBoolean(Scope *sc);
accept(Visitor * v)1358     void accept(Visitor *v) { v->visit(this); }
1359 };
1360 
1361 class AndAndExp : public BinExp
1362 {
1363 public:
1364     AndAndExp(Loc loc, Expression *e1, Expression *e2);
1365     Expression *toBoolean(Scope *sc);
accept(Visitor * v)1366     void accept(Visitor *v) { v->visit(this); }
1367 };
1368 
1369 class CmpExp : public BinExp
1370 {
1371 public:
1372     CmpExp(TOK op, Loc loc, Expression *e1, Expression *e2);
1373 
accept(Visitor * v)1374     void accept(Visitor *v) { v->visit(this); }
1375 };
1376 
1377 class InExp : public BinExp
1378 {
1379 public:
1380     InExp(Loc loc, Expression *e1, Expression *e2);
1381 
accept(Visitor * v)1382     void accept(Visitor *v) { v->visit(this); }
1383 };
1384 
1385 class RemoveExp : public BinExp
1386 {
1387 public:
1388     RemoveExp(Loc loc, Expression *e1, Expression *e2);
accept(Visitor * v)1389     void accept(Visitor *v) { v->visit(this); }
1390 };
1391 
1392 // == and !=
1393 
1394 class EqualExp : public BinExp
1395 {
1396 public:
1397     EqualExp(TOK op, Loc loc, Expression *e1, Expression *e2);
1398 
accept(Visitor * v)1399     void accept(Visitor *v) { v->visit(this); }
1400 };
1401 
1402 // is and !is
1403 
1404 class IdentityExp : public BinExp
1405 {
1406 public:
1407     IdentityExp(TOK op, Loc loc, Expression *e1, Expression *e2);
accept(Visitor * v)1408     void accept(Visitor *v) { v->visit(this); }
1409 };
1410 
1411 /****************************************************************/
1412 
1413 class CondExp : public BinExp
1414 {
1415 public:
1416     Expression *econd;
1417 
1418     CondExp(Loc loc, Expression *econd, Expression *e1, Expression *e2);
1419     Expression *syntaxCopy();
1420     int checkModifiable(Scope *sc, int flag);
1421     bool isLvalue();
1422     Expression *toLvalue(Scope *sc, Expression *e);
1423     Expression *modifiableLvalue(Scope *sc, Expression *e);
1424     Expression *toBoolean(Scope *sc);
1425     void hookDtors(Scope *sc);
1426 
accept(Visitor * v)1427     void accept(Visitor *v) { v->visit(this); }
1428 };
1429 
1430 /****************************************************************/
1431 
1432 class DefaultInitExp : public Expression
1433 {
1434 public:
1435     TOK subop;             // which of the derived classes this is
1436 
1437     DefaultInitExp(Loc loc, TOK subop, int size);
accept(Visitor * v)1438     void accept(Visitor *v) { v->visit(this); }
1439 };
1440 
1441 class FileInitExp : public DefaultInitExp
1442 {
1443 public:
1444     FileInitExp(Loc loc, TOK tok);
1445     Expression *resolveLoc(Loc loc, Scope *sc);
accept(Visitor * v)1446     void accept(Visitor *v) { v->visit(this); }
1447 };
1448 
1449 class LineInitExp : public DefaultInitExp
1450 {
1451 public:
1452     LineInitExp(Loc loc);
1453     Expression *resolveLoc(Loc loc, Scope *sc);
accept(Visitor * v)1454     void accept(Visitor *v) { v->visit(this); }
1455 };
1456 
1457 class ModuleInitExp : public DefaultInitExp
1458 {
1459 public:
1460     ModuleInitExp(Loc loc);
1461     Expression *resolveLoc(Loc loc, Scope *sc);
accept(Visitor * v)1462     void accept(Visitor *v) { v->visit(this); }
1463 };
1464 
1465 class FuncInitExp : public DefaultInitExp
1466 {
1467 public:
1468     FuncInitExp(Loc loc);
1469     Expression *resolveLoc(Loc loc, Scope *sc);
accept(Visitor * v)1470     void accept(Visitor *v) { v->visit(this); }
1471 };
1472 
1473 class PrettyFuncInitExp : public DefaultInitExp
1474 {
1475 public:
1476     PrettyFuncInitExp(Loc loc);
1477     Expression *resolveLoc(Loc loc, Scope *sc);
accept(Visitor * v)1478     void accept(Visitor *v) { v->visit(this); }
1479 };
1480 
1481 /****************************************************************/
1482 
1483 /* A type meant as a union of all the Expression types,
1484  * to serve essentially as a Variant that will sit on the stack
1485  * during CTFE to reduce memory consumption.
1486  */
1487 struct UnionExp
1488 {
UnionExpUnionExp1489     UnionExp() { }  // yes, default constructor does nothing
1490 
UnionExpUnionExp1491     UnionExp(Expression *e)
1492     {
1493         memcpy(this, (void *)e, e->size);
1494     }
1495 
1496     /* Extract pointer to Expression
1497      */
expUnionExp1498     Expression *exp() { return (Expression *)&u; }
1499 
1500     /* Convert to an allocated Expression
1501      */
1502     Expression *copy();
1503 
1504 private:
1505     // Ensure that the union is suitably aligned.
1506 #if defined(__GNUC__) || defined(__clang__)
1507     __attribute__((aligned(8)))
1508 #elif defined(_MSC_VER)
1509     __declspec(align(8))
1510 #elif defined(__DMC__)
1511     #pragma pack(8)
1512 #endif
1513     union
1514     {
1515         char exp       [sizeof(Expression)];
1516         char integerexp[sizeof(IntegerExp)];
1517         char errorexp  [sizeof(ErrorExp)];
1518         char realexp   [sizeof(RealExp)];
1519         char complexexp[sizeof(ComplexExp)];
1520         char symoffexp [sizeof(SymOffExp)];
1521         char stringexp [sizeof(StringExp)];
1522         char arrayliteralexp [sizeof(ArrayLiteralExp)];
1523         char assocarrayliteralexp [sizeof(AssocArrayLiteralExp)];
1524         char structliteralexp [sizeof(StructLiteralExp)];
1525         char nullexp   [sizeof(NullExp)];
1526         char dotvarexp [sizeof(DotVarExp)];
1527         char addrexp   [sizeof(AddrExp)];
1528         char indexexp  [sizeof(IndexExp)];
1529         char sliceexp  [sizeof(SliceExp)];
1530         char vectorexp [sizeof(VectorExp)];
1531     } u;
1532 #if defined(__DMC__)
1533     #pragma pack()
1534 #endif
1535 };
1536 
1537 /****************************************************************/
1538 
1539 /* Special values used by the interpreter
1540  */
1541 
1542 Expression *expType(Type *type, Expression *e);
1543 
1544 UnionExp Neg(Type *type, Expression *e1);
1545 UnionExp Com(Type *type, Expression *e1);
1546 UnionExp Not(Type *type, Expression *e1);
1547 UnionExp Bool(Type *type, Expression *e1);
1548 UnionExp Cast(Loc loc, Type *type, Type *to, Expression *e1);
1549 UnionExp ArrayLength(Type *type, Expression *e1);
1550 UnionExp Ptr(Type *type, Expression *e1);
1551 
1552 UnionExp Add(Loc loc, Type *type, Expression *e1, Expression *e2);
1553 UnionExp Min(Loc loc, Type *type, Expression *e1, Expression *e2);
1554 UnionExp Mul(Loc loc, Type *type, Expression *e1, Expression *e2);
1555 UnionExp Div(Loc loc, Type *type, Expression *e1, Expression *e2);
1556 UnionExp Mod(Loc loc, Type *type, Expression *e1, Expression *e2);
1557 UnionExp Pow(Loc loc, Type *type, Expression *e1, Expression *e2);
1558 UnionExp Shl(Loc loc, Type *type, Expression *e1, Expression *e2);
1559 UnionExp Shr(Loc loc, Type *type, Expression *e1, Expression *e2);
1560 UnionExp Ushr(Loc loc, Type *type, Expression *e1, Expression *e2);
1561 UnionExp And(Loc loc, Type *type, Expression *e1, Expression *e2);
1562 UnionExp Or(Loc loc, Type *type, Expression *e1, Expression *e2);
1563 UnionExp Xor(Loc loc, Type *type, Expression *e1, Expression *e2);
1564 UnionExp Index(Type *type, Expression *e1, Expression *e2);
1565 UnionExp Cat(Type *type, Expression *e1, Expression *e2);
1566 
1567 UnionExp Equal(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2);
1568 UnionExp Cmp(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2);
1569 UnionExp Identity(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2);
1570 
1571 UnionExp Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr);
1572 
1573 // Const-folding functions used by CTFE
1574 
1575 void sliceAssignArrayLiteralFromString(ArrayLiteralExp *existingAE, StringExp *newval, size_t firstIndex);
1576 void sliceAssignStringFromArrayLiteral(StringExp *existingSE, ArrayLiteralExp *newae, size_t firstIndex);
1577 void sliceAssignStringFromString(StringExp *existingSE, StringExp *newstr, size_t firstIndex);
1578 
1579 int sliceCmpStringWithString(StringExp *se1, StringExp *se2, size_t lo1, size_t lo2, size_t len);
1580 int sliceCmpStringWithArray(StringExp *se1, ArrayLiteralExp *ae2, size_t lo1, size_t lo2, size_t len);
1581