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