expression.h revision 1.1.1.3 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()
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();
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
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);
258 void accept(Visitor *v) { v->visit(this); }
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);
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();
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();
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);
316 void accept(Visitor *v) { v->visit(this); }
317 };
318
319 class DollarExp : public IdentifierExp
320 {
321 public:
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);
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
347 void accept(Visitor *v) { v->visit(this); }
348 };
349
350 class SuperExp : public ThisExp
351 {
352 public:
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();
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);
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
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
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
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
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();
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();
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();
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
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();
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
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
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
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);
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
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
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();
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();
655 void accept(Visitor *v) { v->visit(this); }
656 };
657
658 class HaltExp : public Expression
659 {
660 public:
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();
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
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
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);
719 void accept(Visitor *v) { v->visit(this); }
720 };
721
722 /****************************************************************/
723
724 class MixinExp : public UnaExp
725 {
726 public:
727 void accept(Visitor *v) { v->visit(this); }
728 };
729
730 class ImportExp : public UnaExp
731 {
732 public:
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
743 void accept(Visitor *v) { v->visit(this); }
744 };
745
746 class ThrowExp : public UnaExp
747 {
748 public:
749 ThrowExp *syntaxCopy();
750
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);
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();
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);
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();
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
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
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
839 void accept(Visitor *v) { v->visit(this); }
840 };
841
842 class AddrExp : public UnaExp
843 {
844 public:
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
855 void accept(Visitor *v) { v->visit(this); }
856 };
857
858 class NegExp : public UnaExp
859 {
860 public:
861 void accept(Visitor *v) { v->visit(this); }
862 };
863
864 class UAddExp : public UnaExp
865 {
866 public:
867 void accept(Visitor *v) { v->visit(this); }
868 };
869
870 class ComExp : public UnaExp
871 {
872 public:
873 void accept(Visitor *v) { v->visit(this); }
874 };
875
876 class NotExp : public UnaExp
877 {
878 public:
879 void accept(Visitor *v) { v->visit(this); }
880 };
881
882 class DeleteExp : public UnaExp
883 {
884 public:
885 bool isRAII;
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
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();
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);
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
940 void accept(Visitor *v) { v->visit(this); }
941 };
942
943 class ArrayLengthExp : public UnaExp
944 {
945 public:
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();
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);
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);
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
990 void accept(Visitor *v) { v->visit(this); }
991 };
992
993 /****************************************************************/
994
995 class DotExp : public BinExp
996 {
997 public:
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);
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
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:
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:
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
1060 void accept(Visitor *v) { v->visit(this); }
1061 };
1062
1063 class ConstructExp : public AssignExp
1064 {
1065 public:
1066 void accept(Visitor *v) { v->visit(this); }
1067 };
1068
1069 class BlitExp : public AssignExp
1070 {
1071 public:
1072 void accept(Visitor *v) { v->visit(this); }
1073 };
1074
1075 class AddAssignExp : public BinAssignExp
1076 {
1077 public:
1078 void accept(Visitor *v) { v->visit(this); }
1079 };
1080
1081 class MinAssignExp : public BinAssignExp
1082 {
1083 public:
1084 void accept(Visitor *v) { v->visit(this); }
1085 };
1086
1087 class MulAssignExp : public BinAssignExp
1088 {
1089 public:
1090 void accept(Visitor *v) { v->visit(this); }
1091 };
1092
1093 class DivAssignExp : public BinAssignExp
1094 {
1095 public:
1096 void accept(Visitor *v) { v->visit(this); }
1097 };
1098
1099 class ModAssignExp : public BinAssignExp
1100 {
1101 public:
1102 void accept(Visitor *v) { v->visit(this); }
1103 };
1104
1105 class AndAssignExp : public BinAssignExp
1106 {
1107 public:
1108 void accept(Visitor *v) { v->visit(this); }
1109 };
1110
1111 class OrAssignExp : public BinAssignExp
1112 {
1113 public:
1114 void accept(Visitor *v) { v->visit(this); }
1115 };
1116
1117 class XorAssignExp : public BinAssignExp
1118 {
1119 public:
1120 void accept(Visitor *v) { v->visit(this); }
1121 };
1122
1123 class PowAssignExp : public BinAssignExp
1124 {
1125 public:
1126 void accept(Visitor *v) { v->visit(this); }
1127 };
1128
1129 class ShlAssignExp : public BinAssignExp
1130 {
1131 public:
1132 void accept(Visitor *v) { v->visit(this); }
1133 };
1134
1135 class ShrAssignExp : public BinAssignExp
1136 {
1137 public:
1138 void accept(Visitor *v) { v->visit(this); }
1139 };
1140
1141 class UshrAssignExp : public BinAssignExp
1142 {
1143 public:
1144 void accept(Visitor *v) { v->visit(this); }
1145 };
1146
1147 class CatAssignExp : public BinAssignExp
1148 {
1149 public:
1150 void accept(Visitor *v) { v->visit(this); }
1151 };
1152
1153 class AddExp : public BinExp
1154 {
1155 public:
1156 void accept(Visitor *v) { v->visit(this); }
1157 };
1158
1159 class MinExp : public BinExp
1160 {
1161 public:
1162 void accept(Visitor *v) { v->visit(this); }
1163 };
1164
1165 class CatExp : public BinExp
1166 {
1167 public:
1168 void accept(Visitor *v) { v->visit(this); }
1169 };
1170
1171 class MulExp : public BinExp
1172 {
1173 public:
1174 void accept(Visitor *v) { v->visit(this); }
1175 };
1176
1177 class DivExp : public BinExp
1178 {
1179 public:
1180 void accept(Visitor *v) { v->visit(this); }
1181 };
1182
1183 class ModExp : public BinExp
1184 {
1185 public:
1186 void accept(Visitor *v) { v->visit(this); }
1187 };
1188
1189 class PowExp : public BinExp
1190 {
1191 public:
1192 void accept(Visitor *v) { v->visit(this); }
1193 };
1194
1195 class ShlExp : public BinExp
1196 {
1197 public:
1198 void accept(Visitor *v) { v->visit(this); }
1199 };
1200
1201 class ShrExp : public BinExp
1202 {
1203 public:
1204 void accept(Visitor *v) { v->visit(this); }
1205 };
1206
1207 class UshrExp : public BinExp
1208 {
1209 public:
1210 void accept(Visitor *v) { v->visit(this); }
1211 };
1212
1213 class AndExp : public BinExp
1214 {
1215 public:
1216 void accept(Visitor *v) { v->visit(this); }
1217 };
1218
1219 class OrExp : public BinExp
1220 {
1221 public:
1222 void accept(Visitor *v) { v->visit(this); }
1223 };
1224
1225 class XorExp : public BinExp
1226 {
1227 public:
1228 void accept(Visitor *v) { v->visit(this); }
1229 };
1230
1231 class LogicalExp : public BinExp
1232 {
1233 public:
1234 void accept(Visitor *v) { v->visit(this); }
1235 };
1236
1237 class CmpExp : public BinExp
1238 {
1239 public:
1240 void accept(Visitor *v) { v->visit(this); }
1241 };
1242
1243 class InExp : public BinExp
1244 {
1245 public:
1246 void accept(Visitor *v) { v->visit(this); }
1247 };
1248
1249 class RemoveExp : public BinExp
1250 {
1251 public:
1252 void accept(Visitor *v) { v->visit(this); }
1253 };
1254
1255 // == and !=
1256
1257 class EqualExp : public BinExp
1258 {
1259 public:
1260 void accept(Visitor *v) { v->visit(this); }
1261 };
1262
1263 // is and !is
1264
1265 class IdentityExp : public BinExp
1266 {
1267 public:
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
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
1295 void accept(Visitor *v) { v->visit(this); }
1296 };
1297
1298 /****************************************************************/
1299
1300 class DefaultInitExp : public Expression
1301 {
1302 public:
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);
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);
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);
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);
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);
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 {
1349 UnionExp() { } // yes, default constructor does nothing
1350
1351 UnionExp(Expression *e)
1352 {
1353 memcpy(this, (void *)e, e->size);
1354 }
1355
1356 /* Extract pointer to Expression
1357 */
1358 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
1404 void accept(Visitor *v) { v->visit(this); }
1405 };
1406