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