2 /* Compiler implementation of the D programming language
3 * Copyright (C) 1999-2023 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
15 #include "arraytypes.h"
19 #include "root/complex_t.h"
20 #include "root/dcompat.h"
21 #include "root/optional.h"
26 class TupleDeclaration
;
28 class FuncDeclaration
;
29 class FuncLiteralDeclaration
;
30 class CtorDeclaration
;
35 class StructDeclaration
;
36 class TemplateInstance
;
37 class TemplateDeclaration
;
38 class ClassDeclaration
;
41 class LoweredAssignExp
;
44 typedef union tree_node Symbol
;
46 struct Symbol
; // back end symbol
49 void expandTuples(Expressions
*exps
, Identifiers
*names
= nullptr);
50 bool isTrivialExp(Expression
*e
);
51 bool hasSideEffect(Expression
*e
, bool assumeImpureCalls
= false);
54 BE
canThrow(Expression
*e
, FuncDeclaration
*func
, ErrorSink
*eSink
);
56 typedef unsigned char OwnedBy
;
59 OWNEDcode
, // normal code expression in AST
60 OWNEDctfe
, // value expression for CTFE
61 OWNEDcache
// constant value cached for CTFE
64 #define WANTvalue 0 // default
65 #define WANTexpand 1 // expand const/immutable variables if possible
68 * Specifies how the checkModify deals with certain situations
70 enum class ModifyFlags
72 /// Issue error messages on invalid modifications of the variable
74 /// No errors are emitted for invalid modifications
76 /// The modification occurs for a subfield of the current variable
80 class Expression
: public ASTNode
83 Type
*type
; // !=NULL means that semantic() has been run
84 Loc loc
; // file location
85 EXP op
; // to minimize use of dynamic_cast
90 virtual Expression
*syntaxCopy();
92 // kludge for template.isExpression()
93 DYNCAST
dyncast() const override final
{ return DYNCAST_EXPRESSION
; }
95 const char *toChars() const override
;
97 virtual dinteger_t
toInteger();
98 virtual uinteger_t
toUInteger();
99 virtual real_t
toReal();
100 virtual real_t
toImaginary();
101 virtual complex_t
toComplex();
102 virtual StringExp
*toStringExp();
103 virtual bool isLvalue();
104 virtual Expression
*toLvalue(Scope
*sc
, Expression
*e
);
105 virtual Expression
*modifiableLvalue(Scope
*sc
, Expression
*e
);
106 Expression
*implicitCastTo(Scope
*sc
, Type
*t
);
107 MATCH
implicitConvTo(Type
*t
);
108 Expression
*castTo(Scope
*sc
, Type
*t
);
109 virtual Expression
*resolveLoc(const Loc
&loc
, Scope
*sc
);
110 virtual bool checkType();
111 virtual bool checkValue();
112 bool checkDeprecated(Scope
*sc
, Dsymbol
*s
);
113 virtual Expression
*addDtorHook(Scope
*sc
);
114 Expression
*addressOf();
117 Expression
*optimize(int result
, bool keepLvalue
= false);
119 // Entry point for CTFE.
120 // A compile-time result is required. Give an error if not possible
121 Expression
*ctfeInterpret();
123 virtual bool isIdentical(const Expression
*e
) const;
124 virtual Optional
<bool> toBool();
125 virtual bool hasCode()
130 IntegerExp
* isIntegerExp();
131 ErrorExp
* isErrorExp();
132 VoidInitExp
* isVoidInitExp();
133 RealExp
* isRealExp();
134 ComplexExp
* isComplexExp();
135 IdentifierExp
* isIdentifierExp();
136 DollarExp
* isDollarExp();
137 DsymbolExp
* isDsymbolExp();
138 ThisExp
* isThisExp();
139 SuperExp
* isSuperExp();
140 NullExp
* isNullExp();
141 StringExp
* isStringExp();
142 TupleExp
* isTupleExp();
143 ArrayLiteralExp
* isArrayLiteralExp();
144 AssocArrayLiteralExp
* isAssocArrayLiteralExp();
145 StructLiteralExp
* isStructLiteralExp();
146 TypeExp
* isTypeExp();
147 ScopeExp
* isScopeExp();
148 TemplateExp
* isTemplateExp();
150 NewAnonClassExp
* isNewAnonClassExp();
151 SymOffExp
* isSymOffExp();
153 OverExp
* isOverExp();
154 FuncExp
* isFuncExp();
155 DeclarationExp
* isDeclarationExp();
156 TypeidExp
* isTypeidExp();
157 TraitsExp
* isTraitsExp();
158 HaltExp
* isHaltExp();
160 MixinExp
* isMixinExp();
161 ImportExp
* isImportExp();
162 AssertExp
* isAssertExp();
163 DotIdExp
* isDotIdExp();
164 DotTemplateExp
* isDotTemplateExp();
165 DotVarExp
* isDotVarExp();
166 DotTemplateInstanceExp
* isDotTemplateInstanceExp();
167 DelegateExp
* isDelegateExp();
168 DotTypeExp
* isDotTypeExp();
169 CallExp
* isCallExp();
170 AddrExp
* isAddrExp();
173 UAddExp
* isUAddExp();
176 DeleteExp
* isDeleteExp();
177 CastExp
* isCastExp();
178 VectorExp
* isVectorExp();
179 VectorArrayExp
* isVectorArrayExp();
180 SliceExp
* isSliceExp();
181 ArrayLengthExp
* isArrayLengthExp();
182 ArrayExp
* isArrayExp();
184 CommaExp
* isCommaExp();
185 IntervalExp
* isIntervalExp();
186 DelegatePtrExp
* isDelegatePtrExp();
187 DelegateFuncptrExp
* isDelegateFuncptrExp();
188 IndexExp
* isIndexExp();
189 PostExp
* isPostExp();
191 AssignExp
* isAssignExp();
192 ConstructExp
* isConstructExp();
193 BlitExp
* isBlitExp();
194 AddAssignExp
* isAddAssignExp();
195 MinAssignExp
* isMinAssignExp();
196 MulAssignExp
* isMulAssignExp();
197 DivAssignExp
* isDivAssignExp();
198 ModAssignExp
* isModAssignExp();
199 AndAssignExp
* isAndAssignExp();
200 OrAssignExp
* isOrAssignExp();
201 XorAssignExp
* isXorAssignExp();
202 PowAssignExp
* isPowAssignExp();
203 ShlAssignExp
* isShlAssignExp();
204 ShrAssignExp
* isShrAssignExp();
205 UshrAssignExp
* isUshrAssignExp();
206 CatAssignExp
* isCatAssignExp();
207 CatElemAssignExp
* isCatElemAssignExp();
208 CatDcharAssignExp
* isCatDcharAssignExp();
218 UshrExp
* isUshrExp();
222 LogicalExp
* isLogicalExp();
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();
239 BinAssignExp
* isBinAssignExp();
240 LoweredAssignExp
* isLoweredAssignExp();
242 void accept(Visitor
*v
) override
{ v
->visit(this); }
245 class IntegerExp final
: public Expression
250 static IntegerExp
*create(const Loc
&loc
, dinteger_t value
, Type
*type
);
251 static void emplace(UnionExp
*pue
, const Loc
&loc
, dinteger_t value
, Type
*type
);
252 bool equals(const RootObject
* const o
) const override
;
253 dinteger_t
toInteger() override
;
254 real_t
toReal() override
;
255 real_t
toImaginary() override
;
256 complex_t
toComplex() override
;
257 Optional
<bool> toBool() override
;
258 Expression
*toLvalue(Scope
*sc
, Expression
*e
) override
;
259 void accept(Visitor
*v
) override
{ v
->visit(this); }
260 dinteger_t
getInteger() { return value
; }
261 void setInteger(dinteger_t value
);
263 static IntegerExp
literal();
266 class ErrorExp final
: public Expression
269 Expression
*toLvalue(Scope
*sc
, Expression
*e
) override
;
270 void accept(Visitor
*v
) override
{ v
->visit(this); }
272 static ErrorExp
*errorexp
; // handy shared value
275 class RealExp final
: public Expression
280 static RealExp
*create(const Loc
&loc
, real_t value
, Type
*type
);
281 static void emplace(UnionExp
*pue
, const Loc
&loc
, real_t value
, Type
*type
);
282 bool equals(const RootObject
* const o
) const override
;
283 bool isIdentical(const Expression
*e
) const override
;
284 dinteger_t
toInteger() override
;
285 uinteger_t
toUInteger() override
;
286 real_t
toReal() override
;
287 real_t
toImaginary() override
;
288 complex_t
toComplex() override
;
289 Optional
<bool> toBool() override
;
290 void accept(Visitor
*v
) override
{ v
->visit(this); }
293 class ComplexExp final
: public Expression
298 static ComplexExp
*create(const Loc
&loc
, complex_t value
, Type
*type
);
299 static void emplace(UnionExp
*pue
, const Loc
&loc
, complex_t value
, Type
*type
);
300 bool equals(const RootObject
* const o
) const override
;
301 bool isIdentical(const Expression
*e
) const override
;
302 dinteger_t
toInteger() override
;
303 uinteger_t
toUInteger() override
;
304 real_t
toReal() override
;
305 real_t
toImaginary() override
;
306 complex_t
toComplex() override
;
307 Optional
<bool> toBool() override
;
308 void accept(Visitor
*v
) override
{ v
->visit(this); }
311 class IdentifierExp
: public Expression
317 static IdentifierExp
*create(const Loc
&loc
, Identifier
*ident
);
318 bool isLvalue() override final
;
319 Expression
*toLvalue(Scope
*sc
, Expression
*e
) override final
;
320 void accept(Visitor
*v
) override
{ v
->visit(this); }
323 class DollarExp final
: public IdentifierExp
326 void accept(Visitor
*v
) override
{ v
->visit(this); }
329 class DsymbolExp final
: public Expression
335 DsymbolExp
*syntaxCopy() override
;
336 bool isLvalue() override
;
337 Expression
*toLvalue(Scope
*sc
, Expression
*e
) override
;
338 void accept(Visitor
*v
) override
{ v
->visit(this); }
341 class ThisExp
: public Expression
346 ThisExp
*syntaxCopy() override
;
347 Optional
<bool> toBool() override
;
348 bool isLvalue() override
;
349 Expression
*toLvalue(Scope
*sc
, Expression
*e
) override
;
351 void accept(Visitor
*v
) override
{ v
->visit(this); }
354 class SuperExp final
: public ThisExp
357 bool isLvalue() override
;
358 Expression
* toLvalue(Scope
* sc
, Expression
* e
) final override
;
359 void accept(Visitor
*v
) override
{ v
->visit(this); }
362 class NullExp final
: public Expression
365 bool equals(const RootObject
* const o
) const override
;
366 Optional
<bool> toBool() override
;
367 StringExp
*toStringExp() override
;
368 void accept(Visitor
*v
) override
{ v
->visit(this); }
371 class StringExp final
: public Expression
374 utf8_t postfix
; // 'c', 'w', 'd'
376 void *string
; // char, wchar, or dchar data
377 size_t len
; // number of chars, wchars, or dchars
378 unsigned char sz
; // 1: char, 2: wchar, 4: dchar
379 bool committed
; // if type is committed
380 bool hexString
; // if string is parsed from a hex string literal
382 static StringExp
*create(const Loc
&loc
, const char *s
);
383 static StringExp
*create(const Loc
&loc
, const void *s
, d_size_t len
);
384 static void emplace(UnionExp
*pue
, const Loc
&loc
, const char *s
);
385 bool equals(const RootObject
* const o
) const override
;
386 char32_t
getCodeUnit(d_size_t i
) const;
387 void setCodeUnit(d_size_t i
, char32_t c
);
388 StringExp
*toStringExp() override
;
389 StringExp
*toUTF8(Scope
*sc
);
390 Optional
<bool> toBool() override
;
391 bool isLvalue() override
;
392 Expression
*toLvalue(Scope
*sc
, Expression
*e
) override
;
393 Expression
*modifiableLvalue(Scope
*sc
, Expression
*e
) override
;
394 void accept(Visitor
*v
) override
{ v
->visit(this); }
395 size_t numberOfCodeUnits(int tynto
= 0) const;
396 void writeTo(void* dest
, bool zero
, int tyto
= 0) const;
401 class TupleExp final
: public Expression
404 Expression
*e0
; // side-effect part
405 /* Tuple-field access may need to take out its side effect part.
409 * (ref __tup = foo(); tuple(__tup.field0, __tup.field1, ...))
410 * The declaration of temporary variable __tup will be stored in TupleExp::e0.
414 static TupleExp
*create(const Loc
&loc
, Expressions
*exps
);
415 TupleExp
*syntaxCopy() override
;
416 bool equals(const RootObject
* const o
) const override
;
418 void accept(Visitor
*v
) override
{ v
->visit(this); }
421 class ArrayLiteralExp final
: public Expression
427 Expressions
*elements
;
429 static ArrayLiteralExp
*create(const Loc
&loc
, Expressions
*elements
);
430 static void emplace(UnionExp
*pue
, const Loc
&loc
, Expressions
*elements
);
431 ArrayLiteralExp
*syntaxCopy() override
;
432 bool equals(const RootObject
* const o
) const override
;
433 Expression
*getElement(d_size_t i
); // use opIndex instead
434 Expression
*opIndex(d_size_t i
);
435 Optional
<bool> toBool() override
;
436 StringExp
*toStringExp() override
;
438 void accept(Visitor
*v
) override
{ v
->visit(this); }
441 class AssocArrayLiteralExp final
: public Expression
447 Expression
* lowering
;
449 bool equals(const RootObject
* const o
) const override
;
450 AssocArrayLiteralExp
*syntaxCopy() override
;
451 Optional
<bool> toBool() override
;
453 void accept(Visitor
*v
) override
{ v
->visit(this); }
456 class StructLiteralExp final
: public Expression
459 StructDeclaration
*sd
; // which aggregate this is for
460 Expressions
*elements
; // parallels sd->fields[] with NULL entries for fields to skip
461 Type
*stype
; // final type of result (can be different from sd's type)
465 Symbol
*sym
; // back end symbol to initialize with literal
467 // those fields need to prevent a infinite recursion when one field of struct initialized with 'this' pointer.
468 StructLiteralExp
*inlinecopy
;
471 /** pointer to the origin instance of the expression.
472 * once a new expression is created, origin is set to 'this'.
473 * anytime when an expression copy is created, 'origin' pointer is set to
474 * 'origin' pointer value of the original expression.
476 StructLiteralExp
*origin
;
479 /** anytime when recursive function is calling, 'stageflags' marks with bit flag of
480 * current stage and unmarks before return from this function.
481 * 'inlinecopy' uses similar 'stageflags' and from multiple evaluation 'doInline'
482 * (with infinite recursion) of this expression.
486 d_bool useStaticInit
; // if this is true, use the StructDeclaration's init symbol
487 d_bool isOriginal
; // used when moving instances to indicate `this is this.origin`
490 static StructLiteralExp
*create(const Loc
&loc
, StructDeclaration
*sd
, void *elements
, Type
*stype
= NULL
);
491 bool equals(const RootObject
* const o
) const override
;
492 StructLiteralExp
*syntaxCopy() override
;
493 Expression
*getField(Type
*type
, unsigned offset
);
494 int getFieldIndex(Type
*type
, unsigned offset
);
495 Expression
*addDtorHook(Scope
*sc
) override
;
496 Expression
*toLvalue(Scope
*sc
, Expression
*e
) override
;
498 void accept(Visitor
*v
) override
{ v
->visit(this); }
501 class TypeExp final
: public Expression
504 TypeExp
*syntaxCopy() override
;
505 bool checkType() override
;
506 bool checkValue() override
;
507 void accept(Visitor
*v
) override
{ v
->visit(this); }
510 class ScopeExp final
: public Expression
515 ScopeExp
*syntaxCopy() override
;
516 bool checkType() override
;
517 bool checkValue() override
;
518 void accept(Visitor
*v
) override
{ v
->visit(this); }
521 class TemplateExp final
: public Expression
524 TemplateDeclaration
*td
;
527 bool isLvalue() override
;
528 Expression
*toLvalue(Scope
*sc
, Expression
*e
) override
;
529 bool checkType() override
;
530 bool checkValue() override
;
531 void accept(Visitor
*v
) override
{ v
->visit(this); }
534 class NewExp final
: public Expression
537 /* newtype(arguments)
539 Expression
*thisexp
; // if !NULL, 'this' for class being allocated
541 Expressions
*arguments
; // Array of Expression's
542 Identifiers
*names
; // Array of names corresponding to expressions
544 Expression
*argprefix
; // expression to be evaluated just before arguments[]
546 CtorDeclaration
*member
; // constructor function
547 d_bool onstack
; // allocate on stack
548 d_bool thrownew
; // this NewExp is the expression of a ThrowStatement
550 Expression
*lowering
; // lowered druntime hook: `_d_newclass`
552 static NewExp
*create(const Loc
&loc
, Expression
*thisexp
, Type
*newtype
, Expressions
*arguments
);
553 NewExp
*syntaxCopy() override
;
555 void accept(Visitor
*v
) override
{ v
->visit(this); }
558 class NewAnonClassExp final
: public Expression
561 /* class baseclasses { } (arguments)
563 Expression
*thisexp
; // if !NULL, 'this' for class being allocated
564 ClassDeclaration
*cd
; // class being instantiated
565 Expressions
*arguments
; // Array of Expression's to call class constructor
567 NewAnonClassExp
*syntaxCopy() override
;
568 void accept(Visitor
*v
) override
{ v
->visit(this); }
571 class SymbolExp
: public Expression
575 Dsymbol
*originalScope
;
578 void accept(Visitor
*v
) override
{ v
->visit(this); }
581 // Offset from symbol
583 class SymOffExp final
: public SymbolExp
588 Optional
<bool> toBool() override
;
590 void accept(Visitor
*v
) override
{ v
->visit(this); }
595 class VarExp final
: public SymbolExp
598 d_bool delegateWasExtracted
;
599 static VarExp
*create(const Loc
&loc
, Declaration
*var
, bool hasOverloads
= true);
600 bool equals(const RootObject
* const o
) const override
;
601 bool isLvalue() override
;
602 Expression
*toLvalue(Scope
*sc
, Expression
*e
) override
;
603 Expression
*modifiableLvalue(Scope
*sc
, Expression
*e
) override
;
605 void accept(Visitor
*v
) override
{ v
->visit(this); }
610 class OverExp final
: public Expression
615 bool isLvalue() override
;
616 Expression
*toLvalue(Scope
*sc
, Expression
*e
) override
;
617 void accept(Visitor
*v
) override
{ v
->visit(this); }
620 // Function/Delegate literal
622 class FuncExp final
: public Expression
625 FuncLiteralDeclaration
*fd
;
626 TemplateDeclaration
*td
;
629 bool equals(const RootObject
* const o
) const override
;
630 FuncExp
*syntaxCopy() override
;
631 const char *toChars() const override
;
632 bool checkType() override
;
633 bool checkValue() override
;
635 void accept(Visitor
*v
) override
{ v
->visit(this); }
638 // Declaration of a symbol
640 // D grammar allows declarations only as statements. However in AST representation
641 // it can be part of any expression. This is used, for example, during internal
642 // syntax re-writes to inject hidden symbols.
643 class DeclarationExp final
: public Expression
646 Dsymbol
*declaration
;
648 DeclarationExp
*syntaxCopy() override
;
650 bool hasCode() override
;
652 void accept(Visitor
*v
) override
{ v
->visit(this); }
655 class TypeidExp final
: public Expression
660 TypeidExp
*syntaxCopy() override
;
661 void accept(Visitor
*v
) override
{ v
->visit(this); }
664 class TraitsExp final
: public Expression
670 TraitsExp
*syntaxCopy() override
;
671 void accept(Visitor
*v
) override
{ v
->visit(this); }
674 class HaltExp final
: public Expression
677 void accept(Visitor
*v
) override
{ v
->visit(this); }
680 class IsExp final
: public Expression
683 /* is(targ id tok tspec)
684 * is(targ id == tok2)
687 Identifier
*id
; // can be NULL
688 Type
*tspec
; // can be NULL
689 TemplateParameters
*parameters
;
690 TOK tok
; // ':' or '=='
691 TOK tok2
; // 'struct', 'union', etc.
693 IsExp
*syntaxCopy() override
;
694 void accept(Visitor
*v
) override
{ v
->visit(this); }
697 /****************************************************************/
699 class UnaExp
: public Expression
704 UnaExp
*syntaxCopy() override
;
705 Expression
*incompatibleTypes();
706 Expression
*resolveLoc(const Loc
&loc
, Scope
*sc
) override final
;
708 void accept(Visitor
*v
) override
{ v
->visit(this); }
711 class BinExp
: public Expression
717 Type
*att1
; // Save alias this type to detect recursion
718 Type
*att2
; // Save alias this type to detect recursion
720 BinExp
*syntaxCopy() override
;
721 Expression
*incompatibleTypes();
723 Expression
*reorderSettingAAElem(Scope
*sc
);
725 void accept(Visitor
*v
) override
{ v
->visit(this); }
728 class BinAssignExp
: public BinExp
731 bool isLvalue() override final
;
732 Expression
*toLvalue(Scope
*sc
, Expression
*ex
) override final
;
733 Expression
*modifiableLvalue(Scope
*sc
, Expression
*e
) override final
;
734 void accept(Visitor
*v
) override
{ v
->visit(this); }
737 /****************************************************************/
739 class MixinExp final
: public UnaExp
742 void accept(Visitor
*v
) override
{ v
->visit(this); }
745 class ImportExp final
: public UnaExp
748 void accept(Visitor
*v
) override
{ v
->visit(this); }
751 class AssertExp final
: public UnaExp
756 AssertExp
*syntaxCopy() override
;
758 void accept(Visitor
*v
) override
{ v
->visit(this); }
761 class ThrowExp final
: public UnaExp
764 ThrowExp
*syntaxCopy() override
;
766 void accept(Visitor
*v
) override
{ v
->visit(this); }
769 class DotIdExp final
: public UnaExp
773 d_bool noderef
; // true if the result of the expression will never be dereferenced
774 d_bool wantsym
; // do not replace Symbol with its initializer during semantic()
775 d_bool arrow
; // ImportC: if -> instead of .
777 static DotIdExp
*create(const Loc
&loc
, Expression
*e
, Identifier
*ident
);
778 void accept(Visitor
*v
) override
{ v
->visit(this); }
781 class DotTemplateExp final
: public UnaExp
784 TemplateDeclaration
*td
;
786 bool checkType() override
;
787 bool checkValue() override
;
788 void accept(Visitor
*v
) override
{ v
->visit(this); }
791 class DotVarExp final
: public UnaExp
797 bool isLvalue() override
;
798 Expression
*toLvalue(Scope
*sc
, Expression
*e
) override
;
799 Expression
*modifiableLvalue(Scope
*sc
, Expression
*e
) override
;
800 void accept(Visitor
*v
) override
{ v
->visit(this); }
803 class DotTemplateInstanceExp final
: public UnaExp
806 TemplateInstance
*ti
;
808 DotTemplateInstanceExp
*syntaxCopy() override
;
809 bool findTempDecl(Scope
*sc
);
810 bool checkType() override
;
811 bool checkValue() override
;
812 void accept(Visitor
*v
) override
{ v
->visit(this); }
815 class DelegateExp final
: public UnaExp
818 FuncDeclaration
*func
;
820 VarDeclaration
*vthis2
; // container for multi-context
823 void accept(Visitor
*v
) override
{ v
->visit(this); }
826 class DotTypeExp final
: public UnaExp
829 Dsymbol
*sym
; // symbol that represents a type
831 void accept(Visitor
*v
) override
{ v
->visit(this); }
834 class CallExp final
: public UnaExp
837 Expressions
*arguments
; // function arguments
839 FuncDeclaration
*f
; // symbol to call
840 d_bool directcall
; // true if a virtual call is devirtualized
841 d_bool inDebugStatement
; // true if this was in a debug statement
842 d_bool ignoreAttributes
; // don't enforce attributes (e.g. call @gc function in @nogc code)
843 d_bool isUfcsRewrite
; // the first argument was pushed in here by a UFCS rewrite
844 VarDeclaration
*vthis2
; // container for multi-context
846 static CallExp
*create(const Loc
&loc
, Expression
*e
, Expressions
*exps
);
847 static CallExp
*create(const Loc
&loc
, Expression
*e
);
848 static CallExp
*create(const Loc
&loc
, Expression
*e
, Expression
*earg1
);
849 static CallExp
*create(const Loc
&loc
, FuncDeclaration
*fd
, Expression
*earg1
);
851 CallExp
*syntaxCopy() override
;
852 bool isLvalue() override
;
853 Expression
*toLvalue(Scope
*sc
, Expression
*e
) override
;
854 Expression
*addDtorHook(Scope
*sc
) override
;
856 void accept(Visitor
*v
) override
{ v
->visit(this); }
859 class AddrExp final
: public UnaExp
862 void accept(Visitor
*v
) override
{ v
->visit(this); }
865 class PtrExp final
: public UnaExp
868 bool isLvalue() override
;
869 Expression
*toLvalue(Scope
*sc
, Expression
*e
) override
;
870 Expression
*modifiableLvalue(Scope
*sc
, Expression
*e
) override
;
872 void accept(Visitor
*v
) override
{ v
->visit(this); }
875 class NegExp final
: public UnaExp
878 void accept(Visitor
*v
) override
{ v
->visit(this); }
881 class UAddExp final
: public UnaExp
884 void accept(Visitor
*v
) override
{ v
->visit(this); }
887 class ComExp final
: public UnaExp
890 void accept(Visitor
*v
) override
{ v
->visit(this); }
893 class NotExp final
: public UnaExp
896 void accept(Visitor
*v
) override
{ v
->visit(this); }
899 class DeleteExp final
: public UnaExp
903 void accept(Visitor
*v
) override
{ v
->visit(this); }
906 class CastExp final
: public UnaExp
909 // Possible to cast to one type while painting to another type
910 Type
*to
; // type to cast to
911 unsigned char mod
; // MODxxxxx
913 CastExp
*syntaxCopy() override
;
914 bool isLvalue() override
;
915 Expression
*toLvalue(Scope
*sc
, Expression
*e
) override
;
917 void accept(Visitor
*v
) override
{ v
->visit(this); }
920 class VectorExp final
: public UnaExp
923 TypeVector
*to
; // the target vector type before semantic()
924 unsigned dim
; // number of elements in the vector
927 static VectorExp
*create(const Loc
&loc
, Expression
*e
, Type
*t
);
928 static void emplace(UnionExp
*pue
, const Loc
&loc
, Expression
*e
, Type
*t
);
929 VectorExp
*syntaxCopy() override
;
930 void accept(Visitor
*v
) override
{ v
->visit(this); }
933 class VectorArrayExp final
: public UnaExp
936 bool isLvalue() override
;
937 Expression
*toLvalue(Scope
*sc
, Expression
*e
) override
;
938 void accept(Visitor
*v
) override
{ v
->visit(this); }
941 class SliceExp final
: public UnaExp
944 Expression
*upr
; // NULL if implicit 0
945 Expression
*lwr
; // NULL if implicit [length - 1]
946 VarDeclaration
*lengthVar
;
948 bool upperIsInBounds() const; // true if upr <= e1.length
949 bool upperIsInBounds(bool v
);
950 bool lowerIsLessThanUpper() const; // true if lwr <= upr
951 bool lowerIsLessThanUpper(bool v
);
952 bool arrayop() const; // an array operation, rather than a slice
953 bool arrayop(bool v
);
958 SliceExp
*syntaxCopy() override
;
959 bool isLvalue() override
;
960 Expression
*toLvalue(Scope
*sc
, Expression
*e
) override
;
961 Expression
*modifiableLvalue(Scope
*sc
, Expression
*e
) override
;
962 Optional
<bool> toBool() override
;
964 void accept(Visitor
*v
) override
{ v
->visit(this); }
967 class ArrayLengthExp final
: public UnaExp
970 void accept(Visitor
*v
) override
{ v
->visit(this); }
973 class IntervalExp final
: public Expression
979 IntervalExp
*syntaxCopy() override
;
980 void accept(Visitor
*v
) override
{ v
->visit(this); }
983 class DelegatePtrExp final
: public UnaExp
986 bool isLvalue() override
;
987 Expression
*toLvalue(Scope
*sc
, Expression
*e
) override
;
988 Expression
*modifiableLvalue(Scope
*sc
, Expression
*e
) override
;
989 void accept(Visitor
*v
) override
{ v
->visit(this); }
992 class DelegateFuncptrExp final
: public UnaExp
995 bool isLvalue() override
;
996 Expression
*toLvalue(Scope
*sc
, Expression
*e
) override
;
997 Expression
*modifiableLvalue(Scope
*sc
, Expression
*e
) override
;
998 void accept(Visitor
*v
) override
{ v
->visit(this); }
1001 // e1[a0,a1,a2,a3,...]
1003 class ArrayExp final
: public UnaExp
1006 Expressions
*arguments
; // Array of Expression's
1007 size_t currentDimension
; // for opDollar
1008 VarDeclaration
*lengthVar
;
1010 ArrayExp
*syntaxCopy() override
;
1011 bool isLvalue() override
;
1012 Expression
*toLvalue(Scope
*sc
, Expression
*e
) override
;
1014 void accept(Visitor
*v
) override
{ v
->visit(this); }
1017 /****************************************************************/
1019 class DotExp final
: public BinExp
1022 void accept(Visitor
*v
) override
{ v
->visit(this); }
1025 class CommaExp final
: public BinExp
1029 d_bool allowCommaExp
;
1030 bool isLvalue() override
;
1031 Expression
*toLvalue(Scope
*sc
, Expression
*e
) override
;
1032 Expression
*modifiableLvalue(Scope
*sc
, Expression
*e
) override
;
1033 Optional
<bool> toBool() override
;
1034 Expression
*addDtorHook(Scope
*sc
) override
;
1035 void accept(Visitor
*v
) override
{ v
->visit(this); }
1038 class IndexExp final
: public BinExp
1041 VarDeclaration
*lengthVar
;
1043 d_bool indexIsInBounds
; // true if 0 <= e2 && e2 <= e1.length - 1
1045 IndexExp
*syntaxCopy() override
;
1046 bool isLvalue() override
;
1047 Expression
*toLvalue(Scope
*sc
, Expression
*e
) override
;
1048 Expression
*modifiableLvalue(Scope
*sc
, Expression
*e
) override
;
1050 void accept(Visitor
*v
) override
{ v
->visit(this); }
1053 /* For both i++ and i--
1055 class PostExp final
: public BinExp
1058 void accept(Visitor
*v
) override
{ v
->visit(this); }
1061 /* For both ++i and --i
1063 class PreExp final
: public UnaExp
1066 void accept(Visitor
*v
) override
{ v
->visit(this); }
1069 enum class MemorySet
1071 none
= 0, // simple assignment
1072 blockAssign
= 1, // setting the contents of an array
1073 referenceInit
= 2 // setting the reference of STCref variable
1076 class AssignExp
: public BinExp
1081 bool isLvalue() override final
;
1082 Expression
*toLvalue(Scope
*sc
, Expression
*ex
) override final
;
1084 void accept(Visitor
*v
) override
{ v
->visit(this); }
1087 class ConstructExp final
: public AssignExp
1090 void accept(Visitor
*v
) override
{ v
->visit(this); }
1093 class LoweredAssignExp final
: public AssignExp
1096 Expression
*lowering
;
1098 const char *toChars() const override
;
1099 void accept(Visitor
*v
) override
{ v
->visit(this); }
1102 class BlitExp final
: public AssignExp
1105 void accept(Visitor
*v
) override
{ v
->visit(this); }
1108 class AddAssignExp final
: public BinAssignExp
1111 void accept(Visitor
*v
) override
{ v
->visit(this); }
1114 class MinAssignExp final
: public BinAssignExp
1117 void accept(Visitor
*v
) override
{ v
->visit(this); }
1120 class MulAssignExp final
: public BinAssignExp
1123 void accept(Visitor
*v
) override
{ v
->visit(this); }
1126 class DivAssignExp final
: public BinAssignExp
1129 void accept(Visitor
*v
) override
{ v
->visit(this); }
1132 class ModAssignExp final
: public BinAssignExp
1135 void accept(Visitor
*v
) override
{ v
->visit(this); }
1138 class AndAssignExp final
: public BinAssignExp
1141 void accept(Visitor
*v
) override
{ v
->visit(this); }
1144 class OrAssignExp final
: public BinAssignExp
1147 void accept(Visitor
*v
) override
{ v
->visit(this); }
1150 class XorAssignExp final
: public BinAssignExp
1153 void accept(Visitor
*v
) override
{ v
->visit(this); }
1156 class PowAssignExp final
: public BinAssignExp
1159 void accept(Visitor
*v
) override
{ v
->visit(this); }
1162 class ShlAssignExp final
: public BinAssignExp
1165 void accept(Visitor
*v
) override
{ v
->visit(this); }
1168 class ShrAssignExp final
: public BinAssignExp
1171 void accept(Visitor
*v
) override
{ v
->visit(this); }
1174 class UshrAssignExp final
: public BinAssignExp
1177 void accept(Visitor
*v
) override
{ v
->visit(this); }
1180 class CatAssignExp
: public BinAssignExp
1183 void accept(Visitor
*v
) override
{ v
->visit(this); }
1186 class CatElemAssignExp final
: public CatAssignExp
1189 void accept(Visitor
*v
) override
{ v
->visit(this); }
1192 class CatDcharAssignExp final
: public CatAssignExp
1195 void accept(Visitor
*v
) override
{ v
->visit(this); }
1198 class AddExp final
: public BinExp
1201 void accept(Visitor
*v
) override
{ v
->visit(this); }
1204 class MinExp final
: public BinExp
1207 void accept(Visitor
*v
) override
{ v
->visit(this); }
1210 class CatExp final
: public BinExp
1213 Expression
*lowering
; // call to druntime hook `_d_arraycatnTX`
1215 void accept(Visitor
*v
) override
{ v
->visit(this); }
1218 class MulExp final
: public BinExp
1221 void accept(Visitor
*v
) override
{ v
->visit(this); }
1224 class DivExp final
: public BinExp
1227 void accept(Visitor
*v
) override
{ v
->visit(this); }
1230 class ModExp final
: public BinExp
1233 void accept(Visitor
*v
) override
{ v
->visit(this); }
1236 class PowExp final
: public BinExp
1239 void accept(Visitor
*v
) override
{ v
->visit(this); }
1242 class ShlExp final
: public BinExp
1245 void accept(Visitor
*v
) override
{ v
->visit(this); }
1248 class ShrExp final
: public BinExp
1251 void accept(Visitor
*v
) override
{ v
->visit(this); }
1254 class UshrExp final
: public BinExp
1257 void accept(Visitor
*v
) override
{ v
->visit(this); }
1260 class AndExp final
: public BinExp
1263 void accept(Visitor
*v
) override
{ v
->visit(this); }
1266 class OrExp final
: public BinExp
1269 void accept(Visitor
*v
) override
{ v
->visit(this); }
1272 class XorExp final
: public BinExp
1275 void accept(Visitor
*v
) override
{ v
->visit(this); }
1278 class LogicalExp final
: public BinExp
1281 void accept(Visitor
*v
) override
{ v
->visit(this); }
1284 class CmpExp final
: public BinExp
1287 void accept(Visitor
*v
) override
{ v
->visit(this); }
1290 class InExp final
: public BinExp
1293 void accept(Visitor
*v
) override
{ v
->visit(this); }
1296 class RemoveExp final
: public BinExp
1299 void accept(Visitor
*v
) override
{ v
->visit(this); }
1304 class EqualExp final
: public BinExp
1307 void accept(Visitor
*v
) override
{ v
->visit(this); }
1312 class IdentityExp final
: public BinExp
1315 void accept(Visitor
*v
) override
{ v
->visit(this); }
1318 /****************************************************************/
1320 class CondExp final
: public BinExp
1325 CondExp
*syntaxCopy() override
;
1326 bool isLvalue() override
;
1327 Expression
*toLvalue(Scope
*sc
, Expression
*e
) override
;
1328 Expression
*modifiableLvalue(Scope
*sc
, Expression
*e
) override
;
1329 void hookDtors(Scope
*sc
);
1331 void accept(Visitor
*v
) override
{ v
->visit(this); }
1334 class GenericExp final
: Expression
1336 Expression
*cntlExp
;
1340 GenericExp
*syntaxCopy() override
;
1342 void accept(Visitor
*v
) override
{ v
->visit(this); }
1345 /****************************************************************/
1347 class DefaultInitExp
: public Expression
1350 void accept(Visitor
*v
) override
{ v
->visit(this); }
1353 class FileInitExp final
: public DefaultInitExp
1356 Expression
*resolveLoc(const Loc
&loc
, Scope
*sc
) override
;
1357 void accept(Visitor
*v
) override
{ v
->visit(this); }
1360 class LineInitExp final
: public DefaultInitExp
1363 Expression
*resolveLoc(const Loc
&loc
, Scope
*sc
) override
;
1364 void accept(Visitor
*v
) override
{ v
->visit(this); }
1367 class ModuleInitExp final
: public DefaultInitExp
1370 Expression
*resolveLoc(const Loc
&loc
, Scope
*sc
) override
;
1371 void accept(Visitor
*v
) override
{ v
->visit(this); }
1374 class FuncInitExp final
: public DefaultInitExp
1377 Expression
*resolveLoc(const Loc
&loc
, Scope
*sc
) override
;
1378 void accept(Visitor
*v
) override
{ v
->visit(this); }
1381 class PrettyFuncInitExp final
: public DefaultInitExp
1384 Expression
*resolveLoc(const Loc
&loc
, Scope
*sc
) override
;
1385 void accept(Visitor
*v
) override
{ v
->visit(this); }
1388 /****************************************************************/
1390 /* A type meant as a union of all the Expression types,
1391 * to serve essentially as a Variant that will sit on the stack
1392 * during CTFE to reduce memory consumption.
1396 UnionExp() { } // yes, default constructor does nothing
1398 UnionExp(Expression
*e
)
1400 memcpy(this, (void *)e
, e
->size());
1403 /* Extract pointer to Expression
1405 Expression
*exp() { return (Expression
*)&u
; }
1407 /* Convert to an allocated Expression
1412 // Ensure that the union is suitably aligned.
1413 #if defined(__GNUC__) || defined(__clang__)
1414 __attribute__((aligned(8)))
1415 #elif defined(_MSC_VER)
1416 __declspec(align(8))
1417 #elif defined(__DMC__)
1422 char exp
[sizeof(Expression
)];
1423 char integerexp
[sizeof(IntegerExp
)];
1424 char errorexp
[sizeof(ErrorExp
)];
1425 char realexp
[sizeof(RealExp
)];
1426 char complexexp
[sizeof(ComplexExp
)];
1427 char symoffexp
[sizeof(SymOffExp
)];
1428 char stringexp
[sizeof(StringExp
)];
1429 char arrayliteralexp
[sizeof(ArrayLiteralExp
)];
1430 char assocarrayliteralexp
[sizeof(AssocArrayLiteralExp
)];
1431 char structliteralexp
[sizeof(StructLiteralExp
)];
1432 char nullexp
[sizeof(NullExp
)];
1433 char dotvarexp
[sizeof(DotVarExp
)];
1434 char addrexp
[sizeof(AddrExp
)];
1435 char indexexp
[sizeof(IndexExp
)];
1436 char sliceexp
[sizeof(SliceExp
)];
1437 char vectorexp
[sizeof(VectorExp
)];
1439 #if defined(__DMC__)
1444 /****************************************************************/
1446 class ObjcClassReferenceExp final
: public Expression
1449 ClassDeclaration
* classDeclaration
;
1451 void accept(Visitor
*v
) override
{ v
->visit(this); }