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