]> gcc.gnu.org Git - gcc.git/blob - gcc/d/dmd/expression.h
9ab1cab9877f377dacb270fbdd7b02152f9f554b
[gcc.git] / gcc / d / dmd / expression.h
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 override final { return DYNCAST_EXPRESSION; }
94
95 const char *toChars() const override;
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 CatElemAssignExp* isCatElemAssignExp();
210 CatDcharAssignExp* isCatDcharAssignExp();
211 AddExp* isAddExp();
212 MinExp* isMinExp();
213 CatExp* isCatExp();
214 MulExp* isMulExp();
215 DivExp* isDivExp();
216 ModExp* isModExp();
217 PowExp* isPowExp();
218 ShlExp* isShlExp();
219 ShrExp* isShrExp();
220 UshrExp* isUshrExp();
221 AndExp* isAndExp();
222 OrExp* isOrExp();
223 XorExp* isXorExp();
224 LogicalExp* isLogicalExp();
225 InExp* isInExp();
226 RemoveExp* isRemoveExp();
227 EqualExp* isEqualExp();
228 IdentityExp* isIdentityExp();
229 CondExp* isCondExp();
230 GenericExp* isGenericExp();
231 DefaultInitExp* isDefaultInitExp();
232 FileInitExp* isFileInitExp();
233 LineInitExp* isLineInitExp();
234 ModuleInitExp* isModuleInitExp();
235 FuncInitExp* isFuncInitExp();
236 PrettyFuncInitExp* isPrettyFuncInitExp();
237 ClassReferenceExp* isClassReferenceExp();
238 ThrownExceptionExp* isThrownExceptionExp();
239 UnaExp* isUnaExp();
240 BinExp* isBinExp();
241 BinAssignExp* isBinAssignExp();
242
243 void accept(Visitor *v) override { v->visit(this); }
244 };
245
246 class IntegerExp final : public Expression
247 {
248 public:
249 dinteger_t value;
250
251 static IntegerExp *create(const Loc &loc, dinteger_t value, Type *type);
252 static void emplace(UnionExp *pue, const Loc &loc, dinteger_t value, Type *type);
253 bool equals(const RootObject *o) const override;
254 dinteger_t toInteger() override;
255 real_t toReal() override;
256 real_t toImaginary() override;
257 complex_t toComplex() override;
258 Optional<bool> toBool() override;
259 Expression *toLvalue(Scope *sc, Expression *e) override;
260 void accept(Visitor *v) override { v->visit(this); }
261 dinteger_t getInteger() { return value; }
262 void setInteger(dinteger_t value);
263 template<int v>
264 static IntegerExp literal();
265 };
266
267 class ErrorExp final : public Expression
268 {
269 public:
270 Expression *toLvalue(Scope *sc, Expression *e) override;
271 void accept(Visitor *v) override { v->visit(this); }
272
273 static ErrorExp *errorexp; // handy shared value
274 };
275
276 class RealExp final : public Expression
277 {
278 public:
279 real_t value;
280
281 static RealExp *create(const Loc &loc, real_t value, Type *type);
282 static void emplace(UnionExp *pue, const Loc &loc, real_t value, Type *type);
283 bool equals(const RootObject *o) 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); }
291 };
292
293 class ComplexExp final : public Expression
294 {
295 public:
296 complex_t value;
297
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 *o) const override;
301 dinteger_t toInteger() override;
302 uinteger_t toUInteger() override;
303 real_t toReal() override;
304 real_t toImaginary() override;
305 complex_t toComplex() override;
306 Optional<bool> toBool() override;
307 void accept(Visitor *v) override { v->visit(this); }
308 };
309
310 class IdentifierExp : public Expression
311 {
312 public:
313 Identifier *ident;
314
315 static IdentifierExp *create(const Loc &loc, Identifier *ident);
316 bool isLvalue() override final;
317 Expression *toLvalue(Scope *sc, Expression *e) override final;
318 void accept(Visitor *v) override { v->visit(this); }
319 };
320
321 class DollarExp final : public IdentifierExp
322 {
323 public:
324 void accept(Visitor *v) override { v->visit(this); }
325 };
326
327 class DsymbolExp final : public Expression
328 {
329 public:
330 Dsymbol *s;
331 bool hasOverloads;
332
333 DsymbolExp *syntaxCopy() override;
334 bool isLvalue() override;
335 Expression *toLvalue(Scope *sc, Expression *e) override;
336 void accept(Visitor *v) override { v->visit(this); }
337 };
338
339 class ThisExp : public Expression
340 {
341 public:
342 VarDeclaration *var;
343
344 ThisExp *syntaxCopy() override;
345 Optional<bool> toBool() override;
346 bool isLvalue() override final;
347 Expression *toLvalue(Scope *sc, Expression *e) override final;
348
349 void accept(Visitor *v) override { v->visit(this); }
350 };
351
352 class SuperExp final : public ThisExp
353 {
354 public:
355 void accept(Visitor *v) override { v->visit(this); }
356 };
357
358 class NullExp final : public Expression
359 {
360 public:
361 bool equals(const RootObject *o) const override;
362 Optional<bool> toBool() override;
363 StringExp *toStringExp() override;
364 void accept(Visitor *v) override { v->visit(this); }
365 };
366
367 class StringExp final : public Expression
368 {
369 public:
370 void *string; // char, wchar, or dchar data
371 size_t len; // number of chars, wchars, or dchars
372 unsigned char sz; // 1: char, 2: wchar, 4: dchar
373 unsigned char committed; // !=0 if type is committed
374 utf8_t postfix; // 'c', 'w', 'd'
375 OwnedBy ownedByCtfe;
376
377 static StringExp *create(const Loc &loc, const char *s);
378 static StringExp *create(const Loc &loc, const void *s, d_size_t len);
379 static void emplace(UnionExp *pue, const Loc &loc, const char *s);
380 bool equals(const RootObject *o) const override;
381 char32_t getCodeUnit(d_size_t i) const;
382 void setCodeUnit(d_size_t i, char32_t c);
383 StringExp *toStringExp() override;
384 StringExp *toUTF8(Scope *sc);
385 Optional<bool> toBool() override;
386 bool isLvalue() override;
387 Expression *toLvalue(Scope *sc, Expression *e) override;
388 Expression *modifiableLvalue(Scope *sc, Expression *e) override;
389 void accept(Visitor *v) override { v->visit(this); }
390 size_t numberOfCodeUnits(int tynto = 0) const;
391 void writeTo(void* dest, bool zero, int tyto = 0) const;
392 };
393
394 // Tuple
395
396 class TupleExp final : public Expression
397 {
398 public:
399 Expression *e0; // side-effect part
400 /* Tuple-field access may need to take out its side effect part.
401 * For example:
402 * foo().tupleof
403 * is rewritten as:
404 * (ref __tup = foo(); tuple(__tup.field0, __tup.field1, ...))
405 * The declaration of temporary variable __tup will be stored in TupleExp::e0.
406 */
407 Expressions *exps;
408
409 static TupleExp *create(const Loc &loc, Expressions *exps);
410 TupleExp *syntaxCopy() override;
411 bool equals(const RootObject *o) const override;
412
413 void accept(Visitor *v) override { v->visit(this); }
414 };
415
416 class ArrayLiteralExp final : public Expression
417 {
418 public:
419 Expression *basis;
420 Expressions *elements;
421 OwnedBy ownedByCtfe;
422
423 static ArrayLiteralExp *create(const Loc &loc, Expressions *elements);
424 static void emplace(UnionExp *pue, const Loc &loc, Expressions *elements);
425 ArrayLiteralExp *syntaxCopy() override;
426 bool equals(const RootObject *o) const override;
427 Expression *getElement(d_size_t i); // use opIndex instead
428 Expression *opIndex(d_size_t i);
429 Optional<bool> toBool() override;
430 StringExp *toStringExp() override;
431
432 void accept(Visitor *v) override { v->visit(this); }
433 };
434
435 class AssocArrayLiteralExp final : public Expression
436 {
437 public:
438 Expressions *keys;
439 Expressions *values;
440 OwnedBy ownedByCtfe;
441
442 bool equals(const RootObject *o) const override;
443 AssocArrayLiteralExp *syntaxCopy() override;
444 Optional<bool> toBool() override;
445
446 void accept(Visitor *v) override { v->visit(this); }
447 };
448
449 class StructLiteralExp final : public Expression
450 {
451 public:
452 StructDeclaration *sd; // which aggregate this is for
453 Expressions *elements; // parallels sd->fields[] with NULL entries for fields to skip
454 Type *stype; // final type of result (can be different from sd's type)
455
456 Symbol *sym; // back end symbol to initialize with literal
457
458 /** pointer to the origin instance of the expression.
459 * once a new expression is created, origin is set to 'this'.
460 * anytime when an expression copy is created, 'origin' pointer is set to
461 * 'origin' pointer value of the original expression.
462 */
463 StructLiteralExp *origin;
464
465 // those fields need to prevent a infinite recursion when one field of struct initialized with 'this' pointer.
466 StructLiteralExp *inlinecopy;
467
468 /** anytime when recursive function is calling, 'stageflags' marks with bit flag of
469 * current stage and unmarks before return from this function.
470 * 'inlinecopy' uses similar 'stageflags' and from multiple evaluation 'doInline'
471 * (with infinite recursion) of this expression.
472 */
473 int stageflags;
474
475 bool useStaticInit; // if this is true, use the StructDeclaration's init symbol
476 bool isOriginal; // used when moving instances to indicate `this is this.origin`
477 OwnedBy ownedByCtfe;
478
479 static StructLiteralExp *create(const Loc &loc, StructDeclaration *sd, void *elements, Type *stype = NULL);
480 bool equals(const RootObject *o) const override;
481 StructLiteralExp *syntaxCopy() override;
482 Expression *getField(Type *type, unsigned offset);
483 int getFieldIndex(Type *type, unsigned offset);
484 Expression *addDtorHook(Scope *sc) override;
485 Expression *toLvalue(Scope *sc, Expression *e) override;
486
487 void accept(Visitor *v) override { v->visit(this); }
488 };
489
490 class TypeExp final : public Expression
491 {
492 public:
493 TypeExp *syntaxCopy() override;
494 bool checkType() override;
495 bool checkValue() override;
496 void accept(Visitor *v) override { v->visit(this); }
497 };
498
499 class ScopeExp final : public Expression
500 {
501 public:
502 ScopeDsymbol *sds;
503
504 ScopeExp *syntaxCopy() override;
505 bool checkType() override;
506 bool checkValue() override;
507 void accept(Visitor *v) override { v->visit(this); }
508 };
509
510 class TemplateExp final : public Expression
511 {
512 public:
513 TemplateDeclaration *td;
514 FuncDeclaration *fd;
515
516 bool isLvalue() override;
517 Expression *toLvalue(Scope *sc, Expression *e) override;
518 bool checkType() override;
519 bool checkValue() override;
520 void accept(Visitor *v) override { v->visit(this); }
521 };
522
523 class NewExp final : public Expression
524 {
525 public:
526 /* newtype(arguments)
527 */
528 Expression *thisexp; // if !NULL, 'this' for class being allocated
529 Type *newtype;
530 Expressions *arguments; // Array of Expression's
531
532 Expression *argprefix; // expression to be evaluated just before arguments[]
533
534 CtorDeclaration *member; // constructor function
535 bool onstack; // allocate on stack
536 bool thrownew; // this NewExp is the expression of a ThrowStatement
537
538 static NewExp *create(const Loc &loc, Expression *thisexp, Type *newtype, Expressions *arguments);
539 NewExp *syntaxCopy() override;
540
541 void accept(Visitor *v) override { v->visit(this); }
542 };
543
544 class NewAnonClassExp final : public Expression
545 {
546 public:
547 /* class baseclasses { } (arguments)
548 */
549 Expression *thisexp; // if !NULL, 'this' for class being allocated
550 ClassDeclaration *cd; // class being instantiated
551 Expressions *arguments; // Array of Expression's to call class constructor
552
553 NewAnonClassExp *syntaxCopy() override;
554 void accept(Visitor *v) override { v->visit(this); }
555 };
556
557 class SymbolExp : public Expression
558 {
559 public:
560 Declaration *var;
561 Dsymbol *originalScope;
562 bool hasOverloads;
563
564 void accept(Visitor *v) override { v->visit(this); }
565 };
566
567 // Offset from symbol
568
569 class SymOffExp final : public SymbolExp
570 {
571 public:
572 dinteger_t offset;
573
574 Optional<bool> toBool() override;
575
576 void accept(Visitor *v) override { v->visit(this); }
577 };
578
579 // Variable
580
581 class VarExp final : public SymbolExp
582 {
583 public:
584 bool delegateWasExtracted;
585 static VarExp *create(const Loc &loc, Declaration *var, bool hasOverloads = true);
586 bool equals(const RootObject *o) const override;
587 bool isLvalue() override;
588 Expression *toLvalue(Scope *sc, Expression *e) override;
589 Expression *modifiableLvalue(Scope *sc, Expression *e) override;
590
591 void accept(Visitor *v) override { v->visit(this); }
592 };
593
594 // Overload Set
595
596 class OverExp final : public Expression
597 {
598 public:
599 OverloadSet *vars;
600
601 bool isLvalue() override;
602 Expression *toLvalue(Scope *sc, Expression *e) override;
603 void accept(Visitor *v) override { v->visit(this); }
604 };
605
606 // Function/Delegate literal
607
608 class FuncExp final : public Expression
609 {
610 public:
611 FuncLiteralDeclaration *fd;
612 TemplateDeclaration *td;
613 TOK tok;
614
615 bool equals(const RootObject *o) const override;
616 FuncExp *syntaxCopy() override;
617 const char *toChars() const override;
618 bool checkType() override;
619 bool checkValue() override;
620
621 void accept(Visitor *v) override { v->visit(this); }
622 };
623
624 // Declaration of a symbol
625
626 // D grammar allows declarations only as statements. However in AST representation
627 // it can be part of any expression. This is used, for example, during internal
628 // syntax re-writes to inject hidden symbols.
629 class DeclarationExp final : public Expression
630 {
631 public:
632 Dsymbol *declaration;
633
634 DeclarationExp *syntaxCopy() override;
635
636 bool hasCode() override;
637
638 void accept(Visitor *v) override { v->visit(this); }
639 };
640
641 class TypeidExp final : public Expression
642 {
643 public:
644 RootObject *obj;
645
646 TypeidExp *syntaxCopy() override;
647 void accept(Visitor *v) override { v->visit(this); }
648 };
649
650 class TraitsExp final : public Expression
651 {
652 public:
653 Identifier *ident;
654 Objects *args;
655
656 TraitsExp *syntaxCopy() override;
657 void accept(Visitor *v) override { v->visit(this); }
658 };
659
660 class HaltExp final : public Expression
661 {
662 public:
663 void accept(Visitor *v) override { v->visit(this); }
664 };
665
666 class IsExp final : public Expression
667 {
668 public:
669 /* is(targ id tok tspec)
670 * is(targ id == tok2)
671 */
672 Type *targ;
673 Identifier *id; // can be NULL
674 Type *tspec; // can be NULL
675 TemplateParameters *parameters;
676 TOK tok; // ':' or '=='
677 TOK tok2; // 'struct', 'union', etc.
678
679 IsExp *syntaxCopy() override;
680 void accept(Visitor *v) override { v->visit(this); }
681 };
682
683 /****************************************************************/
684
685 class UnaExp : public Expression
686 {
687 public:
688 Expression *e1;
689 Type *att1; // Save alias this type to detect recursion
690
691 UnaExp *syntaxCopy() override;
692 Expression *incompatibleTypes();
693 Expression *resolveLoc(const Loc &loc, Scope *sc) override final;
694
695 void accept(Visitor *v) override { v->visit(this); }
696 };
697
698 class BinExp : public Expression
699 {
700 public:
701 Expression *e1;
702 Expression *e2;
703
704 Type *att1; // Save alias this type to detect recursion
705 Type *att2; // Save alias this type to detect recursion
706
707 BinExp *syntaxCopy() override;
708 Expression *incompatibleTypes();
709
710 Expression *reorderSettingAAElem(Scope *sc);
711
712 void accept(Visitor *v) override { v->visit(this); }
713 };
714
715 class BinAssignExp : public BinExp
716 {
717 public:
718 bool isLvalue() override final;
719 Expression *toLvalue(Scope *sc, Expression *ex) override final;
720 Expression *modifiableLvalue(Scope *sc, Expression *e) override final;
721 void accept(Visitor *v) override { v->visit(this); }
722 };
723
724 /****************************************************************/
725
726 class MixinExp final : public UnaExp
727 {
728 public:
729 void accept(Visitor *v) override { v->visit(this); }
730 };
731
732 class ImportExp final : public UnaExp
733 {
734 public:
735 void accept(Visitor *v) override { v->visit(this); }
736 };
737
738 class AssertExp final : public UnaExp
739 {
740 public:
741 Expression *msg;
742
743 AssertExp *syntaxCopy() override;
744
745 void accept(Visitor *v) override { v->visit(this); }
746 };
747
748 class ThrowExp final : public UnaExp
749 {
750 public:
751 ThrowExp *syntaxCopy() override;
752
753 void accept(Visitor *v) override { v->visit(this); }
754 };
755
756 class DotIdExp final : public UnaExp
757 {
758 public:
759 Identifier *ident;
760 bool noderef; // true if the result of the expression will never be dereferenced
761 bool wantsym; // do not replace Symbol with its initializer during semantic()
762 bool arrow; // ImportC: if -> instead of .
763
764 static DotIdExp *create(const Loc &loc, Expression *e, Identifier *ident);
765 void accept(Visitor *v) override { v->visit(this); }
766 };
767
768 class DotTemplateExp final : public UnaExp
769 {
770 public:
771 TemplateDeclaration *td;
772
773 bool checkType() override;
774 bool checkValue() override;
775 void accept(Visitor *v) override { v->visit(this); }
776 };
777
778 class DotVarExp final : public UnaExp
779 {
780 public:
781 Declaration *var;
782 bool hasOverloads;
783
784 bool isLvalue() override;
785 Expression *toLvalue(Scope *sc, Expression *e) override;
786 Expression *modifiableLvalue(Scope *sc, Expression *e) override;
787 void accept(Visitor *v) override { v->visit(this); }
788 };
789
790 class DotTemplateInstanceExp final : public UnaExp
791 {
792 public:
793 TemplateInstance *ti;
794
795 DotTemplateInstanceExp *syntaxCopy() override;
796 bool findTempDecl(Scope *sc);
797 bool checkType() override;
798 bool checkValue() override;
799 void accept(Visitor *v) override { v->visit(this); }
800 };
801
802 class DelegateExp final : public UnaExp
803 {
804 public:
805 FuncDeclaration *func;
806 bool hasOverloads;
807 VarDeclaration *vthis2; // container for multi-context
808
809
810 void accept(Visitor *v) override { v->visit(this); }
811 };
812
813 class DotTypeExp final : public UnaExp
814 {
815 public:
816 Dsymbol *sym; // symbol that represents a type
817
818 void accept(Visitor *v) override { v->visit(this); }
819 };
820
821 class CallExp final : public UnaExp
822 {
823 public:
824 Expressions *arguments; // function arguments
825 FuncDeclaration *f; // symbol to call
826 bool directcall; // true if a virtual call is devirtualized
827 bool inDebugStatement; // true if this was in a debug statement
828 bool ignoreAttributes; // don't enforce attributes (e.g. call @gc function in @nogc code)
829 VarDeclaration *vthis2; // container for multi-context
830
831 static CallExp *create(const Loc &loc, Expression *e, Expressions *exps);
832 static CallExp *create(const Loc &loc, Expression *e);
833 static CallExp *create(const Loc &loc, Expression *e, Expression *earg1);
834 static CallExp *create(const Loc &loc, FuncDeclaration *fd, Expression *earg1);
835
836 CallExp *syntaxCopy() override;
837 bool isLvalue() override;
838 Expression *toLvalue(Scope *sc, Expression *e) override;
839 Expression *addDtorHook(Scope *sc) override;
840
841 void accept(Visitor *v) override { v->visit(this); }
842 };
843
844 class AddrExp final : public UnaExp
845 {
846 public:
847 void accept(Visitor *v) override { v->visit(this); }
848 };
849
850 class PtrExp final : public UnaExp
851 {
852 public:
853 bool isLvalue() override;
854 Expression *toLvalue(Scope *sc, Expression *e) override;
855 Expression *modifiableLvalue(Scope *sc, Expression *e) override;
856
857 void accept(Visitor *v) override { v->visit(this); }
858 };
859
860 class NegExp final : public UnaExp
861 {
862 public:
863 void accept(Visitor *v) override { v->visit(this); }
864 };
865
866 class UAddExp final : public UnaExp
867 {
868 public:
869 void accept(Visitor *v) override { v->visit(this); }
870 };
871
872 class ComExp final : public UnaExp
873 {
874 public:
875 void accept(Visitor *v) override { v->visit(this); }
876 };
877
878 class NotExp final : public UnaExp
879 {
880 public:
881 void accept(Visitor *v) override { v->visit(this); }
882 };
883
884 class DeleteExp final : public UnaExp
885 {
886 public:
887 bool isRAII;
888 void accept(Visitor *v) override { v->visit(this); }
889 };
890
891 class CastExp final : public UnaExp
892 {
893 public:
894 // Possible to cast to one type while painting to another type
895 Type *to; // type to cast to
896 unsigned char mod; // MODxxxxx
897
898 CastExp *syntaxCopy() override;
899 bool isLvalue() override;
900 Expression *toLvalue(Scope *sc, Expression *e) override;
901
902 void accept(Visitor *v) override { v->visit(this); }
903 };
904
905 class VectorExp final : public UnaExp
906 {
907 public:
908 TypeVector *to; // the target vector type before semantic()
909 unsigned dim; // number of elements in the vector
910 OwnedBy ownedByCtfe;
911
912 static VectorExp *create(const Loc &loc, Expression *e, Type *t);
913 static void emplace(UnionExp *pue, const Loc &loc, Expression *e, Type *t);
914 VectorExp *syntaxCopy() override;
915 void accept(Visitor *v) override { v->visit(this); }
916 };
917
918 class VectorArrayExp final : public UnaExp
919 {
920 public:
921 bool isLvalue() override;
922 Expression *toLvalue(Scope *sc, Expression *e) override;
923 void accept(Visitor *v) override { v->visit(this); }
924 };
925
926 class SliceExp final : public UnaExp
927 {
928 public:
929 Expression *upr; // NULL if implicit 0
930 Expression *lwr; // NULL if implicit [length - 1]
931 VarDeclaration *lengthVar;
932 bool upperIsInBounds; // true if upr <= e1.length
933 bool lowerIsLessThanUpper; // true if lwr <= upr
934 bool arrayop; // an array operation, rather than a slice
935
936 SliceExp *syntaxCopy() override;
937 bool isLvalue() override;
938 Expression *toLvalue(Scope *sc, Expression *e) override;
939 Expression *modifiableLvalue(Scope *sc, Expression *e) override;
940 Optional<bool> toBool() override;
941
942 void accept(Visitor *v) override { v->visit(this); }
943 };
944
945 class ArrayLengthExp final : public UnaExp
946 {
947 public:
948 void accept(Visitor *v) override { v->visit(this); }
949 };
950
951 class IntervalExp final : public Expression
952 {
953 public:
954 Expression *lwr;
955 Expression *upr;
956
957 IntervalExp *syntaxCopy() override;
958 void accept(Visitor *v) override { v->visit(this); }
959 };
960
961 class DelegatePtrExp final : public UnaExp
962 {
963 public:
964 bool isLvalue() override;
965 Expression *toLvalue(Scope *sc, Expression *e) override;
966 Expression *modifiableLvalue(Scope *sc, Expression *e) override;
967 void accept(Visitor *v) override { v->visit(this); }
968 };
969
970 class DelegateFuncptrExp final : public UnaExp
971 {
972 public:
973 bool isLvalue() override;
974 Expression *toLvalue(Scope *sc, Expression *e) override;
975 Expression *modifiableLvalue(Scope *sc, Expression *e) override;
976 void accept(Visitor *v) override { v->visit(this); }
977 };
978
979 // e1[a0,a1,a2,a3,...]
980
981 class ArrayExp final : public UnaExp
982 {
983 public:
984 Expressions *arguments; // Array of Expression's
985 size_t currentDimension; // for opDollar
986 VarDeclaration *lengthVar;
987
988 ArrayExp *syntaxCopy() override;
989 bool isLvalue() override;
990 Expression *toLvalue(Scope *sc, Expression *e) override;
991
992 void accept(Visitor *v) override { v->visit(this); }
993 };
994
995 /****************************************************************/
996
997 class DotExp final : public BinExp
998 {
999 public:
1000 void accept(Visitor *v) override { v->visit(this); }
1001 };
1002
1003 class CommaExp final : public BinExp
1004 {
1005 public:
1006 bool isGenerated;
1007 bool allowCommaExp;
1008 bool isLvalue() override;
1009 Expression *toLvalue(Scope *sc, Expression *e) override;
1010 Expression *modifiableLvalue(Scope *sc, Expression *e) override;
1011 Optional<bool> toBool() override;
1012 Expression *addDtorHook(Scope *sc) override;
1013 void accept(Visitor *v) override { v->visit(this); }
1014 };
1015
1016 class IndexExp final : public BinExp
1017 {
1018 public:
1019 VarDeclaration *lengthVar;
1020 bool modifiable;
1021 bool indexIsInBounds; // true if 0 <= e2 && e2 <= e1.length - 1
1022
1023 IndexExp *syntaxCopy() override;
1024 bool isLvalue() override;
1025 Expression *toLvalue(Scope *sc, Expression *e) override;
1026 Expression *modifiableLvalue(Scope *sc, Expression *e) override;
1027
1028 void accept(Visitor *v) override { v->visit(this); }
1029 };
1030
1031 /* For both i++ and i--
1032 */
1033 class PostExp final : public BinExp
1034 {
1035 public:
1036 void accept(Visitor *v) override { v->visit(this); }
1037 };
1038
1039 /* For both ++i and --i
1040 */
1041 class PreExp final : public UnaExp
1042 {
1043 public:
1044 void accept(Visitor *v) override { v->visit(this); }
1045 };
1046
1047 enum class MemorySet
1048 {
1049 none = 0, // simple assignment
1050 blockAssign = 1, // setting the contents of an array
1051 referenceInit = 2 // setting the reference of STCref variable
1052 };
1053
1054 class AssignExp : public BinExp
1055 {
1056 public:
1057 MemorySet memset;
1058
1059 bool isLvalue() override final;
1060 Expression *toLvalue(Scope *sc, Expression *ex) override final;
1061
1062 void accept(Visitor *v) override { v->visit(this); }
1063 };
1064
1065 class ConstructExp final : public AssignExp
1066 {
1067 public:
1068 void accept(Visitor *v) override { v->visit(this); }
1069 };
1070
1071 class BlitExp final : public AssignExp
1072 {
1073 public:
1074 void accept(Visitor *v) override { v->visit(this); }
1075 };
1076
1077 class AddAssignExp final : public BinAssignExp
1078 {
1079 public:
1080 void accept(Visitor *v) override { v->visit(this); }
1081 };
1082
1083 class MinAssignExp final : public BinAssignExp
1084 {
1085 public:
1086 void accept(Visitor *v) override { v->visit(this); }
1087 };
1088
1089 class MulAssignExp final : public BinAssignExp
1090 {
1091 public:
1092 void accept(Visitor *v) override { v->visit(this); }
1093 };
1094
1095 class DivAssignExp final : public BinAssignExp
1096 {
1097 public:
1098 void accept(Visitor *v) override { v->visit(this); }
1099 };
1100
1101 class ModAssignExp final : public BinAssignExp
1102 {
1103 public:
1104 void accept(Visitor *v) override { v->visit(this); }
1105 };
1106
1107 class AndAssignExp final : public BinAssignExp
1108 {
1109 public:
1110 void accept(Visitor *v) override { v->visit(this); }
1111 };
1112
1113 class OrAssignExp final : public BinAssignExp
1114 {
1115 public:
1116 void accept(Visitor *v) override { v->visit(this); }
1117 };
1118
1119 class XorAssignExp final : public BinAssignExp
1120 {
1121 public:
1122 void accept(Visitor *v) override { v->visit(this); }
1123 };
1124
1125 class PowAssignExp final : public BinAssignExp
1126 {
1127 public:
1128 void accept(Visitor *v) override { v->visit(this); }
1129 };
1130
1131 class ShlAssignExp final : public BinAssignExp
1132 {
1133 public:
1134 void accept(Visitor *v) override { v->visit(this); }
1135 };
1136
1137 class ShrAssignExp final : public BinAssignExp
1138 {
1139 public:
1140 void accept(Visitor *v) override { v->visit(this); }
1141 };
1142
1143 class UshrAssignExp final : public BinAssignExp
1144 {
1145 public:
1146 void accept(Visitor *v) override { v->visit(this); }
1147 };
1148
1149 class CatAssignExp : public BinAssignExp
1150 {
1151 public:
1152 void accept(Visitor *v) override { v->visit(this); }
1153 };
1154
1155 class CatElemAssignExp final : public CatAssignExp
1156 {
1157 public:
1158 void accept(Visitor *v) override { v->visit(this); }
1159 };
1160
1161 class CatDcharAssignExp final : public CatAssignExp
1162 {
1163 public:
1164 void accept(Visitor *v) override { v->visit(this); }
1165 };
1166
1167 class AddExp final : public BinExp
1168 {
1169 public:
1170 void accept(Visitor *v) override { v->visit(this); }
1171 };
1172
1173 class MinExp final : public BinExp
1174 {
1175 public:
1176 void accept(Visitor *v) override { v->visit(this); }
1177 };
1178
1179 class CatExp final : public BinExp
1180 {
1181 public:
1182 void accept(Visitor *v) override { v->visit(this); }
1183 };
1184
1185 class MulExp final : public BinExp
1186 {
1187 public:
1188 void accept(Visitor *v) override { v->visit(this); }
1189 };
1190
1191 class DivExp final : public BinExp
1192 {
1193 public:
1194 void accept(Visitor *v) override { v->visit(this); }
1195 };
1196
1197 class ModExp final : public BinExp
1198 {
1199 public:
1200 void accept(Visitor *v) override { v->visit(this); }
1201 };
1202
1203 class PowExp final : public BinExp
1204 {
1205 public:
1206 void accept(Visitor *v) override { v->visit(this); }
1207 };
1208
1209 class ShlExp final : public BinExp
1210 {
1211 public:
1212 void accept(Visitor *v) override { v->visit(this); }
1213 };
1214
1215 class ShrExp final : public BinExp
1216 {
1217 public:
1218 void accept(Visitor *v) override { v->visit(this); }
1219 };
1220
1221 class UshrExp final : public BinExp
1222 {
1223 public:
1224 void accept(Visitor *v) override { v->visit(this); }
1225 };
1226
1227 class AndExp final : public BinExp
1228 {
1229 public:
1230 void accept(Visitor *v) override { v->visit(this); }
1231 };
1232
1233 class OrExp final : public BinExp
1234 {
1235 public:
1236 void accept(Visitor *v) override { v->visit(this); }
1237 };
1238
1239 class XorExp final : public BinExp
1240 {
1241 public:
1242 void accept(Visitor *v) override { v->visit(this); }
1243 };
1244
1245 class LogicalExp final : public BinExp
1246 {
1247 public:
1248 void accept(Visitor *v) override { v->visit(this); }
1249 };
1250
1251 class CmpExp final : public BinExp
1252 {
1253 public:
1254 void accept(Visitor *v) override { v->visit(this); }
1255 };
1256
1257 class InExp final : public BinExp
1258 {
1259 public:
1260 void accept(Visitor *v) override { v->visit(this); }
1261 };
1262
1263 class RemoveExp final : public BinExp
1264 {
1265 public:
1266 void accept(Visitor *v) override { v->visit(this); }
1267 };
1268
1269 // == and !=
1270
1271 class EqualExp final : public BinExp
1272 {
1273 public:
1274 void accept(Visitor *v) override { v->visit(this); }
1275 };
1276
1277 // is and !is
1278
1279 class IdentityExp final : public BinExp
1280 {
1281 public:
1282 void accept(Visitor *v) override { v->visit(this); }
1283 };
1284
1285 /****************************************************************/
1286
1287 class CondExp final : public BinExp
1288 {
1289 public:
1290 Expression *econd;
1291
1292 CondExp *syntaxCopy() override;
1293 bool isLvalue() override;
1294 Expression *toLvalue(Scope *sc, Expression *e) override;
1295 Expression *modifiableLvalue(Scope *sc, Expression *e) override;
1296 void hookDtors(Scope *sc);
1297
1298 void accept(Visitor *v) override { v->visit(this); }
1299 };
1300
1301 class GenericExp final : Expression
1302 {
1303 Expression *cntlExp;
1304 Types *types;
1305 Expressions *exps;
1306
1307 GenericExp *syntaxCopy() override;
1308
1309 void accept(Visitor *v) override { v->visit(this); }
1310 };
1311
1312 /****************************************************************/
1313
1314 class DefaultInitExp : public Expression
1315 {
1316 public:
1317 void accept(Visitor *v) override { v->visit(this); }
1318 };
1319
1320 class FileInitExp final : public DefaultInitExp
1321 {
1322 public:
1323 Expression *resolveLoc(const Loc &loc, Scope *sc) override;
1324 void accept(Visitor *v) override { v->visit(this); }
1325 };
1326
1327 class LineInitExp final : public DefaultInitExp
1328 {
1329 public:
1330 Expression *resolveLoc(const Loc &loc, Scope *sc) override;
1331 void accept(Visitor *v) override { v->visit(this); }
1332 };
1333
1334 class ModuleInitExp final : public DefaultInitExp
1335 {
1336 public:
1337 Expression *resolveLoc(const Loc &loc, Scope *sc) override;
1338 void accept(Visitor *v) override { v->visit(this); }
1339 };
1340
1341 class FuncInitExp final : public DefaultInitExp
1342 {
1343 public:
1344 Expression *resolveLoc(const Loc &loc, Scope *sc) override;
1345 void accept(Visitor *v) override { v->visit(this); }
1346 };
1347
1348 class PrettyFuncInitExp final : public DefaultInitExp
1349 {
1350 public:
1351 Expression *resolveLoc(const Loc &loc, Scope *sc) override;
1352 void accept(Visitor *v) override { v->visit(this); }
1353 };
1354
1355 /****************************************************************/
1356
1357 /* A type meant as a union of all the Expression types,
1358 * to serve essentially as a Variant that will sit on the stack
1359 * during CTFE to reduce memory consumption.
1360 */
1361 struct UnionExp
1362 {
1363 UnionExp() { } // yes, default constructor does nothing
1364
1365 UnionExp(Expression *e)
1366 {
1367 memcpy(this, (void *)e, e->size);
1368 }
1369
1370 /* Extract pointer to Expression
1371 */
1372 Expression *exp() { return (Expression *)&u; }
1373
1374 /* Convert to an allocated Expression
1375 */
1376 Expression *copy();
1377
1378 private:
1379 // Ensure that the union is suitably aligned.
1380 #if defined(__GNUC__) || defined(__clang__)
1381 __attribute__((aligned(8)))
1382 #elif defined(_MSC_VER)
1383 __declspec(align(8))
1384 #elif defined(__DMC__)
1385 #pragma pack(8)
1386 #endif
1387 union
1388 {
1389 char exp [sizeof(Expression)];
1390 char integerexp[sizeof(IntegerExp)];
1391 char errorexp [sizeof(ErrorExp)];
1392 char realexp [sizeof(RealExp)];
1393 char complexexp[sizeof(ComplexExp)];
1394 char symoffexp [sizeof(SymOffExp)];
1395 char stringexp [sizeof(StringExp)];
1396 char arrayliteralexp [sizeof(ArrayLiteralExp)];
1397 char assocarrayliteralexp [sizeof(AssocArrayLiteralExp)];
1398 char structliteralexp [sizeof(StructLiteralExp)];
1399 char nullexp [sizeof(NullExp)];
1400 char dotvarexp [sizeof(DotVarExp)];
1401 char addrexp [sizeof(AddrExp)];
1402 char indexexp [sizeof(IndexExp)];
1403 char sliceexp [sizeof(SliceExp)];
1404 char vectorexp [sizeof(VectorExp)];
1405 } u;
1406 #if defined(__DMC__)
1407 #pragma pack()
1408 #endif
1409 };
1410
1411 /****************************************************************/
1412
1413 class ObjcClassReferenceExp final : public Expression
1414 {
1415 public:
1416 ClassDeclaration* classDeclaration;
1417
1418 void accept(Visitor *v) override { v->visit(this); }
1419 };
This page took 0.093347 seconds and 4 git commands to generate.