xref: /netbsd-src/external/gpl3/gcc/dist/gcc/d/dmd/expression.h (revision b1e838363e3c6fc78a55519254d99869742dd33c)
1 
2 /* Compiler implementation of the D programming language
3  * Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
4  * written by Walter Bright
5  * https://www.digitalmars.com
6  * Distributed under the Boost Software License, Version 1.0.
7  * https://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 "ast_node.h"
14 #include "globals.h"
15 #include "arraytypes.h"
16 #include "visitor.h"
17 #include "tokens.h"
18 
19 #include "root/complex_t.h"
20 #include "root/dcompat.h"
21 #include "root/optional.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 CtorDeclaration;
31 class Dsymbol;
32 class ScopeDsymbol;
33 class Expression;
34 class Declaration;
35 class StructDeclaration;
36 class TemplateInstance;
37 class TemplateDeclaration;
38 class ClassDeclaration;
39 class OverloadSet;
40 class StringExp;
41 struct UnionExp;
42 #ifdef IN_GCC
43 typedef union tree_node Symbol;
44 #else
45 struct Symbol;          // back end symbol
46 #endif
47 
48 void expandTuples(Expressions *exps);
49 bool isTrivialExp(Expression *e);
50 bool hasSideEffect(Expression *e, bool assumeImpureCalls = false);
51 
52 enum BE : int32_t;
53 BE canThrow(Expression *e, FuncDeclaration *func, bool mustNotThrow);
54 
55 typedef unsigned char OwnedBy;
56 enum
57 {
58     OWNEDcode,      // normal code expression in AST
59     OWNEDctfe,      // value expression for CTFE
60     OWNEDcache      // constant value cached for CTFE
61 };
62 
63 #define WANTvalue  0 // default
64 #define WANTexpand 1 // expand const/immutable variables if possible
65 
66 /**
67  * Specifies how the checkModify deals with certain situations
68  */
69 enum class ModifyFlags
70 {
71     /// Issue error messages on invalid modifications of the variable
72     none,
73     /// No errors are emitted for invalid modifications
74     noError = 0x1,
75     /// The modification occurs for a subfield of the current variable
76     fieldAssign = 0x2,
77 };
78 
79 class Expression : public ASTNode
80 {
81 public:
82     EXP op;                     // to minimize use of dynamic_cast
83     unsigned char size;         // # of bytes in Expression so we can copy() it
84     unsigned char parens;       // if this is a parenthesized expression
85     Type *type;                 // !=NULL means that semantic() has been run
86     Loc loc;                    // file location
87 
88     static void _init();
89     Expression *copy();
90     virtual Expression *syntaxCopy();
91 
92     // kludge for template.isExpression()
dyncast()93     DYNCAST dyncast() const { return DYNCAST_EXPRESSION; }
94 
95     const char *toChars() const;
96     void error(const char *format, ...) const;
97     void warning(const char *format, ...) const;
98     void deprecation(const char *format, ...) const;
99 
100     virtual dinteger_t toInteger();
101     virtual uinteger_t toUInteger();
102     virtual real_t toReal();
103     virtual real_t toImaginary();
104     virtual complex_t toComplex();
105     virtual StringExp *toStringExp();
106     virtual bool isLvalue();
107     virtual Expression *toLvalue(Scope *sc, Expression *e);
108     virtual Expression *modifiableLvalue(Scope *sc, Expression *e);
109     Expression *implicitCastTo(Scope *sc, Type *t);
110     MATCH implicitConvTo(Type *t);
111     Expression *castTo(Scope *sc, Type *t);
112     virtual Expression *resolveLoc(const Loc &loc, Scope *sc);
113     virtual bool checkType();
114     virtual bool checkValue();
115     bool checkDeprecated(Scope *sc, Dsymbol *s);
116     virtual Expression *addDtorHook(Scope *sc);
117     Expression *addressOf();
118     Expression *deref();
119 
120     Expression *optimize(int result, bool keepLvalue = false);
121 
122     // Entry point for CTFE.
123     // A compile-time result is required. Give an error if not possible
124     Expression *ctfeInterpret();
125     int isConst();
126     virtual Optional<bool> toBool();
hasCode()127     virtual bool hasCode()
128     {
129         return true;
130     }
131 
132     IntegerExp* isIntegerExp();
133     ErrorExp* isErrorExp();
134     VoidInitExp* isVoidInitExp();
135     RealExp* isRealExp();
136     ComplexExp* isComplexExp();
137     IdentifierExp* isIdentifierExp();
138     DollarExp* isDollarExp();
139     DsymbolExp* isDsymbolExp();
140     ThisExp* isThisExp();
141     SuperExp* isSuperExp();
142     NullExp* isNullExp();
143     StringExp* isStringExp();
144     TupleExp* isTupleExp();
145     ArrayLiteralExp* isArrayLiteralExp();
146     AssocArrayLiteralExp* isAssocArrayLiteralExp();
147     StructLiteralExp* isStructLiteralExp();
148     TypeExp* isTypeExp();
149     ScopeExp* isScopeExp();
150     TemplateExp* isTemplateExp();
151     NewExp* isNewExp();
152     NewAnonClassExp* isNewAnonClassExp();
153     SymOffExp* isSymOffExp();
154     VarExp* isVarExp();
155     OverExp* isOverExp();
156     FuncExp* isFuncExp();
157     DeclarationExp* isDeclarationExp();
158     TypeidExp* isTypeidExp();
159     TraitsExp* isTraitsExp();
160     HaltExp* isHaltExp();
161     IsExp* isExp();
162     MixinExp* isMixinExp();
163     ImportExp* isImportExp();
164     AssertExp* isAssertExp();
165     DotIdExp* isDotIdExp();
166     DotTemplateExp* isDotTemplateExp();
167     DotVarExp* isDotVarExp();
168     DotTemplateInstanceExp* isDotTemplateInstanceExp();
169     DelegateExp* isDelegateExp();
170     DotTypeExp* isDotTypeExp();
171     CallExp* isCallExp();
172     AddrExp* isAddrExp();
173     PtrExp* isPtrExp();
174     NegExp* isNegExp();
175     UAddExp* isUAddExp();
176     ComExp* isComExp();
177     NotExp* isNotExp();
178     DeleteExp* isDeleteExp();
179     CastExp* isCastExp();
180     VectorExp* isVectorExp();
181     VectorArrayExp* isVectorArrayExp();
182     SliceExp* isSliceExp();
183     ArrayLengthExp* isArrayLengthExp();
184     ArrayExp* isArrayExp();
185     DotExp* isDotExp();
186     CommaExp* isCommaExp();
187     IntervalExp* isIntervalExp();
188     DelegatePtrExp* isDelegatePtrExp();
189     DelegateFuncptrExp* isDelegateFuncptrExp();
190     IndexExp* isIndexExp();
191     PostExp* isPostExp();
192     PreExp* isPreExp();
193     AssignExp* isAssignExp();
194     ConstructExp* isConstructExp();
195     BlitExp* isBlitExp();
196     AddAssignExp* isAddAssignExp();
197     MinAssignExp* isMinAssignExp();
198     MulAssignExp* isMulAssignExp();
199     DivAssignExp* isDivAssignExp();
200     ModAssignExp* isModAssignExp();
201     AndAssignExp* isAndAssignExp();
202     OrAssignExp* isOrAssignExp();
203     XorAssignExp* isXorAssignExp();
204     PowAssignExp* isPowAssignExp();
205     ShlAssignExp* isShlAssignExp();
206     ShrAssignExp* isShrAssignExp();
207     UshrAssignExp* isUshrAssignExp();
208     CatAssignExp* isCatAssignExp();
209     AddExp* isAddExp();
210     MinExp* isMinExp();
211     CatExp* isCatExp();
212     MulExp* isMulExp();
213     DivExp* isDivExp();
214     ModExp* isModExp();
215     PowExp* isPowExp();
216     ShlExp* isShlExp();
217     ShrExp* isShrExp();
218     UshrExp* isUshrExp();
219     AndExp* isAndExp();
220     OrExp* isOrExp();
221     XorExp* isXorExp();
222     LogicalExp* isLogicalExp();
223     InExp* isInExp();
224     RemoveExp* isRemoveExp();
225     EqualExp* isEqualExp();
226     IdentityExp* isIdentityExp();
227     CondExp* isCondExp();
228     GenericExp* isGenericExp();
229     DefaultInitExp* isDefaultInitExp();
230     FileInitExp* isFileInitExp();
231     LineInitExp* isLineInitExp();
232     ModuleInitExp* isModuleInitExp();
233     FuncInitExp* isFuncInitExp();
234     PrettyFuncInitExp* isPrettyFuncInitExp();
235     ClassReferenceExp* isClassReferenceExp();
236     ThrownExceptionExp* isThrownExceptionExp();
237     UnaExp* isUnaExp();
238     BinExp* isBinExp();
239     BinAssignExp* isBinAssignExp();
240 
accept(Visitor * v)241     void accept(Visitor *v) { v->visit(this); }
242 };
243 
244 class IntegerExp : public Expression
245 {
246 public:
247     dinteger_t value;
248 
249     static IntegerExp *create(const Loc &loc, dinteger_t value, Type *type);
250     static void emplace(UnionExp *pue, const Loc &loc, dinteger_t value, Type *type);
251     bool equals(const RootObject *o) const;
252     dinteger_t toInteger();
253     real_t toReal();
254     real_t toImaginary();
255     complex_t toComplex();
256     Optional<bool> toBool();
257     Expression *toLvalue(Scope *sc, Expression *e);
accept(Visitor * v)258     void accept(Visitor *v) { v->visit(this); }
getInteger()259     dinteger_t getInteger() { return value; }
260     void setInteger(dinteger_t value);
261     template<int v>
262     static IntegerExp literal();
263 };
264 
265 class ErrorExp : public Expression
266 {
267 public:
268     Expression *toLvalue(Scope *sc, Expression *e);
accept(Visitor * v)269     void accept(Visitor *v) { v->visit(this); }
270 
271     static ErrorExp *errorexp; // handy shared value
272 };
273 
274 class RealExp : public Expression
275 {
276 public:
277     real_t value;
278 
279     static RealExp *create(const Loc &loc, real_t value, Type *type);
280     static void emplace(UnionExp *pue, const Loc &loc, real_t value, Type *type);
281     bool equals(const RootObject *o) const;
282     dinteger_t toInteger();
283     uinteger_t toUInteger();
284     real_t toReal();
285     real_t toImaginary();
286     complex_t toComplex();
287     Optional<bool> toBool();
accept(Visitor * v)288     void accept(Visitor *v) { v->visit(this); }
289 };
290 
291 class ComplexExp : public Expression
292 {
293 public:
294     complex_t value;
295 
296     static ComplexExp *create(const Loc &loc, complex_t value, Type *type);
297     static void emplace(UnionExp *pue, const Loc &loc, complex_t value, Type *type);
298     bool equals(const RootObject *o) const;
299     dinteger_t toInteger();
300     uinteger_t toUInteger();
301     real_t toReal();
302     real_t toImaginary();
303     complex_t toComplex();
304     Optional<bool> toBool();
accept(Visitor * v)305     void accept(Visitor *v) { v->visit(this); }
306 };
307 
308 class IdentifierExp : public Expression
309 {
310 public:
311     Identifier *ident;
312 
313     static IdentifierExp *create(const Loc &loc, Identifier *ident);
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 DollarExp : public IdentifierExp
320 {
321 public:
accept(Visitor * v)322     void accept(Visitor *v) { v->visit(this); }
323 };
324 
325 class DsymbolExp : public Expression
326 {
327 public:
328     Dsymbol *s;
329     bool hasOverloads;
330 
331     DsymbolExp *syntaxCopy();
332     bool isLvalue();
333     Expression *toLvalue(Scope *sc, Expression *e);
accept(Visitor * v)334     void accept(Visitor *v) { v->visit(this); }
335 };
336 
337 class ThisExp : public Expression
338 {
339 public:
340     VarDeclaration *var;
341 
342     ThisExp *syntaxCopy();
343     Optional<bool> toBool();
344     bool isLvalue();
345     Expression *toLvalue(Scope *sc, Expression *e);
346 
accept(Visitor * v)347     void accept(Visitor *v) { v->visit(this); }
348 };
349 
350 class SuperExp : public ThisExp
351 {
352 public:
accept(Visitor * v)353     void accept(Visitor *v) { v->visit(this); }
354 };
355 
356 class NullExp : public Expression
357 {
358 public:
359     bool equals(const RootObject *o) const;
360     Optional<bool> toBool();
361     StringExp *toStringExp();
accept(Visitor * v)362     void accept(Visitor *v) { v->visit(this); }
363 };
364 
365 class StringExp : public Expression
366 {
367 public:
368     void *string;       // char, wchar, or dchar data
369     size_t len;         // number of chars, wchars, or dchars
370     unsigned char sz;   // 1: char, 2: wchar, 4: dchar
371     unsigned char committed;    // !=0 if type is committed
372     utf8_t postfix;      // 'c', 'w', 'd'
373     OwnedBy ownedByCtfe;
374 
375     static StringExp *create(const Loc &loc, const char *s);
376     static StringExp *create(const Loc &loc, const void *s, d_size_t len);
377     static void emplace(UnionExp *pue, const Loc &loc, const char *s);
378     bool equals(const RootObject *o) const;
379     char32_t getCodeUnit(d_size_t i) const;
380     void setCodeUnit(d_size_t i, char32_t c);
381     StringExp *toStringExp();
382     StringExp *toUTF8(Scope *sc);
383     Optional<bool> toBool();
384     bool isLvalue();
385     Expression *toLvalue(Scope *sc, Expression *e);
386     Expression *modifiableLvalue(Scope *sc, Expression *e);
accept(Visitor * v)387     void accept(Visitor *v) { v->visit(this); }
388     size_t numberOfCodeUnits(int tynto = 0) const;
389     void writeTo(void* dest, bool zero, int tyto = 0) const;
390 };
391 
392 // Tuple
393 
394 class TupleExp : public Expression
395 {
396 public:
397     Expression *e0;     // side-effect part
398     /* Tuple-field access may need to take out its side effect part.
399      * For example:
400      *      foo().tupleof
401      * is rewritten as:
402      *      (ref __tup = foo(); tuple(__tup.field0, __tup.field1, ...))
403      * The declaration of temporary variable __tup will be stored in TupleExp::e0.
404      */
405     Expressions *exps;
406 
407     static TupleExp *create(const Loc &loc, Expressions *exps);
408     TupleExp *syntaxCopy();
409     bool equals(const RootObject *o) const;
410 
accept(Visitor * v)411     void accept(Visitor *v) { v->visit(this); }
412 };
413 
414 class ArrayLiteralExp : public Expression
415 {
416 public:
417     Expression *basis;
418     Expressions *elements;
419     OwnedBy ownedByCtfe;
420 
421     static ArrayLiteralExp *create(const Loc &loc, Expressions *elements);
422     static void emplace(UnionExp *pue, const Loc &loc, Expressions *elements);
423     ArrayLiteralExp *syntaxCopy();
424     bool equals(const RootObject *o) const;
425     Expression *getElement(d_size_t i); // use opIndex instead
426     Expression *opIndex(d_size_t i);
427     Optional<bool> toBool();
428     StringExp *toStringExp();
429 
accept(Visitor * v)430     void accept(Visitor *v) { v->visit(this); }
431 };
432 
433 class AssocArrayLiteralExp : public Expression
434 {
435 public:
436     Expressions *keys;
437     Expressions *values;
438     OwnedBy ownedByCtfe;
439 
440     bool equals(const RootObject *o) const;
441     AssocArrayLiteralExp *syntaxCopy();
442     Optional<bool> toBool();
443 
accept(Visitor * v)444     void accept(Visitor *v) { v->visit(this); }
445 };
446 
447 class StructLiteralExp : public Expression
448 {
449 public:
450     StructDeclaration *sd;      // which aggregate this is for
451     Expressions *elements;      // parallels sd->fields[] with NULL entries for fields to skip
452     Type *stype;                // final type of result (can be different from sd's type)
453 
454     Symbol *sym;                // back end symbol to initialize with literal
455 
456     /** pointer to the origin instance of the expression.
457      * once a new expression is created, origin is set to 'this'.
458      * anytime when an expression copy is created, 'origin' pointer is set to
459      * 'origin' pointer value of the original expression.
460      */
461     StructLiteralExp *origin;
462 
463     // those fields need to prevent a infinite recursion when one field of struct initialized with 'this' pointer.
464     StructLiteralExp *inlinecopy;
465 
466     /** anytime when recursive function is calling, 'stageflags' marks with bit flag of
467      * current stage and unmarks before return from this function.
468      * 'inlinecopy' uses similar 'stageflags' and from multiple evaluation 'doInline'
469      * (with infinite recursion) of this expression.
470      */
471     int stageflags;
472 
473     bool useStaticInit;         // if this is true, use the StructDeclaration's init symbol
474     bool isOriginal;            // used when moving instances to indicate `this is this.origin`
475     OwnedBy ownedByCtfe;
476 
477     static StructLiteralExp *create(const Loc &loc, StructDeclaration *sd, void *elements, Type *stype = NULL);
478     bool equals(const RootObject *o) const;
479     StructLiteralExp *syntaxCopy();
480     Expression *getField(Type *type, unsigned offset);
481     int getFieldIndex(Type *type, unsigned offset);
482     Expression *addDtorHook(Scope *sc);
483     Expression *toLvalue(Scope *sc, Expression *e);
484 
accept(Visitor * v)485     void accept(Visitor *v) { v->visit(this); }
486 };
487 
488 class TypeExp : public Expression
489 {
490 public:
491     TypeExp *syntaxCopy();
492     bool checkType();
493     bool checkValue();
accept(Visitor * v)494     void accept(Visitor *v) { v->visit(this); }
495 };
496 
497 class ScopeExp : public Expression
498 {
499 public:
500     ScopeDsymbol *sds;
501 
502     ScopeExp *syntaxCopy();
503     bool checkType();
504     bool checkValue();
accept(Visitor * v)505     void accept(Visitor *v) { v->visit(this); }
506 };
507 
508 class TemplateExp : public Expression
509 {
510 public:
511     TemplateDeclaration *td;
512     FuncDeclaration *fd;
513 
514     bool isLvalue();
515     Expression *toLvalue(Scope *sc, Expression *e);
516     bool checkType();
517     bool checkValue();
accept(Visitor * v)518     void accept(Visitor *v) { v->visit(this); }
519 };
520 
521 class NewExp : public Expression
522 {
523 public:
524     /* newtype(arguments)
525      */
526     Expression *thisexp;        // if !NULL, 'this' for class being allocated
527     Type *newtype;
528     Expressions *arguments;     // Array of Expression's
529 
530     Expression *argprefix;      // expression to be evaluated just before arguments[]
531 
532     CtorDeclaration *member;    // constructor function
533     bool onstack;               // allocate on stack
534     bool thrownew;              // this NewExp is the expression of a ThrowStatement
535 
536     static NewExp *create(const Loc &loc, Expression *thisexp, Type *newtype, Expressions *arguments);
537     NewExp *syntaxCopy();
538 
accept(Visitor * v)539     void accept(Visitor *v) { v->visit(this); }
540 };
541 
542 class NewAnonClassExp : public Expression
543 {
544 public:
545     /* class baseclasses { } (arguments)
546      */
547     Expression *thisexp;        // if !NULL, 'this' for class being allocated
548     ClassDeclaration *cd;       // class being instantiated
549     Expressions *arguments;     // Array of Expression's to call class constructor
550 
551     NewAnonClassExp *syntaxCopy();
accept(Visitor * v)552     void accept(Visitor *v) { v->visit(this); }
553 };
554 
555 class SymbolExp : public Expression
556 {
557 public:
558     Declaration *var;
559     Dsymbol *originalScope;
560     bool hasOverloads;
561 
accept(Visitor * v)562     void accept(Visitor *v) { v->visit(this); }
563 };
564 
565 // Offset from symbol
566 
567 class SymOffExp : public SymbolExp
568 {
569 public:
570     dinteger_t offset;
571 
572     Optional<bool> toBool();
573 
accept(Visitor * v)574     void accept(Visitor *v) { v->visit(this); }
575 };
576 
577 // Variable
578 
579 class VarExp : public SymbolExp
580 {
581 public:
582     bool delegateWasExtracted;
583     static VarExp *create(const Loc &loc, Declaration *var, bool hasOverloads = true);
584     bool equals(const RootObject *o) const;
585     bool isLvalue();
586     Expression *toLvalue(Scope *sc, Expression *e);
587     Expression *modifiableLvalue(Scope *sc, Expression *e);
588 
accept(Visitor * v)589     void accept(Visitor *v) { v->visit(this); }
590 };
591 
592 // Overload Set
593 
594 class OverExp : public Expression
595 {
596 public:
597     OverloadSet *vars;
598 
599     bool isLvalue();
600     Expression *toLvalue(Scope *sc, Expression *e);
accept(Visitor * v)601     void accept(Visitor *v) { v->visit(this); }
602 };
603 
604 // Function/Delegate literal
605 
606 class FuncExp : public Expression
607 {
608 public:
609     FuncLiteralDeclaration *fd;
610     TemplateDeclaration *td;
611     TOK tok;
612 
613     bool equals(const RootObject *o) const;
614     FuncExp *syntaxCopy();
615     const char *toChars() const;
616     bool checkType();
617     bool checkValue();
618 
accept(Visitor * v)619     void accept(Visitor *v) { v->visit(this); }
620 };
621 
622 // Declaration of a symbol
623 
624 // D grammar allows declarations only as statements. However in AST representation
625 // it can be part of any expression. This is used, for example, during internal
626 // syntax re-writes to inject hidden symbols.
627 class DeclarationExp : public Expression
628 {
629 public:
630     Dsymbol *declaration;
631 
632     DeclarationExp *syntaxCopy();
633 
634     bool hasCode();
635 
accept(Visitor * v)636     void accept(Visitor *v) { v->visit(this); }
637 };
638 
639 class TypeidExp : public Expression
640 {
641 public:
642     RootObject *obj;
643 
644     TypeidExp *syntaxCopy();
accept(Visitor * v)645     void accept(Visitor *v) { v->visit(this); }
646 };
647 
648 class TraitsExp : public Expression
649 {
650 public:
651     Identifier *ident;
652     Objects *args;
653 
654     TraitsExp *syntaxCopy();
accept(Visitor * v)655     void accept(Visitor *v) { v->visit(this); }
656 };
657 
658 class HaltExp : public Expression
659 {
660 public:
accept(Visitor * v)661     void accept(Visitor *v) { v->visit(this); }
662 };
663 
664 class IsExp : public Expression
665 {
666 public:
667     /* is(targ id tok tspec)
668      * is(targ id == tok2)
669      */
670     Type *targ;
671     Identifier *id;     // can be NULL
672     Type *tspec;        // can be NULL
673     TemplateParameters *parameters;
674     TOK tok;       // ':' or '=='
675     TOK tok2;      // 'struct', 'union', etc.
676 
677     IsExp *syntaxCopy();
accept(Visitor * v)678     void accept(Visitor *v) { v->visit(this); }
679 };
680 
681 /****************************************************************/
682 
683 class UnaExp : public Expression
684 {
685 public:
686     Expression *e1;
687     Type *att1; // Save alias this type to detect recursion
688 
689     UnaExp *syntaxCopy();
690     Expression *incompatibleTypes();
691     Expression *resolveLoc(const Loc &loc, Scope *sc);
692 
accept(Visitor * v)693     void accept(Visitor *v) { v->visit(this); }
694 };
695 
696 class BinExp : public Expression
697 {
698 public:
699     Expression *e1;
700     Expression *e2;
701 
702     Type *att1; // Save alias this type to detect recursion
703     Type *att2; // Save alias this type to detect recursion
704 
705     BinExp *syntaxCopy();
706     Expression *incompatibleTypes();
707 
708     Expression *reorderSettingAAElem(Scope *sc);
709 
accept(Visitor * v)710     void accept(Visitor *v) { v->visit(this); }
711 };
712 
713 class BinAssignExp : public BinExp
714 {
715 public:
716     bool isLvalue();
717     Expression *toLvalue(Scope *sc, Expression *ex);
718     Expression *modifiableLvalue(Scope *sc, Expression *e);
accept(Visitor * v)719     void accept(Visitor *v) { v->visit(this); }
720 };
721 
722 /****************************************************************/
723 
724 class MixinExp : public UnaExp
725 {
726 public:
accept(Visitor * v)727     void accept(Visitor *v) { v->visit(this); }
728 };
729 
730 class ImportExp : public UnaExp
731 {
732 public:
accept(Visitor * v)733     void accept(Visitor *v) { v->visit(this); }
734 };
735 
736 class AssertExp : public UnaExp
737 {
738 public:
739     Expression *msg;
740 
741     AssertExp *syntaxCopy();
742 
accept(Visitor * v)743     void accept(Visitor *v) { v->visit(this); }
744 };
745 
746 class ThrowExp : public UnaExp
747 {
748 public:
749     ThrowExp *syntaxCopy();
750 
accept(Visitor * v)751     void accept(Visitor *v) { v->visit(this); }
752 };
753 
754 class DotIdExp : public UnaExp
755 {
756 public:
757     Identifier *ident;
758     bool noderef;       // true if the result of the expression will never be dereferenced
759     bool wantsym;       // do not replace Symbol with its initializer during semantic()
760     bool arrow;         // ImportC: if -> instead of .
761 
762     static DotIdExp *create(const Loc &loc, Expression *e, Identifier *ident);
accept(Visitor * v)763     void accept(Visitor *v) { v->visit(this); }
764 };
765 
766 class DotTemplateExp : public UnaExp
767 {
768 public:
769     TemplateDeclaration *td;
770 
771     bool checkType();
772     bool checkValue();
accept(Visitor * v)773     void accept(Visitor *v) { v->visit(this); }
774 };
775 
776 class DotVarExp : public UnaExp
777 {
778 public:
779     Declaration *var;
780     bool hasOverloads;
781 
782     bool isLvalue();
783     Expression *toLvalue(Scope *sc, Expression *e);
784     Expression *modifiableLvalue(Scope *sc, Expression *e);
accept(Visitor * v)785     void accept(Visitor *v) { v->visit(this); }
786 };
787 
788 class DotTemplateInstanceExp : public UnaExp
789 {
790 public:
791     TemplateInstance *ti;
792 
793     DotTemplateInstanceExp *syntaxCopy();
794     bool findTempDecl(Scope *sc);
795     bool checkType();
796     bool checkValue();
accept(Visitor * v)797     void accept(Visitor *v) { v->visit(this); }
798 };
799 
800 class DelegateExp : public UnaExp
801 {
802 public:
803     FuncDeclaration *func;
804     bool hasOverloads;
805     VarDeclaration *vthis2;  // container for multi-context
806 
807 
accept(Visitor * v)808     void accept(Visitor *v) { v->visit(this); }
809 };
810 
811 class DotTypeExp : public UnaExp
812 {
813 public:
814     Dsymbol *sym;               // symbol that represents a type
815 
accept(Visitor * v)816     void accept(Visitor *v) { v->visit(this); }
817 };
818 
819 class CallExp : public UnaExp
820 {
821 public:
822     Expressions *arguments;     // function arguments
823     FuncDeclaration *f;         // symbol to call
824     bool directcall;            // true if a virtual call is devirtualized
825     bool inDebugStatement;      // true if this was in a debug statement
826     bool ignoreAttributes;      // don't enforce attributes (e.g. call @gc function in @nogc code)
827     VarDeclaration *vthis2;     // container for multi-context
828 
829     static CallExp *create(const Loc &loc, Expression *e, Expressions *exps);
830     static CallExp *create(const Loc &loc, Expression *e);
831     static CallExp *create(const Loc &loc, Expression *e, Expression *earg1);
832     static CallExp *create(const Loc &loc, FuncDeclaration *fd, Expression *earg1);
833 
834     CallExp *syntaxCopy();
835     bool isLvalue();
836     Expression *toLvalue(Scope *sc, Expression *e);
837     Expression *addDtorHook(Scope *sc);
838 
accept(Visitor * v)839     void accept(Visitor *v) { v->visit(this); }
840 };
841 
842 class AddrExp : public UnaExp
843 {
844 public:
accept(Visitor * v)845     void accept(Visitor *v) { v->visit(this); }
846 };
847 
848 class PtrExp : public UnaExp
849 {
850 public:
851     bool isLvalue();
852     Expression *toLvalue(Scope *sc, Expression *e);
853     Expression *modifiableLvalue(Scope *sc, Expression *e);
854 
accept(Visitor * v)855     void accept(Visitor *v) { v->visit(this); }
856 };
857 
858 class NegExp : public UnaExp
859 {
860 public:
accept(Visitor * v)861     void accept(Visitor *v) { v->visit(this); }
862 };
863 
864 class UAddExp : public UnaExp
865 {
866 public:
accept(Visitor * v)867     void accept(Visitor *v) { v->visit(this); }
868 };
869 
870 class ComExp : public UnaExp
871 {
872 public:
accept(Visitor * v)873     void accept(Visitor *v) { v->visit(this); }
874 };
875 
876 class NotExp : public UnaExp
877 {
878 public:
accept(Visitor * v)879     void accept(Visitor *v) { v->visit(this); }
880 };
881 
882 class DeleteExp : public UnaExp
883 {
884 public:
885     bool isRAII;
accept(Visitor * v)886     void accept(Visitor *v) { v->visit(this); }
887 };
888 
889 class CastExp : public UnaExp
890 {
891 public:
892     // Possible to cast to one type while painting to another type
893     Type *to;                   // type to cast to
894     unsigned char mod;          // MODxxxxx
895 
896     CastExp *syntaxCopy();
897     bool isLvalue();
898     Expression *toLvalue(Scope *sc, Expression *e);
899 
accept(Visitor * v)900     void accept(Visitor *v) { v->visit(this); }
901 };
902 
903 class VectorExp : public UnaExp
904 {
905 public:
906     TypeVector *to;             // the target vector type before semantic()
907     unsigned dim;               // number of elements in the vector
908     OwnedBy ownedByCtfe;
909 
910     static VectorExp *create(const Loc &loc, Expression *e, Type *t);
911     static void emplace(UnionExp *pue, const Loc &loc, Expression *e, Type *t);
912     VectorExp *syntaxCopy();
accept(Visitor * v)913     void accept(Visitor *v) { v->visit(this); }
914 };
915 
916 class VectorArrayExp : public UnaExp
917 {
918 public:
919     bool isLvalue();
920     Expression *toLvalue(Scope *sc, Expression *e);
accept(Visitor * v)921     void accept(Visitor *v) { v->visit(this); }
922 };
923 
924 class SliceExp : public UnaExp
925 {
926 public:
927     Expression *upr;            // NULL if implicit 0
928     Expression *lwr;            // NULL if implicit [length - 1]
929     VarDeclaration *lengthVar;
930     bool upperIsInBounds;       // true if upr <= e1.length
931     bool lowerIsLessThanUpper;  // true if lwr <= upr
932     bool arrayop;               // an array operation, rather than a slice
933 
934     SliceExp *syntaxCopy();
935     bool isLvalue();
936     Expression *toLvalue(Scope *sc, Expression *e);
937     Expression *modifiableLvalue(Scope *sc, Expression *e);
938     Optional<bool> toBool();
939 
accept(Visitor * v)940     void accept(Visitor *v) { v->visit(this); }
941 };
942 
943 class ArrayLengthExp : public UnaExp
944 {
945 public:
accept(Visitor * v)946     void accept(Visitor *v) { v->visit(this); }
947 };
948 
949 class IntervalExp : public Expression
950 {
951 public:
952     Expression *lwr;
953     Expression *upr;
954 
955     IntervalExp *syntaxCopy();
accept(Visitor * v)956     void accept(Visitor *v) { v->visit(this); }
957 };
958 
959 class DelegatePtrExp : public UnaExp
960 {
961 public:
962     bool isLvalue();
963     Expression *toLvalue(Scope *sc, Expression *e);
964     Expression *modifiableLvalue(Scope *sc, Expression *e);
accept(Visitor * v)965     void accept(Visitor *v) { v->visit(this); }
966 };
967 
968 class DelegateFuncptrExp : public UnaExp
969 {
970 public:
971     bool isLvalue();
972     Expression *toLvalue(Scope *sc, Expression *e);
973     Expression *modifiableLvalue(Scope *sc, Expression *e);
accept(Visitor * v)974     void accept(Visitor *v) { v->visit(this); }
975 };
976 
977 // e1[a0,a1,a2,a3,...]
978 
979 class ArrayExp : public UnaExp
980 {
981 public:
982     Expressions *arguments;             // Array of Expression's
983     size_t currentDimension;            // for opDollar
984     VarDeclaration *lengthVar;
985 
986     ArrayExp *syntaxCopy();
987     bool isLvalue();
988     Expression *toLvalue(Scope *sc, Expression *e);
989 
accept(Visitor * v)990     void accept(Visitor *v) { v->visit(this); }
991 };
992 
993 /****************************************************************/
994 
995 class DotExp : public BinExp
996 {
997 public:
accept(Visitor * v)998     void accept(Visitor *v) { v->visit(this); }
999 };
1000 
1001 class CommaExp : public BinExp
1002 {
1003 public:
1004     bool isGenerated;
1005     bool allowCommaExp;
1006     bool isLvalue();
1007     Expression *toLvalue(Scope *sc, Expression *e);
1008     Expression *modifiableLvalue(Scope *sc, Expression *e);
1009     Optional<bool> toBool();
1010     Expression *addDtorHook(Scope *sc);
accept(Visitor * v)1011     void accept(Visitor *v) { v->visit(this); }
1012 };
1013 
1014 class IndexExp : public BinExp
1015 {
1016 public:
1017     VarDeclaration *lengthVar;
1018     bool modifiable;
1019     bool indexIsInBounds;       // true if 0 <= e2 && e2 <= e1.length - 1
1020 
1021     IndexExp *syntaxCopy();
1022     bool isLvalue();
1023     Expression *toLvalue(Scope *sc, Expression *e);
1024     Expression *modifiableLvalue(Scope *sc, Expression *e);
1025 
accept(Visitor * v)1026     void accept(Visitor *v) { v->visit(this); }
1027 };
1028 
1029 /* For both i++ and i--
1030  */
1031 class PostExp : public BinExp
1032 {
1033 public:
accept(Visitor * v)1034     void accept(Visitor *v) { v->visit(this); }
1035 };
1036 
1037 /* For both ++i and --i
1038  */
1039 class PreExp : public UnaExp
1040 {
1041 public:
accept(Visitor * v)1042     void accept(Visitor *v) { v->visit(this); }
1043 };
1044 
1045 enum class MemorySet
1046 {
1047     none            = 0,    // simple assignment
1048     blockAssign     = 1,    // setting the contents of an array
1049     referenceInit   = 2     // setting the reference of STCref variable
1050 };
1051 
1052 class AssignExp : public BinExp
1053 {
1054 public:
1055     MemorySet memset;
1056 
1057     bool isLvalue();
1058     Expression *toLvalue(Scope *sc, Expression *ex);
1059 
accept(Visitor * v)1060     void accept(Visitor *v) { v->visit(this); }
1061 };
1062 
1063 class ConstructExp : public AssignExp
1064 {
1065 public:
accept(Visitor * v)1066     void accept(Visitor *v) { v->visit(this); }
1067 };
1068 
1069 class BlitExp : public AssignExp
1070 {
1071 public:
accept(Visitor * v)1072     void accept(Visitor *v) { v->visit(this); }
1073 };
1074 
1075 class AddAssignExp : public BinAssignExp
1076 {
1077 public:
accept(Visitor * v)1078     void accept(Visitor *v) { v->visit(this); }
1079 };
1080 
1081 class MinAssignExp : public BinAssignExp
1082 {
1083 public:
accept(Visitor * v)1084     void accept(Visitor *v) { v->visit(this); }
1085 };
1086 
1087 class MulAssignExp : public BinAssignExp
1088 {
1089 public:
accept(Visitor * v)1090     void accept(Visitor *v) { v->visit(this); }
1091 };
1092 
1093 class DivAssignExp : public BinAssignExp
1094 {
1095 public:
accept(Visitor * v)1096     void accept(Visitor *v) { v->visit(this); }
1097 };
1098 
1099 class ModAssignExp : public BinAssignExp
1100 {
1101 public:
accept(Visitor * v)1102     void accept(Visitor *v) { v->visit(this); }
1103 };
1104 
1105 class AndAssignExp : public BinAssignExp
1106 {
1107 public:
accept(Visitor * v)1108     void accept(Visitor *v) { v->visit(this); }
1109 };
1110 
1111 class OrAssignExp : public BinAssignExp
1112 {
1113 public:
accept(Visitor * v)1114     void accept(Visitor *v) { v->visit(this); }
1115 };
1116 
1117 class XorAssignExp : public BinAssignExp
1118 {
1119 public:
accept(Visitor * v)1120     void accept(Visitor *v) { v->visit(this); }
1121 };
1122 
1123 class PowAssignExp : public BinAssignExp
1124 {
1125 public:
accept(Visitor * v)1126     void accept(Visitor *v) { v->visit(this); }
1127 };
1128 
1129 class ShlAssignExp : public BinAssignExp
1130 {
1131 public:
accept(Visitor * v)1132     void accept(Visitor *v) { v->visit(this); }
1133 };
1134 
1135 class ShrAssignExp : public BinAssignExp
1136 {
1137 public:
accept(Visitor * v)1138     void accept(Visitor *v) { v->visit(this); }
1139 };
1140 
1141 class UshrAssignExp : public BinAssignExp
1142 {
1143 public:
accept(Visitor * v)1144     void accept(Visitor *v) { v->visit(this); }
1145 };
1146 
1147 class CatAssignExp : public BinAssignExp
1148 {
1149 public:
accept(Visitor * v)1150     void accept(Visitor *v) { v->visit(this); }
1151 };
1152 
1153 class AddExp : public BinExp
1154 {
1155 public:
accept(Visitor * v)1156     void accept(Visitor *v) { v->visit(this); }
1157 };
1158 
1159 class MinExp : public BinExp
1160 {
1161 public:
accept(Visitor * v)1162     void accept(Visitor *v) { v->visit(this); }
1163 };
1164 
1165 class CatExp : public BinExp
1166 {
1167 public:
accept(Visitor * v)1168     void accept(Visitor *v) { v->visit(this); }
1169 };
1170 
1171 class MulExp : public BinExp
1172 {
1173 public:
accept(Visitor * v)1174     void accept(Visitor *v) { v->visit(this); }
1175 };
1176 
1177 class DivExp : public BinExp
1178 {
1179 public:
accept(Visitor * v)1180     void accept(Visitor *v) { v->visit(this); }
1181 };
1182 
1183 class ModExp : public BinExp
1184 {
1185 public:
accept(Visitor * v)1186     void accept(Visitor *v) { v->visit(this); }
1187 };
1188 
1189 class PowExp : public BinExp
1190 {
1191 public:
accept(Visitor * v)1192     void accept(Visitor *v) { v->visit(this); }
1193 };
1194 
1195 class ShlExp : public BinExp
1196 {
1197 public:
accept(Visitor * v)1198     void accept(Visitor *v) { v->visit(this); }
1199 };
1200 
1201 class ShrExp : public BinExp
1202 {
1203 public:
accept(Visitor * v)1204     void accept(Visitor *v) { v->visit(this); }
1205 };
1206 
1207 class UshrExp : public BinExp
1208 {
1209 public:
accept(Visitor * v)1210     void accept(Visitor *v) { v->visit(this); }
1211 };
1212 
1213 class AndExp : public BinExp
1214 {
1215 public:
accept(Visitor * v)1216     void accept(Visitor *v) { v->visit(this); }
1217 };
1218 
1219 class OrExp : public BinExp
1220 {
1221 public:
accept(Visitor * v)1222     void accept(Visitor *v) { v->visit(this); }
1223 };
1224 
1225 class XorExp : public BinExp
1226 {
1227 public:
accept(Visitor * v)1228     void accept(Visitor *v) { v->visit(this); }
1229 };
1230 
1231 class LogicalExp : public BinExp
1232 {
1233 public:
accept(Visitor * v)1234     void accept(Visitor *v) { v->visit(this); }
1235 };
1236 
1237 class CmpExp : public BinExp
1238 {
1239 public:
accept(Visitor * v)1240     void accept(Visitor *v) { v->visit(this); }
1241 };
1242 
1243 class InExp : public BinExp
1244 {
1245 public:
accept(Visitor * v)1246     void accept(Visitor *v) { v->visit(this); }
1247 };
1248 
1249 class RemoveExp : public BinExp
1250 {
1251 public:
accept(Visitor * v)1252     void accept(Visitor *v) { v->visit(this); }
1253 };
1254 
1255 // == and !=
1256 
1257 class EqualExp : public BinExp
1258 {
1259 public:
accept(Visitor * v)1260     void accept(Visitor *v) { v->visit(this); }
1261 };
1262 
1263 // is and !is
1264 
1265 class IdentityExp : public BinExp
1266 {
1267 public:
accept(Visitor * v)1268     void accept(Visitor *v) { v->visit(this); }
1269 };
1270 
1271 /****************************************************************/
1272 
1273 class CondExp : public BinExp
1274 {
1275 public:
1276     Expression *econd;
1277 
1278     CondExp *syntaxCopy();
1279     bool isLvalue();
1280     Expression *toLvalue(Scope *sc, Expression *e);
1281     Expression *modifiableLvalue(Scope *sc, Expression *e);
1282     void hookDtors(Scope *sc);
1283 
accept(Visitor * v)1284     void accept(Visitor *v) { v->visit(this); }
1285 };
1286 
1287 class GenericExp : Expression
1288 {
1289     Expression *cntlExp;
1290     Types *types;
1291     Expressions *exps;
1292 
1293     GenericExp *syntaxCopy();
1294 
accept(Visitor * v)1295     void accept(Visitor *v) { v->visit(this); }
1296 };
1297 
1298 /****************************************************************/
1299 
1300 class DefaultInitExp : public Expression
1301 {
1302 public:
accept(Visitor * v)1303     void accept(Visitor *v) { v->visit(this); }
1304 };
1305 
1306 class FileInitExp : public DefaultInitExp
1307 {
1308 public:
1309     Expression *resolveLoc(const Loc &loc, Scope *sc);
accept(Visitor * v)1310     void accept(Visitor *v) { v->visit(this); }
1311 };
1312 
1313 class LineInitExp : public DefaultInitExp
1314 {
1315 public:
1316     Expression *resolveLoc(const Loc &loc, Scope *sc);
accept(Visitor * v)1317     void accept(Visitor *v) { v->visit(this); }
1318 };
1319 
1320 class ModuleInitExp : public DefaultInitExp
1321 {
1322 public:
1323     Expression *resolveLoc(const Loc &loc, Scope *sc);
accept(Visitor * v)1324     void accept(Visitor *v) { v->visit(this); }
1325 };
1326 
1327 class FuncInitExp : public DefaultInitExp
1328 {
1329 public:
1330     Expression *resolveLoc(const Loc &loc, Scope *sc);
accept(Visitor * v)1331     void accept(Visitor *v) { v->visit(this); }
1332 };
1333 
1334 class PrettyFuncInitExp : public DefaultInitExp
1335 {
1336 public:
1337     Expression *resolveLoc(const Loc &loc, Scope *sc);
accept(Visitor * v)1338     void accept(Visitor *v) { v->visit(this); }
1339 };
1340 
1341 /****************************************************************/
1342 
1343 /* A type meant as a union of all the Expression types,
1344  * to serve essentially as a Variant that will sit on the stack
1345  * during CTFE to reduce memory consumption.
1346  */
1347 struct UnionExp
1348 {
UnionExpUnionExp1349     UnionExp() { }  // yes, default constructor does nothing
1350 
UnionExpUnionExp1351     UnionExp(Expression *e)
1352     {
1353         memcpy(this, (void *)e, e->size);
1354     }
1355 
1356     /* Extract pointer to Expression
1357      */
expUnionExp1358     Expression *exp() { return (Expression *)&u; }
1359 
1360     /* Convert to an allocated Expression
1361      */
1362     Expression *copy();
1363 
1364 private:
1365     // Ensure that the union is suitably aligned.
1366 #if defined(__GNUC__) || defined(__clang__)
1367     __attribute__((aligned(8)))
1368 #elif defined(_MSC_VER)
1369     __declspec(align(8))
1370 #elif defined(__DMC__)
1371     #pragma pack(8)
1372 #endif
1373     union
1374     {
1375         char exp       [sizeof(Expression)];
1376         char integerexp[sizeof(IntegerExp)];
1377         char errorexp  [sizeof(ErrorExp)];
1378         char realexp   [sizeof(RealExp)];
1379         char complexexp[sizeof(ComplexExp)];
1380         char symoffexp [sizeof(SymOffExp)];
1381         char stringexp [sizeof(StringExp)];
1382         char arrayliteralexp [sizeof(ArrayLiteralExp)];
1383         char assocarrayliteralexp [sizeof(AssocArrayLiteralExp)];
1384         char structliteralexp [sizeof(StructLiteralExp)];
1385         char nullexp   [sizeof(NullExp)];
1386         char dotvarexp [sizeof(DotVarExp)];
1387         char addrexp   [sizeof(AddrExp)];
1388         char indexexp  [sizeof(IndexExp)];
1389         char sliceexp  [sizeof(SliceExp)];
1390         char vectorexp [sizeof(VectorExp)];
1391     } u;
1392 #if defined(__DMC__)
1393     #pragma pack()
1394 #endif
1395 };
1396 
1397 /****************************************************************/
1398 
1399 class ObjcClassReferenceExp : public Expression
1400 {
1401 public:
1402     ClassDeclaration* classDeclaration;
1403 
accept(Visitor * v)1404     void accept(Visitor *v) { v->visit(this); }
1405 };
1406