1 2 /* Compiler implementation of the D programming language 3 * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved 4 * written by Walter Bright 5 * http://www.digitalmars.com 6 * Distributed under the Boost Software License, Version 1.0. 7 * http://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 "complex_t.h" 14 #include "globals.h" 15 #include "identifier.h" 16 #include "arraytypes.h" 17 #include "intrange.h" 18 #include "visitor.h" 19 #include "tokens.h" 20 21 #include "root/rmem.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 Declaration; 31 class CtorDeclaration; 32 class NewDeclaration; 33 class Dsymbol; 34 class Import; 35 class Module; 36 class ScopeDsymbol; 37 class Expression; 38 class Declaration; 39 class AggregateDeclaration; 40 class StructDeclaration; 41 class TemplateInstance; 42 class TemplateDeclaration; 43 class ClassDeclaration; 44 class BinExp; 45 class OverloadSet; 46 class Initializer; 47 class StringExp; 48 class ArrayExp; 49 class SliceExp; 50 struct UnionExp; 51 #ifdef IN_GCC 52 typedef union tree_node Symbol; 53 #else 54 struct Symbol; // back end symbol 55 #endif 56 57 Expression *resolveProperties(Scope *sc, Expression *e); 58 Expression *resolvePropertiesOnly(Scope *sc, Expression *e1); 59 bool checkAccess(Loc loc, Scope *sc, Expression *e, Declaration *d); 60 bool checkAccess(Loc loc, Scope *sc, Package *p); 61 Expression *build_overload(Loc loc, Scope *sc, Expression *ethis, Expression *earg, Dsymbol *d); 62 Dsymbol *search_function(ScopeDsymbol *ad, Identifier *funcid); 63 void expandTuples(Expressions *exps); 64 TupleDeclaration *isAliasThisTuple(Expression *e); 65 int expandAliasThisTuples(Expressions *exps, size_t starti = 0); 66 FuncDeclaration *hasThis(Scope *sc); 67 Expression *fromConstInitializer(int result, Expression *e); 68 bool arrayExpressionSemantic(Expressions *exps, Scope *sc, bool preserveErrors = false); 69 TemplateDeclaration *getFuncTemplateDecl(Dsymbol *s); 70 Expression *valueNoDtor(Expression *e); 71 int modifyFieldVar(Loc loc, Scope *sc, VarDeclaration *var, Expression *e1); 72 Expression *resolveAliasThis(Scope *sc, Expression *e, bool gag = false); 73 Expression *doCopyOrMove(Scope *sc, Expression *e); 74 Expression *resolveOpDollar(Scope *sc, ArrayExp *ae, Expression **pe0); 75 Expression *resolveOpDollar(Scope *sc, ArrayExp *ae, IntervalExp *ie, Expression **pe0); 76 Expression *integralPromotions(Expression *e, Scope *sc); 77 bool discardValue(Expression *e); 78 bool isTrivialExp(Expression *e); 79 80 int isConst(Expression *e); 81 Expression *toDelegate(Expression *e, Type* t, Scope *sc); 82 AggregateDeclaration *isAggregate(Type *t); 83 IntRange getIntRange(Expression *e); 84 bool checkNonAssignmentArrayOp(Expression *e, bool suggestion = false); 85 bool isUnaArrayOp(TOK op); 86 bool isBinArrayOp(TOK op); 87 bool isBinAssignArrayOp(TOK op); 88 bool isArrayOpOperand(Expression *e); 89 Expression *arrayOp(BinExp *e, Scope *sc); 90 Expression *arrayOp(BinAssignExp *e, Scope *sc); 91 bool hasSideEffect(Expression *e); 92 bool canThrow(Expression *e, FuncDeclaration *func, bool mustNotThrow); 93 Expression *Expression_optimize(Expression *e, int result, bool keepLvalue); 94 MATCH implicitConvTo(Expression *e, Type *t); 95 Expression *implicitCastTo(Expression *e, Scope *sc, Type *t); 96 Expression *castTo(Expression *e, Scope *sc, Type *t); 97 Expression *ctfeInterpret(Expression *); 98 Expression *inlineCopy(Expression *e, Scope *sc); 99 Expression *op_overload(Expression *e, Scope *sc); 100 Type *toStaticArrayType(SliceExp *e); 101 Expression *scaleFactor(BinExp *be, Scope *sc); 102 Expression *typeCombine(BinExp *be, Scope *sc); 103 Expression *inferType(Expression *e, Type *t, int flag = 0); 104 Expression *semanticTraits(TraitsExp *e, Scope *sc); 105 Type *getIndirection(Type *t); 106 107 Expression *checkGC(Scope *sc, Expression *e); 108 109 /* Run CTFE on the expression, but allow the expression to be a TypeExp 110 * or a tuple containing a TypeExp. (This is required by pragma(msg)). 111 */ 112 Expression *ctfeInterpretForPragmaMsg(Expression *e); 113 114 enum OwnedBy 115 { 116 OWNEDcode, // normal code expression in AST 117 OWNEDctfe, // value expression for CTFE 118 OWNEDcache // constant value cached for CTFE 119 }; 120 121 #define WANTvalue 0 // default 122 #define WANTexpand 1 // expand const/immutable variables if possible 123 124 class Expression : public RootObject 125 { 126 public: 127 Loc loc; // file location 128 Type *type; // !=NULL means that semantic() has been run 129 TOK op; // to minimize use of dynamic_cast 130 unsigned char size; // # of bytes in Expression so we can copy() it 131 unsigned char parens; // if this is a parenthesized expression 132 133 Expression(Loc loc, TOK op, int size); 134 static void _init(); 135 Expression *copy(); 136 virtual Expression *syntaxCopy(); 137 138 // kludge for template.isExpression() dyncast()139 int dyncast() const { return DYNCAST_EXPRESSION; } 140 141 void print(); 142 const char *toChars(); 143 void error(const char *format, ...) const; 144 void warning(const char *format, ...) const; 145 void deprecation(const char *format, ...) const; 146 147 // creates a single expression which is effectively (e1, e2) 148 // this new expression does not necessarily need to have valid D source code representation, 149 // for example, it may include declaration expressions 150 static Expression *combine(Expression *e1, Expression *e2); 151 static Expression *extractLast(Expression *e, Expression **pe0); 152 static Expressions *arraySyntaxCopy(Expressions *exps); 153 154 virtual dinteger_t toInteger(); 155 virtual uinteger_t toUInteger(); 156 virtual real_t toReal(); 157 virtual real_t toImaginary(); 158 virtual complex_t toComplex(); 159 virtual StringExp *toStringExp(); 160 virtual TupleExp *toTupleExp(); 161 virtual bool isLvalue(); 162 virtual Expression *toLvalue(Scope *sc, Expression *e); 163 virtual Expression *modifiableLvalue(Scope *sc, Expression *e); implicitCastTo(Scope * sc,Type * t)164 Expression *implicitCastTo(Scope *sc, Type *t) 165 { 166 return ::implicitCastTo(this, sc, t); 167 } implicitConvTo(Type * t)168 MATCH implicitConvTo(Type *t) 169 { 170 return ::implicitConvTo(this, t); 171 } castTo(Scope * sc,Type * t)172 Expression *castTo(Scope *sc, Type *t) 173 { 174 return ::castTo(this, sc, t); 175 } 176 virtual Expression *resolveLoc(Loc loc, Scope *sc); 177 virtual bool checkType(); 178 virtual bool checkValue(); 179 bool checkScalar(); 180 bool checkNoBool(); 181 bool checkIntegral(); 182 bool checkArithmetic(); 183 void checkDeprecated(Scope *sc, Dsymbol *s); 184 bool checkPurity(Scope *sc, FuncDeclaration *f); 185 bool checkPurity(Scope *sc, VarDeclaration *v); 186 bool checkSafety(Scope *sc, FuncDeclaration *f); 187 bool checkNogc(Scope *sc, FuncDeclaration *f); 188 bool checkPostblit(Scope *sc, Type *t); 189 bool checkRightThis(Scope *sc); 190 bool checkReadModifyWrite(TOK rmwOp, Expression *ex = NULL); 191 virtual int checkModifiable(Scope *sc, int flag = 0); 192 virtual Expression *toBoolean(Scope *sc); 193 virtual Expression *addDtorHook(Scope *sc); 194 Expression *addressOf(); 195 Expression *deref(); 196 197 Expression *optimize(int result, bool keepLvalue = false) 198 { 199 return Expression_optimize(this, result, keepLvalue); 200 } 201 202 // Entry point for CTFE. 203 // A compile-time result is required. Give an error if not possible ctfeInterpret()204 Expression *ctfeInterpret() 205 { 206 return ::ctfeInterpret(this); 207 } 208 isConst()209 int isConst() { return ::isConst(this); } 210 virtual bool isBool(bool result); op_overload(Scope * sc)211 Expression *op_overload(Scope *sc) 212 { 213 return ::op_overload(this, sc); 214 } 215 hasCode()216 virtual bool hasCode() 217 { 218 return true; 219 } 220 accept(Visitor * v)221 virtual void accept(Visitor *v) { v->visit(this); } 222 }; 223 224 class IntegerExp : public Expression 225 { 226 public: 227 dinteger_t value; 228 229 IntegerExp(Loc loc, dinteger_t value, Type *type); 230 IntegerExp(dinteger_t value); 231 static IntegerExp *create(Loc loc, dinteger_t value, Type *type); 232 bool equals(RootObject *o); 233 dinteger_t toInteger(); 234 real_t toReal(); 235 real_t toImaginary(); 236 complex_t toComplex(); 237 bool isBool(bool result); 238 Expression *toLvalue(Scope *sc, Expression *e); accept(Visitor * v)239 void accept(Visitor *v) { v->visit(this); } getInteger()240 dinteger_t getInteger() { return value; } 241 void setInteger(dinteger_t value); 242 void normalize(); 243 }; 244 245 class ErrorExp : public Expression 246 { 247 public: 248 ErrorExp(); 249 Expression *toLvalue(Scope *sc, Expression *e); accept(Visitor * v)250 void accept(Visitor *v) { v->visit(this); } 251 252 static ErrorExp *errorexp; // handy shared value 253 }; 254 255 class RealExp : public Expression 256 { 257 public: 258 real_t value; 259 260 RealExp(Loc loc, real_t value, Type *type); 261 static RealExp *create(Loc loc, real_t value, Type *type); 262 bool equals(RootObject *o); 263 dinteger_t toInteger(); 264 uinteger_t toUInteger(); 265 real_t toReal(); 266 real_t toImaginary(); 267 complex_t toComplex(); 268 bool isBool(bool result); accept(Visitor * v)269 void accept(Visitor *v) { v->visit(this); } 270 }; 271 272 class ComplexExp : public Expression 273 { 274 public: 275 complex_t value; 276 277 ComplexExp(Loc loc, complex_t value, Type *type); 278 static ComplexExp *create(Loc loc, complex_t value, Type *type); 279 bool equals(RootObject *o); 280 dinteger_t toInteger(); 281 uinteger_t toUInteger(); 282 real_t toReal(); 283 real_t toImaginary(); 284 complex_t toComplex(); 285 bool isBool(bool result); accept(Visitor * v)286 void accept(Visitor *v) { v->visit(this); } 287 }; 288 289 class IdentifierExp : public Expression 290 { 291 public: 292 Identifier *ident; 293 294 IdentifierExp(Loc loc, Identifier *ident); 295 static IdentifierExp *create(Loc loc, Identifier *ident); 296 bool isLvalue(); 297 Expression *toLvalue(Scope *sc, Expression *e); accept(Visitor * v)298 void accept(Visitor *v) { v->visit(this); } 299 }; 300 301 class DollarExp : public IdentifierExp 302 { 303 public: 304 DollarExp(Loc loc); accept(Visitor * v)305 void accept(Visitor *v) { v->visit(this); } 306 }; 307 308 class DsymbolExp : public Expression 309 { 310 public: 311 Dsymbol *s; 312 bool hasOverloads; 313 314 DsymbolExp(Loc loc, Dsymbol *s, bool hasOverloads = true); 315 bool isLvalue(); 316 Expression *toLvalue(Scope *sc, Expression *e); accept(Visitor * v)317 void accept(Visitor *v) { v->visit(this); } 318 }; 319 320 class ThisExp : public Expression 321 { 322 public: 323 VarDeclaration *var; 324 325 ThisExp(Loc loc); 326 bool isBool(bool result); 327 bool isLvalue(); 328 Expression *toLvalue(Scope *sc, Expression *e); 329 accept(Visitor * v)330 void accept(Visitor *v) { v->visit(this); } 331 }; 332 333 class SuperExp : public ThisExp 334 { 335 public: 336 SuperExp(Loc loc); 337 accept(Visitor * v)338 void accept(Visitor *v) { v->visit(this); } 339 }; 340 341 class NullExp : public Expression 342 { 343 public: 344 unsigned char committed; // !=0 if type is committed 345 346 NullExp(Loc loc, Type *t = NULL); 347 bool equals(RootObject *o); 348 bool isBool(bool result); 349 StringExp *toStringExp(); accept(Visitor * v)350 void accept(Visitor *v) { v->visit(this); } 351 }; 352 353 class StringExp : public Expression 354 { 355 public: 356 void *string; // char, wchar, or dchar data 357 size_t len; // number of chars, wchars, or dchars 358 unsigned char sz; // 1: char, 2: wchar, 4: dchar 359 unsigned char committed; // !=0 if type is committed 360 utf8_t postfix; // 'c', 'w', 'd' 361 OwnedBy ownedByCtfe; 362 363 StringExp(Loc loc, char *s); 364 StringExp(Loc loc, void *s, size_t len); 365 StringExp(Loc loc, void *s, size_t len, utf8_t postfix); 366 static StringExp *create(Loc loc, char *s); 367 static StringExp *create(Loc loc, void *s, size_t len); 368 bool equals(RootObject *o); 369 StringExp *toStringExp(); 370 StringExp *toUTF8(Scope *sc); 371 int compare(RootObject *obj); 372 bool isBool(bool result); 373 bool isLvalue(); 374 Expression *toLvalue(Scope *sc, Expression *e); 375 Expression *modifiableLvalue(Scope *sc, Expression *e); 376 unsigned charAt(uinteger_t i) const; accept(Visitor * v)377 void accept(Visitor *v) { v->visit(this); } 378 size_t numberOfCodeUnits(int tynto = 0) const; 379 void writeTo(void* dest, bool zero, int tyto = 0) const; 380 char *toPtr(); 381 }; 382 383 // Tuple 384 385 class TupleExp : public Expression 386 { 387 public: 388 Expression *e0; // side-effect part 389 /* Tuple-field access may need to take out its side effect part. 390 * For example: 391 * foo().tupleof 392 * is rewritten as: 393 * (ref __tup = foo(); tuple(__tup.field0, __tup.field1, ...)) 394 * The declaration of temporary variable __tup will be stored in TupleExp::e0. 395 */ 396 Expressions *exps; 397 398 TupleExp(Loc loc, Expression *e0, Expressions *exps); 399 TupleExp(Loc loc, Expressions *exps); 400 TupleExp(Loc loc, TupleDeclaration *tup); 401 TupleExp *toTupleExp(); 402 Expression *syntaxCopy(); 403 bool equals(RootObject *o); 404 accept(Visitor * v)405 void accept(Visitor *v) { v->visit(this); } 406 }; 407 408 class ArrayLiteralExp : public Expression 409 { 410 public: 411 Expression *basis; 412 Expressions *elements; 413 OwnedBy ownedByCtfe; 414 415 ArrayLiteralExp(Loc loc, Type *type, Expressions *elements); 416 ArrayLiteralExp(Loc loc, Type *type, Expression *e); 417 ArrayLiteralExp(Loc loc, Type *type, Expression *basis, Expressions *elements); 418 static ArrayLiteralExp *create(Loc loc, Expressions *elements); 419 Expression *syntaxCopy(); 420 bool equals(RootObject *o); 421 Expression *getElement(d_size_t i); 422 static Expressions* copyElements(Expression *e1, Expression *e2 = NULL); 423 bool isBool(bool result); 424 StringExp *toStringExp(); 425 accept(Visitor * v)426 void accept(Visitor *v) { v->visit(this); } 427 }; 428 429 class AssocArrayLiteralExp : public Expression 430 { 431 public: 432 Expressions *keys; 433 Expressions *values; 434 OwnedBy ownedByCtfe; 435 436 AssocArrayLiteralExp(Loc loc, Expressions *keys, Expressions *values); 437 bool equals(RootObject *o); 438 Expression *syntaxCopy(); 439 bool isBool(bool result); 440 accept(Visitor * v)441 void accept(Visitor *v) { v->visit(this); } 442 }; 443 444 // scrubReturnValue is running 445 #define stageScrub 0x1 446 // hasNonConstPointers is running 447 #define stageSearchPointers 0x2 448 // optimize is running 449 #define stageOptimize 0x4 450 // apply is running 451 #define stageApply 0x8 452 //inlineScan is running 453 #define stageInlineScan 0x10 454 // toCBuffer is running 455 #define stageToCBuffer 0x20 456 457 class StructLiteralExp : public Expression 458 { 459 public: 460 StructDeclaration *sd; // which aggregate this is for 461 Expressions *elements; // parallels sd->fields[] with NULL entries for fields to skip 462 Type *stype; // final type of result (can be different from sd's type) 463 464 bool useStaticInit; // if this is true, use the StructDeclaration's init symbol 465 Symbol *sym; // back end symbol to initialize with literal 466 467 OwnedBy ownedByCtfe; 468 469 // pointer to the origin instance of the expression. 470 // once a new expression is created, origin is set to 'this'. 471 // anytime when an expression copy is created, 'origin' pointer is set to 472 // 'origin' pointer value of the original expression. 473 StructLiteralExp *origin; 474 475 // those fields need to prevent a infinite recursion when one field of struct initialized with 'this' pointer. 476 StructLiteralExp *inlinecopy; 477 478 // anytime when recursive function is calling, 'stageflags' marks with bit flag of 479 // current stage and unmarks before return from this function. 480 // 'inlinecopy' uses similar 'stageflags' and from multiple evaluation 'doInline' 481 // (with infinite recursion) of this expression. 482 int stageflags; 483 484 StructLiteralExp(Loc loc, StructDeclaration *sd, Expressions *elements, Type *stype = NULL); 485 static StructLiteralExp *create(Loc loc, StructDeclaration *sd, void *elements, Type *stype = NULL); 486 bool equals(RootObject *o); 487 Expression *syntaxCopy(); 488 Expression *getField(Type *type, unsigned offset); 489 int getFieldIndex(Type *type, unsigned offset); 490 Expression *addDtorHook(Scope *sc); 491 accept(Visitor * v)492 void accept(Visitor *v) { v->visit(this); } 493 }; 494 495 class DotIdExp; 496 DotIdExp *typeDotIdExp(Loc loc, Type *type, Identifier *ident); 497 498 class TypeExp : public Expression 499 { 500 public: 501 TypeExp(Loc loc, Type *type); 502 Expression *syntaxCopy(); 503 bool checkType(); 504 bool checkValue(); accept(Visitor * v)505 void accept(Visitor *v) { v->visit(this); } 506 }; 507 508 class ScopeExp : public Expression 509 { 510 public: 511 ScopeDsymbol *sds; 512 513 ScopeExp(Loc loc, ScopeDsymbol *sds); 514 Expression *syntaxCopy(); 515 bool checkType(); 516 bool checkValue(); accept(Visitor * v)517 void accept(Visitor *v) { v->visit(this); } 518 }; 519 520 class TemplateExp : public Expression 521 { 522 public: 523 TemplateDeclaration *td; 524 FuncDeclaration *fd; 525 526 TemplateExp(Loc loc, TemplateDeclaration *td, FuncDeclaration *fd = NULL); 527 bool isLvalue(); 528 Expression *toLvalue(Scope *sc, Expression *e); 529 bool checkType(); 530 bool checkValue(); accept(Visitor * v)531 void accept(Visitor *v) { v->visit(this); } 532 }; 533 534 class NewExp : public Expression 535 { 536 public: 537 /* thisexp.new(newargs) newtype(arguments) 538 */ 539 Expression *thisexp; // if !NULL, 'this' for class being allocated 540 Expressions *newargs; // Array of Expression's to call new operator 541 Type *newtype; 542 Expressions *arguments; // Array of Expression's 543 544 Expression *argprefix; // expression to be evaluated just before arguments[] 545 546 CtorDeclaration *member; // constructor function 547 NewDeclaration *allocator; // allocator function 548 int onstack; // allocate on stack 549 550 NewExp(Loc loc, Expression *thisexp, Expressions *newargs, 551 Type *newtype, Expressions *arguments); 552 static NewExp *create(Loc loc, Expression *thisexp, Expressions *newargs, Type *newtype, Expressions *arguments); 553 Expression *syntaxCopy(); 554 accept(Visitor * v)555 void accept(Visitor *v) { v->visit(this); } 556 }; 557 558 class NewAnonClassExp : public Expression 559 { 560 public: 561 /* thisexp.new(newargs) class baseclasses { } (arguments) 562 */ 563 Expression *thisexp; // if !NULL, 'this' for class being allocated 564 Expressions *newargs; // Array of Expression's to call new operator 565 ClassDeclaration *cd; // class being instantiated 566 Expressions *arguments; // Array of Expression's to call class constructor 567 568 NewAnonClassExp(Loc loc, Expression *thisexp, Expressions *newargs, 569 ClassDeclaration *cd, Expressions *arguments); 570 Expression *syntaxCopy(); accept(Visitor * v)571 void accept(Visitor *v) { v->visit(this); } 572 }; 573 574 class SymbolExp : public Expression 575 { 576 public: 577 Declaration *var; 578 bool hasOverloads; 579 SymbolExp(Loc loc, TOK op, int size, Declaration *var, bool hasOverloads); 580 accept(Visitor * v)581 void accept(Visitor *v) { v->visit(this); } 582 }; 583 584 // Offset from symbol 585 586 class SymOffExp : public SymbolExp 587 { 588 public: 589 dinteger_t offset; 590 591 SymOffExp(Loc loc, Declaration *var, dinteger_t offset, bool hasOverloads = true); 592 bool isBool(bool result); 593 accept(Visitor * v)594 void accept(Visitor *v) { v->visit(this); } 595 }; 596 597 // Variable 598 599 class VarExp : public SymbolExp 600 { 601 public: 602 VarExp(Loc loc, Declaration *var, bool hasOverloads = true); 603 static VarExp *create(Loc loc, Declaration *var, bool hasOverloads = true); 604 bool equals(RootObject *o); 605 int checkModifiable(Scope *sc, int flag); 606 bool checkReadModifyWrite(); 607 bool isLvalue(); 608 Expression *toLvalue(Scope *sc, Expression *e); 609 Expression *modifiableLvalue(Scope *sc, Expression *e); 610 accept(Visitor * v)611 void accept(Visitor *v) { v->visit(this); } 612 }; 613 614 // Overload Set 615 616 class OverExp : public Expression 617 { 618 public: 619 OverloadSet *vars; 620 621 OverExp(Loc loc, OverloadSet *s); 622 bool isLvalue(); 623 Expression *toLvalue(Scope *sc, Expression *e); accept(Visitor * v)624 void accept(Visitor *v) { v->visit(this); } 625 }; 626 627 // Function/Delegate literal 628 629 class FuncExp : public Expression 630 { 631 public: 632 FuncLiteralDeclaration *fd; 633 TemplateDeclaration *td; 634 TOK tok; 635 636 FuncExp(Loc loc, Dsymbol *s); 637 bool equals(RootObject *o); 638 void genIdent(Scope *sc); 639 Expression *syntaxCopy(); 640 MATCH matchType(Type *to, Scope *sc, FuncExp **pfe, int flag = 0); 641 const char *toChars(); 642 bool checkType(); 643 bool checkValue(); 644 accept(Visitor * v)645 void accept(Visitor *v) { v->visit(this); } 646 }; 647 648 // Declaration of a symbol 649 650 // D grammar allows declarations only as statements. However in AST representation 651 // it can be part of any expression. This is used, for example, during internal 652 // syntax re-writes to inject hidden symbols. 653 class DeclarationExp : public Expression 654 { 655 public: 656 Dsymbol *declaration; 657 658 DeclarationExp(Loc loc, Dsymbol *declaration); 659 Expression *syntaxCopy(); 660 661 bool hasCode(); 662 accept(Visitor * v)663 void accept(Visitor *v) { v->visit(this); } 664 }; 665 666 class TypeidExp : public Expression 667 { 668 public: 669 RootObject *obj; 670 671 TypeidExp(Loc loc, RootObject *obj); 672 Expression *syntaxCopy(); accept(Visitor * v)673 void accept(Visitor *v) { v->visit(this); } 674 }; 675 676 class TraitsExp : public Expression 677 { 678 public: 679 Identifier *ident; 680 Objects *args; 681 682 TraitsExp(Loc loc, Identifier *ident, Objects *args); 683 Expression *syntaxCopy(); accept(Visitor * v)684 void accept(Visitor *v) { v->visit(this); } 685 }; 686 687 class HaltExp : public Expression 688 { 689 public: 690 HaltExp(Loc loc); 691 accept(Visitor * v)692 void accept(Visitor *v) { v->visit(this); } 693 }; 694 695 class IsExp : public Expression 696 { 697 public: 698 /* is(targ id tok tspec) 699 * is(targ id == tok2) 700 */ 701 Type *targ; 702 Identifier *id; // can be NULL 703 TOK tok; // ':' or '==' 704 Type *tspec; // can be NULL 705 TOK tok2; // 'struct', 'union', etc. 706 TemplateParameters *parameters; 707 708 IsExp(Loc loc, Type *targ, Identifier *id, TOK tok, Type *tspec, 709 TOK tok2, TemplateParameters *parameters); 710 Expression *syntaxCopy(); accept(Visitor * v)711 void accept(Visitor *v) { v->visit(this); } 712 }; 713 714 /****************************************************************/ 715 716 class UnaExp : public Expression 717 { 718 public: 719 Expression *e1; 720 Type *att1; // Save alias this type to detect recursion 721 722 UnaExp(Loc loc, TOK op, int size, Expression *e1); 723 Expression *syntaxCopy(); 724 Expression *incompatibleTypes(); 725 Expression *resolveLoc(Loc loc, Scope *sc); 726 accept(Visitor * v)727 void accept(Visitor *v) { v->visit(this); } 728 }; 729 730 typedef UnionExp (*fp_t)(Loc loc, Type *, Expression *, Expression *); 731 typedef int (*fp2_t)(Loc loc, TOK, Expression *, Expression *); 732 733 class BinExp : public Expression 734 { 735 public: 736 Expression *e1; 737 Expression *e2; 738 739 Type *att1; // Save alias this type to detect recursion 740 Type *att2; // Save alias this type to detect recursion 741 742 BinExp(Loc loc, TOK op, int size, Expression *e1, Expression *e2); 743 Expression *syntaxCopy(); 744 Expression *incompatibleTypes(); 745 Expression *checkOpAssignTypes(Scope *sc); 746 bool checkIntegralBin(); 747 bool checkArithmeticBin(); 748 749 Expression *reorderSettingAAElem(Scope *sc); 750 accept(Visitor * v)751 void accept(Visitor *v) { v->visit(this); } 752 }; 753 754 class BinAssignExp : public BinExp 755 { 756 public: 757 BinAssignExp(Loc loc, TOK op, int size, Expression *e1, Expression *e2); 758 759 bool isLvalue(); 760 Expression *toLvalue(Scope *sc, Expression *ex); 761 Expression *modifiableLvalue(Scope *sc, Expression *e); accept(Visitor * v)762 void accept(Visitor *v) { v->visit(this); } 763 }; 764 765 /****************************************************************/ 766 767 class CompileExp : public UnaExp 768 { 769 public: 770 CompileExp(Loc loc, Expression *e); accept(Visitor * v)771 void accept(Visitor *v) { v->visit(this); } 772 }; 773 774 class ImportExp : public UnaExp 775 { 776 public: 777 ImportExp(Loc loc, Expression *e); accept(Visitor * v)778 void accept(Visitor *v) { v->visit(this); } 779 }; 780 781 class AssertExp : public UnaExp 782 { 783 public: 784 Expression *msg; 785 786 AssertExp(Loc loc, Expression *e, Expression *msg = NULL); 787 Expression *syntaxCopy(); 788 accept(Visitor * v)789 void accept(Visitor *v) { v->visit(this); } 790 }; 791 792 class DotIdExp : public UnaExp 793 { 794 public: 795 Identifier *ident; 796 bool noderef; // true if the result of the expression will never be dereferenced 797 bool wantsym; // do not replace Symbol with its initializer during semantic() 798 799 DotIdExp(Loc loc, Expression *e, Identifier *ident); 800 static DotIdExp *create(Loc loc, Expression *e, Identifier *ident); accept(Visitor * v)801 void accept(Visitor *v) { v->visit(this); } 802 }; 803 804 class DotTemplateExp : public UnaExp 805 { 806 public: 807 TemplateDeclaration *td; 808 809 DotTemplateExp(Loc loc, Expression *e, TemplateDeclaration *td); 810 bool checkType(); 811 bool checkValue(); accept(Visitor * v)812 void accept(Visitor *v) { v->visit(this); } 813 }; 814 815 class DotVarExp : public UnaExp 816 { 817 public: 818 Declaration *var; 819 bool hasOverloads; 820 821 DotVarExp(Loc loc, Expression *e, Declaration *var, bool hasOverloads = true); 822 int checkModifiable(Scope *sc, int flag); 823 bool checkReadModifyWrite(); 824 bool isLvalue(); 825 Expression *toLvalue(Scope *sc, Expression *e); 826 Expression *modifiableLvalue(Scope *sc, Expression *e); accept(Visitor * v)827 void accept(Visitor *v) { v->visit(this); } 828 }; 829 830 class DotTemplateInstanceExp : public UnaExp 831 { 832 public: 833 TemplateInstance *ti; 834 835 DotTemplateInstanceExp(Loc loc, Expression *e, Identifier *name, Objects *tiargs); 836 DotTemplateInstanceExp(Loc loc, Expression *e, TemplateInstance *ti); 837 Expression *syntaxCopy(); 838 bool findTempDecl(Scope *sc); accept(Visitor * v)839 void accept(Visitor *v) { v->visit(this); } 840 }; 841 842 class DelegateExp : public UnaExp 843 { 844 public: 845 FuncDeclaration *func; 846 bool hasOverloads; 847 848 DelegateExp(Loc loc, Expression *e, FuncDeclaration *func, bool hasOverloads = true); 849 accept(Visitor * v)850 void accept(Visitor *v) { v->visit(this); } 851 }; 852 853 class DotTypeExp : public UnaExp 854 { 855 public: 856 Dsymbol *sym; // symbol that represents a type 857 858 DotTypeExp(Loc loc, Expression *e, Dsymbol *sym); accept(Visitor * v)859 void accept(Visitor *v) { v->visit(this); } 860 }; 861 862 class CallExp : public UnaExp 863 { 864 public: 865 Expressions *arguments; // function arguments 866 FuncDeclaration *f; // symbol to call 867 bool directcall; // true if a virtual call is devirtualized 868 CallExp(Loc loc, Expression *e, Expressions *exps); 869 CallExp(Loc loc, Expression *e); 870 CallExp(Loc loc, Expression *e, Expression *earg1); 871 CallExp(Loc loc, Expression *e, Expression *earg1, Expression *earg2); 872 873 static CallExp *create(Loc loc, Expression *e, Expressions *exps); 874 static CallExp *create(Loc loc, Expression *e); 875 static CallExp *create(Loc loc, Expression *e, Expression *earg1); 876 877 Expression *syntaxCopy(); 878 bool isLvalue(); 879 Expression *toLvalue(Scope *sc, Expression *e); 880 Expression *addDtorHook(Scope *sc); 881 accept(Visitor * v)882 void accept(Visitor *v) { v->visit(this); } 883 }; 884 885 class AddrExp : public UnaExp 886 { 887 public: 888 AddrExp(Loc loc, Expression *e); 889 AddrExp(Loc loc, Expression *e, Type *t); 890 accept(Visitor * v)891 void accept(Visitor *v) { v->visit(this); } 892 }; 893 894 class PtrExp : public UnaExp 895 { 896 public: 897 PtrExp(Loc loc, Expression *e); 898 PtrExp(Loc loc, Expression *e, Type *t); 899 int checkModifiable(Scope *sc, int flag); 900 bool isLvalue(); 901 Expression *toLvalue(Scope *sc, Expression *e); 902 Expression *modifiableLvalue(Scope *sc, Expression *e); 903 accept(Visitor * v)904 void accept(Visitor *v) { v->visit(this); } 905 }; 906 907 class NegExp : public UnaExp 908 { 909 public: 910 NegExp(Loc loc, Expression *e); 911 accept(Visitor * v)912 void accept(Visitor *v) { v->visit(this); } 913 }; 914 915 class UAddExp : public UnaExp 916 { 917 public: 918 UAddExp(Loc loc, Expression *e); 919 accept(Visitor * v)920 void accept(Visitor *v) { v->visit(this); } 921 }; 922 923 class ComExp : public UnaExp 924 { 925 public: 926 ComExp(Loc loc, Expression *e); 927 accept(Visitor * v)928 void accept(Visitor *v) { v->visit(this); } 929 }; 930 931 class NotExp : public UnaExp 932 { 933 public: 934 NotExp(Loc loc, Expression *e); accept(Visitor * v)935 void accept(Visitor *v) { v->visit(this); } 936 }; 937 938 class DeleteExp : public UnaExp 939 { 940 public: 941 bool isRAII; 942 DeleteExp(Loc loc, Expression *e, bool isRAII); 943 Expression *toBoolean(Scope *sc); accept(Visitor * v)944 void accept(Visitor *v) { v->visit(this); } 945 }; 946 947 class CastExp : public UnaExp 948 { 949 public: 950 // Possible to cast to one type while painting to another type 951 Type *to; // type to cast to 952 unsigned char mod; // MODxxxxx 953 954 CastExp(Loc loc, Expression *e, Type *t); 955 CastExp(Loc loc, Expression *e, unsigned char mod); 956 Expression *syntaxCopy(); 957 accept(Visitor * v)958 void accept(Visitor *v) { v->visit(this); } 959 }; 960 961 class VectorExp : public UnaExp 962 { 963 public: 964 TypeVector *to; // the target vector type before semantic() 965 unsigned dim; // number of elements in the vector 966 OwnedBy ownedByCtfe; 967 968 VectorExp(Loc loc, Expression *e, Type *t); 969 static VectorExp *create(Loc loc, Expression *e, Type *t); 970 Expression *syntaxCopy(); accept(Visitor * v)971 void accept(Visitor *v) { v->visit(this); } 972 }; 973 974 class VectorArrayExp : public UnaExp 975 { 976 public: 977 VectorArrayExp(Loc loc, Expression *e1); 978 bool isLvalue(); 979 Expression *toLvalue(Scope *sc, Expression *e); accept(Visitor * v)980 void accept(Visitor *v) { v->visit(this); } 981 }; 982 983 class SliceExp : public UnaExp 984 { 985 public: 986 Expression *upr; // NULL if implicit 0 987 Expression *lwr; // NULL if implicit [length - 1] 988 VarDeclaration *lengthVar; 989 bool upperIsInBounds; // true if upr <= e1.length 990 bool lowerIsLessThanUpper; // true if lwr <= upr 991 bool arrayop; // an array operation, rather than a slice 992 993 SliceExp(Loc loc, Expression *e1, IntervalExp *ie); 994 SliceExp(Loc loc, Expression *e1, Expression *lwr, Expression *upr); 995 Expression *syntaxCopy(); 996 int checkModifiable(Scope *sc, int flag); 997 bool isLvalue(); 998 Expression *toLvalue(Scope *sc, Expression *e); 999 Expression *modifiableLvalue(Scope *sc, Expression *e); 1000 bool isBool(bool result); 1001 accept(Visitor * v)1002 void accept(Visitor *v) { v->visit(this); } 1003 }; 1004 1005 class ArrayLengthExp : public UnaExp 1006 { 1007 public: 1008 ArrayLengthExp(Loc loc, Expression *e1); 1009 1010 static Expression *rewriteOpAssign(BinExp *exp); accept(Visitor * v)1011 void accept(Visitor *v) { v->visit(this); } 1012 }; 1013 1014 class IntervalExp : public Expression 1015 { 1016 public: 1017 Expression *lwr; 1018 Expression *upr; 1019 1020 IntervalExp(Loc loc, Expression *lwr, Expression *upr); 1021 Expression *syntaxCopy(); accept(Visitor * v)1022 void accept(Visitor *v) { v->visit(this); } 1023 }; 1024 1025 class DelegatePtrExp : public UnaExp 1026 { 1027 public: 1028 DelegatePtrExp(Loc loc, Expression *e1); 1029 bool isLvalue(); 1030 Expression *toLvalue(Scope *sc, Expression *e); 1031 Expression *modifiableLvalue(Scope *sc, Expression *e); accept(Visitor * v)1032 void accept(Visitor *v) { v->visit(this); } 1033 }; 1034 1035 class DelegateFuncptrExp : public UnaExp 1036 { 1037 public: 1038 DelegateFuncptrExp(Loc loc, Expression *e1); 1039 bool isLvalue(); 1040 Expression *toLvalue(Scope *sc, Expression *e); 1041 Expression *modifiableLvalue(Scope *sc, Expression *e); accept(Visitor * v)1042 void accept(Visitor *v) { v->visit(this); } 1043 }; 1044 1045 // e1[a0,a1,a2,a3,...] 1046 1047 class ArrayExp : public UnaExp 1048 { 1049 public: 1050 Expressions *arguments; // Array of Expression's 1051 size_t currentDimension; // for opDollar 1052 VarDeclaration *lengthVar; 1053 1054 ArrayExp(Loc loc, Expression *e1, Expression *index = NULL); 1055 ArrayExp(Loc loc, Expression *e1, Expressions *args); 1056 Expression *syntaxCopy(); 1057 bool isLvalue(); 1058 Expression *toLvalue(Scope *sc, Expression *e); 1059 accept(Visitor * v)1060 void accept(Visitor *v) { v->visit(this); } 1061 }; 1062 1063 /****************************************************************/ 1064 1065 class DotExp : public BinExp 1066 { 1067 public: 1068 DotExp(Loc loc, Expression *e1, Expression *e2); accept(Visitor * v)1069 void accept(Visitor *v) { v->visit(this); } 1070 }; 1071 1072 class CommaExp : public BinExp 1073 { 1074 public: 1075 bool isGenerated; 1076 bool allowCommaExp; 1077 CommaExp(Loc loc, Expression *e1, Expression *e2, bool generated = true); 1078 int checkModifiable(Scope *sc, int flag); 1079 bool isLvalue(); 1080 Expression *toLvalue(Scope *sc, Expression *e); 1081 Expression *modifiableLvalue(Scope *sc, Expression *e); 1082 bool isBool(bool result); 1083 Expression *toBoolean(Scope *sc); 1084 Expression *addDtorHook(Scope *sc); accept(Visitor * v)1085 void accept(Visitor *v) { v->visit(this); } 1086 }; 1087 1088 class IndexExp : public BinExp 1089 { 1090 public: 1091 VarDeclaration *lengthVar; 1092 bool modifiable; 1093 bool indexIsInBounds; // true if 0 <= e2 && e2 <= e1.length - 1 1094 1095 IndexExp(Loc loc, Expression *e1, Expression *e2); 1096 Expression *syntaxCopy(); 1097 int checkModifiable(Scope *sc, int flag); 1098 bool isLvalue(); 1099 Expression *toLvalue(Scope *sc, Expression *e); 1100 Expression *modifiableLvalue(Scope *sc, Expression *e); 1101 1102 Expression *markSettingAAElem(); 1103 accept(Visitor * v)1104 void accept(Visitor *v) { v->visit(this); } 1105 }; 1106 1107 /* For both i++ and i-- 1108 */ 1109 class PostExp : public BinExp 1110 { 1111 public: 1112 PostExp(TOK op, Loc loc, Expression *e); accept(Visitor * v)1113 void accept(Visitor *v) { v->visit(this); } 1114 }; 1115 1116 /* For both ++i and --i 1117 */ 1118 class PreExp : public UnaExp 1119 { 1120 public: 1121 PreExp(TOK op, Loc loc, Expression *e); accept(Visitor * v)1122 void accept(Visitor *v) { v->visit(this); } 1123 }; 1124 1125 enum MemorySet 1126 { 1127 blockAssign = 1, // setting the contents of an array 1128 referenceInit = 2 // setting the reference of STCref variable 1129 }; 1130 1131 class AssignExp : public BinExp 1132 { 1133 public: 1134 int memset; // combination of MemorySet flags 1135 1136 AssignExp(Loc loc, Expression *e1, Expression *e2); 1137 bool isLvalue(); 1138 Expression *toLvalue(Scope *sc, Expression *ex); 1139 Expression *toBoolean(Scope *sc); 1140 accept(Visitor * v)1141 void accept(Visitor *v) { v->visit(this); } 1142 }; 1143 1144 class ConstructExp : public AssignExp 1145 { 1146 public: 1147 ConstructExp(Loc loc, Expression *e1, Expression *e2); 1148 ConstructExp(Loc loc, VarDeclaration *v, Expression *e2); accept(Visitor * v)1149 void accept(Visitor *v) { v->visit(this); } 1150 }; 1151 1152 class BlitExp : public AssignExp 1153 { 1154 public: 1155 BlitExp(Loc loc, Expression *e1, Expression *e2); 1156 BlitExp(Loc loc, VarDeclaration *v, Expression *e2); accept(Visitor * v)1157 void accept(Visitor *v) { v->visit(this); } 1158 }; 1159 1160 class AddAssignExp : public BinAssignExp 1161 { 1162 public: 1163 AddAssignExp(Loc loc, Expression *e1, Expression *e2); accept(Visitor * v)1164 void accept(Visitor *v) { v->visit(this); } 1165 }; 1166 1167 class MinAssignExp : public BinAssignExp 1168 { 1169 public: 1170 MinAssignExp(Loc loc, Expression *e1, Expression *e2); accept(Visitor * v)1171 void accept(Visitor *v) { v->visit(this); } 1172 }; 1173 1174 class MulAssignExp : public BinAssignExp 1175 { 1176 public: 1177 MulAssignExp(Loc loc, Expression *e1, Expression *e2); accept(Visitor * v)1178 void accept(Visitor *v) { v->visit(this); } 1179 }; 1180 1181 class DivAssignExp : public BinAssignExp 1182 { 1183 public: 1184 DivAssignExp(Loc loc, Expression *e1, Expression *e2); accept(Visitor * v)1185 void accept(Visitor *v) { v->visit(this); } 1186 }; 1187 1188 class ModAssignExp : public BinAssignExp 1189 { 1190 public: 1191 ModAssignExp(Loc loc, Expression *e1, Expression *e2); accept(Visitor * v)1192 void accept(Visitor *v) { v->visit(this); } 1193 }; 1194 1195 class AndAssignExp : public BinAssignExp 1196 { 1197 public: 1198 AndAssignExp(Loc loc, Expression *e1, Expression *e2); accept(Visitor * v)1199 void accept(Visitor *v) { v->visit(this); } 1200 }; 1201 1202 class OrAssignExp : public BinAssignExp 1203 { 1204 public: 1205 OrAssignExp(Loc loc, Expression *e1, Expression *e2); accept(Visitor * v)1206 void accept(Visitor *v) { v->visit(this); } 1207 }; 1208 1209 class XorAssignExp : public BinAssignExp 1210 { 1211 public: 1212 XorAssignExp(Loc loc, Expression *e1, Expression *e2); accept(Visitor * v)1213 void accept(Visitor *v) { v->visit(this); } 1214 }; 1215 1216 class PowAssignExp : public BinAssignExp 1217 { 1218 public: 1219 PowAssignExp(Loc loc, Expression *e1, Expression *e2); accept(Visitor * v)1220 void accept(Visitor *v) { v->visit(this); } 1221 }; 1222 1223 class ShlAssignExp : public BinAssignExp 1224 { 1225 public: 1226 ShlAssignExp(Loc loc, Expression *e1, Expression *e2); accept(Visitor * v)1227 void accept(Visitor *v) { v->visit(this); } 1228 }; 1229 1230 class ShrAssignExp : public BinAssignExp 1231 { 1232 public: 1233 ShrAssignExp(Loc loc, Expression *e1, Expression *e2); accept(Visitor * v)1234 void accept(Visitor *v) { v->visit(this); } 1235 }; 1236 1237 class UshrAssignExp : public BinAssignExp 1238 { 1239 public: 1240 UshrAssignExp(Loc loc, Expression *e1, Expression *e2); accept(Visitor * v)1241 void accept(Visitor *v) { v->visit(this); } 1242 }; 1243 1244 class CatAssignExp : public BinAssignExp 1245 { 1246 public: 1247 CatAssignExp(Loc loc, Expression *e1, Expression *e2); accept(Visitor * v)1248 void accept(Visitor *v) { v->visit(this); } 1249 }; 1250 1251 class AddExp : public BinExp 1252 { 1253 public: 1254 AddExp(Loc loc, Expression *e1, Expression *e2); 1255 accept(Visitor * v)1256 void accept(Visitor *v) { v->visit(this); } 1257 }; 1258 1259 class MinExp : public BinExp 1260 { 1261 public: 1262 MinExp(Loc loc, Expression *e1, Expression *e2); 1263 accept(Visitor * v)1264 void accept(Visitor *v) { v->visit(this); } 1265 }; 1266 1267 class CatExp : public BinExp 1268 { 1269 public: 1270 CatExp(Loc loc, Expression *e1, Expression *e2); 1271 accept(Visitor * v)1272 void accept(Visitor *v) { v->visit(this); } 1273 }; 1274 1275 class MulExp : public BinExp 1276 { 1277 public: 1278 MulExp(Loc loc, Expression *e1, Expression *e2); 1279 accept(Visitor * v)1280 void accept(Visitor *v) { v->visit(this); } 1281 }; 1282 1283 class DivExp : public BinExp 1284 { 1285 public: 1286 DivExp(Loc loc, Expression *e1, Expression *e2); 1287 accept(Visitor * v)1288 void accept(Visitor *v) { v->visit(this); } 1289 }; 1290 1291 class ModExp : public BinExp 1292 { 1293 public: 1294 ModExp(Loc loc, Expression *e1, Expression *e2); 1295 accept(Visitor * v)1296 void accept(Visitor *v) { v->visit(this); } 1297 }; 1298 1299 class PowExp : public BinExp 1300 { 1301 public: 1302 PowExp(Loc loc, Expression *e1, Expression *e2); 1303 accept(Visitor * v)1304 void accept(Visitor *v) { v->visit(this); } 1305 }; 1306 1307 class ShlExp : public BinExp 1308 { 1309 public: 1310 ShlExp(Loc loc, Expression *e1, Expression *e2); 1311 accept(Visitor * v)1312 void accept(Visitor *v) { v->visit(this); } 1313 }; 1314 1315 class ShrExp : public BinExp 1316 { 1317 public: 1318 ShrExp(Loc loc, Expression *e1, Expression *e2); 1319 accept(Visitor * v)1320 void accept(Visitor *v) { v->visit(this); } 1321 }; 1322 1323 class UshrExp : public BinExp 1324 { 1325 public: 1326 UshrExp(Loc loc, Expression *e1, Expression *e2); 1327 accept(Visitor * v)1328 void accept(Visitor *v) { v->visit(this); } 1329 }; 1330 1331 class AndExp : public BinExp 1332 { 1333 public: 1334 AndExp(Loc loc, Expression *e1, Expression *e2); 1335 accept(Visitor * v)1336 void accept(Visitor *v) { v->visit(this); } 1337 }; 1338 1339 class OrExp : public BinExp 1340 { 1341 public: 1342 OrExp(Loc loc, Expression *e1, Expression *e2); 1343 accept(Visitor * v)1344 void accept(Visitor *v) { v->visit(this); } 1345 }; 1346 1347 class XorExp : public BinExp 1348 { 1349 public: 1350 XorExp(Loc loc, Expression *e1, Expression *e2); 1351 accept(Visitor * v)1352 void accept(Visitor *v) { v->visit(this); } 1353 }; 1354 1355 class OrOrExp : public BinExp 1356 { 1357 public: 1358 OrOrExp(Loc loc, Expression *e1, Expression *e2); 1359 Expression *toBoolean(Scope *sc); accept(Visitor * v)1360 void accept(Visitor *v) { v->visit(this); } 1361 }; 1362 1363 class AndAndExp : public BinExp 1364 { 1365 public: 1366 AndAndExp(Loc loc, Expression *e1, Expression *e2); 1367 Expression *toBoolean(Scope *sc); accept(Visitor * v)1368 void accept(Visitor *v) { v->visit(this); } 1369 }; 1370 1371 class CmpExp : public BinExp 1372 { 1373 public: 1374 CmpExp(TOK op, Loc loc, Expression *e1, Expression *e2); 1375 accept(Visitor * v)1376 void accept(Visitor *v) { v->visit(this); } 1377 }; 1378 1379 class InExp : public BinExp 1380 { 1381 public: 1382 InExp(Loc loc, Expression *e1, Expression *e2); 1383 accept(Visitor * v)1384 void accept(Visitor *v) { v->visit(this); } 1385 }; 1386 1387 class RemoveExp : public BinExp 1388 { 1389 public: 1390 RemoveExp(Loc loc, Expression *e1, Expression *e2); accept(Visitor * v)1391 void accept(Visitor *v) { v->visit(this); } 1392 }; 1393 1394 // == and != 1395 1396 class EqualExp : public BinExp 1397 { 1398 public: 1399 EqualExp(TOK op, Loc loc, Expression *e1, Expression *e2); 1400 accept(Visitor * v)1401 void accept(Visitor *v) { v->visit(this); } 1402 }; 1403 1404 // is and !is 1405 1406 class IdentityExp : public BinExp 1407 { 1408 public: 1409 IdentityExp(TOK op, Loc loc, Expression *e1, Expression *e2); accept(Visitor * v)1410 void accept(Visitor *v) { v->visit(this); } 1411 }; 1412 1413 /****************************************************************/ 1414 1415 class CondExp : public BinExp 1416 { 1417 public: 1418 Expression *econd; 1419 1420 CondExp(Loc loc, Expression *econd, Expression *e1, Expression *e2); 1421 Expression *syntaxCopy(); 1422 int checkModifiable(Scope *sc, int flag); 1423 bool isLvalue(); 1424 Expression *toLvalue(Scope *sc, Expression *e); 1425 Expression *modifiableLvalue(Scope *sc, Expression *e); 1426 Expression *toBoolean(Scope *sc); 1427 void hookDtors(Scope *sc); 1428 accept(Visitor * v)1429 void accept(Visitor *v) { v->visit(this); } 1430 }; 1431 1432 /****************************************************************/ 1433 1434 class DefaultInitExp : public Expression 1435 { 1436 public: 1437 TOK subop; // which of the derived classes this is 1438 1439 DefaultInitExp(Loc loc, TOK subop, int size); accept(Visitor * v)1440 void accept(Visitor *v) { v->visit(this); } 1441 }; 1442 1443 class FileInitExp : public DefaultInitExp 1444 { 1445 public: 1446 FileInitExp(Loc loc, TOK tok); 1447 Expression *resolveLoc(Loc loc, Scope *sc); accept(Visitor * v)1448 void accept(Visitor *v) { v->visit(this); } 1449 }; 1450 1451 class LineInitExp : public DefaultInitExp 1452 { 1453 public: 1454 LineInitExp(Loc loc); 1455 Expression *resolveLoc(Loc loc, Scope *sc); accept(Visitor * v)1456 void accept(Visitor *v) { v->visit(this); } 1457 }; 1458 1459 class ModuleInitExp : public DefaultInitExp 1460 { 1461 public: 1462 ModuleInitExp(Loc loc); 1463 Expression *resolveLoc(Loc loc, Scope *sc); accept(Visitor * v)1464 void accept(Visitor *v) { v->visit(this); } 1465 }; 1466 1467 class FuncInitExp : public DefaultInitExp 1468 { 1469 public: 1470 FuncInitExp(Loc loc); 1471 Expression *resolveLoc(Loc loc, Scope *sc); accept(Visitor * v)1472 void accept(Visitor *v) { v->visit(this); } 1473 }; 1474 1475 class PrettyFuncInitExp : public DefaultInitExp 1476 { 1477 public: 1478 PrettyFuncInitExp(Loc loc); 1479 Expression *resolveLoc(Loc loc, Scope *sc); accept(Visitor * v)1480 void accept(Visitor *v) { v->visit(this); } 1481 }; 1482 1483 /****************************************************************/ 1484 1485 /* A type meant as a union of all the Expression types, 1486 * to serve essentially as a Variant that will sit on the stack 1487 * during CTFE to reduce memory consumption. 1488 */ 1489 struct UnionExp 1490 { UnionExpUnionExp1491 UnionExp() { } // yes, default constructor does nothing 1492 UnionExpUnionExp1493 UnionExp(Expression *e) 1494 { 1495 memcpy(this, (void *)e, e->size); 1496 } 1497 1498 /* Extract pointer to Expression 1499 */ expUnionExp1500 Expression *exp() { return (Expression *)&u; } 1501 1502 /* Convert to an allocated Expression 1503 */ 1504 Expression *copy(); 1505 1506 private: 1507 // Ensure that the union is suitably aligned. 1508 #if defined(__GNUC__) || defined(__clang__) 1509 __attribute__((aligned(8))) 1510 #elif defined(_MSC_VER) 1511 __declspec(align(8)) 1512 #elif defined(__DMC__) 1513 #pragma pack(8) 1514 #endif 1515 union 1516 { 1517 char exp [sizeof(Expression)]; 1518 char integerexp[sizeof(IntegerExp)]; 1519 char errorexp [sizeof(ErrorExp)]; 1520 char realexp [sizeof(RealExp)]; 1521 char complexexp[sizeof(ComplexExp)]; 1522 char symoffexp [sizeof(SymOffExp)]; 1523 char stringexp [sizeof(StringExp)]; 1524 char arrayliteralexp [sizeof(ArrayLiteralExp)]; 1525 char assocarrayliteralexp [sizeof(AssocArrayLiteralExp)]; 1526 char structliteralexp [sizeof(StructLiteralExp)]; 1527 char nullexp [sizeof(NullExp)]; 1528 char dotvarexp [sizeof(DotVarExp)]; 1529 char addrexp [sizeof(AddrExp)]; 1530 char indexexp [sizeof(IndexExp)]; 1531 char sliceexp [sizeof(SliceExp)]; 1532 char vectorexp [sizeof(VectorExp)]; 1533 } u; 1534 #if defined(__DMC__) 1535 #pragma pack() 1536 #endif 1537 }; 1538 1539 /****************************************************************/ 1540 1541 /* Special values used by the interpreter 1542 */ 1543 1544 Expression *expType(Type *type, Expression *e); 1545 1546 UnionExp Neg(Type *type, Expression *e1); 1547 UnionExp Com(Type *type, Expression *e1); 1548 UnionExp Not(Type *type, Expression *e1); 1549 UnionExp Bool(Type *type, Expression *e1); 1550 UnionExp Cast(Loc loc, Type *type, Type *to, Expression *e1); 1551 UnionExp ArrayLength(Type *type, Expression *e1); 1552 UnionExp Ptr(Type *type, Expression *e1); 1553 1554 UnionExp Add(Loc loc, Type *type, Expression *e1, Expression *e2); 1555 UnionExp Min(Loc loc, Type *type, Expression *e1, Expression *e2); 1556 UnionExp Mul(Loc loc, Type *type, Expression *e1, Expression *e2); 1557 UnionExp Div(Loc loc, Type *type, Expression *e1, Expression *e2); 1558 UnionExp Mod(Loc loc, Type *type, Expression *e1, Expression *e2); 1559 UnionExp Pow(Loc loc, Type *type, Expression *e1, Expression *e2); 1560 UnionExp Shl(Loc loc, Type *type, Expression *e1, Expression *e2); 1561 UnionExp Shr(Loc loc, Type *type, Expression *e1, Expression *e2); 1562 UnionExp Ushr(Loc loc, Type *type, Expression *e1, Expression *e2); 1563 UnionExp And(Loc loc, Type *type, Expression *e1, Expression *e2); 1564 UnionExp Or(Loc loc, Type *type, Expression *e1, Expression *e2); 1565 UnionExp Xor(Loc loc, Type *type, Expression *e1, Expression *e2); 1566 UnionExp Index(Type *type, Expression *e1, Expression *e2); 1567 UnionExp Cat(Type *type, Expression *e1, Expression *e2); 1568 1569 UnionExp Equal(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2); 1570 UnionExp Cmp(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2); 1571 UnionExp Identity(TOK op, Loc loc, Type *type, Expression *e1, Expression *e2); 1572 1573 UnionExp Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr); 1574 1575 // Const-folding functions used by CTFE 1576 1577 void sliceAssignArrayLiteralFromString(ArrayLiteralExp *existingAE, StringExp *newval, size_t firstIndex); 1578 void sliceAssignStringFromArrayLiteral(StringExp *existingSE, ArrayLiteralExp *newae, size_t firstIndex); 1579 void sliceAssignStringFromString(StringExp *existingSE, StringExp *newstr, size_t firstIndex); 1580 1581 int sliceCmpStringWithString(StringExp *se1, StringExp *se2, size_t lo1, size_t lo2, size_t len); 1582 int sliceCmpStringWithArray(StringExp *se1, ArrayLiteralExp *ae2, size_t lo1, size_t lo2, size_t len); 1583