1 /** 2 * Defines AST nodes for the parsing stage. 3 * 4 * Copyright: Copyright (C) 1999-2021 by The D Language Foundation, All Rights Reserved 5 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 6 * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/astbase.d, _astbase.d) 7 * Documentation: https://dlang.org/phobos/dmd_astbase.html 8 * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/astbase.d 9 */ 10 11 module dmd.astbase; 12 13 import dmd.parsetimevisitor; 14 15 /** The ASTBase family defines a family of AST nodes appropriate for parsing with 16 * no semantic information. It defines all the AST nodes that the parser needs 17 * and also all the conveniance methods and variables. The resulting AST can be 18 * visited with the strict, permissive and transitive visitors. 19 * The ASTBase family is used to instantiate the parser in the parser library. 20 */ 21 struct ASTBase 22 { 23 import dmd.root.file; 24 import dmd.root.filename; 25 import dmd.root.array; 26 import dmd.root.rootobject; 27 import dmd.root.outbuffer; 28 import dmd.root.ctfloat; 29 import dmd.root.rmem; 30 import dmd.root.string : toDString; 31 import dmd.root.stringtable; 32 33 import dmd.tokens; 34 import dmd.identifier; 35 import dmd.globals; 36 import dmd.id; 37 import dmd.errors; 38 import dmd.lexer; 39 40 import core.stdc.string; 41 import core.stdc.stdarg; 42 43 alias Dsymbols = Array!(Dsymbol); 44 alias Objects = Array!(RootObject); 45 alias Expressions = Array!(Expression); 46 alias TemplateParameters = Array!(TemplateParameter); 47 alias BaseClasses = Array!(BaseClass*); 48 alias Parameters = Array!(Parameter); 49 alias Statements = Array!(Statement); 50 alias Catches = Array!(Catch); 51 alias Identifiers = Array!(Identifier); 52 alias Initializers = Array!(Initializer); 53 alias Ensures = Array!(Ensure); 54 55 enum Sizeok : ubyte 56 { 57 none, // size of aggregate is not yet able to compute 58 fwd, // size of aggregate is ready to compute 59 done, // size of aggregate is set correctly 60 } 61 62 enum Baseok : ubyte 63 { 64 none, // base classes not computed yet 65 start, // in process of resolving base classes 66 done, // all base classes are resolved 67 semanticdone, // all base classes semantic done 68 } 69 70 enum MODFlags : int 71 { 72 const_ = 1, // type is const 73 immutable_ = 4, // type is immutable 74 shared_ = 2, // type is shared 75 wild = 8, // type is wild 76 wildconst = (MODFlags.wild | MODFlags.const_), // type is wild const 77 mutable = 0x10, // type is mutable (only used in wildcard matching) 78 } 79 80 alias MOD = ubyte; 81 82 enum STC : ulong 83 { 84 undefined_ = 0L, 85 static_ = (1L << 0), 86 extern_ = (1L << 1), 87 const_ = (1L << 2), 88 final_ = (1L << 3), 89 abstract_ = (1L << 4), 90 parameter = (1L << 5), 91 field = (1L << 6), 92 override_ = (1L << 7), 93 auto_ = (1L << 8), 94 synchronized_ = (1L << 9), 95 deprecated_ = (1L << 10), 96 in_ = (1L << 11), // in parameter 97 out_ = (1L << 12), // out parameter 98 lazy_ = (1L << 13), // lazy parameter 99 foreach_ = (1L << 14), // variable for foreach loop 100 //(1L << 15) 101 variadic = (1L << 16), // the 'variadic' parameter in: T foo(T a, U b, V variadic...) 102 ctorinit = (1L << 17), // can only be set inside constructor 103 templateparameter = (1L << 18), // template parameter 104 scope_ = (1L << 19), 105 immutable_ = (1L << 20), 106 ref_ = (1L << 21), 107 init = (1L << 22), // has explicit initializer 108 manifest = (1L << 23), // manifest constant 109 nodtor = (1L << 24), // don't run destructor 110 nothrow_ = (1L << 25), // never throws exceptions 111 pure_ = (1L << 26), // pure function 112 tls = (1L << 27), // thread local 113 alias_ = (1L << 28), // alias parameter 114 shared_ = (1L << 29), // accessible from multiple threads 115 gshared = (1L << 30), // accessible from multiple threads, but not typed as "shared" 116 wild = (1L << 31), // for "wild" type constructor 117 property = (1L << 32), 118 safe = (1L << 33), 119 trusted = (1L << 34), 120 system = (1L << 35), 121 ctfe = (1L << 36), // can be used in CTFE, even if it is static 122 disable = (1L << 37), // for functions that are not callable 123 result = (1L << 38), // for result variables passed to out contracts 124 nodefaultctor = (1L << 39), // must be set inside constructor 125 temp = (1L << 40), // temporary variable 126 rvalue = (1L << 41), // force rvalue for variables 127 nogc = (1L << 42), // @nogc 128 volatile_ = (1L << 43), // destined for volatile in the back end 129 return_ = (1L << 44), // 'return ref' or 'return scope' for function parameters 130 autoref = (1L << 45), // Mark for the already deduced 'auto ref' parameter 131 inference = (1L << 46), // do attribute inference 132 exptemp = (1L << 47), // temporary variable that has lifetime restricted to an expression 133 maybescope = (1L << 48), // parameter might be 'scope' 134 scopeinferred = (1L << 49), // 'scope' has been inferred and should not be part of mangling 135 future = (1L << 50), // introducing new base class function 136 local = (1L << 51), // do not forward (see dmd.dsymbol.ForwardingScopeDsymbol). 137 returninferred = (1L << 52), // 'return' has been inferred and should not be part of mangling 138 live = (1L << 53), // function @live attribute 139 140 safeGroup = STC.safe | STC.trusted | STC.system, 141 IOR = STC.in_ | STC.ref_ | STC.out_, 142 TYPECTOR = (STC.const_ | STC.immutable_ | STC.shared_ | STC.wild), 143 FUNCATTR = (STC.ref_ | STC.nothrow_ | STC.nogc | STC.pure_ | STC.property | STC.live | 144 safeGroup), 145 } 146 147 extern (C++) __gshared const(StorageClass) STCStorageClass = 148 (STC.auto_ | STC.scope_ | STC.static_ | STC.extern_ | STC.const_ | STC.final_ | 149 STC.abstract_ | STC.synchronized_ | STC.deprecated_ | STC.override_ | STC.lazy_ | 150 STC.alias_ | STC.out_ | STC.in_ | STC.manifest | STC.immutable_ | STC.shared_ | 151 STC.wild | STC.nothrow_ | STC.nogc | STC.pure_ | STC.ref_ | STC.return_ | STC.tls | 152 STC.gshared | STC.property | STC.live | 153 STC.safeGroup | STC.disable); 154 155 enum ENUMTY : int 156 { 157 Tarray, // slice array, aka T[] 158 Tsarray, // static array, aka T[dimension] 159 Taarray, // associative array, aka T[type] 160 Tpointer, 161 Treference, 162 Tfunction, 163 Tident, 164 Tclass, 165 Tstruct, 166 Tenum, 167 168 Tdelegate, 169 Tnone, 170 Tvoid, 171 Tint8, 172 Tuns8, 173 Tint16, 174 Tuns16, 175 Tint32, 176 Tuns32, 177 Tint64, 178 179 Tuns64, 180 Tfloat32, 181 Tfloat64, 182 Tfloat80, 183 Timaginary32, 184 Timaginary64, 185 Timaginary80, 186 Tcomplex32, 187 Tcomplex64, 188 Tcomplex80, 189 190 Tbool, 191 Tchar, 192 Twchar, 193 Tdchar, 194 Terror, 195 Tinstance, 196 Ttypeof, 197 Ttuple, 198 Tslice, 199 Treturn, 200 201 Tnull, 202 Tvector, 203 Tint128, 204 Tuns128, 205 Ttraits, 206 Tmixin, 207 Tnoreturn, 208 TMAX 209 } 210 211 alias Tarray = ENUMTY.Tarray; 212 alias Tsarray = ENUMTY.Tsarray; 213 alias Taarray = ENUMTY.Taarray; 214 alias Tpointer = ENUMTY.Tpointer; 215 alias Treference = ENUMTY.Treference; 216 alias Tfunction = ENUMTY.Tfunction; 217 alias Tident = ENUMTY.Tident; 218 alias Tclass = ENUMTY.Tclass; 219 alias Tstruct = ENUMTY.Tstruct; 220 alias Tenum = ENUMTY.Tenum; 221 alias Tdelegate = ENUMTY.Tdelegate; 222 alias Tnone = ENUMTY.Tnone; 223 alias Tvoid = ENUMTY.Tvoid; 224 alias Tint8 = ENUMTY.Tint8; 225 alias Tuns8 = ENUMTY.Tuns8; 226 alias Tint16 = ENUMTY.Tint16; 227 alias Tuns16 = ENUMTY.Tuns16; 228 alias Tint32 = ENUMTY.Tint32; 229 alias Tuns32 = ENUMTY.Tuns32; 230 alias Tint64 = ENUMTY.Tint64; 231 alias Tuns64 = ENUMTY.Tuns64; 232 alias Tfloat32 = ENUMTY.Tfloat32; 233 alias Tfloat64 = ENUMTY.Tfloat64; 234 alias Tfloat80 = ENUMTY.Tfloat80; 235 alias Timaginary32 = ENUMTY.Timaginary32; 236 alias Timaginary64 = ENUMTY.Timaginary64; 237 alias Timaginary80 = ENUMTY.Timaginary80; 238 alias Tcomplex32 = ENUMTY.Tcomplex32; 239 alias Tcomplex64 = ENUMTY.Tcomplex64; 240 alias Tcomplex80 = ENUMTY.Tcomplex80; 241 alias Tbool = ENUMTY.Tbool; 242 alias Tchar = ENUMTY.Tchar; 243 alias Twchar = ENUMTY.Twchar; 244 alias Tdchar = ENUMTY.Tdchar; 245 alias Terror = ENUMTY.Terror; 246 alias Tinstance = ENUMTY.Tinstance; 247 alias Ttypeof = ENUMTY.Ttypeof; 248 alias Ttuple = ENUMTY.Ttuple; 249 alias Tslice = ENUMTY.Tslice; 250 alias Treturn = ENUMTY.Treturn; 251 alias Tnull = ENUMTY.Tnull; 252 alias Tvector = ENUMTY.Tvector; 253 alias Tint128 = ENUMTY.Tint128; 254 alias Tuns128 = ENUMTY.Tuns128; 255 alias Ttraits = ENUMTY.Ttraits; 256 alias Tmixin = ENUMTY.Tmixin; 257 alias Tnoreturn = ENUMTY.Tnoreturn; 258 alias TMAX = ENUMTY.TMAX; 259 260 alias TY = ubyte; 261 262 enum TFlags 263 { 264 integral = 1, 265 floating = 2, 266 unsigned = 4, 267 real_ = 8, 268 imaginary = 0x10, 269 complex = 0x20, 270 } 271 272 enum PKG : int 273 { 274 unknown, // not yet determined whether it's a package.d or not 275 module_, // already determined that's an actual package.d 276 package_, // already determined that's an actual package 277 } 278 279 enum StructPOD : int 280 { 281 no, // struct is not POD 282 yes, // struct is POD 283 fwd, // POD not yet computed 284 } 285 286 enum TRUST : ubyte 287 { 288 default_ = 0, 289 system = 1, // @system (same as TRUST.default) 290 trusted = 2, // @trusted 291 safe = 3, // @safe 292 live = 4, // @live 293 } 294 295 enum PURE : ubyte 296 { 297 impure = 0, // not pure at all 298 fwdref = 1, // it's pure, but not known which level yet 299 weak = 2, // no mutable globals are read or written 300 const_ = 3, // parameters are values or const 301 strong = 4, // parameters are values or immutable 302 } 303 304 enum AliasThisRec : int 305 { 306 no = 0, // no alias this recursion 307 yes = 1, // alias this has recursive dependency 308 fwdref = 2, // not yet known 309 typeMask = 3, // mask to read no/yes/fwdref 310 tracing = 0x4, // mark in progress of implicitConvTo/deduceWild 311 tracingDT = 0x8, // mark in progress of deduceType 312 } 313 314 enum VarArg : ubyte 315 { 316 none = 0, /// fixed number of arguments 317 variadic = 1, /// T t, ...) can be C-style (core.stdc.stdarg) or D-style (core.vararg) 318 typesafe = 2, /// T t ...) typesafe https://dlang.org/spec/function.html#typesafe_variadic_functions 319 /// or https://dlang.org/spec/function.html#typesafe_variadic_functions 320 } 321 322 alias Visitor = ParseTimeVisitor!ASTBase; 323 324 extern (C++) abstract class ASTNode : RootObject 325 { 326 abstract void accept(Visitor v); 327 } 328 329 extern (C++) class Dsymbol : ASTNode 330 { 331 Loc loc; 332 Identifier ident; 333 UnitTestDeclaration ddocUnittest; 334 UserAttributeDeclaration userAttribDecl; 335 Dsymbol parent; 336 337 const(char)* comment; 338 339 final extern (D) this() {} 340 final extern (D) this(Identifier ident) 341 { 342 this.ident = ident; 343 } 344 345 final extern (D) this(const ref Loc loc, Identifier ident) 346 { 347 this.loc = loc; 348 this.ident = ident; 349 } 350 351 void addComment(const(char)* comment) 352 { 353 if (!this.comment) 354 this.comment = comment; 355 else if (comment && strcmp(cast(char*)comment, cast(char*)this.comment) != 0) 356 this.comment = Lexer.combineComments(this.comment.toDString(), comment.toDString(), true); 357 } 358 359 override const(char)* toChars() const 360 { 361 return ident ? ident.toChars() : "__anonymous"; 362 } 363 364 bool oneMember(Dsymbol *ps, Identifier ident) 365 { 366 *ps = this; 367 return true; 368 } 369 370 extern (D) static bool oneMembers(ref Dsymbols members, Dsymbol* ps, Identifier ident) 371 { 372 Dsymbol s = null; 373 for (size_t i = 0; i < members.dim; i++) 374 { 375 Dsymbol sx = members[i]; 376 bool x = sx.oneMember(ps, ident); 377 if (!x) 378 { 379 assert(*ps is null); 380 return false; 381 } 382 if (*ps) 383 { 384 assert(ident); 385 if (!(*ps).ident || !(*ps).ident.equals(ident)) 386 continue; 387 if (!s) 388 s = *ps; 389 else if (s.isOverloadable() && (*ps).isOverloadable()) 390 { 391 // keep head of overload set 392 FuncDeclaration f1 = s.isFuncDeclaration(); 393 FuncDeclaration f2 = (*ps).isFuncDeclaration(); 394 if (f1 && f2) 395 { 396 for (; f1 != f2; f1 = f1.overnext0) 397 { 398 if (f1.overnext0 is null) 399 { 400 f1.overnext0 = f2; 401 break; 402 } 403 } 404 } 405 } 406 else // more than one symbol 407 { 408 *ps = null; 409 //printf("\tfalse 2\n"); 410 return false; 411 } 412 } 413 } 414 *ps = s; 415 return true; 416 } 417 418 bool isOverloadable() const 419 { 420 return false; 421 } 422 423 const(char)* kind() const 424 { 425 return "symbol"; 426 } 427 428 static if (__VERSION__ < 2092) 429 final void error(const(char)* format, ...) 430 { 431 va_list ap; 432 va_start(ap, format); 433 // last parameter : toPrettyChars 434 verror(loc, format, ap, kind(), ""); 435 va_end(ap); 436 } 437 else 438 pragma(printf) final void error(const(char)* format, ...) 439 { 440 va_list ap; 441 va_start(ap, format); 442 // last parameter : toPrettyChars 443 verror(loc, format, ap, kind(), ""); 444 va_end(ap); 445 } 446 447 inout(AttribDeclaration) isAttribDeclaration() inout 448 { 449 return null; 450 } 451 452 inout(TemplateDeclaration) isTemplateDeclaration() inout 453 { 454 return null; 455 } 456 457 inout(FuncLiteralDeclaration) isFuncLiteralDeclaration() inout 458 { 459 return null; 460 } 461 462 inout(FuncDeclaration) isFuncDeclaration() inout 463 { 464 return null; 465 } 466 467 inout(VarDeclaration) isVarDeclaration() inout 468 { 469 return null; 470 } 471 472 inout(TemplateInstance) isTemplateInstance() inout 473 { 474 return null; 475 } 476 477 inout(Declaration) isDeclaration() inout 478 { 479 return null; 480 } 481 482 inout(AliasAssign) isAliasAssign() inout 483 { 484 return null; 485 } 486 487 inout(ClassDeclaration) isClassDeclaration() inout 488 { 489 return null; 490 } 491 492 inout(AggregateDeclaration) isAggregateDeclaration() inout 493 { 494 return null; 495 } 496 497 Dsymbol syntaxCopy(Dsymbol s) 498 { 499 return null; 500 } 501 502 override final DYNCAST dyncast() const 503 { 504 return DYNCAST.dsymbol; 505 } 506 507 override void accept(Visitor v) 508 { 509 v.visit(this); 510 } 511 } 512 513 extern (C++) class AliasThis : Dsymbol 514 { 515 Identifier ident; 516 517 extern (D) this(const ref Loc loc, Identifier ident) 518 { 519 super(null); 520 this.loc = loc; 521 this.ident = ident; 522 } 523 524 override void accept(Visitor v) 525 { 526 v.visit(this); 527 } 528 } 529 530 extern (C++) final class AliasAssign : Dsymbol 531 { 532 Identifier ident; 533 Type type; 534 Dsymbol aliassym; 535 536 extern (D) this(const ref Loc loc, Identifier ident, Type type, Dsymbol aliassym) 537 { 538 super(null); 539 this.loc = loc; 540 this.ident = ident; 541 this.type = type; 542 this.aliassym = aliassym; 543 } 544 545 override inout(AliasAssign) isAliasAssign() inout 546 { 547 return this; 548 } 549 550 override void accept(Visitor v) 551 { 552 v.visit(this); 553 } 554 } 555 556 extern (C++) abstract class Declaration : Dsymbol 557 { 558 StorageClass storage_class; 559 Visibility visibility; 560 LINK linkage; 561 Type type; 562 short inuse; 563 ubyte adFlags; 564 565 final extern (D) this(Identifier id) 566 { 567 super(id); 568 storage_class = STC.undefined_; 569 visibility = Visibility(Visibility.Kind.undefined); 570 linkage = LINK.default_; 571 } 572 573 override final inout(Declaration) isDeclaration() inout 574 { 575 return this; 576 } 577 578 override void accept(Visitor v) 579 { 580 v.visit(this); 581 } 582 } 583 584 extern (C++) class ScopeDsymbol : Dsymbol 585 { 586 Dsymbols* members; 587 final extern (D) this() {} 588 final extern (D) this(Identifier id) 589 { 590 super(id); 591 } 592 593 override void accept(Visitor v) 594 { 595 v.visit(this); 596 } 597 } 598 599 extern (C++) class Import : Dsymbol 600 { 601 Identifier[] packages; 602 Identifier id; 603 Identifier aliasId; 604 int isstatic; 605 Visibility visibility; 606 607 Identifiers names; 608 Identifiers aliases; 609 610 extern (D) this(const ref Loc loc, Identifier[] packages, Identifier id, Identifier aliasId, int isstatic) 611 { 612 super(null); 613 this.loc = loc; 614 this.packages = packages; 615 this.id = id; 616 this.aliasId = aliasId; 617 this.isstatic = isstatic; 618 this.visibility = Visibility(Visibility.Kind.private_); 619 620 if (aliasId) 621 { 622 // import [cstdio] = std.stdio; 623 this.ident = aliasId; 624 } 625 else if (packages.length > 0) 626 { 627 // import [std].stdio; 628 this.ident = packages[0]; 629 } 630 else 631 { 632 // import [foo]; 633 this.ident = id; 634 } 635 } 636 void addAlias(Identifier name, Identifier _alias) 637 { 638 if (isstatic) 639 error("cannot have an import bind list"); 640 if (!aliasId) 641 this.ident = null; 642 643 names.push(name); 644 aliases.push(_alias); 645 } 646 647 override void accept(Visitor v) 648 { 649 v.visit(this); 650 } 651 } 652 653 extern (C++) abstract class AttribDeclaration : Dsymbol 654 { 655 Dsymbols* decl; 656 657 final extern (D) this(Dsymbols *decl) 658 { 659 this.decl = decl; 660 } 661 662 final extern (D) this(const ref Loc loc, Identifier ident, Dsymbols* decl) 663 { 664 super(loc, ident); 665 this.decl = decl; 666 } 667 668 override final inout(AttribDeclaration) isAttribDeclaration() inout 669 { 670 return this; 671 } 672 673 override void accept(Visitor v) 674 { 675 v.visit(this); 676 } 677 } 678 679 extern (C++) final class StaticAssert : Dsymbol 680 { 681 Expression exp; 682 Expression msg; 683 684 extern (D) this(const ref Loc loc, Expression exp, Expression msg) 685 { 686 super(Id.empty); 687 this.loc = loc; 688 this.exp = exp; 689 this.msg = msg; 690 } 691 } 692 693 extern (C++) final class DebugSymbol : Dsymbol 694 { 695 uint level; 696 697 extern (D) this(const ref Loc loc, Identifier ident) 698 { 699 super(ident); 700 this.loc = loc; 701 } 702 extern (D) this(const ref Loc loc, uint level) 703 { 704 this.level = level; 705 this.loc = loc; 706 } 707 708 override void accept(Visitor v) 709 { 710 v.visit(this); 711 } 712 } 713 714 extern (C++) final class VersionSymbol : Dsymbol 715 { 716 uint level; 717 718 extern (D) this(const ref Loc loc, Identifier ident) 719 { 720 super(ident); 721 this.loc = loc; 722 } 723 extern (D) this(const ref Loc loc, uint level) 724 { 725 this.level = level; 726 this.loc = loc; 727 } 728 729 override void accept(Visitor v) 730 { 731 v.visit(this); 732 } 733 } 734 735 extern (C++) class VarDeclaration : Declaration 736 { 737 Type type; 738 Initializer _init; 739 enum AdrOnStackNone = ~0u; 740 uint ctfeAdrOnStack; 741 uint sequenceNumber; 742 __gshared uint nextSequenceNumber; 743 744 final extern (D) this(const ref Loc loc, Type type, Identifier id, Initializer _init, StorageClass st = STC.undefined_) 745 { 746 super(id); 747 this.type = type; 748 this._init = _init; 749 this.loc = loc; 750 this.storage_class = st; 751 sequenceNumber = ++nextSequenceNumber; 752 ctfeAdrOnStack = AdrOnStackNone; 753 } 754 755 override final inout(VarDeclaration) isVarDeclaration() inout 756 { 757 return this; 758 } 759 760 override void accept(Visitor v) 761 { 762 v.visit(this); 763 } 764 } 765 766 extern (C++) struct Ensure 767 { 768 Identifier id; 769 Statement ensure; 770 } 771 772 extern (C++) class FuncDeclaration : Declaration 773 { 774 Statement fbody; 775 Statements* frequires; 776 Ensures* fensures; 777 Loc endloc; 778 StorageClass storage_class; 779 Type type; 780 bool inferRetType; 781 ForeachStatement fes; 782 FuncDeclaration overnext0; 783 784 final extern (D) this(const ref Loc loc, Loc endloc, Identifier id, StorageClass storage_class, Type type) 785 { 786 super(id); 787 this.storage_class = storage_class; 788 this.type = type; 789 if (type) 790 { 791 // Normalize storage_class, because function-type related attributes 792 // are already set in the 'type' in parsing phase. 793 this.storage_class &= ~(STC.TYPECTOR | STC.FUNCATTR); 794 } 795 this.loc = loc; 796 this.endloc = endloc; 797 inferRetType = (type && type.nextOf() is null); 798 } 799 800 FuncLiteralDeclaration isFuncLiteralDeclaration() 801 { 802 return null; 803 } 804 805 override bool isOverloadable() const 806 { 807 return true; 808 } 809 810 override final inout(FuncDeclaration) isFuncDeclaration() inout 811 { 812 return this; 813 } 814 815 override void accept(Visitor v) 816 { 817 v.visit(this); 818 } 819 } 820 821 extern (C++) final class AliasDeclaration : Declaration 822 { 823 Dsymbol aliassym; 824 825 extern (D) this(const ref Loc loc, Identifier id, Dsymbol s) 826 { 827 super(id); 828 this.loc = loc; 829 this.aliassym = s; 830 } 831 832 extern (D) this(const ref Loc loc, Identifier id, Type type) 833 { 834 super(id); 835 this.loc = loc; 836 this.type = type; 837 } 838 839 override bool isOverloadable() const 840 { 841 //assume overloadable until alias is resolved; 842 // should be modified when semantic analysis is added 843 return true; 844 } 845 846 override void accept(Visitor v) 847 { 848 v.visit(this); 849 } 850 } 851 852 extern (C++) final class TupleDeclaration : Declaration 853 { 854 Objects* objects; 855 856 extern (D) this(const ref Loc loc, Identifier id, Objects* objects) 857 { 858 super(id); 859 this.loc = loc; 860 this.objects = objects; 861 } 862 863 override void accept(Visitor v) 864 { 865 v.visit(this); 866 } 867 } 868 869 extern (C++) final class FuncLiteralDeclaration : FuncDeclaration 870 { 871 TOK tok; 872 873 extern (D) this(const ref Loc loc, Loc endloc, Type type, TOK tok, ForeachStatement fes, Identifier id = null) 874 { 875 super(loc, endloc, null, STC.undefined_, type); 876 this.ident = id ? id : Id.empty; 877 this.tok = tok; 878 this.fes = fes; 879 } 880 881 override inout(FuncLiteralDeclaration) isFuncLiteralDeclaration() inout 882 { 883 return this; 884 } 885 886 override void accept(Visitor v) 887 { 888 v.visit(this); 889 } 890 } 891 892 extern (C++) final class PostBlitDeclaration : FuncDeclaration 893 { 894 extern (D) this(const ref Loc loc, Loc endloc, StorageClass stc, Identifier id) 895 { 896 super(loc, endloc, id, stc, null); 897 } 898 899 override void accept(Visitor v) 900 { 901 v.visit(this); 902 } 903 } 904 905 extern (C++) final class CtorDeclaration : FuncDeclaration 906 { 907 extern (D) this(const ref Loc loc, Loc endloc, StorageClass stc, Type type, bool isCopyCtor = false) 908 { 909 super(loc, endloc, Id.ctor, stc, type); 910 } 911 912 override void accept(Visitor v) 913 { 914 v.visit(this); 915 } 916 } 917 918 extern (C++) final class DtorDeclaration : FuncDeclaration 919 { 920 extern (D) this(const ref Loc loc, Loc endloc) 921 { 922 super(loc, endloc, Id.dtor, STC.undefined_, null); 923 } 924 extern (D) this(const ref Loc loc, Loc endloc, StorageClass stc, Identifier id) 925 { 926 super(loc, endloc, id, stc, null); 927 } 928 929 override void accept(Visitor v) 930 { 931 v.visit(this); 932 } 933 } 934 935 extern (C++) final class InvariantDeclaration : FuncDeclaration 936 { 937 extern (D) this(const ref Loc loc, Loc endloc, StorageClass stc, Identifier id, Statement fbody) 938 { 939 super(loc, endloc, id ? id : Identifier.generateId("__invariant"), stc, null); 940 this.fbody = fbody; 941 } 942 943 override void accept(Visitor v) 944 { 945 v.visit(this); 946 } 947 } 948 949 extern (C++) final class UnitTestDeclaration : FuncDeclaration 950 { 951 char* codedoc; 952 953 extern (D) this(const ref Loc loc, Loc endloc, StorageClass stc, char* codedoc) 954 { 955 super(loc, endloc, Identifier.generateIdWithLoc("__unittest", loc), stc, null); 956 this.codedoc = codedoc; 957 } 958 959 override void accept(Visitor v) 960 { 961 v.visit(this); 962 } 963 } 964 965 extern (C++) final class NewDeclaration : FuncDeclaration 966 { 967 ParameterList parameterList; 968 969 extern (D) this(const ref Loc loc, Loc endloc, StorageClass stc, ref ParameterList parameterList) 970 { 971 super(loc, endloc, Id.classNew, STC.static_ | stc, null); 972 this.parameterList = parameterList; 973 } 974 975 override void accept(Visitor v) 976 { 977 v.visit(this); 978 } 979 } 980 981 extern (C++) class StaticCtorDeclaration : FuncDeclaration 982 { 983 final extern (D) this(const ref Loc loc, Loc endloc, StorageClass stc) 984 { 985 super(loc, endloc, Identifier.generateIdWithLoc("_staticCtor", loc), STC.static_ | stc, null); 986 } 987 final extern (D) this(const ref Loc loc, Loc endloc, string name, StorageClass stc) 988 { 989 super(loc, endloc, Identifier.generateIdWithLoc(name, loc), STC.static_ | stc, null); 990 } 991 992 override void accept(Visitor v) 993 { 994 v.visit(this); 995 } 996 } 997 998 extern (C++) class StaticDtorDeclaration : FuncDeclaration 999 { 1000 final extern (D) this()(Loc loc, Loc endloc, StorageClass stc) 1001 { 1002 super(loc, endloc, Identifier.generateIdWithLoc("__staticDtor", loc), STC.static_ | stc, null); 1003 } 1004 final extern (D) this(const ref Loc loc, Loc endloc, string name, StorageClass stc) 1005 { 1006 super(loc, endloc, Identifier.generateIdWithLoc(name, loc), STC.static_ | stc, null); 1007 } 1008 1009 override void accept(Visitor v) 1010 { 1011 v.visit(this); 1012 } 1013 } 1014 1015 extern (C++) final class SharedStaticCtorDeclaration : StaticCtorDeclaration 1016 { 1017 extern (D) this(const ref Loc loc, Loc endloc, StorageClass stc) 1018 { 1019 super(loc, endloc, "_sharedStaticCtor", stc); 1020 } 1021 1022 override void accept(Visitor v) 1023 { 1024 v.visit(this); 1025 } 1026 } 1027 1028 extern (C++) final class SharedStaticDtorDeclaration : StaticDtorDeclaration 1029 { 1030 extern (D) this(const ref Loc loc, Loc endloc, StorageClass stc) 1031 { 1032 super(loc, endloc, "_sharedStaticDtor", stc); 1033 } 1034 1035 override void accept(Visitor v) 1036 { 1037 v.visit(this); 1038 } 1039 } 1040 1041 extern (C++) class Package : ScopeDsymbol 1042 { 1043 PKG isPkgMod; 1044 uint tag; 1045 1046 final extern (D) this(Identifier ident) 1047 { 1048 super(ident); 1049 this.isPkgMod = PKG.unknown; 1050 __gshared uint packageTag; 1051 this.tag = packageTag++; 1052 } 1053 1054 override void accept(Visitor v) 1055 { 1056 v.visit(this); 1057 } 1058 } 1059 1060 extern (C++) final class EnumDeclaration : ScopeDsymbol 1061 { 1062 Type type; 1063 Type memtype; 1064 Visibility visibility; 1065 1066 extern (D) this(const ref Loc loc, Identifier id, Type memtype) 1067 { 1068 super(id); 1069 this.loc = loc; 1070 type = new TypeEnum(this); 1071 this.memtype = memtype; 1072 visibility = Visibility(Visibility.Kind.undefined); 1073 } 1074 1075 override void accept(Visitor v) 1076 { 1077 v.visit(this); 1078 } 1079 } 1080 1081 extern (C++) abstract class AggregateDeclaration : ScopeDsymbol 1082 { 1083 Visibility visibility; 1084 Sizeok sizeok; 1085 Type type; 1086 1087 final extern (D) this(const ref Loc loc, Identifier id) 1088 { 1089 super(id); 1090 this.loc = loc; 1091 visibility = Visibility(Visibility.Kind.public_); 1092 sizeok = Sizeok.none; 1093 } 1094 1095 override final inout(AggregateDeclaration) isAggregateDeclaration() inout 1096 { 1097 return this; 1098 } 1099 1100 override void accept(Visitor v) 1101 { 1102 v.visit(this); 1103 } 1104 } 1105 1106 extern (C++) final class TemplateDeclaration : ScopeDsymbol 1107 { 1108 TemplateParameters* parameters; 1109 TemplateParameters* origParameters; 1110 Expression constraint; 1111 bool literal; 1112 bool ismixin; 1113 bool isstatic; 1114 Visibility visibility; 1115 Dsymbol onemember; 1116 1117 extern (D) this(const ref Loc loc, Identifier id, TemplateParameters* parameters, Expression constraint, Dsymbols* decldefs, bool ismixin = false, bool literal = false) 1118 { 1119 super(id); 1120 this.loc = loc; 1121 this.parameters = parameters; 1122 this.origParameters = parameters; 1123 this.members = decldefs; 1124 this.literal = literal; 1125 this.ismixin = ismixin; 1126 this.isstatic = true; 1127 this.visibility = Visibility(Visibility.Kind.undefined); 1128 1129 if (members && ident) 1130 { 1131 Dsymbol s; 1132 if (Dsymbol.oneMembers(*members, &s, ident) && s) 1133 { 1134 onemember = s; 1135 s.parent = this; 1136 } 1137 } 1138 } 1139 1140 override bool isOverloadable() const 1141 { 1142 return true; 1143 } 1144 1145 override inout(TemplateDeclaration) isTemplateDeclaration () inout 1146 { 1147 return this; 1148 } 1149 1150 override void accept(Visitor v) 1151 { 1152 v.visit(this); 1153 } 1154 } 1155 1156 extern (C++) class TemplateInstance : ScopeDsymbol 1157 { 1158 Identifier name; 1159 Objects* tiargs; 1160 Dsymbol tempdecl; 1161 bool semantictiargsdone; 1162 bool havetempdecl; 1163 TemplateInstance inst; 1164 1165 final extern (D) this(const ref Loc loc, Identifier ident, Objects* tiargs) 1166 { 1167 super(null); 1168 this.loc = loc; 1169 this.name = ident; 1170 this.tiargs = tiargs; 1171 } 1172 1173 final extern (D) this(const ref Loc loc, TemplateDeclaration td, Objects* tiargs) 1174 { 1175 super(null); 1176 this.loc = loc; 1177 this.name = td.ident; 1178 this.tempdecl = td; 1179 this.semantictiargsdone = true; 1180 this.havetempdecl = true; 1181 } 1182 1183 override final inout(TemplateInstance) isTemplateInstance() inout 1184 { 1185 return this; 1186 } 1187 1188 static Objects* arraySyntaxCopy(Objects* objs) 1189 { 1190 Objects* a = null; 1191 if (objs) 1192 { 1193 a = new Objects(); 1194 a.setDim(objs.dim); 1195 for (size_t i = 0; i < objs.dim; i++) 1196 (*a)[i] = objectSyntaxCopy((*objs)[i]); 1197 } 1198 return a; 1199 } 1200 1201 static RootObject objectSyntaxCopy(RootObject o) 1202 { 1203 if (!o) 1204 return null; 1205 if (Type t = isType(o)) 1206 return t.syntaxCopy(); 1207 if (Expression e = isExpression(o)) 1208 return e.syntaxCopy(); 1209 return o; 1210 } 1211 1212 override TemplateInstance syntaxCopy(Dsymbol s) 1213 { 1214 TemplateInstance ti = s ? cast(TemplateInstance)s : new TemplateInstance(loc, name, null); 1215 ti.tiargs = arraySyntaxCopy(tiargs); 1216 TemplateDeclaration td; 1217 if (inst && tempdecl && (td = tempdecl.isTemplateDeclaration()) !is null) 1218 td.ScopeDsymbol.syntaxCopy(ti); 1219 else 1220 ScopeDsymbol.syntaxCopy(ti); 1221 return ti; 1222 } 1223 1224 override void accept(Visitor v) 1225 { 1226 v.visit(this); 1227 } 1228 } 1229 1230 extern (C++) final class Nspace : ScopeDsymbol 1231 { 1232 /** 1233 * Namespace identifier resolved during semantic. 1234 */ 1235 Expression identExp; 1236 1237 extern (D) this(const ref Loc loc, Identifier ident, Expression identExp, Dsymbols* members) 1238 { 1239 super(ident); 1240 this.loc = loc; 1241 this.members = members; 1242 this.identExp = identExp; 1243 } 1244 1245 override void accept(Visitor v) 1246 { 1247 v.visit(this); 1248 } 1249 } 1250 1251 extern (C++) final class CompileDeclaration : AttribDeclaration 1252 { 1253 Expressions* exps; 1254 1255 extern (D) this(const ref Loc loc, Expressions* exps) 1256 { 1257 super(null); 1258 this.loc = loc; 1259 this.exps = exps; 1260 } 1261 1262 override void accept(Visitor v) 1263 { 1264 v.visit(this); 1265 } 1266 } 1267 1268 extern (C++) final class UserAttributeDeclaration : AttribDeclaration 1269 { 1270 Expressions* atts; 1271 1272 extern (D) this(Expressions* atts, Dsymbols* decl) 1273 { 1274 super(decl); 1275 this.atts = atts; 1276 } 1277 1278 override UserAttributeDeclaration syntaxCopy(Dsymbol s) 1279 { 1280 Expressions* a = this.atts ? new Expressions(this.atts.length) : null; 1281 Dsymbols* d = this.decl ? new Dsymbols(this.decl.length) : null; 1282 1283 if (this.atts) 1284 foreach (idx, entry; *this.atts) 1285 (*a)[idx] = entry.syntaxCopy(); 1286 if (this.decl) 1287 foreach (idx, entry; *this.decl) 1288 (*d)[idx] = entry.syntaxCopy(null); 1289 1290 return new UserAttributeDeclaration(a, d); 1291 } 1292 1293 extern (D) static Expressions* concat(Expressions* udas1, Expressions* udas2) 1294 { 1295 Expressions* udas; 1296 if (!udas1 || udas1.dim == 0) 1297 udas = udas2; 1298 else if (!udas2 || udas2.dim == 0) 1299 udas = udas1; 1300 else 1301 { 1302 udas = new Expressions(2); 1303 (*udas)[0] = new TupleExp(Loc.initial, udas1); 1304 (*udas)[1] = new TupleExp(Loc.initial, udas2); 1305 } 1306 return udas; 1307 } 1308 1309 override void accept(Visitor v) 1310 { 1311 v.visit(this); 1312 } 1313 } 1314 1315 extern (C++) final class LinkDeclaration : AttribDeclaration 1316 { 1317 LINK linkage; 1318 1319 extern (D) this(const ref Loc loc, LINK p, Dsymbols* decl) 1320 { 1321 super(loc, null, decl); 1322 this.linkage = p; 1323 } 1324 1325 override void accept(Visitor v) 1326 { 1327 v.visit(this); 1328 } 1329 } 1330 1331 extern (C++) final class AnonDeclaration : AttribDeclaration 1332 { 1333 bool isunion; 1334 1335 extern (D) this(const ref Loc loc, bool isunion, Dsymbols* decl) 1336 { 1337 super(decl); 1338 this.loc = loc; 1339 this.isunion = isunion; 1340 } 1341 1342 override void accept(Visitor v) 1343 { 1344 v.visit(this); 1345 } 1346 } 1347 1348 extern (C++) final class AlignDeclaration : AttribDeclaration 1349 { 1350 Expression ealign; 1351 1352 extern (D) this(const ref Loc loc, Expression ealign, Dsymbols* decl) 1353 { 1354 super(decl); 1355 this.loc = loc; 1356 this.ealign = ealign; 1357 } 1358 1359 override void accept(Visitor v) 1360 { 1361 v.visit(this); 1362 } 1363 } 1364 1365 extern (C++) final class CPPMangleDeclaration : AttribDeclaration 1366 { 1367 CPPMANGLE cppmangle; 1368 1369 extern (D) this(const ref Loc loc, CPPMANGLE p, Dsymbols* decl) 1370 { 1371 super(loc, null, decl); 1372 cppmangle = p; 1373 } 1374 1375 override void accept(Visitor v) 1376 { 1377 v.visit(this); 1378 } 1379 } 1380 1381 extern (C++) final class CPPNamespaceDeclaration : AttribDeclaration 1382 { 1383 Expression exp; 1384 1385 extern (D) this(const ref Loc loc, Identifier ident, Dsymbols* decl) 1386 { 1387 super(loc, ident, decl); 1388 } 1389 1390 extern (D) this(const ref Loc loc, Expression exp, Dsymbols* decl) 1391 { 1392 super(loc, null, decl); 1393 this.exp = exp; 1394 } 1395 1396 override void accept(Visitor v) 1397 { 1398 v.visit(this); 1399 } 1400 } 1401 1402 extern (C++) final class VisibilityDeclaration : AttribDeclaration 1403 { 1404 Visibility visibility; 1405 Identifier[] pkg_identifiers; 1406 1407 extern (D) this(const ref Loc loc, Visibility v, Dsymbols* decl) 1408 { 1409 super(decl); 1410 this.loc = loc; 1411 this.visibility = v; 1412 } 1413 extern (D) this(const ref Loc loc, Identifier[] pkg_identifiers, Dsymbols* decl) 1414 { 1415 super(decl); 1416 this.loc = loc; 1417 this.visibility.kind = Visibility.Kind.package_; 1418 this.visibility.pkg = null; 1419 this.pkg_identifiers = pkg_identifiers; 1420 } 1421 1422 override void accept(Visitor v) 1423 { 1424 v.visit(this); 1425 } 1426 } 1427 1428 extern (C++) final class PragmaDeclaration : AttribDeclaration 1429 { 1430 Expressions* args; 1431 1432 extern (D) this(const ref Loc loc, Identifier ident, Expressions* args, Dsymbols* decl) 1433 { 1434 super(decl); 1435 this.loc = loc; 1436 this.ident = ident; 1437 this.args = args; 1438 } 1439 1440 override void accept(Visitor v) 1441 { 1442 v.visit(this); 1443 } 1444 } 1445 1446 extern (C++) class StorageClassDeclaration : AttribDeclaration 1447 { 1448 StorageClass stc; 1449 1450 final extern (D) this(StorageClass stc, Dsymbols* decl) 1451 { 1452 super(decl); 1453 this.stc = stc; 1454 } 1455 1456 override void accept(Visitor v) 1457 { 1458 v.visit(this); 1459 } 1460 } 1461 1462 extern (C++) class ConditionalDeclaration : AttribDeclaration 1463 { 1464 Condition condition; 1465 Dsymbols* elsedecl; 1466 1467 final extern (D) this(const ref Loc loc, Condition condition, Dsymbols* decl, Dsymbols* elsedecl) 1468 { 1469 super(loc, null, decl); 1470 this.condition = condition; 1471 this.elsedecl = elsedecl; 1472 } 1473 1474 override void accept(Visitor v) 1475 { 1476 v.visit(this); 1477 } 1478 } 1479 1480 extern (C++) final class DeprecatedDeclaration : StorageClassDeclaration 1481 { 1482 Expression msg; 1483 1484 extern (D) this(Expression msg, Dsymbols* decl) 1485 { 1486 super(STC.deprecated_, decl); 1487 this.msg = msg; 1488 } 1489 1490 override void accept(Visitor v) 1491 { 1492 v.visit(this); 1493 } 1494 } 1495 1496 extern (C++) final class StaticIfDeclaration : ConditionalDeclaration 1497 { 1498 extern (D) this(const ref Loc loc, Condition condition, Dsymbols* decl, Dsymbols* elsedecl) 1499 { 1500 super(loc, condition, decl, elsedecl); 1501 } 1502 1503 override void accept(Visitor v) 1504 { 1505 v.visit(this); 1506 } 1507 } 1508 1509 extern (C++) final class StaticForeachDeclaration : AttribDeclaration 1510 { 1511 StaticForeach sfe; 1512 1513 extern (D) this(StaticForeach sfe, Dsymbols* decl) 1514 { 1515 super(sfe.loc, null, decl); 1516 this.sfe = sfe; 1517 } 1518 1519 override void accept(Visitor v) 1520 { 1521 v.visit(this); 1522 } 1523 } 1524 1525 extern (C++) final class EnumMember : VarDeclaration 1526 { 1527 Expression origValue; 1528 Type origType; 1529 1530 @property ref value() { return (cast(ExpInitializer)_init).exp; } 1531 1532 extern (D) this(const ref Loc loc, Identifier id, Expression value, Type origType) 1533 { 1534 super(loc, null, id ? id : Id.empty, new ExpInitializer(loc, value)); 1535 this.origValue = value; 1536 this.origType = origType; 1537 } 1538 1539 extern(D) this(const ref Loc loc, Identifier id, Expression value, Type memtype, 1540 StorageClass stc, UserAttributeDeclaration uad, DeprecatedDeclaration dd) 1541 { 1542 this(loc, id, value, memtype); 1543 storage_class = stc; 1544 userAttribDecl = uad; 1545 // just ignore `dd` 1546 } 1547 1548 override void accept(Visitor v) 1549 { 1550 v.visit(this); 1551 } 1552 } 1553 1554 extern (C++) final class Module : Package 1555 { 1556 extern (C++) __gshared AggregateDeclaration moduleinfo; 1557 1558 const FileName srcfile; 1559 const(char)* arg; 1560 1561 extern (D) this(const(char)* filename, Identifier ident, int doDocComment, int doHdrGen) 1562 { 1563 super(ident); 1564 this.arg = filename; 1565 srcfile = FileName(FileName.defaultExt(filename.toDString, global.mars_ext)); 1566 } 1567 1568 override void accept(Visitor v) 1569 { 1570 v.visit(this); 1571 } 1572 } 1573 1574 extern (C++) class StructDeclaration : AggregateDeclaration 1575 { 1576 int zeroInit; 1577 StructPOD ispod; 1578 1579 final extern (D) this(const ref Loc loc, Identifier id, bool inObject) 1580 { 1581 super(loc, id); 1582 zeroInit = 0; 1583 ispod = StructPOD.fwd; 1584 type = new TypeStruct(this); 1585 if (inObject) 1586 { 1587 if (id == Id.ModuleInfo && !Module.moduleinfo) 1588 Module.moduleinfo = this; 1589 } 1590 } 1591 1592 override void accept(Visitor v) 1593 { 1594 v.visit(this); 1595 } 1596 } 1597 1598 extern (C++) final class UnionDeclaration : StructDeclaration 1599 { 1600 extern (D) this(const ref Loc loc, Identifier id) 1601 { 1602 super(loc, id, false); 1603 } 1604 1605 override void accept(Visitor v) 1606 { 1607 v.visit(this); 1608 } 1609 } 1610 1611 extern (C++) class ClassDeclaration : AggregateDeclaration 1612 { 1613 extern (C++) __gshared 1614 { 1615 // Names found by reading object.d in druntime 1616 ClassDeclaration object; 1617 ClassDeclaration throwable; 1618 ClassDeclaration exception; 1619 ClassDeclaration errorException; 1620 ClassDeclaration cpp_type_info_ptr; // Object.__cpp_type_info_ptr 1621 } 1622 1623 BaseClasses* baseclasses; 1624 Baseok baseok; 1625 1626 final extern (D) this(const ref Loc loc, Identifier id, BaseClasses* baseclasses, Dsymbols* members, bool inObject) 1627 { 1628 if(!id) 1629 id = Identifier.generateId("__anonclass"); 1630 assert(id); 1631 1632 super(loc, id); 1633 1634 __gshared const(char)* msg = "only object.d can define this reserved class name"; 1635 1636 if (baseclasses) 1637 { 1638 // Actually, this is a transfer 1639 this.baseclasses = baseclasses; 1640 } 1641 else 1642 this.baseclasses = new BaseClasses(); 1643 1644 this.members = members; 1645 1646 //printf("ClassDeclaration(%s), dim = %d\n", id.toChars(), this.baseclasses.dim); 1647 1648 // For forward references 1649 type = new TypeClass(this); 1650 1651 if (id) 1652 { 1653 // Look for special class names 1654 if (id == Id.__sizeof || id == Id.__xalignof || id == Id._mangleof) 1655 error("illegal class name"); 1656 1657 // BUG: What if this is the wrong TypeInfo, i.e. it is nested? 1658 if (id.toChars()[0] == 'T') 1659 { 1660 if (id == Id.TypeInfo) 1661 { 1662 if (!inObject) 1663 error("%s", msg); 1664 Type.dtypeinfo = this; 1665 } 1666 if (id == Id.TypeInfo_Class) 1667 { 1668 if (!inObject) 1669 error("%s", msg); 1670 Type.typeinfoclass = this; 1671 } 1672 if (id == Id.TypeInfo_Interface) 1673 { 1674 if (!inObject) 1675 error("%s", msg); 1676 Type.typeinfointerface = this; 1677 } 1678 if (id == Id.TypeInfo_Struct) 1679 { 1680 if (!inObject) 1681 error("%s", msg); 1682 Type.typeinfostruct = this; 1683 } 1684 if (id == Id.TypeInfo_Pointer) 1685 { 1686 if (!inObject) 1687 error("%s", msg); 1688 Type.typeinfopointer = this; 1689 } 1690 if (id == Id.TypeInfo_Array) 1691 { 1692 if (!inObject) 1693 error("%s", msg); 1694 Type.typeinfoarray = this; 1695 } 1696 if (id == Id.TypeInfo_StaticArray) 1697 { 1698 //if (!inObject) 1699 // Type.typeinfostaticarray.error("%s", msg); 1700 Type.typeinfostaticarray = this; 1701 } 1702 if (id == Id.TypeInfo_AssociativeArray) 1703 { 1704 if (!inObject) 1705 error("%s", msg); 1706 Type.typeinfoassociativearray = this; 1707 } 1708 if (id == Id.TypeInfo_Enum) 1709 { 1710 if (!inObject) 1711 error("%s", msg); 1712 Type.typeinfoenum = this; 1713 } 1714 if (id == Id.TypeInfo_Function) 1715 { 1716 if (!inObject) 1717 error("%s", msg); 1718 Type.typeinfofunction = this; 1719 } 1720 if (id == Id.TypeInfo_Delegate) 1721 { 1722 if (!inObject) 1723 error("%s", msg); 1724 Type.typeinfodelegate = this; 1725 } 1726 if (id == Id.TypeInfo_Tuple) 1727 { 1728 if (!inObject) 1729 error("%s", msg); 1730 Type.typeinfotypelist = this; 1731 } 1732 if (id == Id.TypeInfo_Const) 1733 { 1734 if (!inObject) 1735 error("%s", msg); 1736 Type.typeinfoconst = this; 1737 } 1738 if (id == Id.TypeInfo_Invariant) 1739 { 1740 if (!inObject) 1741 error("%s", msg); 1742 Type.typeinfoinvariant = this; 1743 } 1744 if (id == Id.TypeInfo_Shared) 1745 { 1746 if (!inObject) 1747 error("%s", msg); 1748 Type.typeinfoshared = this; 1749 } 1750 if (id == Id.TypeInfo_Wild) 1751 { 1752 if (!inObject) 1753 error("%s", msg); 1754 Type.typeinfowild = this; 1755 } 1756 if (id == Id.TypeInfo_Vector) 1757 { 1758 if (!inObject) 1759 error("%s", msg); 1760 Type.typeinfovector = this; 1761 } 1762 } 1763 1764 if (id == Id.Object) 1765 { 1766 if (!inObject) 1767 error("%s", msg); 1768 object = this; 1769 } 1770 1771 if (id == Id.Throwable) 1772 { 1773 if (!inObject) 1774 error("%s", msg); 1775 throwable = this; 1776 } 1777 if (id == Id.Exception) 1778 { 1779 if (!inObject) 1780 error("%s", msg); 1781 exception = this; 1782 } 1783 if (id == Id.Error) 1784 { 1785 if (!inObject) 1786 error("%s", msg); 1787 errorException = this; 1788 } 1789 if (id == Id.cpp_type_info_ptr) 1790 { 1791 if (!inObject) 1792 error("%s", msg); 1793 cpp_type_info_ptr = this; 1794 } 1795 } 1796 baseok = Baseok.none; 1797 } 1798 1799 override final inout(ClassDeclaration) isClassDeclaration() inout 1800 { 1801 return this; 1802 } 1803 1804 override void accept(Visitor v) 1805 { 1806 v.visit(this); 1807 } 1808 } 1809 1810 extern (C++) class InterfaceDeclaration : ClassDeclaration 1811 { 1812 final extern (D) this(const ref Loc loc, Identifier id, BaseClasses* baseclasses) 1813 { 1814 super(loc, id, baseclasses, null, false); 1815 } 1816 1817 override void accept(Visitor v) 1818 { 1819 v.visit(this); 1820 } 1821 } 1822 1823 extern (C++) class TemplateMixin : TemplateInstance 1824 { 1825 TypeQualified tqual; 1826 1827 extern (D) this(const ref Loc loc, Identifier ident, TypeQualified tqual, Objects *tiargs) 1828 { 1829 super(loc, 1830 tqual.idents.dim ? cast(Identifier)tqual.idents[tqual.idents.dim - 1] : (cast(TypeIdentifier)tqual).ident, 1831 tiargs ? tiargs : new Objects()); 1832 this.ident = ident; 1833 this.tqual = tqual; 1834 } 1835 1836 override void accept(Visitor v) 1837 { 1838 v.visit(this); 1839 } 1840 } 1841 1842 extern (C++) struct ParameterList 1843 { 1844 Parameters* parameters; 1845 StorageClass stc; // storage class of ... 1846 VarArg varargs = VarArg.none; 1847 1848 this(Parameters* parameters, VarArg varargs = VarArg.none, StorageClass stc = 0) 1849 { 1850 this.parameters = parameters; 1851 this.varargs = varargs; 1852 this.stc = stc; 1853 } 1854 } 1855 1856 extern (C++) final class Parameter : ASTNode 1857 { 1858 StorageClass storageClass; 1859 Type type; 1860 Identifier ident; 1861 Expression defaultArg; 1862 UserAttributeDeclaration userAttribDecl; // user defined attributes 1863 1864 extern (D) alias ForeachDg = int delegate(size_t idx, Parameter param); 1865 1866 final extern (D) this(StorageClass storageClass, Type type, Identifier ident, Expression defaultArg, UserAttributeDeclaration userAttribDecl) 1867 { 1868 this.storageClass = storageClass; 1869 this.type = type; 1870 this.ident = ident; 1871 this.defaultArg = defaultArg; 1872 this.userAttribDecl = userAttribDecl; 1873 } 1874 1875 static size_t dim(Parameters* parameters) 1876 { 1877 size_t nargs = 0; 1878 1879 int dimDg(size_t n, Parameter p) 1880 { 1881 ++nargs; 1882 return 0; 1883 } 1884 1885 _foreach(parameters, &dimDg); 1886 return nargs; 1887 } 1888 1889 static Parameter getNth(Parameters* parameters, size_t nth, size_t* pn = null) 1890 { 1891 Parameter param; 1892 1893 int getNthParamDg(size_t n, Parameter p) 1894 { 1895 if (n == nth) 1896 { 1897 param = p; 1898 return 1; 1899 } 1900 return 0; 1901 } 1902 1903 int res = _foreach(parameters, &getNthParamDg); 1904 return res ? param : null; 1905 } 1906 1907 extern (D) static int _foreach(Parameters* parameters, scope ForeachDg dg, size_t* pn = null) 1908 { 1909 assert(dg); 1910 if (!parameters) 1911 return 0; 1912 1913 size_t n = pn ? *pn : 0; // take over index 1914 int result = 0; 1915 foreach (i; 0 .. parameters.dim) 1916 { 1917 Parameter p = (*parameters)[i]; 1918 Type t = p.type.toBasetype(); 1919 1920 if (t.ty == Ttuple) 1921 { 1922 TypeTuple tu = cast(TypeTuple)t; 1923 result = _foreach(tu.arguments, dg, &n); 1924 } 1925 else 1926 result = dg(n++, p); 1927 1928 if (result) 1929 break; 1930 } 1931 1932 if (pn) 1933 *pn = n; // update index 1934 return result; 1935 } 1936 1937 Parameter syntaxCopy() 1938 { 1939 return new Parameter(storageClass, type ? type.syntaxCopy() : null, ident, defaultArg ? defaultArg.syntaxCopy() : null, userAttribDecl ? userAttribDecl.syntaxCopy(null) : null); 1940 } 1941 1942 override void accept(Visitor v) 1943 { 1944 v.visit(this); 1945 } 1946 1947 static Parameters* arraySyntaxCopy(Parameters* parameters) 1948 { 1949 Parameters* params = null; 1950 if (parameters) 1951 { 1952 params = new Parameters(); 1953 params.setDim(parameters.dim); 1954 for (size_t i = 0; i < params.dim; i++) 1955 (*params)[i] = (*parameters)[i].syntaxCopy(); 1956 } 1957 return params; 1958 } 1959 1960 } 1961 1962 enum STMT : ubyte 1963 { 1964 Error, 1965 Peel, 1966 Exp, DtorExp, 1967 Compile, 1968 Compound, CompoundDeclaration, CompoundAsm, 1969 UnrolledLoop, 1970 Scope, 1971 Forwarding, 1972 While, 1973 Do, 1974 For, 1975 Foreach, 1976 ForeachRange, 1977 If, 1978 Conditional, 1979 StaticForeach, 1980 Pragma, 1981 StaticAssert, 1982 Switch, 1983 Case, 1984 CaseRange, 1985 Default, 1986 GotoDefault, 1987 GotoCase, 1988 SwitchError, 1989 Return, 1990 Break, 1991 Continue, 1992 Synchronized, 1993 With, 1994 TryCatch, 1995 TryFinally, 1996 ScopeGuard, 1997 Throw, 1998 Debug, 1999 Goto, 2000 Label, 2001 Asm, InlineAsm, GccAsm, 2002 Import, 2003 } 2004 2005 extern (C++) abstract class Statement : ASTNode 2006 { 2007 Loc loc; 2008 STMT stmt; 2009 2010 final extern (D) this(const ref Loc loc, STMT stmt) 2011 { 2012 this.loc = loc; 2013 this.stmt = stmt; 2014 } 2015 2016 nothrow pure @nogc 2017 inout(ExpStatement) isExpStatement() inout { return stmt == STMT.Exp ? cast(typeof(return))this : null; } 2018 2019 nothrow pure @nogc 2020 inout(CompoundStatement) isCompoundStatement() inout { return stmt == STMT.Compound ? cast(typeof(return))this : null; } 2021 2022 nothrow pure @nogc 2023 inout(ReturnStatement) isReturnStatement() inout { return stmt == STMT.Return ? cast(typeof(return))this : null; } 2024 2025 override void accept(Visitor v) 2026 { 2027 v.visit(this); 2028 } 2029 } 2030 2031 extern (C++) final class ImportStatement : Statement 2032 { 2033 Dsymbols* imports; 2034 2035 extern (D) this(const ref Loc loc, Dsymbols* imports) 2036 { 2037 super(loc, STMT.Import); 2038 this.imports = imports; 2039 } 2040 2041 override void accept(Visitor v) 2042 { 2043 v.visit(this); 2044 } 2045 } 2046 2047 extern (C++) final class ScopeStatement : Statement 2048 { 2049 Statement statement; 2050 Loc endloc; 2051 2052 extern (D) this(const ref Loc loc, Statement s, Loc endloc) 2053 { 2054 super(loc, STMT.Scope); 2055 this.statement = s; 2056 this.endloc = endloc; 2057 } 2058 2059 override void accept(Visitor v) 2060 { 2061 v.visit(this); 2062 } 2063 } 2064 2065 extern (C++) final class ReturnStatement : Statement 2066 { 2067 Expression exp; 2068 2069 extern (D) this(const ref Loc loc, Expression exp) 2070 { 2071 super(loc, STMT.Return); 2072 this.exp = exp; 2073 } 2074 2075 override void accept(Visitor v) 2076 { 2077 v.visit(this); 2078 } 2079 } 2080 2081 extern (C++) final class LabelStatement : Statement 2082 { 2083 Identifier ident; 2084 Statement statement; 2085 2086 final extern (D) this(const ref Loc loc, Identifier ident, Statement statement) 2087 { 2088 super(loc, STMT.Label); 2089 this.ident = ident; 2090 this.statement = statement; 2091 } 2092 2093 override void accept(Visitor v) 2094 { 2095 v.visit(this); 2096 } 2097 } 2098 2099 extern (C++) final class StaticAssertStatement : Statement 2100 { 2101 StaticAssert sa; 2102 2103 final extern (D) this(StaticAssert sa) 2104 { 2105 super(sa.loc, STMT.StaticAssert); 2106 this.sa = sa; 2107 } 2108 2109 override void accept(Visitor v) 2110 { 2111 v.visit(this); 2112 } 2113 } 2114 2115 extern (C++) final class CompileStatement : Statement 2116 { 2117 Expressions* exps; 2118 2119 final extern (D) this(const ref Loc loc, Expressions* exps) 2120 { 2121 super(loc, STMT.Compile); 2122 this.exps = exps; 2123 } 2124 2125 override void accept(Visitor v) 2126 { 2127 v.visit(this); 2128 } 2129 } 2130 2131 extern (C++) final class WhileStatement : Statement 2132 { 2133 Expression condition; 2134 Statement _body; 2135 Loc endloc; 2136 2137 extern (D) this(const ref Loc loc, Expression c, Statement b, Loc endloc) 2138 { 2139 super(loc, STMT.While); 2140 condition = c; 2141 _body = b; 2142 this.endloc = endloc; 2143 } 2144 2145 override void accept(Visitor v) 2146 { 2147 v.visit(this); 2148 } 2149 } 2150 2151 extern (C++) final class ForStatement : Statement 2152 { 2153 Statement _init; 2154 Expression condition; 2155 Expression increment; 2156 Statement _body; 2157 Loc endloc; 2158 2159 extern (D) this(const ref Loc loc, Statement _init, Expression condition, Expression increment, Statement _body, Loc endloc) 2160 { 2161 super(loc, STMT.For); 2162 this._init = _init; 2163 this.condition = condition; 2164 this.increment = increment; 2165 this._body = _body; 2166 this.endloc = endloc; 2167 } 2168 2169 override void accept(Visitor v) 2170 { 2171 v.visit(this); 2172 } 2173 } 2174 2175 extern (C++) final class DoStatement : Statement 2176 { 2177 Statement _body; 2178 Expression condition; 2179 Loc endloc; 2180 2181 extern (D) this(const ref Loc loc, Statement b, Expression c, Loc endloc) 2182 { 2183 super(loc, STMT.Do); 2184 _body = b; 2185 condition = c; 2186 this.endloc = endloc; 2187 } 2188 2189 override void accept(Visitor v) 2190 { 2191 v.visit(this); 2192 } 2193 } 2194 2195 extern (C++) final class ForeachRangeStatement : Statement 2196 { 2197 TOK op; // TOK.foreach_ or TOK.foreach_reverse_ 2198 Parameter prm; // loop index variable 2199 Expression lwr; 2200 Expression upr; 2201 Statement _body; 2202 Loc endloc; // location of closing curly bracket 2203 2204 2205 extern (D) this(const ref Loc loc, TOK op, Parameter prm, Expression lwr, Expression upr, Statement _body, Loc endloc) 2206 { 2207 super(loc, STMT.ForeachRange); 2208 this.op = op; 2209 this.prm = prm; 2210 this.lwr = lwr; 2211 this.upr = upr; 2212 this._body = _body; 2213 this.endloc = endloc; 2214 } 2215 2216 override void accept(Visitor v) 2217 { 2218 v.visit(this); 2219 } 2220 } 2221 2222 extern (C++) final class ForeachStatement : Statement 2223 { 2224 TOK op; // TOK.foreach_ or TOK.foreach_reverse_ 2225 Parameters* parameters; // array of Parameter*'s 2226 Expression aggr; 2227 Statement _body; 2228 Loc endloc; // location of closing curly bracket 2229 2230 extern (D) this(const ref Loc loc, TOK op, Parameters* parameters, Expression aggr, Statement _body, Loc endloc) 2231 { 2232 super(loc, STMT.Foreach); 2233 this.op = op; 2234 this.parameters = parameters; 2235 this.aggr = aggr; 2236 this._body = _body; 2237 this.endloc = endloc; 2238 } 2239 2240 override void accept(Visitor v) 2241 { 2242 v.visit(this); 2243 } 2244 } 2245 2246 extern (C++) final class IfStatement : Statement 2247 { 2248 Parameter prm; 2249 Expression condition; 2250 Statement ifbody; 2251 Statement elsebody; 2252 VarDeclaration match; // for MatchExpression results 2253 Loc endloc; // location of closing curly bracket 2254 2255 extern (D) this(const ref Loc loc, Parameter prm, Expression condition, Statement ifbody, Statement elsebody, Loc endloc) 2256 { 2257 super(loc, STMT.If); 2258 this.prm = prm; 2259 this.condition = condition; 2260 this.ifbody = ifbody; 2261 this.elsebody = elsebody; 2262 this.endloc = endloc; 2263 } 2264 2265 override void accept(Visitor v) 2266 { 2267 v.visit(this); 2268 } 2269 } 2270 2271 extern (C++) final class ScopeGuardStatement : Statement 2272 { 2273 TOK tok; 2274 Statement statement; 2275 2276 extern (D) this(const ref Loc loc, TOK tok, Statement statement) 2277 { 2278 super(loc, STMT.ScopeGuard); 2279 this.tok = tok; 2280 this.statement = statement; 2281 } 2282 2283 override void accept(Visitor v) 2284 { 2285 v.visit(this); 2286 } 2287 } 2288 2289 extern (C++) final class ConditionalStatement : Statement 2290 { 2291 Condition condition; 2292 Statement ifbody; 2293 Statement elsebody; 2294 2295 extern (D) this(const ref Loc loc, Condition condition, Statement ifbody, Statement elsebody) 2296 { 2297 super(loc, STMT.Conditional); 2298 this.condition = condition; 2299 this.ifbody = ifbody; 2300 this.elsebody = elsebody; 2301 } 2302 2303 override void accept(Visitor v) 2304 { 2305 v.visit(this); 2306 } 2307 } 2308 2309 extern (C++) final class StaticForeachStatement : Statement 2310 { 2311 StaticForeach sfe; 2312 2313 extern (D) this(const ref Loc loc, StaticForeach sfe) 2314 { 2315 super(loc, STMT.StaticForeach); 2316 this.sfe = sfe; 2317 } 2318 2319 override void accept(Visitor v) 2320 { 2321 v.visit(this); 2322 } 2323 } 2324 2325 extern (C++) final class PragmaStatement : Statement 2326 { 2327 Identifier ident; 2328 Expressions* args; // array of Expression's 2329 Statement _body; 2330 2331 extern (D) this(const ref Loc loc, Identifier ident, Expressions* args, Statement _body) 2332 { 2333 super(loc, STMT.Pragma); 2334 this.ident = ident; 2335 this.args = args; 2336 this._body = _body; 2337 } 2338 2339 override void accept(Visitor v) 2340 { 2341 v.visit(this); 2342 } 2343 } 2344 2345 extern (C++) final class SwitchStatement : Statement 2346 { 2347 Expression condition; 2348 Statement _body; 2349 bool isFinal; 2350 2351 extern (D) this(const ref Loc loc, Expression c, Statement b, bool isFinal) 2352 { 2353 super(loc, STMT.Switch); 2354 this.condition = c; 2355 this._body = b; 2356 this.isFinal = isFinal; 2357 } 2358 2359 override void accept(Visitor v) 2360 { 2361 v.visit(this); 2362 } 2363 } 2364 2365 extern (C++) final class CaseRangeStatement : Statement 2366 { 2367 Expression first; 2368 Expression last; 2369 Statement statement; 2370 2371 extern (D) this(const ref Loc loc, Expression first, Expression last, Statement s) 2372 { 2373 super(loc, STMT.CaseRange); 2374 this.first = first; 2375 this.last = last; 2376 this.statement = s; 2377 } 2378 2379 override void accept(Visitor v) 2380 { 2381 v.visit(this); 2382 } 2383 } 2384 2385 extern (C++) final class CaseStatement : Statement 2386 { 2387 Expression exp; 2388 Statement statement; 2389 2390 extern (D) this(const ref Loc loc, Expression exp, Statement s) 2391 { 2392 super(loc, STMT.Case); 2393 this.exp = exp; 2394 this.statement = s; 2395 } 2396 2397 override void accept(Visitor v) 2398 { 2399 v.visit(this); 2400 } 2401 } 2402 2403 extern (C++) final class DefaultStatement : Statement 2404 { 2405 Statement statement; 2406 2407 extern (D) this(const ref Loc loc, Statement s) 2408 { 2409 super(loc, STMT.Default); 2410 this.statement = s; 2411 } 2412 2413 override void accept(Visitor v) 2414 { 2415 v.visit(this); 2416 } 2417 } 2418 2419 extern (C++) final class BreakStatement : Statement 2420 { 2421 Identifier ident; 2422 2423 extern (D) this(const ref Loc loc, Identifier ident) 2424 { 2425 super(loc, STMT.Break); 2426 this.ident = ident; 2427 } 2428 2429 override void accept(Visitor v) 2430 { 2431 v.visit(this); 2432 } 2433 } 2434 2435 extern (C++) final class ContinueStatement : Statement 2436 { 2437 Identifier ident; 2438 2439 extern (D) this(const ref Loc loc, Identifier ident) 2440 { 2441 super(loc, STMT.Continue); 2442 this.ident = ident; 2443 } 2444 2445 override void accept(Visitor v) 2446 { 2447 v.visit(this); 2448 } 2449 } 2450 2451 extern (C++) final class GotoDefaultStatement : Statement 2452 { 2453 extern (D) this(const ref Loc loc) 2454 { 2455 super(loc, STMT.GotoDefault); 2456 } 2457 2458 override void accept(Visitor v) 2459 { 2460 v.visit(this); 2461 } 2462 } 2463 2464 extern (C++) final class GotoCaseStatement : Statement 2465 { 2466 Expression exp; 2467 2468 extern (D) this(const ref Loc loc, Expression exp) 2469 { 2470 super(loc, STMT.GotoCase); 2471 this.exp = exp; 2472 } 2473 2474 override void accept(Visitor v) 2475 { 2476 v.visit(this); 2477 } 2478 } 2479 2480 extern (C++) final class GotoStatement : Statement 2481 { 2482 Identifier ident; 2483 2484 extern (D) this(const ref Loc loc, Identifier ident) 2485 { 2486 super(loc, STMT.Goto); 2487 this.ident = ident; 2488 } 2489 2490 override void accept(Visitor v) 2491 { 2492 v.visit(this); 2493 } 2494 } 2495 2496 extern (C++) final class SynchronizedStatement : Statement 2497 { 2498 Expression exp; 2499 Statement _body; 2500 2501 extern (D) this(const ref Loc loc, Expression exp, Statement _body) 2502 { 2503 super(loc, STMT.Synchronized); 2504 this.exp = exp; 2505 this._body = _body; 2506 } 2507 2508 override void accept(Visitor v) 2509 { 2510 v.visit(this); 2511 } 2512 } 2513 2514 extern (C++) final class WithStatement : Statement 2515 { 2516 Expression exp; 2517 Statement _body; 2518 Loc endloc; 2519 2520 extern (D) this(const ref Loc loc, Expression exp, Statement _body, Loc endloc) 2521 { 2522 super(loc, STMT.With); 2523 this.exp = exp; 2524 this._body = _body; 2525 this.endloc = endloc; 2526 } 2527 2528 override void accept(Visitor v) 2529 { 2530 v.visit(this); 2531 } 2532 } 2533 2534 extern (C++) final class TryCatchStatement : Statement 2535 { 2536 Statement _body; 2537 Catches* catches; 2538 2539 extern (D) this(const ref Loc loc, Statement _body, Catches* catches) 2540 { 2541 super(loc, STMT.TryCatch); 2542 this._body = _body; 2543 this.catches = catches; 2544 } 2545 2546 override void accept(Visitor v) 2547 { 2548 v.visit(this); 2549 } 2550 } 2551 2552 extern (C++) final class TryFinallyStatement : Statement 2553 { 2554 Statement _body; 2555 Statement finalbody; 2556 2557 extern (D) this(const ref Loc loc, Statement _body, Statement finalbody) 2558 { 2559 super(loc, STMT.TryFinally); 2560 this._body = _body; 2561 this.finalbody = finalbody; 2562 } 2563 2564 override void accept(Visitor v) 2565 { 2566 v.visit(this); 2567 } 2568 } 2569 2570 extern (C++) final class ThrowStatement : Statement 2571 { 2572 Expression exp; 2573 2574 extern (D) this(const ref Loc loc, Expression exp) 2575 { 2576 super(loc, STMT.Throw); 2577 this.exp = exp; 2578 } 2579 2580 override void accept(Visitor v) 2581 { 2582 v.visit(this); 2583 } 2584 } 2585 2586 extern (C++) class AsmStatement : Statement 2587 { 2588 Token* tokens; 2589 2590 extern (D) this(const ref Loc loc, Token* tokens) 2591 { 2592 super(loc, STMT.Asm); 2593 this.tokens = tokens; 2594 } 2595 2596 extern (D) this(const ref Loc loc, Token* tokens, STMT stmt) 2597 { 2598 super(loc, stmt); 2599 this.tokens = tokens; 2600 } 2601 2602 override void accept(Visitor v) 2603 { 2604 v.visit(this); 2605 } 2606 } 2607 2608 extern (C++) final class InlineAsmStatement : AsmStatement 2609 { 2610 extern (D) this(const ref Loc loc, Token* tokens) 2611 { 2612 super(loc, tokens, STMT.InlineAsm); 2613 } 2614 2615 override void accept(Visitor v) 2616 { 2617 v.visit(this); 2618 } 2619 } 2620 2621 extern (C++) final class GccAsmStatement : AsmStatement 2622 { 2623 extern (D) this(const ref Loc loc, Token* tokens) 2624 { 2625 super(loc, tokens, STMT.GccAsm); 2626 } 2627 2628 override void accept(Visitor v) 2629 { 2630 v.visit(this); 2631 } 2632 } 2633 2634 extern (C++) class ExpStatement : Statement 2635 { 2636 Expression exp; 2637 2638 final extern (D) this(const ref Loc loc, Expression exp) 2639 { 2640 super(loc, STMT.Exp); 2641 this.exp = exp; 2642 } 2643 final extern (D) this(const ref Loc loc, Dsymbol declaration) 2644 { 2645 super(loc, STMT.Exp); 2646 this.exp = new DeclarationExp(loc, declaration); 2647 } 2648 2649 override void accept(Visitor v) 2650 { 2651 v.visit(this); 2652 } 2653 } 2654 2655 extern (C++) class CompoundStatement : Statement 2656 { 2657 Statements* statements; 2658 2659 final extern (D) this(const ref Loc loc, Statements* statements) 2660 { 2661 super(loc, STMT.Compound); 2662 this.statements = statements; 2663 } 2664 2665 final extern (D) this(const ref Loc loc, Statements* statements, STMT stmt) 2666 { 2667 super(loc, stmt); 2668 this.statements = statements; 2669 } 2670 2671 final extern (D) this(const ref Loc loc, Statement[] sts...) 2672 { 2673 super(loc, STMT.Compound); 2674 statements = new Statements(); 2675 statements.reserve(sts.length); 2676 foreach (s; sts) 2677 statements.push(s); 2678 } 2679 2680 override void accept(Visitor v) 2681 { 2682 v.visit(this); 2683 } 2684 } 2685 2686 extern (C++) final class CompoundDeclarationStatement : CompoundStatement 2687 { 2688 final extern (D) this(const ref Loc loc, Statements* statements) 2689 { 2690 super(loc, statements, STMT.CompoundDeclaration); 2691 } 2692 2693 override void accept(Visitor v) 2694 { 2695 v.visit(this); 2696 } 2697 } 2698 2699 extern (C++) final class CompoundAsmStatement : CompoundStatement 2700 { 2701 StorageClass stc; 2702 2703 final extern (D) this(const ref Loc loc, Statements* s, StorageClass stc) 2704 { 2705 super(loc, s, STMT.CompoundAsm); 2706 this.stc = stc; 2707 } 2708 2709 override void accept(Visitor v) 2710 { 2711 v.visit(this); 2712 } 2713 } 2714 2715 extern (C++) final class Catch : RootObject 2716 { 2717 Loc loc; 2718 Type type; 2719 Identifier ident; 2720 Statement handler; 2721 2722 extern (D) this(const ref Loc loc, Type t, Identifier id, Statement handler) 2723 { 2724 this.loc = loc; 2725 this.type = t; 2726 this.ident = id; 2727 this.handler = handler; 2728 } 2729 } 2730 2731 extern (C++) abstract class Type : ASTNode 2732 { 2733 TY ty; 2734 MOD mod; 2735 char* deco; 2736 2737 extern (C++) __gshared Type tvoid; 2738 extern (C++) __gshared Type tint8; 2739 extern (C++) __gshared Type tuns8; 2740 extern (C++) __gshared Type tint16; 2741 extern (C++) __gshared Type tuns16; 2742 extern (C++) __gshared Type tint32; 2743 extern (C++) __gshared Type tuns32; 2744 extern (C++) __gshared Type tint64; 2745 extern (C++) __gshared Type tuns64; 2746 extern (C++) __gshared Type tint128; 2747 extern (C++) __gshared Type tuns128; 2748 extern (C++) __gshared Type tfloat32; 2749 extern (C++) __gshared Type tfloat64; 2750 extern (C++) __gshared Type tfloat80; 2751 extern (C++) __gshared Type timaginary32; 2752 extern (C++) __gshared Type timaginary64; 2753 extern (C++) __gshared Type timaginary80; 2754 extern (C++) __gshared Type tcomplex32; 2755 extern (C++) __gshared Type tcomplex64; 2756 extern (C++) __gshared Type tcomplex80; 2757 extern (C++) __gshared Type tbool; 2758 extern (C++) __gshared Type tchar; 2759 extern (C++) __gshared Type twchar; 2760 extern (C++) __gshared Type tdchar; 2761 2762 extern (C++) __gshared Type[TMAX] basic; 2763 2764 extern (C++) __gshared Type tshiftcnt; 2765 extern (C++) __gshared Type tvoidptr; // void* 2766 extern (C++) __gshared Type tstring; // immutable(char)[] 2767 extern (C++) __gshared Type twstring; // immutable(wchar)[] 2768 extern (C++) __gshared Type tdstring; // immutable(dchar)[] 2769 extern (C++) __gshared Type terror; // for error recovery 2770 extern (C++) __gshared Type tnull; // for null type 2771 extern (C++) __gshared Type tnoreturn; // for bottom type 2772 2773 extern (C++) __gshared Type tsize_t; // matches size_t alias 2774 extern (C++) __gshared Type tptrdiff_t; // matches ptrdiff_t alias 2775 extern (C++) __gshared Type thash_t; // matches hash_t alias 2776 2777 2778 2779 extern (C++) __gshared ClassDeclaration dtypeinfo; 2780 extern (C++) __gshared ClassDeclaration typeinfoclass; 2781 extern (C++) __gshared ClassDeclaration typeinfointerface; 2782 extern (C++) __gshared ClassDeclaration typeinfostruct; 2783 extern (C++) __gshared ClassDeclaration typeinfopointer; 2784 extern (C++) __gshared ClassDeclaration typeinfoarray; 2785 extern (C++) __gshared ClassDeclaration typeinfostaticarray; 2786 extern (C++) __gshared ClassDeclaration typeinfoassociativearray; 2787 extern (C++) __gshared ClassDeclaration typeinfovector; 2788 extern (C++) __gshared ClassDeclaration typeinfoenum; 2789 extern (C++) __gshared ClassDeclaration typeinfofunction; 2790 extern (C++) __gshared ClassDeclaration typeinfodelegate; 2791 extern (C++) __gshared ClassDeclaration typeinfotypelist; 2792 extern (C++) __gshared ClassDeclaration typeinfoconst; 2793 extern (C++) __gshared ClassDeclaration typeinfoinvariant; 2794 extern (C++) __gshared ClassDeclaration typeinfoshared; 2795 extern (C++) __gshared ClassDeclaration typeinfowild; 2796 extern (C++) __gshared StringTable!Type stringtable; 2797 extern (C++) __gshared ubyte[TMAX] sizeTy = () 2798 { 2799 ubyte[TMAX] sizeTy = __traits(classInstanceSize, TypeBasic); 2800 sizeTy[Tsarray] = __traits(classInstanceSize, TypeSArray); 2801 sizeTy[Tarray] = __traits(classInstanceSize, TypeDArray); 2802 sizeTy[Taarray] = __traits(classInstanceSize, TypeAArray); 2803 sizeTy[Tpointer] = __traits(classInstanceSize, TypePointer); 2804 sizeTy[Treference] = __traits(classInstanceSize, TypeReference); 2805 sizeTy[Tfunction] = __traits(classInstanceSize, TypeFunction); 2806 sizeTy[Tdelegate] = __traits(classInstanceSize, TypeDelegate); 2807 sizeTy[Tident] = __traits(classInstanceSize, TypeIdentifier); 2808 sizeTy[Tinstance] = __traits(classInstanceSize, TypeInstance); 2809 sizeTy[Ttypeof] = __traits(classInstanceSize, TypeTypeof); 2810 sizeTy[Tenum] = __traits(classInstanceSize, TypeEnum); 2811 sizeTy[Tstruct] = __traits(classInstanceSize, TypeStruct); 2812 sizeTy[Tclass] = __traits(classInstanceSize, TypeClass); 2813 sizeTy[Ttuple] = __traits(classInstanceSize, TypeTuple); 2814 sizeTy[Tslice] = __traits(classInstanceSize, TypeSlice); 2815 sizeTy[Treturn] = __traits(classInstanceSize, TypeReturn); 2816 sizeTy[Terror] = __traits(classInstanceSize, TypeError); 2817 sizeTy[Tnull] = __traits(classInstanceSize, TypeNull); 2818 sizeTy[Tvector] = __traits(classInstanceSize, TypeVector); 2819 sizeTy[Tmixin] = __traits(classInstanceSize, TypeMixin); 2820 sizeTy[Tnoreturn] = __traits(classInstanceSize, TypeNoreturn); 2821 return sizeTy; 2822 }(); 2823 2824 static struct Mcache 2825 { 2826 Type cto; // MODFlags.const_ 2827 Type ito; // MODFlags.immutable_ 2828 Type sto; // MODFlags.shared_ 2829 Type scto; // MODFlags.shared_ | MODFlags.const_ 2830 Type wto; // MODFlags.wild 2831 Type wcto; // MODFlags.wildconst 2832 Type swto; // MODFlags.shared_ | MODFlags.wild 2833 Type swcto; // MODFlags.shared_ | MODFlags.wildconst 2834 } 2835 private Mcache* mcache; 2836 2837 Type pto; 2838 Type rto; 2839 Type arrayof; 2840 2841 // These members are probably used in semnatic analysis 2842 //TypeInfoDeclaration vtinfo; 2843 //type* ctype; 2844 2845 final extern (D) this(TY ty) 2846 { 2847 this.ty = ty; 2848 } 2849 2850 override const(char)* toChars() const 2851 { 2852 return "type"; 2853 } 2854 2855 static void _init() 2856 { 2857 stringtable._init(14_000); 2858 2859 // Set basic types 2860 __gshared TY* basetab = 2861 [ 2862 Tvoid, 2863 Tint8, 2864 Tuns8, 2865 Tint16, 2866 Tuns16, 2867 Tint32, 2868 Tuns32, 2869 Tint64, 2870 Tuns64, 2871 Tint128, 2872 Tuns128, 2873 Tfloat32, 2874 Tfloat64, 2875 Tfloat80, 2876 Timaginary32, 2877 Timaginary64, 2878 Timaginary80, 2879 Tcomplex32, 2880 Tcomplex64, 2881 Tcomplex80, 2882 Tbool, 2883 Tchar, 2884 Twchar, 2885 Tdchar, 2886 Terror 2887 ]; 2888 2889 for (size_t i = 0; basetab[i] != Terror; i++) 2890 { 2891 Type t = new TypeBasic(basetab[i]); 2892 t = t.merge(); 2893 basic[basetab[i]] = t; 2894 } 2895 basic[Terror] = new TypeError(); 2896 2897 tnoreturn = new TypeNoreturn(); 2898 tnoreturn.deco = tnoreturn.merge().deco; 2899 basic[Tnoreturn] = tnoreturn; 2900 2901 tvoid = basic[Tvoid]; 2902 tint8 = basic[Tint8]; 2903 tuns8 = basic[Tuns8]; 2904 tint16 = basic[Tint16]; 2905 tuns16 = basic[Tuns16]; 2906 tint32 = basic[Tint32]; 2907 tuns32 = basic[Tuns32]; 2908 tint64 = basic[Tint64]; 2909 tuns64 = basic[Tuns64]; 2910 tint128 = basic[Tint128]; 2911 tuns128 = basic[Tuns128]; 2912 tfloat32 = basic[Tfloat32]; 2913 tfloat64 = basic[Tfloat64]; 2914 tfloat80 = basic[Tfloat80]; 2915 2916 timaginary32 = basic[Timaginary32]; 2917 timaginary64 = basic[Timaginary64]; 2918 timaginary80 = basic[Timaginary80]; 2919 2920 tcomplex32 = basic[Tcomplex32]; 2921 tcomplex64 = basic[Tcomplex64]; 2922 tcomplex80 = basic[Tcomplex80]; 2923 2924 tbool = basic[Tbool]; 2925 tchar = basic[Tchar]; 2926 twchar = basic[Twchar]; 2927 tdchar = basic[Tdchar]; 2928 2929 tshiftcnt = tint32; 2930 terror = basic[Terror]; 2931 tnoreturn = basic[Tnoreturn]; 2932 tnull = new TypeNull(); 2933 tnull.deco = tnull.merge().deco; 2934 2935 tvoidptr = tvoid.pointerTo(); 2936 tstring = tchar.immutableOf().arrayOf(); 2937 twstring = twchar.immutableOf().arrayOf(); 2938 tdstring = tdchar.immutableOf().arrayOf(); 2939 2940 const isLP64 = global.params.isLP64; 2941 2942 tsize_t = basic[isLP64 ? Tuns64 : Tuns32]; 2943 tptrdiff_t = basic[isLP64 ? Tint64 : Tint32]; 2944 thash_t = tsize_t; 2945 } 2946 2947 extern (D) 2948 final Mcache* getMcache() 2949 { 2950 if (!mcache) 2951 mcache = cast(Mcache*) mem.xcalloc(Mcache.sizeof, 1); 2952 return mcache; 2953 } 2954 2955 final Type pointerTo() 2956 { 2957 if (ty == Terror) 2958 return this; 2959 if (!pto) 2960 { 2961 Type t = new TypePointer(this); 2962 if (ty == Tfunction) 2963 { 2964 t.deco = t.merge().deco; 2965 pto = t; 2966 } 2967 else 2968 pto = t.merge(); 2969 } 2970 return pto; 2971 } 2972 2973 final Type arrayOf() 2974 { 2975 if (ty == Terror) 2976 return this; 2977 if (!arrayof) 2978 { 2979 Type t = new TypeDArray(this); 2980 arrayof = t.merge(); 2981 } 2982 return arrayof; 2983 } 2984 2985 final bool isImmutable() const 2986 { 2987 return (mod & MODFlags.immutable_) != 0; 2988 } 2989 2990 final Type nullAttributes() 2991 { 2992 uint sz = sizeTy[ty]; 2993 Type t = cast(Type)mem.xmalloc(sz); 2994 memcpy(cast(void*)t, cast(void*)this, sz); 2995 // t.mod = NULL; // leave mod unchanged 2996 t.deco = null; 2997 t.arrayof = null; 2998 t.pto = null; 2999 t.rto = null; 3000 t.mcache = null; 3001 //t.vtinfo = null; these aren't used in parsing 3002 //t.ctype = null; 3003 if (t.ty == Tstruct) 3004 (cast(TypeStruct)t).att = AliasThisRec.fwdref; 3005 if (t.ty == Tclass) 3006 (cast(TypeClass)t).att = AliasThisRec.fwdref; 3007 return t; 3008 } 3009 3010 Type makeConst() 3011 { 3012 if (mcache && mcache.cto) 3013 return mcache.cto; 3014 Type t = this.nullAttributes(); 3015 t.mod = MODFlags.const_; 3016 return t; 3017 } 3018 3019 Type makeWildConst() 3020 { 3021 if (mcache && mcache.wcto) 3022 return mcache.wcto; 3023 Type t = this.nullAttributes(); 3024 t.mod = MODFlags.wildconst; 3025 return t; 3026 } 3027 3028 Type makeShared() 3029 { 3030 if (mcache && mcache.sto) 3031 return mcache.sto; 3032 Type t = this.nullAttributes(); 3033 t.mod = MODFlags.shared_; 3034 return t; 3035 } 3036 3037 Type makeSharedConst() 3038 { 3039 if (mcache && mcache.scto) 3040 return mcache.scto; 3041 Type t = this.nullAttributes(); 3042 t.mod = MODFlags.shared_ | MODFlags.const_; 3043 return t; 3044 } 3045 3046 Type makeImmutable() 3047 { 3048 if (mcache && mcache.ito) 3049 return mcache.ito; 3050 Type t = this.nullAttributes(); 3051 t.mod = MODFlags.immutable_; 3052 return t; 3053 } 3054 3055 Type makeWild() 3056 { 3057 if (mcache && mcache.wto) 3058 return mcache.wto; 3059 Type t = this.nullAttributes(); 3060 t.mod = MODFlags.wild; 3061 return t; 3062 } 3063 3064 Type makeSharedWildConst() 3065 { 3066 if (mcache && mcache.swcto) 3067 return mcache.swcto; 3068 Type t = this.nullAttributes(); 3069 t.mod = MODFlags.shared_ | MODFlags.wildconst; 3070 return t; 3071 } 3072 3073 Type makeSharedWild() 3074 { 3075 if (mcache && mcache.swto) 3076 return mcache.swto; 3077 Type t = this.nullAttributes(); 3078 t.mod = MODFlags.shared_ | MODFlags.wild; 3079 return t; 3080 } 3081 3082 // Truncated 3083 final Type merge() 3084 { 3085 if (ty == Terror) 3086 return this; 3087 if (ty == Ttypeof) 3088 return this; 3089 if (ty == Tident) 3090 return this; 3091 if (ty == Tinstance) 3092 return this; 3093 if (ty == Taarray && !(cast(TypeAArray)this).index.merge().deco) 3094 return this; 3095 if (ty != Tenum && nextOf() && !nextOf().deco) 3096 return this; 3097 3098 // if (!deco) - code missing 3099 3100 Type t = this; 3101 assert(t); 3102 return t; 3103 } 3104 3105 final Type addSTC(StorageClass stc) 3106 { 3107 Type t = this; 3108 if (t.isImmutable()) 3109 { 3110 } 3111 else if (stc & STC.immutable_) 3112 { 3113 t = t.makeImmutable(); 3114 } 3115 else 3116 { 3117 if ((stc & STC.shared_) && !t.isShared()) 3118 { 3119 if (t.isWild()) 3120 { 3121 if (t.isConst()) 3122 t = t.makeSharedWildConst(); 3123 else 3124 t = t.makeSharedWild(); 3125 } 3126 else 3127 { 3128 if (t.isConst()) 3129 t = t.makeSharedConst(); 3130 else 3131 t = t.makeShared(); 3132 } 3133 } 3134 if ((stc & STC.const_) && !t.isConst()) 3135 { 3136 if (t.isShared()) 3137 { 3138 if (t.isWild()) 3139 t = t.makeSharedWildConst(); 3140 else 3141 t = t.makeSharedConst(); 3142 } 3143 else 3144 { 3145 if (t.isWild()) 3146 t = t.makeWildConst(); 3147 else 3148 t = t.makeConst(); 3149 } 3150 } 3151 if ((stc & STC.wild) && !t.isWild()) 3152 { 3153 if (t.isShared()) 3154 { 3155 if (t.isConst()) 3156 t = t.makeSharedWildConst(); 3157 else 3158 t = t.makeSharedWild(); 3159 } 3160 else 3161 { 3162 if (t.isConst()) 3163 t = t.makeWildConst(); 3164 else 3165 t = t.makeWild(); 3166 } 3167 } 3168 } 3169 return t; 3170 } 3171 3172 Expression toExpression() 3173 { 3174 return null; 3175 } 3176 3177 Type syntaxCopy() 3178 { 3179 return null; 3180 } 3181 3182 final Type sharedWildConstOf() 3183 { 3184 if (mod == (MODFlags.shared_ | MODFlags.wildconst)) 3185 return this; 3186 if (mcache.swcto) 3187 { 3188 assert(mcache.swcto.mod == (MODFlags.shared_ | MODFlags.wildconst)); 3189 return mcache.swcto; 3190 } 3191 Type t = makeSharedWildConst(); 3192 t = t.merge(); 3193 t.fixTo(this); 3194 return t; 3195 } 3196 3197 final Type sharedConstOf() 3198 { 3199 if (mod == (MODFlags.shared_ | MODFlags.const_)) 3200 return this; 3201 if (mcache.scto) 3202 { 3203 assert(mcache.scto.mod == (MODFlags.shared_ | MODFlags.const_)); 3204 return mcache.scto; 3205 } 3206 Type t = makeSharedConst(); 3207 t = t.merge(); 3208 t.fixTo(this); 3209 return t; 3210 } 3211 3212 final Type wildConstOf() 3213 { 3214 if (mod == MODFlags.wildconst) 3215 return this; 3216 if (mcache && mcache.wcto) 3217 { 3218 assert(mcache.wcto.mod == MODFlags.wildconst); 3219 return mcache.wcto; 3220 } 3221 Type t = makeWildConst(); 3222 t = t.merge(); 3223 t.fixTo(this); 3224 return t; 3225 } 3226 3227 final Type constOf() 3228 { 3229 if (mod == MODFlags.const_) 3230 return this; 3231 if (mcache && mcache.cto) 3232 { 3233 assert(mcache.cto.mod == MODFlags.const_); 3234 return mcache.cto; 3235 } 3236 Type t = makeConst(); 3237 t = t.merge(); 3238 t.fixTo(this); 3239 return t; 3240 } 3241 3242 final Type sharedWildOf() 3243 { 3244 if (mod == (MODFlags.shared_ | MODFlags.wild)) 3245 return this; 3246 if (mcache && mcache.swto) 3247 { 3248 assert(mcache.swto.mod == (MODFlags.shared_ | MODFlags.wild)); 3249 return mcache.swto; 3250 } 3251 Type t = makeSharedWild(); 3252 t = t.merge(); 3253 t.fixTo(this); 3254 return t; 3255 } 3256 3257 final Type wildOf() 3258 { 3259 if (mod == MODFlags.wild) 3260 return this; 3261 if (mcache && mcache.wto) 3262 { 3263 assert(mcache.wto.mod == MODFlags.wild); 3264 return mcache.wto; 3265 } 3266 Type t = makeWild(); 3267 t = t.merge(); 3268 t.fixTo(this); 3269 return t; 3270 } 3271 3272 final Type sharedOf() 3273 { 3274 if (mod == MODFlags.shared_) 3275 return this; 3276 if (mcache && mcache.sto) 3277 { 3278 assert(mcache.sto.mod == MODFlags.shared_); 3279 return mcache.sto; 3280 } 3281 Type t = makeShared(); 3282 t = t.merge(); 3283 t.fixTo(this); 3284 return t; 3285 } 3286 3287 final Type immutableOf() 3288 { 3289 if (isImmutable()) 3290 return this; 3291 if (mcache && mcache.ito) 3292 { 3293 assert(mcache.ito.isImmutable()); 3294 return mcache.ito; 3295 } 3296 Type t = makeImmutable(); 3297 t = t.merge(); 3298 t.fixTo(this); 3299 return t; 3300 } 3301 3302 final void fixTo(Type t) 3303 { 3304 Type mto = null; 3305 Type tn = nextOf(); 3306 if (!tn || ty != Tsarray && tn.mod == t.nextOf().mod) 3307 { 3308 switch (t.mod) 3309 { 3310 case 0: 3311 mto = t; 3312 break; 3313 3314 case MODFlags.const_: 3315 getMcache(); 3316 mcache.cto = t; 3317 break; 3318 3319 case MODFlags.wild: 3320 getMcache(); 3321 mcache.wto = t; 3322 break; 3323 3324 case MODFlags.wildconst: 3325 getMcache(); 3326 mcache.wcto = t; 3327 break; 3328 3329 case MODFlags.shared_: 3330 getMcache(); 3331 mcache.sto = t; 3332 break; 3333 3334 case MODFlags.shared_ | MODFlags.const_: 3335 getMcache(); 3336 mcache.scto = t; 3337 break; 3338 3339 case MODFlags.shared_ | MODFlags.wild: 3340 getMcache(); 3341 mcache.swto = t; 3342 break; 3343 3344 case MODFlags.shared_ | MODFlags.wildconst: 3345 getMcache(); 3346 mcache.swcto = t; 3347 break; 3348 3349 case MODFlags.immutable_: 3350 getMcache(); 3351 mcache.ito = t; 3352 break; 3353 3354 default: 3355 break; 3356 } 3357 } 3358 assert(mod != t.mod); 3359 3360 if (mod) 3361 { 3362 getMcache(); 3363 t.getMcache(); 3364 } 3365 switch (mod) 3366 { 3367 case 0: 3368 break; 3369 3370 case MODFlags.const_: 3371 mcache.cto = mto; 3372 t.mcache.cto = this; 3373 break; 3374 3375 case MODFlags.wild: 3376 mcache.wto = mto; 3377 t.mcache.wto = this; 3378 break; 3379 3380 case MODFlags.wildconst: 3381 mcache.wcto = mto; 3382 t.mcache.wcto = this; 3383 break; 3384 3385 case MODFlags.shared_: 3386 mcache.sto = mto; 3387 t.mcache.sto = this; 3388 break; 3389 3390 case MODFlags.shared_ | MODFlags.const_: 3391 mcache.scto = mto; 3392 t.mcache.scto = this; 3393 break; 3394 3395 case MODFlags.shared_ | MODFlags.wild: 3396 mcache.swto = mto; 3397 t.mcache.swto = this; 3398 break; 3399 3400 case MODFlags.shared_ | MODFlags.wildconst: 3401 mcache.swcto = mto; 3402 t.mcache.swcto = this; 3403 break; 3404 3405 case MODFlags.immutable_: 3406 t.mcache.ito = this; 3407 if (t.mcache.cto) 3408 t.mcache.cto.getMcache().ito = this; 3409 if (t.mcache.sto) 3410 t.mcache.sto.getMcache().ito = this; 3411 if (t.mcache.scto) 3412 t.mcache.scto.getMcache().ito = this; 3413 if (t.mcache.wto) 3414 t.mcache.wto.getMcache().ito = this; 3415 if (t.mcache.wcto) 3416 t.mcache.wcto.getMcache().ito = this; 3417 if (t.mcache.swto) 3418 t.mcache.swto.getMcache().ito = this; 3419 if (t.mcache.swcto) 3420 t.mcache.swcto.getMcache().ito = this; 3421 break; 3422 3423 default: 3424 assert(0); 3425 } 3426 } 3427 3428 final Type addMod(MOD mod) 3429 { 3430 Type t = this; 3431 if (!t.isImmutable()) 3432 { 3433 switch (mod) 3434 { 3435 case 0: 3436 break; 3437 3438 case MODFlags.const_: 3439 if (isShared()) 3440 { 3441 if (isWild()) 3442 t = sharedWildConstOf(); 3443 else 3444 t = sharedConstOf(); 3445 } 3446 else 3447 { 3448 if (isWild()) 3449 t = wildConstOf(); 3450 else 3451 t = constOf(); 3452 } 3453 break; 3454 3455 case MODFlags.wild: 3456 if (isShared()) 3457 { 3458 if (isConst()) 3459 t = sharedWildConstOf(); 3460 else 3461 t = sharedWildOf(); 3462 } 3463 else 3464 { 3465 if (isConst()) 3466 t = wildConstOf(); 3467 else 3468 t = wildOf(); 3469 } 3470 break; 3471 3472 case MODFlags.wildconst: 3473 if (isShared()) 3474 t = sharedWildConstOf(); 3475 else 3476 t = wildConstOf(); 3477 break; 3478 3479 case MODFlags.shared_: 3480 if (isWild()) 3481 { 3482 if (isConst()) 3483 t = sharedWildConstOf(); 3484 else 3485 t = sharedWildOf(); 3486 } 3487 else 3488 { 3489 if (isConst()) 3490 t = sharedConstOf(); 3491 else 3492 t = sharedOf(); 3493 } 3494 break; 3495 3496 case MODFlags.shared_ | MODFlags.const_: 3497 if (isWild()) 3498 t = sharedWildConstOf(); 3499 else 3500 t = sharedConstOf(); 3501 break; 3502 3503 case MODFlags.shared_ | MODFlags.wild: 3504 if (isConst()) 3505 t = sharedWildConstOf(); 3506 else 3507 t = sharedWildOf(); 3508 break; 3509 3510 case MODFlags.shared_ | MODFlags.wildconst: 3511 t = sharedWildConstOf(); 3512 break; 3513 3514 case MODFlags.immutable_: 3515 t = immutableOf(); 3516 break; 3517 3518 default: 3519 assert(0); 3520 } 3521 } 3522 return t; 3523 } 3524 3525 // TypeEnum overrides this method 3526 Type nextOf() 3527 { 3528 return null; 3529 } 3530 3531 // TypeBasic, TypeVector, TypePointer, TypeEnum override this method 3532 bool isscalar() 3533 { 3534 return false; 3535 } 3536 3537 final bool isConst() const 3538 { 3539 return (mod & MODFlags.const_) != 0; 3540 } 3541 3542 final bool isWild() const 3543 { 3544 return (mod & MODFlags.wild) != 0; 3545 } 3546 3547 final bool isShared() const 3548 { 3549 return (mod & MODFlags.shared_) != 0; 3550 } 3551 3552 Type toBasetype() 3553 { 3554 return this; 3555 } 3556 3557 // TypeIdentifier, TypeInstance, TypeTypeOf, TypeReturn, TypeStruct, TypeEnum, TypeClass override this method 3558 Dsymbol toDsymbol(Scope* sc) 3559 { 3560 return null; 3561 } 3562 3563 final pure inout nothrow @nogc 3564 { 3565 inout(TypeError) isTypeError() { return ty == Terror ? cast(typeof(return))this : null; } 3566 inout(TypeVector) isTypeVector() { return ty == Tvector ? cast(typeof(return))this : null; } 3567 inout(TypeSArray) isTypeSArray() { return ty == Tsarray ? cast(typeof(return))this : null; } 3568 inout(TypeDArray) isTypeDArray() { return ty == Tarray ? cast(typeof(return))this : null; } 3569 inout(TypeAArray) isTypeAArray() { return ty == Taarray ? cast(typeof(return))this : null; } 3570 inout(TypePointer) isTypePointer() { return ty == Tpointer ? cast(typeof(return))this : null; } 3571 inout(TypeReference) isTypeReference() { return ty == Treference ? cast(typeof(return))this : null; } 3572 inout(TypeFunction) isTypeFunction() { return ty == Tfunction ? cast(typeof(return))this : null; } 3573 inout(TypeDelegate) isTypeDelegate() { return ty == Tdelegate ? cast(typeof(return))this : null; } 3574 inout(TypeIdentifier) isTypeIdentifier() { return ty == Tident ? cast(typeof(return))this : null; } 3575 inout(TypeInstance) isTypeInstance() { return ty == Tinstance ? cast(typeof(return))this : null; } 3576 inout(TypeTypeof) isTypeTypeof() { return ty == Ttypeof ? cast(typeof(return))this : null; } 3577 inout(TypeReturn) isTypeReturn() { return ty == Treturn ? cast(typeof(return))this : null; } 3578 inout(TypeStruct) isTypeStruct() { return ty == Tstruct ? cast(typeof(return))this : null; } 3579 inout(TypeEnum) isTypeEnum() { return ty == Tenum ? cast(typeof(return))this : null; } 3580 inout(TypeClass) isTypeClass() { return ty == Tclass ? cast(typeof(return))this : null; } 3581 inout(TypeTuple) isTypeTuple() { return ty == Ttuple ? cast(typeof(return))this : null; } 3582 inout(TypeSlice) isTypeSlice() { return ty == Tslice ? cast(typeof(return))this : null; } 3583 inout(TypeNull) isTypeNull() { return ty == Tnull ? cast(typeof(return))this : null; } 3584 inout(TypeMixin) isTypeMixin() { return ty == Tmixin ? cast(typeof(return))this : null; } 3585 inout(TypeTraits) isTypeTraits() { return ty == Ttraits ? cast(typeof(return))this : null; } 3586 } 3587 3588 override void accept(Visitor v) 3589 { 3590 v.visit(this); 3591 } 3592 } 3593 3594 // missing functionality in constructor, but that's ok 3595 // since the class is needed only for its size; need to add all method definitions 3596 extern (C++) final class TypeBasic : Type 3597 { 3598 const(char)* dstring; 3599 uint flags; 3600 3601 extern (D) this(TY ty) 3602 { 3603 super(ty); 3604 const(char)* d; 3605 uint flags = 0; 3606 switch (ty) 3607 { 3608 case Tvoid: 3609 d = Token.toChars(TOK.void_); 3610 break; 3611 3612 case Tint8: 3613 d = Token.toChars(TOK.int8); 3614 flags |= TFlags.integral; 3615 break; 3616 3617 case Tuns8: 3618 d = Token.toChars(TOK.uns8); 3619 flags |= TFlags.integral | TFlags.unsigned; 3620 break; 3621 3622 case Tint16: 3623 d = Token.toChars(TOK.int16); 3624 flags |= TFlags.integral; 3625 break; 3626 3627 case Tuns16: 3628 d = Token.toChars(TOK.uns16); 3629 flags |= TFlags.integral | TFlags.unsigned; 3630 break; 3631 3632 case Tint32: 3633 d = Token.toChars(TOK.int32); 3634 flags |= TFlags.integral; 3635 break; 3636 3637 case Tuns32: 3638 d = Token.toChars(TOK.uns32); 3639 flags |= TFlags.integral | TFlags.unsigned; 3640 break; 3641 3642 case Tfloat32: 3643 d = Token.toChars(TOK.float32); 3644 flags |= TFlags.floating | TFlags.real_; 3645 break; 3646 3647 case Tint64: 3648 d = Token.toChars(TOK.int64); 3649 flags |= TFlags.integral; 3650 break; 3651 3652 case Tuns64: 3653 d = Token.toChars(TOK.uns64); 3654 flags |= TFlags.integral | TFlags.unsigned; 3655 break; 3656 3657 case Tint128: 3658 d = Token.toChars(TOK.int128); 3659 flags |= TFlags.integral; 3660 break; 3661 3662 case Tuns128: 3663 d = Token.toChars(TOK.uns128); 3664 flags |= TFlags.integral | TFlags.unsigned; 3665 break; 3666 3667 case Tfloat64: 3668 d = Token.toChars(TOK.float64); 3669 flags |= TFlags.floating | TFlags.real_; 3670 break; 3671 3672 case Tfloat80: 3673 d = Token.toChars(TOK.float80); 3674 flags |= TFlags.floating | TFlags.real_; 3675 break; 3676 3677 case Timaginary32: 3678 d = Token.toChars(TOK.imaginary32); 3679 flags |= TFlags.floating | TFlags.imaginary; 3680 break; 3681 3682 case Timaginary64: 3683 d = Token.toChars(TOK.imaginary64); 3684 flags |= TFlags.floating | TFlags.imaginary; 3685 break; 3686 3687 case Timaginary80: 3688 d = Token.toChars(TOK.imaginary80); 3689 flags |= TFlags.floating | TFlags.imaginary; 3690 break; 3691 3692 case Tcomplex32: 3693 d = Token.toChars(TOK.complex32); 3694 flags |= TFlags.floating | TFlags.complex; 3695 break; 3696 3697 case Tcomplex64: 3698 d = Token.toChars(TOK.complex64); 3699 flags |= TFlags.floating | TFlags.complex; 3700 break; 3701 3702 case Tcomplex80: 3703 d = Token.toChars(TOK.complex80); 3704 flags |= TFlags.floating | TFlags.complex; 3705 break; 3706 3707 case Tbool: 3708 d = "bool"; 3709 flags |= TFlags.integral | TFlags.unsigned; 3710 break; 3711 3712 case Tchar: 3713 d = Token.toChars(TOK.char_); 3714 flags |= TFlags.integral | TFlags.unsigned; 3715 break; 3716 3717 case Twchar: 3718 d = Token.toChars(TOK.wchar_); 3719 flags |= TFlags.integral | TFlags.unsigned; 3720 break; 3721 3722 case Tdchar: 3723 d = Token.toChars(TOK.dchar_); 3724 flags |= TFlags.integral | TFlags.unsigned; 3725 break; 3726 3727 default: 3728 assert(0); 3729 } 3730 this.dstring = d; 3731 this.flags = flags; 3732 merge(); 3733 } 3734 3735 override bool isscalar() const 3736 { 3737 return (flags & (TFlags.integral | TFlags.floating)) != 0; 3738 } 3739 3740 override void accept(Visitor v) 3741 { 3742 v.visit(this); 3743 } 3744 } 3745 3746 extern (C++) final class TypeError : Type 3747 { 3748 extern (D) this() 3749 { 3750 super(Terror); 3751 } 3752 3753 override TypeError syntaxCopy() 3754 { 3755 return this; 3756 } 3757 3758 override void accept(Visitor v) 3759 { 3760 v.visit(this); 3761 } 3762 } 3763 3764 extern (C++) final class TypeNull : Type 3765 { 3766 extern (D) this() 3767 { 3768 super(Tnull); 3769 } 3770 3771 override TypeNull syntaxCopy() 3772 { 3773 // No semantic analysis done, no need to copy 3774 return this; 3775 } 3776 3777 override void accept(Visitor v) 3778 { 3779 v.visit(this); 3780 } 3781 } 3782 3783 extern (C++) final class TypeNoreturn : Type 3784 { 3785 extern (D) this() 3786 { 3787 super(Tnoreturn); 3788 } 3789 3790 override TypeNoreturn syntaxCopy() 3791 { 3792 // No semantic analysis done, no need to copy 3793 return this; 3794 } 3795 3796 override void accept(Visitor v) 3797 { 3798 v.visit(this); 3799 } 3800 } 3801 3802 extern (C++) class TypeVector : Type 3803 { 3804 Type basetype; 3805 3806 extern (D) this(Type basetype) 3807 { 3808 super(Tvector); 3809 this.basetype = basetype; 3810 } 3811 3812 override TypeVector syntaxCopy() 3813 { 3814 return new TypeVector(basetype.syntaxCopy()); 3815 } 3816 3817 override void accept(Visitor v) 3818 { 3819 v.visit(this); 3820 } 3821 } 3822 3823 extern (C++) final class TypeEnum : Type 3824 { 3825 EnumDeclaration sym; 3826 3827 extern (D) this(EnumDeclaration sym) 3828 { 3829 super(Tenum); 3830 this.sym = sym; 3831 } 3832 3833 override TypeEnum syntaxCopy() 3834 { 3835 return this; 3836 } 3837 3838 override void accept(Visitor v) 3839 { 3840 v.visit(this); 3841 } 3842 } 3843 3844 extern (C++) final class TypeTuple : Type 3845 { 3846 Parameters* arguments; 3847 3848 extern (D) this(Parameters* arguments) 3849 { 3850 super(Ttuple); 3851 this.arguments = arguments; 3852 } 3853 3854 extern (D) this(Expressions* exps) 3855 { 3856 super(Ttuple); 3857 auto arguments = new Parameters(); 3858 if (exps) 3859 { 3860 arguments.setDim(exps.dim); 3861 for (size_t i = 0; i < exps.dim; i++) 3862 { 3863 Expression e = (*exps)[i]; 3864 if (e.type.ty == Ttuple) 3865 e.error("cannot form tuple of tuples"); 3866 auto arg = new Parameter(STC.undefined_, e.type, null, null, null); 3867 (*arguments)[i] = arg; 3868 } 3869 } 3870 this.arguments = arguments; 3871 } 3872 3873 override TypeTuple syntaxCopy() 3874 { 3875 Parameters* args = Parameter.arraySyntaxCopy(arguments); 3876 auto t = new TypeTuple(args); 3877 t.mod = mod; 3878 return t; 3879 } 3880 3881 override void accept(Visitor v) 3882 { 3883 v.visit(this); 3884 } 3885 } 3886 3887 extern (C++) final class TypeClass : Type 3888 { 3889 ClassDeclaration sym; 3890 AliasThisRec att = AliasThisRec.fwdref; 3891 3892 extern (D) this (ClassDeclaration sym) 3893 { 3894 super(Tclass); 3895 this.sym = sym; 3896 } 3897 3898 override TypeClass syntaxCopy() 3899 { 3900 return this; 3901 } 3902 3903 override void accept(Visitor v) 3904 { 3905 v.visit(this); 3906 } 3907 } 3908 3909 extern (C++) final class TypeStruct : Type 3910 { 3911 StructDeclaration sym; 3912 AliasThisRec att = AliasThisRec.fwdref; 3913 bool inuse = false; 3914 3915 extern (D) this(StructDeclaration sym) 3916 { 3917 super(Tstruct); 3918 this.sym = sym; 3919 } 3920 3921 override TypeStruct syntaxCopy() 3922 { 3923 return this; 3924 } 3925 3926 override void accept(Visitor v) 3927 { 3928 v.visit(this); 3929 } 3930 } 3931 3932 extern (C++) final class TypeReference : TypeNext 3933 { 3934 extern (D) this(Type t) 3935 { 3936 super(Treference, t); 3937 // BUG: what about references to static arrays? 3938 } 3939 3940 override TypeReference syntaxCopy() 3941 { 3942 Type t = next.syntaxCopy(); 3943 if (t == next) 3944 return this; 3945 3946 auto result = new TypeReference(t); 3947 result.mod = mod; 3948 return result; 3949 } 3950 3951 override void accept(Visitor v) 3952 { 3953 v.visit(this); 3954 } 3955 } 3956 3957 extern (C++) abstract class TypeNext : Type 3958 { 3959 Type next; 3960 3961 final extern (D) this(TY ty, Type next) 3962 { 3963 super(ty); 3964 this.next = next; 3965 } 3966 3967 override final Type nextOf() 3968 { 3969 return next; 3970 } 3971 3972 override void accept(Visitor v) 3973 { 3974 v.visit(this); 3975 } 3976 } 3977 3978 extern (C++) final class TypeSlice : TypeNext 3979 { 3980 Expression lwr; 3981 Expression upr; 3982 3983 extern (D) this(Type next, Expression lwr, Expression upr) 3984 { 3985 super(Tslice, next); 3986 this.lwr = lwr; 3987 this.upr = upr; 3988 } 3989 3990 override TypeSlice syntaxCopy() 3991 { 3992 auto t = new TypeSlice(next.syntaxCopy(), lwr.syntaxCopy(), upr.syntaxCopy()); 3993 t.mod = mod; 3994 return t; 3995 } 3996 3997 override void accept(Visitor v) 3998 { 3999 v.visit(this); 4000 } 4001 } 4002 4003 extern (C++) class TypeDelegate : TypeNext 4004 { 4005 extern (D) this(Type t) 4006 { 4007 super(Tfunction, t); 4008 ty = Tdelegate; 4009 } 4010 4011 override TypeDelegate syntaxCopy() 4012 { 4013 Type t = next.syntaxCopy(); 4014 if (t == next) 4015 return this; 4016 4017 auto result = new TypeDelegate(t); 4018 result.mod = mod; 4019 return result; 4020 } 4021 4022 override void accept(Visitor v) 4023 { 4024 v.visit(this); 4025 } 4026 } 4027 4028 extern (C++) final class TypePointer : TypeNext 4029 { 4030 extern (D) this(Type t) 4031 { 4032 super(Tpointer, t); 4033 } 4034 4035 override TypePointer syntaxCopy() 4036 { 4037 Type t = next.syntaxCopy(); 4038 if (t == next) 4039 return this; 4040 4041 auto result = new TypePointer(t); 4042 result.mod = mod; 4043 return result; 4044 } 4045 4046 override void accept(Visitor v) 4047 { 4048 v.visit(this); 4049 } 4050 } 4051 4052 extern (C++) class TypeFunction : TypeNext 4053 { 4054 // .next is the return type 4055 4056 ParameterList parameterList; // function parameters 4057 4058 private enum FunctionFlag : uint 4059 { 4060 none = 0, 4061 isnothrow = 0x0001, // nothrow 4062 isnogc = 0x0002, // is @nogc 4063 isproperty = 0x0004, // can be called without parentheses 4064 isref = 0x0008, // returns a reference 4065 isreturn = 0x0010, // 'this' is returned by ref 4066 isscope = 0x0020, // 'this' is scope 4067 isreturninferred= 0x0040, // 'this' is return from inference 4068 isscopeinferred = 0x0080, // 'this' is scope from inference 4069 islive = 0x0100, // is @live 4070 incomplete = 0x0200, // return type or default arguments removed 4071 inoutParam = 0x0400, // inout on the parameters 4072 inoutQual = 0x0800, // inout on the qualifier 4073 } 4074 4075 LINK linkage; // calling convention 4076 FunctionFlag funcFlags; 4077 TRUST trust; // level of trust 4078 PURE purity = PURE.impure; 4079 byte inuse; 4080 Expressions* fargs; // function arguments 4081 4082 extern (D) this(ParameterList pl, Type treturn, LINK linkage, StorageClass stc = 0) 4083 { 4084 super(Tfunction, treturn); 4085 assert(VarArg.none <= pl.varargs && pl.varargs <= VarArg.typesafe); 4086 this.parameterList = pl; 4087 this.linkage = linkage; 4088 4089 if (stc & STC.pure_) 4090 this.purity = PURE.fwdref; 4091 if (stc & STC.nothrow_) 4092 this.isnothrow = true; 4093 if (stc & STC.nogc) 4094 this.isnogc = true; 4095 if (stc & STC.property) 4096 this.isproperty = true; 4097 if (stc & STC.live) 4098 this.islive = true; 4099 4100 if (stc & STC.ref_) 4101 this.isref = true; 4102 if (stc & STC.return_) 4103 this.isreturn = true; 4104 if (stc & STC.scope_) 4105 this.isScopeQual = true; 4106 4107 this.trust = TRUST.default_; 4108 if (stc & STC.safe) 4109 this.trust = TRUST.safe; 4110 if (stc & STC.system) 4111 this.trust = TRUST.system; 4112 if (stc & STC.trusted) 4113 this.trust = TRUST.trusted; 4114 } 4115 4116 override TypeFunction syntaxCopy() 4117 { 4118 Type treturn = next ? next.syntaxCopy() : null; 4119 Parameters* params = Parameter.arraySyntaxCopy(parameterList.parameters); 4120 auto t = new TypeFunction(ParameterList(params, parameterList.varargs), treturn, linkage); 4121 t.mod = mod; 4122 t.isnothrow = isnothrow; 4123 t.isnogc = isnogc; 4124 t.purity = purity; 4125 t.isproperty = isproperty; 4126 t.isref = isref; 4127 t.isreturn = isreturn; 4128 t.isScopeQual = isScopeQual; 4129 t.isreturninferred = isreturninferred; 4130 t.isscopeinferred = isscopeinferred; 4131 t.isInOutParam = isInOutParam; 4132 t.isInOutQual = isInOutQual; 4133 t.trust = trust; 4134 t.fargs = fargs; 4135 return t; 4136 } 4137 4138 /// set or get if the function has the `nothrow` attribute 4139 bool isnothrow() const pure nothrow @safe @nogc 4140 { 4141 return (funcFlags & FunctionFlag.isnothrow) != 0; 4142 } 4143 /// ditto 4144 void isnothrow(bool v) pure nothrow @safe @nogc 4145 { 4146 if (v) funcFlags |= FunctionFlag.isnothrow; 4147 else funcFlags &= ~FunctionFlag.isnothrow; 4148 } 4149 4150 /// set or get if the function has the `@nogc` attribute 4151 bool isnogc() const pure nothrow @safe @nogc 4152 { 4153 return (funcFlags & FunctionFlag.isnogc) != 0; 4154 } 4155 /// ditto 4156 void isnogc(bool v) pure nothrow @safe @nogc 4157 { 4158 if (v) funcFlags |= FunctionFlag.isnogc; 4159 else funcFlags &= ~FunctionFlag.isnogc; 4160 } 4161 4162 /// set or get if the function has the `@property` attribute 4163 bool isproperty() const pure nothrow @safe @nogc 4164 { 4165 return (funcFlags & FunctionFlag.isproperty) != 0; 4166 } 4167 /// ditto 4168 void isproperty(bool v) pure nothrow @safe @nogc 4169 { 4170 if (v) funcFlags |= FunctionFlag.isproperty; 4171 else funcFlags &= ~FunctionFlag.isproperty; 4172 } 4173 4174 /// set or get if the function has the `ref` attribute 4175 bool isref() const pure nothrow @safe @nogc 4176 { 4177 return (funcFlags & FunctionFlag.isref) != 0; 4178 } 4179 /// ditto 4180 void isref(bool v) pure nothrow @safe @nogc 4181 { 4182 if (v) funcFlags |= FunctionFlag.isref; 4183 else funcFlags &= ~FunctionFlag.isref; 4184 } 4185 4186 /// set or get if the function has the `return` attribute 4187 bool isreturn() const pure nothrow @safe @nogc 4188 { 4189 return (funcFlags & FunctionFlag.isreturn) != 0; 4190 } 4191 /// ditto 4192 void isreturn(bool v) pure nothrow @safe @nogc 4193 { 4194 if (v) funcFlags |= FunctionFlag.isreturn; 4195 else funcFlags &= ~FunctionFlag.isreturn; 4196 } 4197 4198 /// set or get if the function has the `scope` attribute 4199 bool isScopeQual() const pure nothrow @safe @nogc 4200 { 4201 return (funcFlags & FunctionFlag.isscope) != 0; 4202 } 4203 /// ditto 4204 void isScopeQual(bool v) pure nothrow @safe @nogc 4205 { 4206 if (v) funcFlags |= FunctionFlag.isscope; 4207 else funcFlags &= ~FunctionFlag.isscope; 4208 } 4209 4210 /// set or get if the function has the `return` attribute inferred 4211 bool isreturninferred() const pure nothrow @safe @nogc 4212 { 4213 return (funcFlags & FunctionFlag.isreturninferred) != 0; 4214 } 4215 /// ditto 4216 void isreturninferred(bool v) pure nothrow @safe @nogc 4217 { 4218 if (v) funcFlags |= FunctionFlag.isreturninferred; 4219 else funcFlags &= ~FunctionFlag.isreturninferred; 4220 } 4221 4222 /// set or get if the function has the `scope` attribute inferred 4223 bool isscopeinferred() const pure nothrow @safe @nogc 4224 { 4225 return (funcFlags & FunctionFlag.isscopeinferred) != 0; 4226 } 4227 /// ditoo 4228 void isscopeinferred(bool v) pure nothrow @safe @nogc 4229 { 4230 if (v) funcFlags |= FunctionFlag.isscopeinferred; 4231 else funcFlags &= ~FunctionFlag.isscopeinferred; 4232 } 4233 4234 /// set or get if the function has the `@live` attribute 4235 bool islive() const pure nothrow @safe @nogc 4236 { 4237 return (funcFlags & FunctionFlag.islive) != 0; 4238 } 4239 /// ditto 4240 void islive(bool v) pure nothrow @safe @nogc 4241 { 4242 if (v) funcFlags |= FunctionFlag.islive; 4243 else funcFlags &= ~FunctionFlag.islive; 4244 } 4245 4246 /// set or get if the return type or the default arguments are removed 4247 bool incomplete() const pure nothrow @safe @nogc 4248 { 4249 return (funcFlags & FunctionFlag.incomplete) != 0; 4250 } 4251 /// ditto 4252 void incomplete(bool v) pure nothrow @safe @nogc 4253 { 4254 if (v) funcFlags |= FunctionFlag.incomplete; 4255 else funcFlags &= ~FunctionFlag.incomplete; 4256 } 4257 4258 /// set or get if the function has the `inout` on the parameters 4259 bool isInOutParam() const pure nothrow @safe @nogc 4260 { 4261 return (funcFlags & FunctionFlag.inoutParam) != 0; 4262 } 4263 /// ditto 4264 void isInOutParam(bool v) pure nothrow @safe @nogc 4265 { 4266 if (v) funcFlags |= FunctionFlag.inoutParam; 4267 else funcFlags &= ~FunctionFlag.inoutParam; 4268 } 4269 4270 /// set or get if the function has the `inout` on the parameters 4271 bool isInOutQual() const pure nothrow @safe @nogc 4272 { 4273 return (funcFlags & FunctionFlag.inoutQual) != 0; 4274 } 4275 /// ditto 4276 void isInOutQual(bool v) pure nothrow @safe @nogc 4277 { 4278 if (v) funcFlags |= FunctionFlag.inoutQual; 4279 else funcFlags &= ~FunctionFlag.inoutQual; 4280 } 4281 /// Returns: `true` the function is `isInOutQual` or `isInOutParam` ,`false` otherwise. 4282 bool iswild() const pure nothrow @safe @nogc 4283 { 4284 return (funcFlags & (FunctionFlag.inoutParam | FunctionFlag.inoutQual)) != 0; 4285 } 4286 4287 override void accept(Visitor v) 4288 { 4289 v.visit(this); 4290 } 4291 } 4292 4293 extern (C++) class TypeArray : TypeNext 4294 { 4295 final extern (D) this(TY ty, Type next) 4296 { 4297 super(ty, next); 4298 } 4299 4300 override void accept(Visitor v) 4301 { 4302 v.visit(this); 4303 } 4304 } 4305 4306 extern (C++) final class TypeDArray : TypeArray 4307 { 4308 extern (D) this(Type t) 4309 { 4310 super(Tarray, t); 4311 } 4312 4313 override TypeDArray syntaxCopy() 4314 { 4315 Type t = next.syntaxCopy(); 4316 if (t == next) 4317 return this; 4318 4319 auto result = new TypeDArray(t); 4320 result.mod = mod; 4321 return result; 4322 } 4323 4324 override void accept(Visitor v) 4325 { 4326 v.visit(this); 4327 } 4328 } 4329 4330 extern (C++) final class TypeAArray : TypeArray 4331 { 4332 Type index; 4333 Loc loc; 4334 4335 extern (D) this(Type t, Type index) 4336 { 4337 super(Taarray, t); 4338 this.index = index; 4339 } 4340 4341 override TypeAArray syntaxCopy() 4342 { 4343 Type t = next.syntaxCopy(); 4344 Type ti = index.syntaxCopy(); 4345 if (t == next && ti == index) 4346 return this; 4347 4348 auto result = new TypeAArray(t, ti); 4349 result.mod = mod; 4350 return result; 4351 } 4352 4353 override Expression toExpression() 4354 { 4355 Expression e = next.toExpression(); 4356 if (e) 4357 { 4358 Expression ei = index.toExpression(); 4359 if (ei) 4360 return new ArrayExp(loc, e, ei); 4361 } 4362 return null; 4363 } 4364 4365 override void accept(Visitor v) 4366 { 4367 v.visit(this); 4368 } 4369 } 4370 4371 extern (C++) final class TypeSArray : TypeArray 4372 { 4373 Expression dim; 4374 4375 final extern (D) this(Type t, Expression dim) 4376 { 4377 super(Tsarray, t); 4378 this.dim = dim; 4379 } 4380 4381 override TypeSArray syntaxCopy() 4382 { 4383 Type t = next.syntaxCopy(); 4384 Expression e = dim.syntaxCopy(); 4385 auto result = new TypeSArray(t, e); 4386 result.mod = mod; 4387 return result; 4388 } 4389 4390 override Expression toExpression() 4391 { 4392 Expression e = next.toExpression(); 4393 if (e) 4394 e = new ArrayExp(dim.loc, e, dim); 4395 return e; 4396 } 4397 4398 override void accept(Visitor v) 4399 { 4400 v.visit(this); 4401 } 4402 } 4403 4404 extern (C++) abstract class TypeQualified : Type 4405 { 4406 Objects idents; 4407 Loc loc; 4408 4409 final extern (D) this(TY ty, Loc loc) 4410 { 4411 super(ty); 4412 this.loc = loc; 4413 } 4414 4415 final void addIdent(Identifier id) 4416 { 4417 idents.push(id); 4418 } 4419 4420 final void addInst(TemplateInstance ti) 4421 { 4422 idents.push(ti); 4423 } 4424 4425 final void addIndex(RootObject e) 4426 { 4427 idents.push(e); 4428 } 4429 4430 final void syntaxCopyHelper(TypeQualified t) 4431 { 4432 idents.setDim(t.idents.dim); 4433 for (size_t i = 0; i < idents.dim; i++) 4434 { 4435 RootObject id = t.idents[i]; 4436 if (id.dyncast() == DYNCAST.dsymbol) 4437 { 4438 TemplateInstance ti = cast(TemplateInstance)id; 4439 ti = ti.syntaxCopy(null); 4440 id = ti; 4441 } 4442 else if (id.dyncast() == DYNCAST.expression) 4443 { 4444 Expression e = cast(Expression)id; 4445 e = e.syntaxCopy(); 4446 id = e; 4447 } 4448 else if (id.dyncast() == DYNCAST.type) 4449 { 4450 Type tx = cast(Type)id; 4451 tx = tx.syntaxCopy(); 4452 id = tx; 4453 } 4454 idents[i] = id; 4455 } 4456 } 4457 4458 final Expression toExpressionHelper(Expression e, size_t i = 0) 4459 { 4460 for (; i < idents.dim; i++) 4461 { 4462 RootObject id = idents[i]; 4463 4464 switch (id.dyncast()) 4465 { 4466 case DYNCAST.identifier: 4467 e = new DotIdExp(e.loc, e, cast(Identifier)id); 4468 break; 4469 4470 case DYNCAST.dsymbol: 4471 auto ti = (cast(Dsymbol)id).isTemplateInstance(); 4472 assert(ti); 4473 e = new DotTemplateInstanceExp(e.loc, e, ti.name, ti.tiargs); 4474 break; 4475 4476 case DYNCAST.type: // Bugzilla 1215 4477 e = new ArrayExp(loc, e, new TypeExp(loc, cast(Type)id)); 4478 break; 4479 4480 case DYNCAST.expression: // Bugzilla 1215 4481 e = new ArrayExp(loc, e, cast(Expression)id); 4482 break; 4483 4484 default: 4485 assert(0); 4486 } 4487 } 4488 return e; 4489 } 4490 4491 override void accept(Visitor v) 4492 { 4493 v.visit(this); 4494 } 4495 } 4496 4497 extern (C++) class TypeTraits : Type 4498 { 4499 TraitsExp exp; 4500 Loc loc; 4501 4502 extern (D) this(const ref Loc loc, TraitsExp exp) 4503 { 4504 super(Tident); 4505 this.loc = loc; 4506 this.exp = exp; 4507 } 4508 4509 override void accept(Visitor v) 4510 { 4511 v.visit(this); 4512 } 4513 4514 override TypeTraits syntaxCopy() 4515 { 4516 TraitsExp te = exp.syntaxCopy(); 4517 TypeTraits tt = new TypeTraits(loc, te); 4518 tt.mod = mod; 4519 return tt; 4520 } 4521 } 4522 4523 extern (C++) final class TypeMixin : Type 4524 { 4525 Loc loc; 4526 Expressions* exps; 4527 RootObject obj; 4528 4529 extern (D) this(const ref Loc loc, Expressions* exps) 4530 { 4531 super(Tmixin); 4532 this.loc = loc; 4533 this.exps = exps; 4534 } 4535 4536 override TypeMixin syntaxCopy() 4537 { 4538 static Expressions* arraySyntaxCopy(Expressions* exps) 4539 { 4540 Expressions* a = null; 4541 if (exps) 4542 { 4543 a = new Expressions(exps.dim); 4544 foreach (i, e; *exps) 4545 { 4546 (*a)[i] = e ? e.syntaxCopy() : null; 4547 } 4548 } 4549 return a; 4550 } 4551 4552 return new TypeMixin(loc, arraySyntaxCopy(exps)); 4553 } 4554 4555 override void accept(Visitor v) 4556 { 4557 v.visit(this); 4558 } 4559 } 4560 4561 extern (C++) final class TypeIdentifier : TypeQualified 4562 { 4563 Identifier ident; 4564 4565 extern (D) this(const ref Loc loc, Identifier ident) 4566 { 4567 super(Tident, loc); 4568 this.ident = ident; 4569 } 4570 4571 override TypeIdentifier syntaxCopy() 4572 { 4573 auto t = new TypeIdentifier(loc, ident); 4574 t.syntaxCopyHelper(this); 4575 t.mod = mod; 4576 return t; 4577 } 4578 4579 override Expression toExpression() 4580 { 4581 return toExpressionHelper(new IdentifierExp(loc, ident)); 4582 } 4583 4584 override void accept(Visitor v) 4585 { 4586 v.visit(this); 4587 } 4588 } 4589 4590 extern (C++) final class TypeReturn : TypeQualified 4591 { 4592 extern (D) this(const ref Loc loc) 4593 { 4594 super(Treturn, loc); 4595 } 4596 4597 override TypeReturn syntaxCopy() 4598 { 4599 auto t = new TypeReturn(loc); 4600 t.syntaxCopyHelper(this); 4601 t.mod = mod; 4602 return t; 4603 } 4604 4605 override void accept(Visitor v) 4606 { 4607 v.visit(this); 4608 } 4609 } 4610 4611 extern (C++) final class TypeTypeof : TypeQualified 4612 { 4613 Expression exp; 4614 4615 extern (D) this(const ref Loc loc, Expression exp) 4616 { 4617 super(Ttypeof, loc); 4618 this.exp = exp; 4619 } 4620 4621 override TypeTypeof syntaxCopy() 4622 { 4623 auto t = new TypeTypeof(loc, exp.syntaxCopy()); 4624 t.syntaxCopyHelper(this); 4625 t.mod = mod; 4626 return t; 4627 } 4628 4629 override void accept(Visitor v) 4630 { 4631 v.visit(this); 4632 } 4633 } 4634 4635 extern (C++) final class TypeInstance : TypeQualified 4636 { 4637 TemplateInstance tempinst; 4638 4639 final extern (D) this(const ref Loc loc, TemplateInstance tempinst) 4640 { 4641 super(Tinstance, loc); 4642 this.tempinst = tempinst; 4643 } 4644 4645 override TypeInstance syntaxCopy() 4646 { 4647 auto t = new TypeInstance(loc, tempinst.syntaxCopy(null)); 4648 t.syntaxCopyHelper(this); 4649 t.mod = mod; 4650 return t; 4651 } 4652 4653 override Expression toExpression() 4654 { 4655 return toExpressionHelper(new ScopeExp(loc, tempinst)); 4656 } 4657 4658 override void accept(Visitor v) 4659 { 4660 v.visit(this); 4661 } 4662 } 4663 4664 extern (C++) abstract class Expression : ASTNode 4665 { 4666 TOK op; 4667 ubyte size; 4668 ubyte parens; 4669 Type type; 4670 Loc loc; 4671 4672 final extern (D) this(const ref Loc loc, TOK op, int size) 4673 { 4674 this.loc = loc; 4675 this.op = op; 4676 this.size = cast(ubyte)size; 4677 } 4678 4679 Expression syntaxCopy() 4680 { 4681 return copy(); 4682 } 4683 4684 final void error(const(char)* format, ...) const 4685 { 4686 if (type != Type.terror) 4687 { 4688 va_list ap; 4689 va_start(ap, format); 4690 verror(loc, format, ap); 4691 va_end(ap); 4692 } 4693 } 4694 4695 final Expression copy() 4696 { 4697 Expression e; 4698 if (!size) 4699 { 4700 assert(0); 4701 } 4702 e = cast(Expression)mem.xmalloc(size); 4703 return cast(Expression)memcpy(cast(void*)e, cast(void*)this, size); 4704 } 4705 4706 override final DYNCAST dyncast() const 4707 { 4708 return DYNCAST.expression; 4709 } 4710 4711 override void accept(Visitor v) 4712 { 4713 v.visit(this); 4714 } 4715 } 4716 4717 extern (C++) final class DeclarationExp : Expression 4718 { 4719 Dsymbol declaration; 4720 4721 extern (D) this(const ref Loc loc, Dsymbol declaration) 4722 { 4723 super(loc, TOK.declaration, __traits(classInstanceSize, DeclarationExp)); 4724 this.declaration = declaration; 4725 } 4726 4727 override void accept(Visitor v) 4728 { 4729 v.visit(this); 4730 } 4731 } 4732 4733 extern (C++) final class IntegerExp : Expression 4734 { 4735 dinteger_t value; 4736 4737 extern (D) this(const ref Loc loc, dinteger_t value, Type type) 4738 { 4739 super(loc, TOK.int64, __traits(classInstanceSize, IntegerExp)); 4740 assert(type); 4741 if (!type.isscalar()) 4742 { 4743 if (type.ty != Terror) 4744 error("integral constant must be scalar type, not %s", type.toChars()); 4745 type = Type.terror; 4746 } 4747 this.type = type; 4748 setInteger(value); 4749 } 4750 4751 void setInteger(dinteger_t value) 4752 { 4753 this.value = value; 4754 normalize(); 4755 } 4756 4757 void normalize() 4758 { 4759 /* 'Normalize' the value of the integer to be in range of the type 4760 */ 4761 switch (type.toBasetype().ty) 4762 { 4763 case Tbool: 4764 value = (value != 0); 4765 break; 4766 4767 case Tint8: 4768 value = cast(d_int8)value; 4769 break; 4770 4771 case Tchar: 4772 case Tuns8: 4773 value = cast(d_uns8)value; 4774 break; 4775 4776 case Tint16: 4777 value = cast(d_int16)value; 4778 break; 4779 4780 case Twchar: 4781 case Tuns16: 4782 value = cast(d_uns16)value; 4783 break; 4784 4785 case Tint32: 4786 value = cast(d_int32)value; 4787 break; 4788 4789 case Tdchar: 4790 case Tuns32: 4791 value = cast(d_uns32)value; 4792 break; 4793 4794 case Tint64: 4795 value = cast(d_int64)value; 4796 break; 4797 4798 case Tuns64: 4799 value = cast(d_uns64)value; 4800 break; 4801 4802 case Tpointer: 4803 if (Target.ptrsize == 8) 4804 goto case Tuns64; 4805 if (Target.ptrsize == 4) 4806 goto case Tuns32; 4807 if (Target.ptrsize == 2) 4808 goto case Tuns16; 4809 assert(0); 4810 4811 default: 4812 break; 4813 } 4814 } 4815 4816 override void accept(Visitor v) 4817 { 4818 v.visit(this); 4819 } 4820 } 4821 4822 extern (C++) final class NewAnonClassExp : Expression 4823 { 4824 Expression thisexp; // if !=null, 'this' for class being allocated 4825 Expressions* newargs; // Array of Expression's to call new operator 4826 ClassDeclaration cd; // class being instantiated 4827 Expressions* arguments; // Array of Expression's to call class constructor 4828 4829 extern (D) this(const ref Loc loc, Expression thisexp, Expressions* newargs, ClassDeclaration cd, Expressions* arguments) 4830 { 4831 super(loc, TOK.newAnonymousClass, __traits(classInstanceSize, NewAnonClassExp)); 4832 this.thisexp = thisexp; 4833 this.newargs = newargs; 4834 this.cd = cd; 4835 this.arguments = arguments; 4836 } 4837 4838 override void accept(Visitor v) 4839 { 4840 v.visit(this); 4841 } 4842 } 4843 4844 extern (C++) final class IsExp : Expression 4845 { 4846 Type targ; 4847 Identifier id; // can be null 4848 Type tspec; // can be null 4849 TemplateParameters* parameters; 4850 TOK tok; // ':' or '==' 4851 TOK tok2; // 'struct', 'union', etc. 4852 4853 extern (D) this(const ref Loc loc, Type targ, Identifier id, TOK tok, Type tspec, TOK tok2, TemplateParameters* parameters) 4854 { 4855 super(loc, TOK.is_, __traits(classInstanceSize, IsExp)); 4856 this.targ = targ; 4857 this.id = id; 4858 this.tok = tok; 4859 this.tspec = tspec; 4860 this.tok2 = tok2; 4861 this.parameters = parameters; 4862 } 4863 4864 override void accept(Visitor v) 4865 { 4866 v.visit(this); 4867 } 4868 } 4869 4870 extern (C++) final class RealExp : Expression 4871 { 4872 real_t value; 4873 4874 extern (D) this(const ref Loc loc, real_t value, Type type) 4875 { 4876 super(loc, TOK.float64, __traits(classInstanceSize, RealExp)); 4877 this.value = value; 4878 this.type = type; 4879 } 4880 4881 override void accept(Visitor v) 4882 { 4883 v.visit(this); 4884 } 4885 } 4886 4887 extern (C++) final class NullExp : Expression 4888 { 4889 extern (D) this(const ref Loc loc, Type type = null) 4890 { 4891 super(loc, TOK.null_, __traits(classInstanceSize, NullExp)); 4892 this.type = type; 4893 } 4894 4895 override void accept(Visitor v) 4896 { 4897 v.visit(this); 4898 } 4899 } 4900 4901 extern (C++) final class TypeidExp : Expression 4902 { 4903 RootObject obj; 4904 4905 extern (D) this(const ref Loc loc, RootObject o) 4906 { 4907 super(loc, TOK.typeid_, __traits(classInstanceSize, TypeidExp)); 4908 this.obj = o; 4909 } 4910 4911 override void accept(Visitor v) 4912 { 4913 v.visit(this); 4914 } 4915 } 4916 4917 extern (C++) final class TraitsExp : Expression 4918 { 4919 Identifier ident; 4920 Objects* args; 4921 4922 extern (D) this(const ref Loc loc, Identifier ident, Objects* args) 4923 { 4924 super(loc, TOK.traits, __traits(classInstanceSize, TraitsExp)); 4925 this.ident = ident; 4926 this.args = args; 4927 } 4928 4929 override TraitsExp syntaxCopy() 4930 { 4931 return new TraitsExp(loc, ident, TemplateInstance.arraySyntaxCopy(args)); 4932 } 4933 4934 override void accept(Visitor v) 4935 { 4936 v.visit(this); 4937 } 4938 } 4939 4940 extern (C++) final class StringExp : Expression 4941 { 4942 union 4943 { 4944 char* string; // if sz == 1 4945 wchar* wstring; // if sz == 2 4946 dchar* dstring; // if sz == 4 4947 } // (const if ownedByCtfe == OwnedBy.code) 4948 size_t len; // number of code units 4949 ubyte sz = 1; // 1: char, 2: wchar, 4: dchar 4950 char postfix = 0; // 'c', 'w', 'd' 4951 4952 extern (D) this(const ref Loc loc, const(void)[] string) 4953 { 4954 super(loc, TOK.string_, __traits(classInstanceSize, StringExp)); 4955 this.string = cast(char*)string.ptr; 4956 this.len = string.length; 4957 this.sz = 1; // work around LDC bug #1286 4958 } 4959 4960 extern (D) this(const ref Loc loc, const(void)[] string, size_t len, ubyte sz, char postfix = 0) 4961 { 4962 super(loc, TOK.string_, __traits(classInstanceSize, StringExp)); 4963 this.string = cast(char*)string; 4964 this.len = len; 4965 this.postfix = postfix; 4966 this.sz = 1; // work around LDC bug #1286 4967 } 4968 4969 /********************************************** 4970 * Write the contents of the string to dest. 4971 * Use numberOfCodeUnits() to determine size of result. 4972 * Params: 4973 * dest = destination 4974 * tyto = encoding type of the result 4975 * zero = add terminating 0 4976 */ 4977 void writeTo(void* dest, bool zero, int tyto = 0) const 4978 { 4979 int encSize; 4980 switch (tyto) 4981 { 4982 case 0: encSize = sz; break; 4983 case Tchar: encSize = 1; break; 4984 case Twchar: encSize = 2; break; 4985 case Tdchar: encSize = 4; break; 4986 default: 4987 assert(0); 4988 } 4989 if (sz == encSize) 4990 { 4991 memcpy(dest, string, len * sz); 4992 if (zero) 4993 memset(dest + len * sz, 0, sz); 4994 } 4995 else 4996 assert(0); 4997 } 4998 4999 extern (D) const(char)[] toStringz() const 5000 { 5001 auto nbytes = len * sz; 5002 char* s = cast(char*)mem.xmalloc_noscan(nbytes + sz); 5003 writeTo(s, true); 5004 return s[0 .. nbytes]; 5005 } 5006 5007 override void accept(Visitor v) 5008 { 5009 v.visit(this); 5010 } 5011 } 5012 5013 extern (C++) class NewExp : Expression 5014 { 5015 Expression thisexp; // if !=null, 'this' for class being allocated 5016 Expressions* newargs; // Array of Expression's to call new operator 5017 Type newtype; 5018 Expressions* arguments; // Array of Expression's 5019 5020 extern (D) this(const ref Loc loc, Expression thisexp, Expressions* newargs, Type newtype, Expressions* arguments) 5021 { 5022 super(loc, TOK.new_, __traits(classInstanceSize, NewExp)); 5023 this.thisexp = thisexp; 5024 this.newargs = newargs; 5025 this.newtype = newtype; 5026 this.arguments = arguments; 5027 } 5028 5029 override void accept(Visitor v) 5030 { 5031 v.visit(this); 5032 } 5033 } 5034 5035 extern (C++) final class AssocArrayLiteralExp : Expression 5036 { 5037 Expressions* keys; 5038 Expressions* values; 5039 5040 extern (D) this(const ref Loc loc, Expressions* keys, Expressions* values) 5041 { 5042 super(loc, TOK.assocArrayLiteral, __traits(classInstanceSize, AssocArrayLiteralExp)); 5043 assert(keys.dim == values.dim); 5044 this.keys = keys; 5045 this.values = values; 5046 } 5047 5048 override void accept(Visitor v) 5049 { 5050 v.visit(this); 5051 } 5052 } 5053 5054 extern (C++) final class ArrayLiteralExp : Expression 5055 { 5056 Expression basis; 5057 Expressions* elements; 5058 5059 extern (D) this(const ref Loc loc, Expressions* elements) 5060 { 5061 super(loc, TOK.arrayLiteral, __traits(classInstanceSize, ArrayLiteralExp)); 5062 this.elements = elements; 5063 } 5064 5065 extern (D) this(const ref Loc loc, Expression e) 5066 { 5067 super(loc, TOK.arrayLiteral, __traits(classInstanceSize, ArrayLiteralExp)); 5068 elements = new Expressions(); 5069 elements.push(e); 5070 } 5071 5072 extern (D) this(const ref Loc loc, Expression basis, Expressions* elements) 5073 { 5074 super(loc, TOK.arrayLiteral, __traits(classInstanceSize, ArrayLiteralExp)); 5075 this.basis = basis; 5076 this.elements = elements; 5077 } 5078 5079 override void accept(Visitor v) 5080 { 5081 v.visit(this); 5082 } 5083 } 5084 5085 extern (C++) final class FuncExp : Expression 5086 { 5087 FuncLiteralDeclaration fd; 5088 TemplateDeclaration td; 5089 TOK tok; 5090 5091 extern (D) this(const ref Loc loc, Dsymbol s) 5092 { 5093 super(loc, TOK.function_, __traits(classInstanceSize, FuncExp)); 5094 this.td = s.isTemplateDeclaration(); 5095 this.fd = s.isFuncLiteralDeclaration(); 5096 if (td) 5097 { 5098 assert(td.literal); 5099 assert(td.members && td.members.dim == 1); 5100 fd = (*td.members)[0].isFuncLiteralDeclaration(); 5101 } 5102 tok = fd.tok; // save original kind of function/delegate/(infer) 5103 assert(fd.fbody); 5104 } 5105 5106 override void accept(Visitor v) 5107 { 5108 v.visit(this); 5109 } 5110 } 5111 5112 extern (C++) final class IntervalExp : Expression 5113 { 5114 Expression lwr; 5115 Expression upr; 5116 5117 extern (D) this(const ref Loc loc, Expression lwr, Expression upr) 5118 { 5119 super(loc, TOK.interval, __traits(classInstanceSize, IntervalExp)); 5120 this.lwr = lwr; 5121 this.upr = upr; 5122 } 5123 5124 override void accept(Visitor v) 5125 { 5126 v.visit(this); 5127 } 5128 } 5129 5130 extern (C++) final class TypeExp : Expression 5131 { 5132 extern (D) this(const ref Loc loc, Type type) 5133 { 5134 super(loc, TOK.type, __traits(classInstanceSize, TypeExp)); 5135 this.type = type; 5136 } 5137 5138 override void accept(Visitor v) 5139 { 5140 v.visit(this); 5141 } 5142 } 5143 5144 extern (C++) final class ScopeExp : Expression 5145 { 5146 ScopeDsymbol sds; 5147 5148 extern (D) this(const ref Loc loc, ScopeDsymbol sds) 5149 { 5150 super(loc, TOK.scope_, __traits(classInstanceSize, ScopeExp)); 5151 this.sds = sds; 5152 assert(!sds.isTemplateDeclaration()); 5153 } 5154 5155 override void accept(Visitor v) 5156 { 5157 v.visit(this); 5158 } 5159 } 5160 5161 extern (C++) class IdentifierExp : Expression 5162 { 5163 Identifier ident; 5164 5165 final extern (D) this(const ref Loc loc, Identifier ident) 5166 { 5167 super(loc, TOK.identifier, __traits(classInstanceSize, IdentifierExp)); 5168 this.ident = ident; 5169 } 5170 5171 override void accept(Visitor v) 5172 { 5173 v.visit(this); 5174 } 5175 } 5176 5177 extern (C++) class UnaExp : Expression 5178 { 5179 Expression e1; 5180 5181 final extern (D) this(const ref Loc loc, TOK op, int size, Expression e1) 5182 { 5183 super(loc, op, size); 5184 this.e1 = e1; 5185 } 5186 5187 override void accept(Visitor v) 5188 { 5189 v.visit(this); 5190 } 5191 } 5192 5193 extern (C++) class DefaultInitExp : Expression 5194 { 5195 final extern (D) this(const ref Loc loc, TOK op, int size) 5196 { 5197 super(loc, op, size); 5198 } 5199 5200 override void accept(Visitor v) 5201 { 5202 v.visit(this); 5203 } 5204 } 5205 5206 extern (C++) abstract class BinExp : Expression 5207 { 5208 Expression e1; 5209 Expression e2; 5210 5211 final extern (D) this(const ref Loc loc, TOK op, int size, Expression e1, Expression e2) 5212 { 5213 super(loc, op, size); 5214 this.e1 = e1; 5215 this.e2 = e2; 5216 } 5217 5218 override void accept(Visitor v) 5219 { 5220 v.visit(this); 5221 } 5222 } 5223 5224 extern (C++) final class DsymbolExp : Expression 5225 { 5226 Dsymbol s; 5227 bool hasOverloads; 5228 5229 extern (D) this(const ref Loc loc, Dsymbol s, bool hasOverloads = true) 5230 { 5231 super(loc, TOK.dSymbol, __traits(classInstanceSize, DsymbolExp)); 5232 this.s = s; 5233 this.hasOverloads = hasOverloads; 5234 } 5235 5236 override void accept(Visitor v) 5237 { 5238 v.visit(this); 5239 } 5240 } 5241 5242 extern (C++) final class TemplateExp : Expression 5243 { 5244 TemplateDeclaration td; 5245 FuncDeclaration fd; 5246 5247 extern (D) this(const ref Loc loc, TemplateDeclaration td, FuncDeclaration fd = null) 5248 { 5249 super(loc, TOK.template_, __traits(classInstanceSize, TemplateExp)); 5250 //printf("TemplateExp(): %s\n", td.toChars()); 5251 this.td = td; 5252 this.fd = fd; 5253 } 5254 5255 override void accept(Visitor v) 5256 { 5257 v.visit(this); 5258 } 5259 } 5260 5261 extern (C++) class SymbolExp : Expression 5262 { 5263 Declaration var; 5264 bool hasOverloads; 5265 5266 final extern (D) this(const ref Loc loc, TOK op, int size, Declaration var, bool hasOverloads) 5267 { 5268 super(loc, op, size); 5269 assert(var); 5270 this.var = var; 5271 this.hasOverloads = hasOverloads; 5272 } 5273 5274 override void accept(Visitor v) 5275 { 5276 v.visit(this); 5277 } 5278 } 5279 5280 extern (C++) final class VarExp : SymbolExp 5281 { 5282 extern (D) this(const ref Loc loc, Declaration var, bool hasOverloads = true) 5283 { 5284 if (var.isVarDeclaration()) 5285 hasOverloads = false; 5286 5287 super(loc, TOK.variable, __traits(classInstanceSize, VarExp), var, hasOverloads); 5288 this.type = var.type; 5289 } 5290 5291 override void accept(Visitor v) 5292 { 5293 v.visit(this); 5294 } 5295 } 5296 5297 extern (C++) final class TupleExp : Expression 5298 { 5299 Expression e0; 5300 Expressions* exps; 5301 5302 extern (D) this(const ref Loc loc, Expression e0, Expressions* exps) 5303 { 5304 super(loc, TOK.tuple, __traits(classInstanceSize, TupleExp)); 5305 //printf("TupleExp(this = %p)\n", this); 5306 this.e0 = e0; 5307 this.exps = exps; 5308 } 5309 5310 extern (D) this(const ref Loc loc, Expressions* exps) 5311 { 5312 super(loc, TOK.tuple, __traits(classInstanceSize, TupleExp)); 5313 //printf("TupleExp(this = %p)\n", this); 5314 this.exps = exps; 5315 } 5316 5317 extern (D) this(const ref Loc loc, TupleDeclaration tup) 5318 { 5319 super(loc, TOK.tuple, __traits(classInstanceSize, TupleExp)); 5320 this.exps = new Expressions(); 5321 5322 this.exps.reserve(tup.objects.dim); 5323 for (size_t i = 0; i < tup.objects.dim; i++) 5324 { 5325 RootObject o = (*tup.objects)[i]; 5326 if (Dsymbol s = getDsymbol(o)) 5327 { 5328 Expression e = new DsymbolExp(loc, s); 5329 this.exps.push(e); 5330 } 5331 else if (o.dyncast() == DYNCAST.expression) 5332 { 5333 auto e = (cast(Expression)o).copy(); 5334 e.loc = loc; // Bugzilla 15669 5335 this.exps.push(e); 5336 } 5337 else if (o.dyncast() == DYNCAST.type) 5338 { 5339 Type t = cast(Type)o; 5340 Expression e = new TypeExp(loc, t); 5341 this.exps.push(e); 5342 } 5343 else 5344 { 5345 error("%s is not an expression", o.toChars()); 5346 } 5347 } 5348 } 5349 5350 extern (C++) Dsymbol isDsymbol(RootObject o) 5351 { 5352 if (!o || o.dyncast || DYNCAST.dsymbol) 5353 return null; 5354 return cast(Dsymbol)o; 5355 } 5356 5357 extern (C++) Dsymbol getDsymbol(RootObject oarg) 5358 { 5359 Dsymbol sa; 5360 Expression ea = isExpression(oarg); 5361 if (ea) 5362 { 5363 // Try to convert Expression to symbol 5364 if (ea.op == TOK.variable) 5365 sa = (cast(VarExp)ea).var; 5366 else if (ea.op == TOK.function_) 5367 { 5368 if ((cast(FuncExp)ea).td) 5369 sa = (cast(FuncExp)ea).td; 5370 else 5371 sa = (cast(FuncExp)ea).fd; 5372 } 5373 else if (ea.op == TOK.template_) 5374 sa = (cast(TemplateExp)ea).td; 5375 else 5376 sa = null; 5377 } 5378 else 5379 { 5380 // Try to convert Type to symbol 5381 Type ta = isType(oarg); 5382 if (ta) 5383 sa = ta.toDsymbol(null); 5384 else 5385 sa = isDsymbol(oarg); // if already a symbol 5386 } 5387 return sa; 5388 } 5389 5390 override void accept(Visitor v) 5391 { 5392 v.visit(this); 5393 } 5394 } 5395 5396 extern (C++) final class DollarExp : IdentifierExp 5397 { 5398 extern (D) this(const ref Loc loc) 5399 { 5400 super(loc, Id.dollar); 5401 } 5402 5403 override void accept(Visitor v) 5404 { 5405 v.visit(this); 5406 } 5407 } 5408 5409 extern (C++) class ThisExp : Expression 5410 { 5411 final extern (D) this(const ref Loc loc) 5412 { 5413 super(loc, TOK.this_, __traits(classInstanceSize, ThisExp)); 5414 } 5415 5416 override void accept(Visitor v) 5417 { 5418 v.visit(this); 5419 } 5420 } 5421 5422 extern (C++) final class SuperExp : ThisExp 5423 { 5424 extern (D) this(const ref Loc loc) 5425 { 5426 super(loc); 5427 op = TOK.super_; 5428 } 5429 5430 override void accept(Visitor v) 5431 { 5432 v.visit(this); 5433 } 5434 } 5435 5436 extern (C++) final class AddrExp : UnaExp 5437 { 5438 extern (D) this(const ref Loc loc, Expression e) 5439 { 5440 super(loc, TOK.address, __traits(classInstanceSize, AddrExp), e); 5441 } 5442 5443 override void accept(Visitor v) 5444 { 5445 v.visit(this); 5446 } 5447 } 5448 5449 extern (C++) final class PreExp : UnaExp 5450 { 5451 extern (D) this(TOK op, Loc loc, Expression e) 5452 { 5453 super(loc, op, __traits(classInstanceSize, PreExp), e); 5454 } 5455 5456 override void accept(Visitor v) 5457 { 5458 v.visit(this); 5459 } 5460 } 5461 5462 extern (C++) final class PtrExp : UnaExp 5463 { 5464 extern (D) this(const ref Loc loc, Expression e) 5465 { 5466 super(loc, TOK.star, __traits(classInstanceSize, PtrExp), e); 5467 } 5468 extern (D) this(const ref Loc loc, Expression e, Type t) 5469 { 5470 super(loc, TOK.star, __traits(classInstanceSize, PtrExp), e); 5471 type = t; 5472 } 5473 5474 override void accept(Visitor v) 5475 { 5476 v.visit(this); 5477 } 5478 } 5479 5480 extern (C++) final class NegExp : UnaExp 5481 { 5482 extern (D) this(const ref Loc loc, Expression e) 5483 { 5484 super(loc, TOK.negate, __traits(classInstanceSize, NegExp), e); 5485 } 5486 5487 override void accept(Visitor v) 5488 { 5489 v.visit(this); 5490 } 5491 } 5492 5493 extern (C++) final class UAddExp : UnaExp 5494 { 5495 extern (D) this(const ref Loc loc, Expression e) 5496 { 5497 super(loc, TOK.uadd, __traits(classInstanceSize, UAddExp), e); 5498 } 5499 5500 override void accept(Visitor v) 5501 { 5502 v.visit(this); 5503 } 5504 } 5505 5506 extern (C++) final class NotExp : UnaExp 5507 { 5508 extern (D) this(const ref Loc loc, Expression e) 5509 { 5510 super(loc, TOK.not, __traits(classInstanceSize, NotExp), e); 5511 } 5512 5513 override void accept(Visitor v) 5514 { 5515 v.visit(this); 5516 } 5517 } 5518 5519 extern (C++) final class ComExp : UnaExp 5520 { 5521 extern (D) this(const ref Loc loc, Expression e) 5522 { 5523 super(loc, TOK.tilde, __traits(classInstanceSize, ComExp), e); 5524 } 5525 5526 override void accept(Visitor v) 5527 { 5528 v.visit(this); 5529 } 5530 } 5531 5532 extern (C++) final class DeleteExp : UnaExp 5533 { 5534 bool isRAII; 5535 5536 extern (D) this(const ref Loc loc, Expression e, bool isRAII) 5537 { 5538 super(loc, TOK.delete_, __traits(classInstanceSize, DeleteExp), e); 5539 this.isRAII = isRAII; 5540 } 5541 5542 override void accept(Visitor v) 5543 { 5544 v.visit(this); 5545 } 5546 } 5547 5548 extern (C++) final class CastExp : UnaExp 5549 { 5550 Type to; 5551 ubyte mod = cast(ubyte)~0; 5552 5553 extern (D) this(const ref Loc loc, Expression e, Type t) 5554 { 5555 super(loc, TOK.cast_, __traits(classInstanceSize, CastExp), e); 5556 this.to = t; 5557 } 5558 extern (D) this(const ref Loc loc, Expression e, ubyte mod) 5559 { 5560 super(loc, TOK.cast_, __traits(classInstanceSize, CastExp), e); 5561 this.mod = mod; 5562 } 5563 5564 override void accept(Visitor v) 5565 { 5566 v.visit(this); 5567 } 5568 } 5569 5570 extern (C++) final class CallExp : UnaExp 5571 { 5572 Expressions* arguments; 5573 5574 extern (D) this(const ref Loc loc, Expression e, Expressions* exps) 5575 { 5576 super(loc, TOK.call, __traits(classInstanceSize, CallExp), e); 5577 this.arguments = exps; 5578 } 5579 5580 extern (D) this(const ref Loc loc, Expression e) 5581 { 5582 super(loc, TOK.call, __traits(classInstanceSize, CallExp), e); 5583 } 5584 5585 extern (D) this(const ref Loc loc, Expression e, Expression earg1) 5586 { 5587 super(loc, TOK.call, __traits(classInstanceSize, CallExp), e); 5588 auto arguments = new Expressions(); 5589 if (earg1) 5590 { 5591 arguments.setDim(1); 5592 (*arguments)[0] = earg1; 5593 } 5594 this.arguments = arguments; 5595 } 5596 5597 extern (D) this(const ref Loc loc, Expression e, Expression earg1, Expression earg2) 5598 { 5599 super(loc, TOK.call, __traits(classInstanceSize, CallExp), e); 5600 auto arguments = new Expressions(); 5601 arguments.setDim(2); 5602 (*arguments)[0] = earg1; 5603 (*arguments)[1] = earg2; 5604 this.arguments = arguments; 5605 } 5606 5607 override void accept(Visitor v) 5608 { 5609 v.visit(this); 5610 } 5611 } 5612 5613 extern (C++) final class DotIdExp : UnaExp 5614 { 5615 Identifier ident; 5616 5617 extern (D) this(const ref Loc loc, Expression e, Identifier ident) 5618 { 5619 super(loc, TOK.dotIdentifier, __traits(classInstanceSize, DotIdExp), e); 5620 this.ident = ident; 5621 } 5622 5623 override void accept(Visitor v) 5624 { 5625 v.visit(this); 5626 } 5627 } 5628 5629 extern (C++) final class AssertExp : UnaExp 5630 { 5631 Expression msg; 5632 5633 extern (D) this(const ref Loc loc, Expression e, Expression msg = null) 5634 { 5635 super(loc, TOK.assert_, __traits(classInstanceSize, AssertExp), e); 5636 this.msg = msg; 5637 } 5638 5639 override void accept(Visitor v) 5640 { 5641 v.visit(this); 5642 } 5643 } 5644 5645 extern (C++) final class MixinExp : Expression 5646 { 5647 Expressions* exps; 5648 5649 extern (D) this(const ref Loc loc, Expressions* exps) 5650 { 5651 super(loc, TOK.mixin_, __traits(classInstanceSize, MixinExp)); 5652 this.exps = exps; 5653 } 5654 5655 override void accept(Visitor v) 5656 { 5657 v.visit(this); 5658 } 5659 } 5660 5661 extern (C++) final class ImportExp : UnaExp 5662 { 5663 extern (D) this(const ref Loc loc, Expression e) 5664 { 5665 super(loc, TOK.import_, __traits(classInstanceSize, ImportExp), e); 5666 } 5667 5668 override void accept(Visitor v) 5669 { 5670 v.visit(this); 5671 } 5672 } 5673 5674 extern (C++) final class DotTemplateInstanceExp : UnaExp 5675 { 5676 TemplateInstance ti; 5677 5678 extern (D) this(const ref Loc loc, Expression e, Identifier name, Objects* tiargs) 5679 { 5680 super(loc, TOK.dotTemplateInstance, __traits(classInstanceSize, DotTemplateInstanceExp), e); 5681 this.ti = new TemplateInstance(loc, name, tiargs); 5682 } 5683 extern (D) this(const ref Loc loc, Expression e, TemplateInstance ti) 5684 { 5685 super(loc, TOK.dotTemplateInstance, __traits(classInstanceSize, DotTemplateInstanceExp), e); 5686 this.ti = ti; 5687 } 5688 5689 override void accept(Visitor v) 5690 { 5691 v.visit(this); 5692 } 5693 } 5694 5695 extern (C++) final class ArrayExp : UnaExp 5696 { 5697 Expressions* arguments; 5698 5699 extern (D) this(const ref Loc loc, Expression e1, Expression index = null) 5700 { 5701 super(loc, TOK.array, __traits(classInstanceSize, ArrayExp), e1); 5702 arguments = new Expressions(); 5703 if (index) 5704 arguments.push(index); 5705 } 5706 5707 extern (D) this(const ref Loc loc, Expression e1, Expressions* args) 5708 { 5709 super(loc, TOK.array, __traits(classInstanceSize, ArrayExp), e1); 5710 arguments = args; 5711 } 5712 5713 override void accept(Visitor v) 5714 { 5715 v.visit(this); 5716 } 5717 } 5718 5719 extern (C++) final class FuncInitExp : DefaultInitExp 5720 { 5721 extern (D) this(const ref Loc loc) 5722 { 5723 super(loc, TOK.functionString, __traits(classInstanceSize, FuncInitExp)); 5724 } 5725 5726 override void accept(Visitor v) 5727 { 5728 v.visit(this); 5729 } 5730 } 5731 5732 extern (C++) final class PrettyFuncInitExp : DefaultInitExp 5733 { 5734 extern (D) this(const ref Loc loc) 5735 { 5736 super(loc, TOK.prettyFunction, __traits(classInstanceSize, PrettyFuncInitExp)); 5737 } 5738 5739 override void accept(Visitor v) 5740 { 5741 v.visit(this); 5742 } 5743 } 5744 5745 extern (C++) final class FileInitExp : DefaultInitExp 5746 { 5747 extern (D) this(const ref Loc loc, TOK tok) 5748 { 5749 super(loc, tok, __traits(classInstanceSize, FileInitExp)); 5750 } 5751 5752 override void accept(Visitor v) 5753 { 5754 v.visit(this); 5755 } 5756 } 5757 5758 extern (C++) final class LineInitExp : DefaultInitExp 5759 { 5760 extern (D) this(const ref Loc loc) 5761 { 5762 super(loc, TOK.line, __traits(classInstanceSize, LineInitExp)); 5763 } 5764 5765 override void accept(Visitor v) 5766 { 5767 v.visit(this); 5768 } 5769 } 5770 5771 extern (C++) final class ModuleInitExp : DefaultInitExp 5772 { 5773 extern (D) this(const ref Loc loc) 5774 { 5775 super(loc, TOK.moduleString, __traits(classInstanceSize, ModuleInitExp)); 5776 } 5777 5778 override void accept(Visitor v) 5779 { 5780 v.visit(this); 5781 } 5782 } 5783 5784 extern (C++) final class CommaExp : BinExp 5785 { 5786 const bool isGenerated; 5787 bool allowCommaExp; 5788 5789 extern (D) this(const ref Loc loc, Expression e1, Expression e2, bool generated = true) 5790 { 5791 super(loc, TOK.comma, __traits(classInstanceSize, CommaExp), e1, e2); 5792 allowCommaExp = isGenerated = generated; 5793 } 5794 5795 override void accept(Visitor v) 5796 { 5797 v.visit(this); 5798 } 5799 } 5800 5801 extern (C++) final class PostExp : BinExp 5802 { 5803 extern (D) this(TOK op, Loc loc, Expression e) 5804 { 5805 super(loc, op, __traits(classInstanceSize, PostExp), e, new IntegerExp(loc, 1, Type.tint32)); 5806 } 5807 5808 override void accept(Visitor v) 5809 { 5810 v.visit(this); 5811 } 5812 } 5813 5814 extern (C++) final class PowExp : BinExp 5815 { 5816 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 5817 { 5818 super(loc, TOK.pow, __traits(classInstanceSize, PowExp), e1, e2); 5819 } 5820 5821 override void accept(Visitor v) 5822 { 5823 v.visit(this); 5824 } 5825 } 5826 5827 extern (C++) final class MulExp : BinExp 5828 { 5829 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 5830 { 5831 super(loc, TOK.mul, __traits(classInstanceSize, MulExp), e1, e2); 5832 } 5833 5834 override void accept(Visitor v) 5835 { 5836 v.visit(this); 5837 } 5838 } 5839 5840 extern (C++) final class DivExp : BinExp 5841 { 5842 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 5843 { 5844 super(loc, TOK.div, __traits(classInstanceSize, DivExp), e1, e2); 5845 } 5846 5847 override void accept(Visitor v) 5848 { 5849 v.visit(this); 5850 } 5851 } 5852 5853 extern (C++) final class ModExp : BinExp 5854 { 5855 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 5856 { 5857 super(loc, TOK.mod, __traits(classInstanceSize, ModExp), e1, e2); 5858 } 5859 5860 override void accept(Visitor v) 5861 { 5862 v.visit(this); 5863 } 5864 } 5865 5866 extern (C++) final class AddExp : BinExp 5867 { 5868 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 5869 { 5870 super(loc, TOK.add, __traits(classInstanceSize, AddExp), e1, e2); 5871 } 5872 5873 override void accept(Visitor v) 5874 { 5875 v.visit(this); 5876 } 5877 } 5878 5879 extern (C++) final class MinExp : BinExp 5880 { 5881 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 5882 { 5883 super(loc, TOK.min, __traits(classInstanceSize, MinExp), e1, e2); 5884 } 5885 5886 override void accept(Visitor v) 5887 { 5888 v.visit(this); 5889 } 5890 } 5891 5892 extern (C++) final class CatExp : BinExp 5893 { 5894 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 5895 { 5896 super(loc, TOK.concatenate, __traits(classInstanceSize, CatExp), e1, e2); 5897 } 5898 5899 override void accept(Visitor v) 5900 { 5901 v.visit(this); 5902 } 5903 } 5904 5905 extern (C++) final class ShlExp : BinExp 5906 { 5907 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 5908 { 5909 super(loc, TOK.leftShift, __traits(classInstanceSize, ShlExp), e1, e2); 5910 } 5911 5912 override void accept(Visitor v) 5913 { 5914 v.visit(this); 5915 } 5916 } 5917 5918 extern (C++) final class ShrExp : BinExp 5919 { 5920 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 5921 { 5922 super(loc, TOK.rightShift, __traits(classInstanceSize, ShrExp), e1, e2); 5923 } 5924 5925 override void accept(Visitor v) 5926 { 5927 v.visit(this); 5928 } 5929 } 5930 5931 extern (C++) final class UshrExp : BinExp 5932 { 5933 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 5934 { 5935 super(loc, TOK.unsignedRightShift, __traits(classInstanceSize, UshrExp), e1, e2); 5936 } 5937 5938 override void accept(Visitor v) 5939 { 5940 v.visit(this); 5941 } 5942 } 5943 5944 extern (C++) final class EqualExp : BinExp 5945 { 5946 extern (D) this(TOK op, Loc loc, Expression e1, Expression e2) 5947 { 5948 super(loc, op, __traits(classInstanceSize, EqualExp), e1, e2); 5949 assert(op == TOK.equal || op == TOK.notEqual); 5950 } 5951 5952 override void accept(Visitor v) 5953 { 5954 v.visit(this); 5955 } 5956 } 5957 5958 extern (C++) final class InExp : BinExp 5959 { 5960 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 5961 { 5962 super(loc, TOK.in_, __traits(classInstanceSize, InExp), e1, e2); 5963 } 5964 5965 override void accept(Visitor v) 5966 { 5967 v.visit(this); 5968 } 5969 } 5970 5971 extern (C++) final class IdentityExp : BinExp 5972 { 5973 extern (D) this(TOK op, Loc loc, Expression e1, Expression e2) 5974 { 5975 super(loc, op, __traits(classInstanceSize, IdentityExp), e1, e2); 5976 } 5977 5978 override void accept(Visitor v) 5979 { 5980 v.visit(this); 5981 } 5982 } 5983 5984 extern (C++) final class CmpExp : BinExp 5985 { 5986 extern (D) this(TOK op, Loc loc, Expression e1, Expression e2) 5987 { 5988 super(loc, op, __traits(classInstanceSize, CmpExp), e1, e2); 5989 } 5990 5991 override void accept(Visitor v) 5992 { 5993 v.visit(this); 5994 } 5995 } 5996 5997 extern (C++) final class AndExp : BinExp 5998 { 5999 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 6000 { 6001 super(loc, TOK.and, __traits(classInstanceSize, AndExp), e1, e2); 6002 } 6003 6004 override void accept(Visitor v) 6005 { 6006 v.visit(this); 6007 } 6008 } 6009 6010 extern (C++) final class XorExp : BinExp 6011 { 6012 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 6013 { 6014 super(loc, TOK.xor, __traits(classInstanceSize, XorExp), e1, e2); 6015 } 6016 6017 override void accept(Visitor v) 6018 { 6019 v.visit(this); 6020 } 6021 } 6022 6023 extern (C++) final class OrExp : BinExp 6024 { 6025 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 6026 { 6027 super(loc, TOK.or, __traits(classInstanceSize, OrExp), e1, e2); 6028 } 6029 6030 override void accept(Visitor v) 6031 { 6032 v.visit(this); 6033 } 6034 } 6035 6036 extern (C++) final class LogicalExp : BinExp 6037 { 6038 extern (D) this(const ref Loc loc, TOK op, Expression e1, Expression e2) 6039 { 6040 super(loc, op, __traits(classInstanceSize, LogicalExp), e1, e2); 6041 } 6042 6043 override void accept(Visitor v) 6044 { 6045 v.visit(this); 6046 } 6047 } 6048 6049 extern (C++) final class CondExp : BinExp 6050 { 6051 Expression econd; 6052 6053 extern (D) this(const ref Loc loc, Expression econd, Expression e1, Expression e2) 6054 { 6055 super(loc, TOK.question, __traits(classInstanceSize, CondExp), e1, e2); 6056 this.econd = econd; 6057 } 6058 6059 override void accept(Visitor v) 6060 { 6061 v.visit(this); 6062 } 6063 } 6064 6065 extern (C++) final class AssignExp : BinExp 6066 { 6067 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 6068 { 6069 super(loc, TOK.assign, __traits(classInstanceSize, AssignExp), e1, e2); 6070 } 6071 6072 override void accept(Visitor v) 6073 { 6074 v.visit(this); 6075 } 6076 } 6077 6078 extern (C++) class BinAssignExp : BinExp 6079 { 6080 final extern (D) this(const ref Loc loc, TOK op, int size, Expression e1, Expression e2) 6081 { 6082 super(loc, op, size, e1, e2); 6083 } 6084 6085 override void accept(Visitor v) 6086 { 6087 v.visit(this); 6088 } 6089 } 6090 6091 extern (C++) final class AddAssignExp : BinAssignExp 6092 { 6093 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 6094 { 6095 super(loc, TOK.addAssign, __traits(classInstanceSize, AddAssignExp), e1, e2); 6096 } 6097 6098 override void accept(Visitor v) 6099 { 6100 v.visit(this); 6101 } 6102 } 6103 6104 extern (C++) final class MinAssignExp : BinAssignExp 6105 { 6106 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 6107 { 6108 super(loc, TOK.minAssign, __traits(classInstanceSize, MinAssignExp), e1, e2); 6109 } 6110 6111 override void accept(Visitor v) 6112 { 6113 v.visit(this); 6114 } 6115 } 6116 6117 extern (C++) final class MulAssignExp : BinAssignExp 6118 { 6119 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 6120 { 6121 super(loc, TOK.mulAssign, __traits(classInstanceSize, MulAssignExp), e1, e2); 6122 } 6123 6124 override void accept(Visitor v) 6125 { 6126 v.visit(this); 6127 } 6128 } 6129 6130 extern (C++) final class DivAssignExp : BinAssignExp 6131 { 6132 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 6133 { 6134 super(loc, TOK.divAssign, __traits(classInstanceSize, DivAssignExp), e1, e2); 6135 } 6136 6137 override void accept(Visitor v) 6138 { 6139 v.visit(this); 6140 } 6141 } 6142 6143 extern (C++) final class ModAssignExp : BinAssignExp 6144 { 6145 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 6146 { 6147 super(loc, TOK.modAssign, __traits(classInstanceSize, ModAssignExp), e1, e2); 6148 } 6149 6150 override void accept(Visitor v) 6151 { 6152 v.visit(this); 6153 } 6154 } 6155 6156 extern (C++) final class PowAssignExp : BinAssignExp 6157 { 6158 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 6159 { 6160 super(loc, TOK.powAssign, __traits(classInstanceSize, PowAssignExp), e1, e2); 6161 } 6162 6163 override void accept(Visitor v) 6164 { 6165 v.visit(this); 6166 } 6167 } 6168 6169 extern (C++) final class AndAssignExp : BinAssignExp 6170 { 6171 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 6172 { 6173 super(loc, TOK.andAssign, __traits(classInstanceSize, AndAssignExp), e1, e2); 6174 } 6175 6176 override void accept(Visitor v) 6177 { 6178 v.visit(this); 6179 } 6180 } 6181 6182 extern (C++) final class OrAssignExp : BinAssignExp 6183 { 6184 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 6185 { 6186 super(loc, TOK.orAssign, __traits(classInstanceSize, OrAssignExp), e1, e2); 6187 } 6188 6189 override void accept(Visitor v) 6190 { 6191 v.visit(this); 6192 } 6193 } 6194 6195 extern (C++) final class XorAssignExp : BinAssignExp 6196 { 6197 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 6198 { 6199 super(loc, TOK.xorAssign, __traits(classInstanceSize, XorAssignExp), e1, e2); 6200 } 6201 6202 override void accept(Visitor v) 6203 { 6204 v.visit(this); 6205 } 6206 } 6207 6208 extern (C++) final class ShlAssignExp : BinAssignExp 6209 { 6210 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 6211 { 6212 super(loc, TOK.leftShiftAssign, __traits(classInstanceSize, ShlAssignExp), e1, e2); 6213 } 6214 6215 override void accept(Visitor v) 6216 { 6217 v.visit(this); 6218 } 6219 } 6220 6221 extern (C++) final class ShrAssignExp : BinAssignExp 6222 { 6223 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 6224 { 6225 super(loc, TOK.rightShiftAssign, __traits(classInstanceSize, ShrAssignExp), e1, e2); 6226 } 6227 6228 override void accept(Visitor v) 6229 { 6230 v.visit(this); 6231 } 6232 } 6233 6234 extern (C++) final class UshrAssignExp : BinAssignExp 6235 { 6236 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 6237 { 6238 super(loc, TOK.unsignedRightShiftAssign, __traits(classInstanceSize, UshrAssignExp), e1, e2); 6239 } 6240 6241 override void accept(Visitor v) 6242 { 6243 v.visit(this); 6244 } 6245 } 6246 6247 extern (C++) final class CatAssignExp : BinAssignExp 6248 { 6249 extern (D) this(const ref Loc loc, Expression e1, Expression e2) 6250 { 6251 super(loc, TOK.concatenateAssign, __traits(classInstanceSize, CatAssignExp), e1, e2); 6252 } 6253 6254 override void accept(Visitor v) 6255 { 6256 v.visit(this); 6257 } 6258 } 6259 6260 extern (C++) class TemplateParameter : ASTNode 6261 { 6262 Loc loc; 6263 Identifier ident; 6264 6265 final extern (D) this(const ref Loc loc, Identifier ident) 6266 { 6267 this.loc = loc; 6268 this.ident = ident; 6269 } 6270 6271 TemplateParameter syntaxCopy(){ return null;} 6272 6273 override void accept(Visitor v) 6274 { 6275 v.visit(this); 6276 } 6277 } 6278 6279 extern (C++) final class TemplateAliasParameter : TemplateParameter 6280 { 6281 Type specType; 6282 RootObject specAlias; 6283 RootObject defaultAlias; 6284 6285 extern (D) this(const ref Loc loc, Identifier ident, Type specType, RootObject specAlias, RootObject defaultAlias) 6286 { 6287 super(loc, ident); 6288 this.ident = ident; 6289 this.specType = specType; 6290 this.specAlias = specAlias; 6291 this.defaultAlias = defaultAlias; 6292 } 6293 6294 override void accept(Visitor v) 6295 { 6296 v.visit(this); 6297 } 6298 } 6299 6300 extern (C++) class TemplateTypeParameter : TemplateParameter 6301 { 6302 Type specType; 6303 Type defaultType; 6304 6305 final extern (D) this(const ref Loc loc, Identifier ident, Type specType, Type defaultType) 6306 { 6307 super(loc, ident); 6308 this.ident = ident; 6309 this.specType = specType; 6310 this.defaultType = defaultType; 6311 } 6312 6313 override void accept(Visitor v) 6314 { 6315 v.visit(this); 6316 } 6317 } 6318 6319 extern (C++) final class TemplateTupleParameter : TemplateParameter 6320 { 6321 extern (D) this(const ref Loc loc, Identifier ident) 6322 { 6323 super(loc, ident); 6324 this.ident = ident; 6325 } 6326 6327 override void accept(Visitor v) 6328 { 6329 v.visit(this); 6330 } 6331 } 6332 6333 extern (C++) final class TemplateValueParameter : TemplateParameter 6334 { 6335 Type valType; 6336 Expression specValue; 6337 Expression defaultValue; 6338 6339 extern (D) this(const ref Loc loc, Identifier ident, Type valType, 6340 Expression specValue, Expression defaultValue) 6341 { 6342 super(loc, ident); 6343 this.ident = ident; 6344 this.valType = valType; 6345 this.specValue = specValue; 6346 this.defaultValue = defaultValue; 6347 } 6348 6349 override void accept(Visitor v) 6350 { 6351 v.visit(this); 6352 } 6353 } 6354 6355 extern (C++) final class TemplateThisParameter : TemplateTypeParameter 6356 { 6357 extern (D) this(const ref Loc loc, Identifier ident, Type specType, Type defaultType) 6358 { 6359 super(loc, ident, specType, defaultType); 6360 } 6361 6362 override void accept(Visitor v) 6363 { 6364 v.visit(this); 6365 } 6366 } 6367 6368 extern (C++) abstract class Condition : ASTNode 6369 { 6370 Loc loc; 6371 6372 final extern (D) this(const ref Loc loc) 6373 { 6374 this.loc = loc; 6375 } 6376 6377 override void accept(Visitor v) 6378 { 6379 v.visit(this); 6380 } 6381 } 6382 6383 extern (C++) final class StaticForeach : RootObject 6384 { 6385 Loc loc; 6386 6387 ForeachStatement aggrfe; 6388 ForeachRangeStatement rangefe; 6389 6390 final extern (D) this(const ref Loc loc, ForeachStatement aggrfe, ForeachRangeStatement rangefe) 6391 in 6392 { 6393 assert(!!aggrfe ^ !!rangefe); 6394 } 6395 do 6396 { 6397 this.loc = loc; 6398 this.aggrfe = aggrfe; 6399 this.rangefe = rangefe; 6400 } 6401 } 6402 6403 extern (C++) final class StaticIfCondition : Condition 6404 { 6405 Expression exp; 6406 6407 final extern (D) this(const ref Loc loc, Expression exp) 6408 { 6409 super(loc); 6410 this.exp = exp; 6411 } 6412 6413 override void accept(Visitor v) 6414 { 6415 v.visit(this); 6416 } 6417 } 6418 6419 extern (C++) class DVCondition : Condition 6420 { 6421 uint level; 6422 Identifier ident; 6423 Module mod; 6424 6425 final extern (D) this(const ref Loc loc, Module mod, uint level, Identifier ident) 6426 { 6427 super(loc); 6428 this.mod = mod; 6429 this.ident = ident; 6430 } 6431 6432 override void accept(Visitor v) 6433 { 6434 v.visit(this); 6435 } 6436 } 6437 6438 extern (C++) final class DebugCondition : DVCondition 6439 { 6440 extern (D) this(const ref Loc loc, Module mod, uint level, Identifier ident) 6441 { 6442 super(loc, mod, level, ident); 6443 } 6444 6445 override void accept(Visitor v) 6446 { 6447 v.visit(this); 6448 } 6449 } 6450 6451 extern (C++) final class VersionCondition : DVCondition 6452 { 6453 extern (D) this(const ref Loc loc, Module mod, uint level, Identifier ident) 6454 { 6455 super(loc, mod, level, ident); 6456 } 6457 6458 override void accept(Visitor v) 6459 { 6460 v.visit(this); 6461 } 6462 } 6463 6464 enum InitKind : ubyte 6465 { 6466 void_, 6467 error, 6468 struct_, 6469 array, 6470 exp, 6471 } 6472 6473 extern (C++) class Initializer : ASTNode 6474 { 6475 Loc loc; 6476 InitKind kind; 6477 6478 final extern (D) this(const ref Loc loc, InitKind kind) 6479 { 6480 this.loc = loc; 6481 this.kind = kind; 6482 } 6483 6484 // this should be abstract and implemented in child classes 6485 Expression toExpression(Type t = null) 6486 { 6487 return null; 6488 } 6489 6490 final ExpInitializer isExpInitializer() 6491 { 6492 return kind == InitKind.exp ? cast(ExpInitializer)cast(void*)this : null; 6493 } 6494 6495 override void accept(Visitor v) 6496 { 6497 v.visit(this); 6498 } 6499 } 6500 6501 extern (C++) final class ExpInitializer : Initializer 6502 { 6503 Expression exp; 6504 6505 extern (D) this(const ref Loc loc, Expression exp) 6506 { 6507 super(loc, InitKind.exp); 6508 this.exp = exp; 6509 } 6510 6511 override void accept(Visitor v) 6512 { 6513 v.visit(this); 6514 } 6515 } 6516 6517 extern (C++) final class StructInitializer : Initializer 6518 { 6519 Identifiers field; 6520 Initializers value; 6521 6522 extern (D) this(const ref Loc loc) 6523 { 6524 super(loc, InitKind.struct_); 6525 } 6526 6527 void addInit(Identifier field, Initializer value) 6528 { 6529 this.field.push(field); 6530 this.value.push(value); 6531 } 6532 6533 override void accept(Visitor v) 6534 { 6535 v.visit(this); 6536 } 6537 } 6538 6539 extern (C++) final class ArrayInitializer : Initializer 6540 { 6541 Expressions index; 6542 Initializers value; 6543 uint dim; 6544 Type type; 6545 6546 extern (D) this(const ref Loc loc) 6547 { 6548 super(loc, InitKind.array); 6549 } 6550 6551 void addInit(Expression index, Initializer value) 6552 { 6553 this.index.push(index); 6554 this.value.push(value); 6555 dim = 0; 6556 type = null; 6557 } 6558 6559 override void accept(Visitor v) 6560 { 6561 v.visit(this); 6562 } 6563 } 6564 6565 extern (C++) final class VoidInitializer : Initializer 6566 { 6567 extern (D) this(const ref Loc loc) 6568 { 6569 super(loc, InitKind.void_); 6570 } 6571 6572 override void accept(Visitor v) 6573 { 6574 v.visit(this); 6575 } 6576 } 6577 6578 extern (C++) final class Tuple : RootObject 6579 { 6580 Objects objects; 6581 6582 // kludge for template.isType() 6583 override DYNCAST dyncast() const 6584 { 6585 return DYNCAST.tuple; 6586 } 6587 6588 override const(char)* toChars() const 6589 { 6590 return objects.toChars(); 6591 } 6592 } 6593 6594 struct BaseClass 6595 { 6596 Type type; 6597 } 6598 6599 struct ModuleDeclaration 6600 { 6601 Loc loc; 6602 Identifier id; 6603 Identifier[] packages; 6604 bool isdeprecated; 6605 Expression msg; 6606 6607 extern (D) this(const ref Loc loc, Identifier[] packages, Identifier id, Expression msg, bool isdeprecated) 6608 { 6609 this.loc = loc; 6610 this.packages = packages; 6611 this.id = id; 6612 this.msg = msg; 6613 this.isdeprecated = isdeprecated; 6614 } 6615 6616 extern (C++) const(char)* toChars() const 6617 { 6618 OutBuffer buf; 6619 foreach (const pid; packages) 6620 { 6621 buf.writestring(pid.toString()); 6622 buf.writeByte('.'); 6623 } 6624 buf.writestring(id.toString()); 6625 return buf.extractChars(); 6626 } 6627 } 6628 6629 struct Visibility 6630 { 6631 enum Kind : ubyte 6632 { 6633 undefined, 6634 none, 6635 private_, 6636 package_, 6637 protected_, 6638 public_, 6639 export_, 6640 } 6641 Kind kind; 6642 Package pkg; 6643 } 6644 6645 struct Scope 6646 { 6647 6648 } 6649 6650 static extern (C++) Tuple isTuple(RootObject o) 6651 { 6652 //return dynamic_cast<Tuple *>(o); 6653 if (!o || o.dyncast() != DYNCAST.tuple) 6654 return null; 6655 return cast(Tuple)o; 6656 } 6657 6658 static extern (C++) Type isType(RootObject o) 6659 { 6660 if (!o || o.dyncast() != DYNCAST.type) 6661 return null; 6662 return cast(Type)o; 6663 } 6664 6665 static extern (C++) Expression isExpression(RootObject o) 6666 { 6667 if (!o || o.dyncast() != DYNCAST.expression) 6668 return null; 6669 return cast(Expression)o; 6670 } 6671 6672 static extern (C++) TemplateParameter isTemplateParameter(RootObject o) 6673 { 6674 if (!o || o.dyncast() != DYNCAST.templateparameter) 6675 return null; 6676 return cast(TemplateParameter)o; 6677 } 6678 6679 6680 static const(char)* visibilityToChars(Visibility.Kind kind) 6681 { 6682 final switch (kind) 6683 { 6684 case Visibility.Kind.undefined: 6685 return null; 6686 case Visibility.Kind.none: 6687 return "none"; 6688 case Visibility.Kind.private_: 6689 return "private"; 6690 case Visibility.Kind.package_: 6691 return "package"; 6692 case Visibility.Kind.protected_: 6693 return "protected"; 6694 case Visibility.Kind.public_: 6695 return "public"; 6696 case Visibility.Kind.export_: 6697 return "export"; 6698 } 6699 } 6700 6701 static bool stcToBuffer(OutBuffer* buf, StorageClass stc) 6702 { 6703 bool result = false; 6704 if ((stc & (STC.return_ | STC.scope_)) == (STC.return_ | STC.scope_)) 6705 stc &= ~STC.scope_; 6706 while (stc) 6707 { 6708 const p = stcToString(stc); 6709 if (!p.length) // there's no visible storage classes 6710 break; 6711 if (!result) 6712 result = true; 6713 else 6714 buf.writeByte(' '); 6715 buf.writestring(p); 6716 } 6717 return result; 6718 } 6719 6720 static extern (C++) Expression typeToExpression(Type t) 6721 { 6722 return t.toExpression; 6723 } 6724 6725 static string stcToString(ref StorageClass stc) 6726 { 6727 static struct SCstring 6728 { 6729 StorageClass stc; 6730 string id; 6731 } 6732 6733 // Note: The identifier needs to be `\0` terminated 6734 // as some code assumes it (e.g. when printing error messages) 6735 static immutable SCstring[] table = 6736 [ 6737 SCstring(STC.auto_, Token.toString(TOK.auto_)), 6738 SCstring(STC.scope_, Token.toString(TOK.scope_)), 6739 SCstring(STC.static_, Token.toString(TOK.static_)), 6740 SCstring(STC.extern_, Token.toString(TOK.extern_)), 6741 SCstring(STC.const_, Token.toString(TOK.const_)), 6742 SCstring(STC.final_, Token.toString(TOK.final_)), 6743 SCstring(STC.abstract_, Token.toString(TOK.abstract_)), 6744 SCstring(STC.synchronized_, Token.toString(TOK.synchronized_)), 6745 SCstring(STC.deprecated_, Token.toString(TOK.deprecated_)), 6746 SCstring(STC.override_, Token.toString(TOK.override_)), 6747 SCstring(STC.lazy_, Token.toString(TOK.lazy_)), 6748 SCstring(STC.alias_, Token.toString(TOK.alias_)), 6749 SCstring(STC.out_, Token.toString(TOK.out_)), 6750 SCstring(STC.in_, Token.toString(TOK.in_)), 6751 SCstring(STC.manifest, Token.toString(TOK.enum_)), 6752 SCstring(STC.immutable_, Token.toString(TOK.immutable_)), 6753 SCstring(STC.shared_, Token.toString(TOK.shared_)), 6754 SCstring(STC.nothrow_, Token.toString(TOK.nothrow_)), 6755 SCstring(STC.wild, Token.toString(TOK.inout_)), 6756 SCstring(STC.pure_, Token.toString(TOK.pure_)), 6757 SCstring(STC.ref_, Token.toString(TOK.ref_)), 6758 SCstring(STC.return_, Token.toString(TOK.return_)), 6759 SCstring(STC.tls, "__thread"), 6760 SCstring(STC.gshared, Token.toString(TOK.gshared)), 6761 SCstring(STC.nogc, "@nogc"), 6762 SCstring(STC.live, "@live"), 6763 SCstring(STC.property, "@property"), 6764 SCstring(STC.safe, "@safe"), 6765 SCstring(STC.trusted, "@trusted"), 6766 SCstring(STC.system, "@system"), 6767 SCstring(STC.disable, "@disable"), 6768 SCstring(STC.future, "@__future"), 6769 SCstring(STC.local, "__local"), 6770 ]; 6771 foreach (ref entry; table) 6772 { 6773 const StorageClass tbl = entry.stc; 6774 assert(tbl & STCStorageClass); 6775 if (stc & tbl) 6776 { 6777 stc &= ~tbl; 6778 return entry.id; 6779 } 6780 } 6781 //printf("stc = %llx\n", stc); 6782 return null; 6783 } 6784 6785 static const(char)* linkageToChars(LINK linkage) 6786 { 6787 final switch (linkage) 6788 { 6789 case LINK.default_: 6790 case LINK.system: 6791 return null; 6792 case LINK.d: 6793 return "D"; 6794 case LINK.c: 6795 return "C"; 6796 case LINK.cpp: 6797 return "C++"; 6798 case LINK.windows: 6799 return "Windows"; 6800 case LINK.objc: 6801 return "Objective-C"; 6802 } 6803 } 6804 6805 struct Target 6806 { 6807 extern (C++) __gshared int ptrsize; 6808 6809 extern (C++) static Type va_listType(const ref Loc loc, Scope* sc) 6810 { 6811 if (global.params.targetOS == TargetOS.Windows) 6812 { 6813 return Type.tchar.pointerTo(); 6814 } 6815 else if (global.params.targetOS & TargetOS.Posix) 6816 { 6817 if (global.params.is64bit) 6818 { 6819 return (new TypeIdentifier(Loc.initial, Identifier.idPool("__va_list_tag"))).pointerTo(); 6820 } 6821 else 6822 { 6823 return Type.tchar.pointerTo(); 6824 } 6825 } 6826 else 6827 { 6828 assert(0); 6829 } 6830 } 6831 } 6832 }