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