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 }