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