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