1 // Written in the D programming language.
2 
3 /**
4  * This module defines an Abstract Syntax Tree for the D language
5  *
6  * Examples:
7  * ---
8  * // TODO
9  * ---
10  *
11  * Copyright: Brian Schott 2013
12  * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt Boost, License 1.0)
13  * Authors: Brian Schott
14  */
15 
16 module dparse.ast;
17 
18 import dparse.lexer;
19 import std.traits;
20 import std.algorithm;
21 import std.array;
22 import std..string;
23 
24 private immutable uint[TypeInfo] typeMap;
25 
26 shared static this()
27 {
28     typeMap[typeid(AddExpression)] = 1;
29     typeMap[typeid(AndAndExpression)] = 2;
30     typeMap[typeid(AndExpression)] = 3;
31     typeMap[typeid(AsmAddExp)] = 4;
32     typeMap[typeid(AsmAndExp)] = 5;
33     typeMap[typeid(AsmBrExp)] = 6;
34     typeMap[typeid(AsmExp)] = 7;
35     typeMap[typeid(AsmEqualExp)] = 8;
36     typeMap[typeid(AsmLogAndExp)] = 9;
37     typeMap[typeid(AsmLogOrExp)] = 10;
38     typeMap[typeid(AsmMulExp)] = 11;
39     typeMap[typeid(AsmOrExp)] = 12;
40     typeMap[typeid(AsmRelExp)] = 13;
41     typeMap[typeid(AsmUnaExp)] = 14;
42     typeMap[typeid(AsmShiftExp)] = 15;
43     typeMap[typeid(AsmXorExp)] = 16;
44     typeMap[typeid(AssertExpression)] = 17;
45     typeMap[typeid(AssignExpression)] = 18;
46     typeMap[typeid(CmpExpression)] = 19;
47     typeMap[typeid(DeleteExpression)] = 20;
48     typeMap[typeid(EqualExpression)] = 21;
49     typeMap[typeid(Expression)] = 22;
50     typeMap[typeid(FunctionCallExpression)] = 23;
51     typeMap[typeid(FunctionLiteralExpression)] = 24;
52     typeMap[typeid(IdentityExpression)] = 25;
53     typeMap[typeid(ImportExpression)] = 26;
54     typeMap[typeid(IndexExpression)] = 27;
55     typeMap[typeid(InExpression)] = 28;
56     typeMap[typeid(IsExpression)] = 29;
57     typeMap[typeid(LambdaExpression)] = 30;
58     typeMap[typeid(MixinExpression)] = 31;
59     typeMap[typeid(MulExpression)] = 32;
60     typeMap[typeid(NewAnonClassExpression)] = 33;
61     typeMap[typeid(NewExpression)] = 34;
62     typeMap[typeid(OrExpression)] = 35;
63     typeMap[typeid(OrOrExpression)] = 36;
64     typeMap[typeid(PowExpression)] = 37;
65     typeMap[typeid(PragmaExpression)] = 38;
66     typeMap[typeid(PrimaryExpression)] = 39;
67     typeMap[typeid(RelExpression)] = 40;
68     typeMap[typeid(ShiftExpression)] = 41;
69     typeMap[typeid(Index)] = 42;
70     typeMap[typeid(TemplateMixinExpression)] = 43;
71     typeMap[typeid(TernaryExpression)] = 44;
72     typeMap[typeid(TraitsExpression)] = 45;
73     typeMap[typeid(TypeidExpression)] = 46;
74     typeMap[typeid(TypeofExpression)] = 47;
75     typeMap[typeid(UnaryExpression)] = 48;
76     typeMap[typeid(XorExpression)] = 49;
77 }
78 
79 /**
80  * Implements the $(LINK2 http://en.wikipedia.org/wiki/Visitor_pattern, Visitor Pattern)
81  * for the various AST classes
82  */
83 abstract class ASTVisitor
84 {
85 public:
86 
87     /** */
88     void visit(const ExpressionNode n)
89     {
90         switch (typeMap[typeid(n)])
91         {
92         case 1: visit(cast(AddExpression) n); break;
93         case 2: visit(cast(AndAndExpression) n); break;
94         case 3: visit(cast(AndExpression) n); break;
95         case 4: visit(cast(AsmAddExp) n); break;
96         case 5: visit(cast(AsmAndExp) n); break;
97         case 6: visit(cast(AsmBrExp) n); break;
98         case 7: visit(cast(AsmExp) n); break;
99         case 8: visit(cast(AsmEqualExp) n); break;
100         case 9: visit(cast(AsmLogAndExp) n); break;
101         case 10: visit(cast(AsmLogOrExp) n); break;
102         case 11: visit(cast(AsmMulExp) n); break;
103         case 12: visit(cast(AsmOrExp) n); break;
104         case 13: visit(cast(AsmRelExp) n); break;
105         case 14: visit(cast(AsmUnaExp) n); break;
106         case 15: visit(cast(AsmShiftExp) n); break;
107         case 16: visit(cast(AsmXorExp) n); break;
108         case 17: visit(cast(AssertExpression) n); break;
109         case 18: visit(cast(AssignExpression) n); break;
110         case 19: visit(cast(CmpExpression) n); break;
111         case 20: visit(cast(DeleteExpression) n); break;
112         case 21: visit(cast(EqualExpression) n); break;
113         case 22: visit(cast(Expression) n); break;
114         case 23: visit(cast(FunctionCallExpression) n); break;
115         case 24: visit(cast(FunctionLiteralExpression) n); break;
116         case 25: visit(cast(IdentityExpression) n); break;
117         case 26: visit(cast(ImportExpression) n); break;
118         case 27: visit(cast(IndexExpression) n); break;
119         case 28: visit(cast(InExpression) n); break;
120         case 29: visit(cast(IsExpression) n); break;
121         case 30: visit(cast(LambdaExpression) n); break;
122         case 31: visit(cast(MixinExpression) n); break;
123         case 32: visit(cast(MulExpression) n); break;
124         case 33: visit(cast(NewAnonClassExpression) n); break;
125         case 34: visit(cast(NewExpression) n); break;
126         case 35: visit(cast(OrExpression) n); break;
127         case 36: visit(cast(OrOrExpression) n); break;
128         case 37: visit(cast(PowExpression) n); break;
129         case 38: visit(cast(PragmaExpression) n); break;
130         case 39: visit(cast(PrimaryExpression) n); break;
131         case 40: visit(cast(RelExpression) n); break;
132         case 41: visit(cast(ShiftExpression) n); break;
133         case 42: visit(cast(Index) n); break;
134         case 43: visit(cast(TemplateMixinExpression) n); break;
135         case 44: visit(cast(TernaryExpression) n); break;
136         case 45: visit(cast(TraitsExpression) n); break;
137         case 46: visit(cast(TypeidExpression) n); break;
138         case 47: visit(cast(TypeofExpression) n); break;
139         case 48: visit(cast(UnaryExpression) n); break;
140         case 49: visit(cast(XorExpression) n); break;
141         default: assert(false, __MODULE__ ~ " has a bug");
142         }
143     }
144 
145     /** */ void visit(const AddExpression addExpression) { addExpression.accept(this); }
146     /** */ void visit(const AliasDeclaration aliasDeclaration) { aliasDeclaration.accept(this); }
147     /** */ void visit(const AliasInitializer aliasInitializer) { aliasInitializer.accept(this); }
148     /** */ void visit(const AliasThisDeclaration aliasThisDeclaration) { aliasThisDeclaration.accept(this); }
149     /** */ void visit(const AlignAttribute alignAttribute) { alignAttribute.accept(this); }
150     /** */ void visit(const AndAndExpression andAndExpression) { andAndExpression.accept(this); }
151     /** */ void visit(const AndExpression andExpression) { andExpression.accept(this); }
152     /** */ void visit(const AnonymousEnumDeclaration anonymousEnumDeclaration) { anonymousEnumDeclaration.accept(this); }
153     /** */ void visit(const AnonymousEnumMember anonymousEnumMember) { anonymousEnumMember.accept(this); }
154     /** */ void visit(const ArgumentList argumentList) { argumentList.accept(this); }
155     /** */ void visit(const Arguments arguments) { arguments.accept(this); }
156     /** */ void visit(const ArrayInitializer arrayInitializer) { arrayInitializer.accept(this); }
157     /** */ void visit(const ArrayLiteral arrayLiteral) { arrayLiteral.accept(this); }
158     /** */ void visit(const ArrayMemberInitialization arrayMemberInitialization) { arrayMemberInitialization.accept(this); }
159     /** */ void visit(const AsmAddExp asmAddExp) { asmAddExp.accept(this); }
160     /** */ void visit(const AsmAndExp asmAndExp) { asmAndExp.accept(this); }
161     /** */ void visit(const AsmBrExp asmBrExp) { asmBrExp.accept(this); }
162     /** */ void visit(const AsmEqualExp asmEqualExp) { asmEqualExp.accept(this); }
163     /** */ void visit(const AsmExp asmExp) { asmExp.accept(this); }
164     /** */ void visit(const AsmInstruction asmInstruction) { asmInstruction.accept(this); }
165     /** */ void visit(const AsmLogAndExp asmLogAndExp) { asmLogAndExp.accept(this); }
166     /** */ void visit(const AsmLogOrExp asmLogOrExp) { asmLogOrExp.accept(this); }
167     /** */ void visit(const AsmMulExp asmMulExp) { asmMulExp.accept(this); }
168     /** */ void visit(const AsmOrExp asmOrExp) { asmOrExp.accept(this); }
169     /** */ void visit(const AsmPrimaryExp asmPrimaryExp) { asmPrimaryExp.accept(this); }
170     /** */ void visit(const AsmRelExp asmRelExp) { asmRelExp.accept(this); }
171     /** */ void visit(const AsmShiftExp asmShiftExp) { asmShiftExp.accept(this); }
172     /** */ void visit(const AsmStatement asmStatement) { asmStatement.accept(this); }
173     /** */ void visit(const AsmTypePrefix asmTypePrefix) { asmTypePrefix.accept(this); }
174     /** */ void visit(const AsmUnaExp asmUnaExp) { asmUnaExp.accept(this); }
175     /** */ void visit(const AsmXorExp asmXorExp) { asmXorExp.accept(this); }
176     /** */ void visit(const AssertExpression assertExpression) { assertExpression.accept(this); }
177     /** */ void visit(const AssignExpression assignExpression) { assignExpression.accept(this); }
178     /** */ void visit(const AssocArrayLiteral assocArrayLiteral) { assocArrayLiteral.accept(this); }
179     /** */ void visit(const AtAttribute atAttribute) { atAttribute.accept(this); }
180     /** */ void visit(const Attribute attribute) { attribute.accept(this); }
181     /** */ void visit(const AttributeDeclaration attributeDeclaration) { attributeDeclaration.accept(this); }
182     /** */ void visit(const AutoDeclaration autoDeclaration) { autoDeclaration.accept(this); }
183     /** */ void visit(const BlockStatement blockStatement) { blockStatement.accept(this); }
184     /** */ void visit(const BodyStatement bodyStatement) { bodyStatement.accept(this); }
185     /** */ void visit(const BreakStatement breakStatement) { breakStatement.accept(this); }
186     /** */ void visit(const BaseClass baseClass) { baseClass.accept(this); }
187     /** */ void visit(const BaseClassList baseClassList) { baseClassList.accept(this); }
188     /** */ void visit(const CaseRangeStatement caseRangeStatement) { caseRangeStatement.accept(this); }
189     /** */ void visit(const CaseStatement caseStatement) { caseStatement.accept(this); }
190     /** */ void visit(const CastExpression castExpression) { castExpression.accept(this); }
191     /** */ void visit(const CastQualifier castQualifier) { castQualifier.accept(this); }
192     /** */ void visit(const Catch catch_) { catch_.accept(this); }
193     /** */ void visit(const Catches catches) { catches.accept(this); }
194     /** */ void visit(const ClassDeclaration classDeclaration) { classDeclaration.accept(this); }
195     /** */ void visit(const CmpExpression cmpExpression) { cmpExpression.accept(this); }
196     /** */ void visit(const CompileCondition compileCondition) { compileCondition.accept(this); }
197     /** */ void visit(const ConditionalDeclaration conditionalDeclaration) { conditionalDeclaration.accept(this); }
198     /** */ void visit(const ConditionalStatement conditionalStatement) { conditionalStatement.accept(this); }
199     /** */ void visit(const Constraint constraint) { constraint.accept(this); }
200     /** */ void visit(const Constructor constructor) { constructor.accept(this); }
201     /** */ void visit(const ContinueStatement continueStatement) { continueStatement.accept(this); }
202     /** */ void visit(const DebugCondition debugCondition) { debugCondition.accept(this); }
203     /** */ void visit(const DebugSpecification debugSpecification) { debugSpecification.accept(this); }
204     /** */ void visit(const Declaration declaration) { declaration.accept(this); }
205     /** */ void visit(const DeclarationOrStatement declarationsOrStatement) { declarationsOrStatement.accept(this); }
206     /** */ void visit(const DeclarationsAndStatements declarationsAndStatements) { declarationsAndStatements.accept(this); }
207     /** */ void visit(const Declarator declarator) { declarator.accept(this); }
208     /** */ void visit(const DefaultStatement defaultStatement) { defaultStatement.accept(this); }
209     /** */ void visit(const DeleteExpression deleteExpression) { deleteExpression.accept(this); }
210     /** */ void visit(const DeleteStatement deleteStatement) { deleteStatement.accept(this); }
211     /** */ void visit(const Deprecated deprecated_) { deprecated_.accept(this); }
212     /** */ void visit(const Destructor destructor) { destructor.accept(this); }
213     /** */ void visit(const DoStatement doStatement) { doStatement.accept(this); }
214     /** */ void visit(const EnumBody enumBody) { enumBody.accept(this); }
215     /** */ void visit(const EnumDeclaration enumDeclaration) { enumDeclaration.accept(this); }
216     /** */ void visit(const EnumMember enumMember) { enumMember.accept(this); }
217     /** */ void visit(const EponymousTemplateDeclaration eponymousTemplateDeclaration) { eponymousTemplateDeclaration.accept(this); }
218     /** */ void visit(const EqualExpression equalExpression) { equalExpression.accept(this); }
219     /** */ void visit(const Expression expression) { expression.accept(this); }
220     /** */ void visit(const ExpressionStatement expressionStatement) { expressionStatement.accept(this); }
221     /** */ void visit(const FinalSwitchStatement finalSwitchStatement) { finalSwitchStatement.accept(this); }
222     /** */ void visit(const Finally finally_) { finally_.accept(this); }
223     /** */ void visit(const ForStatement forStatement) { forStatement.accept(this); }
224     /** */ void visit(const ForeachStatement foreachStatement) { foreachStatement.accept(this); }
225     /** */ void visit(const ForeachType foreachType) { foreachType.accept(this); }
226     /** */ void visit(const ForeachTypeList foreachTypeList) { foreachTypeList.accept(this); }
227     /** */ void visit(const FunctionAttribute functionAttribute) { functionAttribute.accept(this); }
228     /** */ void visit(const FunctionBody functionBody) { functionBody.accept(this); }
229     /** */ void visit(const FunctionCallExpression functionCallExpression) { functionCallExpression.accept(this); }
230     /** */ void visit(const FunctionDeclaration functionDeclaration) { functionDeclaration.accept(this); }
231     /** */ void visit(const FunctionLiteralExpression functionLiteralExpression) { functionLiteralExpression.accept(this); }
232     /** */ void visit(const GotoStatement gotoStatement) { gotoStatement.accept(this); }
233     /** */ void visit(const IdentifierChain identifierChain) { identifierChain.accept(this); }
234     /** */ void visit(const IdentifierList identifierList) { identifierList.accept(this); }
235     /** */ void visit(const IdentifierOrTemplateChain identifierOrTemplateChain) { identifierOrTemplateChain.accept(this); }
236     /** */ void visit(const IdentifierOrTemplateInstance identifierOrTemplateInstance) { identifierOrTemplateInstance.accept(this); }
237     /** */ void visit(const IdentityExpression identityExpression) { identityExpression.accept(this); }
238     /** */ void visit(const IfStatement ifStatement) { ifStatement.accept(this); }
239     /** */ void visit(const ImportBind importBind) { importBind.accept(this); }
240     /** */ void visit(const ImportBindings importBindings) { importBindings.accept(this); }
241     /** */ void visit(const ImportDeclaration importDeclaration) { importDeclaration.accept(this); }
242     /** */ void visit(const ImportExpression importExpression) { importExpression.accept(this); }
243     /** */ void visit(const IndexExpression indexExpression) { indexExpression.accept(this); }
244     /** */ void visit(const InExpression inExpression) { inExpression.accept(this); }
245     /** */ void visit(const InStatement inStatement) { inStatement.accept(this); }
246     /** */ void visit(const Initialize initialize) { initialize.accept(this); }
247     /** */ void visit(const Initializer initializer) { initializer.accept(this); }
248     /** */ void visit(const InterfaceDeclaration interfaceDeclaration) { interfaceDeclaration.accept(this); }
249     /** */ void visit(const Invariant invariant_) { invariant_.accept(this); }
250     /** */ void visit(const IsExpression isExpression) { isExpression.accept(this); }
251     /** */ void visit(const KeyValuePair keyValuePair) { keyValuePair.accept(this); }
252     /** */ void visit(const KeyValuePairs keyValuePairs) { keyValuePairs.accept(this); }
253     /** */ void visit(const LabeledStatement labeledStatement) { labeledStatement.accept(this); }
254     /** */ void visit(const LambdaExpression lambdaExpression) { lambdaExpression.accept(this); }
255     /** */ void visit(const LastCatch lastCatch) { lastCatch.accept(this); }
256     /** */ void visit(const LinkageAttribute linkageAttribute) { linkageAttribute.accept(this); }
257     /** */ void visit(const MemberFunctionAttribute memberFunctionAttribute) { memberFunctionAttribute.accept(this); }
258     /** */ void visit(const MixinDeclaration mixinDeclaration) { mixinDeclaration.accept(this); }
259     /** */ void visit(const MixinExpression mixinExpression) { mixinExpression.accept(this); }
260     /** */ void visit(const MixinTemplateDeclaration mixinTemplateDeclaration) { mixinTemplateDeclaration.accept(this); }
261     /** */ void visit(const MixinTemplateName mixinTemplateName) { mixinTemplateName.accept(this); }
262     /** */ void visit(const Module module_) { module_.accept(this); }
263     /** */ void visit(const ModuleDeclaration moduleDeclaration) { moduleDeclaration.accept(this); }
264     /** */ void visit(const MulExpression mulExpression) { mulExpression.accept(this); }
265     /** */ void visit(const NewAnonClassExpression newAnonClassExpression) { newAnonClassExpression.accept(this); }
266     /** */ void visit(const NewExpression newExpression) { newExpression.accept(this); }
267     /** */ void visit(const NonVoidInitializer nonVoidInitializer) { nonVoidInitializer.accept(this); }
268     /** */ void visit(const Operands operands) { operands.accept(this); }
269     /** */ void visit(const OrExpression orExpression) { orExpression.accept(this); }
270     /** */ void visit(const OrOrExpression orOrExpression) { orOrExpression.accept(this); }
271     /** */ void visit(const OutStatement outStatement) { outStatement.accept(this); }
272     /** */ void visit(const Parameter parameter) { parameter.accept(this); }
273     /** */ void visit(const Parameters parameters) { parameters.accept(this); }
274     /** */ void visit(const Postblit postblit) { postblit.accept(this); }
275     /** */ void visit(const PowExpression powExpression) { powExpression.accept(this); }
276     /** */ void visit(const PragmaDeclaration pragmaDeclaration) { pragmaDeclaration.accept(this); }
277     /** */ void visit(const PragmaExpression pragmaExpression) { pragmaExpression.accept(this); }
278     /** */ void visit(const PrimaryExpression primaryExpression) { primaryExpression.accept(this); }
279     /** */ void visit(const Register register) { register.accept(this); }
280     /** */ void visit(const RelExpression relExpression) { relExpression.accept(this); }
281     /** */ void visit(const ReturnStatement returnStatement) { returnStatement.accept(this); }
282     /** */ void visit(const ScopeGuardStatement scopeGuardStatement) { scopeGuardStatement.accept(this); }
283     /** */ void visit(const SharedStaticConstructor sharedStaticConstructor) { sharedStaticConstructor.accept(this); }
284     /** */ void visit(const SharedStaticDestructor sharedStaticDestructor) { sharedStaticDestructor.accept(this); }
285     /** */ void visit(const ShiftExpression shiftExpression) { shiftExpression.accept(this); }
286     /** */ void visit(const SingleImport singleImport) { singleImport.accept(this); }
287     /** */ void visit(const Index index) { index.accept(this); }
288     /** */ void visit(const Statement statement) { statement.accept(this); }
289     /** */ void visit(const StatementNoCaseNoDefault statementNoCaseNoDefault) { statementNoCaseNoDefault.accept(this); }
290     /** */ void visit(const StaticAssertDeclaration staticAssertDeclaration) { staticAssertDeclaration.accept(this); }
291     /** */ void visit(const StaticForeachDeclaration staticForeachDeclaration) { staticForeachDeclaration.accept(this); }
292     /** */ void visit(const StaticForeachStatement staticForeachStatement) { staticForeachStatement.accept(this); }
293     /** */ void visit(const StaticAssertStatement staticAssertStatement) { staticAssertStatement.accept(this); }
294     /** */ void visit(const StaticConstructor staticConstructor) { staticConstructor.accept(this); }
295     /** */ void visit(const StaticDestructor staticDestructor) { staticDestructor.accept(this); }
296     /** */ void visit(const StaticIfCondition staticIfCondition) { staticIfCondition.accept(this); }
297     /** */ void visit(const StorageClass storageClass) { storageClass.accept(this); }
298     /** */ void visit(const StructBody structBody) { structBody.accept(this); }
299     /** */ void visit(const StructDeclaration structDeclaration) { structDeclaration.accept(this); }
300     /** */ void visit(const StructInitializer structInitializer) { structInitializer.accept(this); }
301     /** */ void visit(const StructMemberInitializer structMemberInitializer) { structMemberInitializer.accept(this); }
302     /** */ void visit(const StructMemberInitializers structMemberInitializers) { structMemberInitializers.accept(this); }
303     /** */ void visit(const SwitchStatement switchStatement) { switchStatement.accept(this); }
304     /** */ void visit(const Symbol symbol) { symbol.accept(this); }
305     /** */ void visit(const SynchronizedStatement synchronizedStatement) { synchronizedStatement.accept(this); }
306     /** */ void visit(const TemplateAliasParameter templateAliasParameter) { templateAliasParameter.accept(this); }
307     /** */ void visit(const TemplateArgument templateArgument) { templateArgument.accept(this); }
308     /** */ void visit(const TemplateArgumentList templateArgumentList) { templateArgumentList.accept(this); }
309     /** */ void visit(const TemplateArguments templateArguments) { templateArguments.accept(this); }
310     /** */ void visit(const TemplateDeclaration templateDeclaration) { templateDeclaration.accept(this); }
311     /** */ void visit(const TemplateInstance templateInstance) { templateInstance.accept(this); }
312     /** */ void visit(const TemplateMixinExpression templateMixinExpression) { templateMixinExpression.accept(this); }
313     /** */ void visit(const TemplateParameter templateParameter) { templateParameter.accept(this); }
314     /** */ void visit(const TemplateParameterList templateParameterList) { templateParameterList.accept(this); }
315     /** */ void visit(const TemplateParameters templateParameters) { templateParameters.accept(this); }
316     /** */ void visit(const TemplateSingleArgument templateSingleArgument) { templateSingleArgument.accept(this); }
317     /** */ void visit(const TemplateThisParameter templateThisParameter) { templateThisParameter.accept(this); }
318     /** */ void visit(const TemplateTupleParameter templateTupleParameter) { templateTupleParameter.accept(this); }
319     /** */ void visit(const TemplateTypeParameter templateTypeParameter) { templateTypeParameter.accept(this); }
320     /** */ void visit(const TemplateValueParameter templateValueParameter) { templateValueParameter.accept(this); }
321     /** */ void visit(const TemplateValueParameterDefault templateValueParameterDefault) { templateValueParameterDefault.accept(this); }
322     /** */ void visit(const TernaryExpression ternaryExpression) { ternaryExpression.accept(this); }
323     /** */ void visit(const ThrowStatement throwStatement) { throwStatement.accept(this); }
324     /** */ void visit(const Token) { }
325     /** */ void visit(const TraitsExpression traitsExpression) { traitsExpression.accept(this); }
326     /** */ void visit(const TryStatement tryStatement) { tryStatement.accept(this); }
327     /** */ void visit(const Type type) { type.accept(this); }
328     /** */ void visit(const Type2 type2) { type2.accept(this); }
329     /** */ void visit(const TypeSpecialization typeSpecialization) { typeSpecialization.accept(this); }
330     /** */ void visit(const TypeSuffix typeSuffix) { typeSuffix.accept(this); }
331     /** */ void visit(const TypeidExpression typeidExpression) { typeidExpression.accept(this); }
332     /** */ void visit(const TypeofExpression typeofExpression) { typeofExpression.accept(this); }
333     /** */ void visit(const UnaryExpression unaryExpression) { unaryExpression.accept(this); }
334     /** */ void visit(const UnionDeclaration unionDeclaration) { unionDeclaration.accept(this); }
335     /** */ void visit(const Unittest unittest_) { unittest_.accept(this); }
336     /** */ void visit(const VariableDeclaration variableDeclaration) { variableDeclaration.accept(this); }
337     /** */ void visit(const Vector vector) { vector.accept(this); }
338     /** */ void visit(const VersionCondition versionCondition) { versionCondition.accept(this); }
339     /** */ void visit(const VersionSpecification versionSpecification) { versionSpecification.accept(this); }
340     /** */ void visit(const WhileStatement whileStatement) { whileStatement.accept(this); }
341     /** */ void visit(const WithStatement withStatement) { withStatement.accept(this); }
342     /** */ void visit(const XorExpression xorExpression) { xorExpression.accept(this); }
343 }
344 
345 interface ASTNode
346 {
347 public:
348     /** */ void accept(ASTVisitor visitor) const;
349 }
350 
351 template visitIfNotNull(fields ...)
352 {
353     static if (fields.length > 1)
354         immutable visitIfNotNull = visitIfNotNull!(fields[0]) ~ visitIfNotNull!(fields[1..$]);
355     else
356     {
357         static if (typeof(fields[0]).stringof[$ - 2 .. $] == "[]")
358         {
359             static if (__traits(hasMember, typeof(fields[0][0]), "classinfo"))
360                 immutable visitIfNotNull = "foreach (i; " ~ fields[0].stringof ~ ") if (i !is null) visitor.visit(i);\n";
361             else
362                 immutable visitIfNotNull = "foreach (i; " ~ fields[0].stringof ~ ") visitor.visit(i);\n";
363         }
364         else static if (__traits(hasMember, typeof(fields[0]), "classinfo"))
365             immutable visitIfNotNull = "if (" ~ fields[0].stringof ~ " !is null) visitor.visit(" ~ fields[0].stringof ~ ");\n";
366         else
367             immutable visitIfNotNull = "visitor.visit(" ~ fields[0].stringof ~ ");\n";
368     }
369 }
370 
371 mixin template OpEquals(bool print = false)
372 {
373     override bool opEquals(Object other) const
374     {
375         static if (print)
376             pragma(msg, generateOpEquals!(typeof(this)));
377         mixin(generateOpEquals!(typeof(this)));
378     }
379 }
380 
381 template generateOpEquals(T)
382 {
383     template opEqualsPart(p ...)
384     {
385         import std.traits;
386         static if (p.length == 0)
387             enum opEqualsPart = "";
388         else static if (!isSomeFunction!(__traits(getMember, T, p[0]))
389             && p[0] != "line" && p[0] != "column" && p[0] != "startLocation"
390             && p[0] != "endLocation" && p[0] != "index")
391         {
392             static if (typeof(__traits(getMember, T, p[0])).stringof[$ - 2 .. $] == "[]")
393             {
394                 enum opEqualsPart = "\nif (obj." ~ p[0] ~ ".length != this." ~ p[0] ~ ".length) return false;\n"
395                     ~ "foreach (i; 0 .. this." ~ p[0] ~ ".length)\n"
396                     ~ "\tif (this." ~ p[0] ~ "[i] != obj." ~ p[0] ~ "[i]) return false;" ~ opEqualsPart!(p[1 .. $]);
397             }
398             else
399                 enum opEqualsPart = "\nif (obj." ~ p[0] ~ " != this." ~ p[0] ~ ") return false;" ~ opEqualsPart!(p[1 .. $]);
400         }
401         else
402             enum opEqualsPart = opEqualsPart!(p[1 .. $]);
403     }
404     enum generateOpEquals = T.stringof ~ " obj = cast(" ~ T.stringof ~ ") other;\n"
405         ~ "if (obj is null) return false;"
406         ~ opEqualsPart!(__traits(derivedMembers, T)) ~ "\n"
407         ~ "return true;";
408 }
409 
410 abstract class ExpressionNode : ASTNode
411 {
412 public:
413     override void accept(ASTVisitor visitor) const
414     {
415         assert (false);
416     }
417 }
418 
419 mixin template BinaryExpressionBody()
420 {
421     ExpressionNode left;
422     ExpressionNode right;
423     size_t line;
424     size_t column;
425 }
426 
427 ///
428 final class AddExpression : ExpressionNode
429 {
430 public:
431     override void accept(ASTVisitor visitor) const
432     {
433         mixin(visitIfNotNull!(left, right));
434     }
435     mixin OpEquals;
436     /** */ IdType operator;
437     mixin BinaryExpressionBody;
438 }
439 
440 ///
441 final class AliasDeclaration : ASTNode
442 {
443 public:
444     override void accept(ASTVisitor visitor) const
445     {
446         mixin(visitIfNotNull!(storageClasses, type, identifierList, initializers));
447     }
448     mixin OpEquals;
449     /** */ StorageClass[] storageClasses;
450     /** */ Type type;
451     /** */ IdentifierList identifierList;
452     /** */ AliasInitializer[] initializers;
453     /** */ string comment;
454     size_t line;
455 }
456 
457 ///
458 final class AliasInitializer : ASTNode
459 {
460 public:
461     override void accept(ASTVisitor visitor) const
462     {
463         mixin(visitIfNotNull!(name, templateParameters, storageClasses, type));
464     }
465     mixin OpEquals;
466     /** */ Token name;
467     /** */ StorageClass[] storageClasses;
468     /** */ TemplateParameters templateParameters;
469     /** */ Type type;
470 }
471 
472 ///
473 final class AliasThisDeclaration : ASTNode
474 {
475 public:
476     override void accept(ASTVisitor visitor) const
477     {
478         mixin(visitIfNotNull!(identifier));
479     }
480     mixin OpEquals;
481     /** */ Token identifier;
482     /** */ string comment;
483 }
484 
485 ///
486 final class AlignAttribute : ASTNode
487 {
488 public:
489     override void accept(ASTVisitor visitor) const
490     {
491         mixin(visitIfNotNull!(intLiteral));
492     }
493     mixin OpEquals;
494     /** */ Token intLiteral;
495 }
496 
497 ///
498 final class AndAndExpression : ExpressionNode
499 {
500 public:
501     override void accept(ASTVisitor visitor) const
502     {
503         mixin(visitIfNotNull!(left, right));
504     }
505     mixin OpEquals;
506     mixin BinaryExpressionBody;
507 }
508 
509 ///
510 final class AndExpression : ExpressionNode
511 {
512 public:
513     override void accept(ASTVisitor visitor) const
514     {
515         mixin(visitIfNotNull!(left, right));
516     }
517     mixin OpEquals;
518     mixin BinaryExpressionBody;
519 }
520 
521 ///
522 final class AnonymousEnumDeclaration : ASTNode
523 {
524     override void accept(ASTVisitor visitor) const
525     {
526         mixin(visitIfNotNull!(baseType, members));
527     }
528     mixin OpEquals;
529     string comment;
530     size_t line;
531     /** */ Type baseType;
532     /** */ AnonymousEnumMember[] members;
533 }
534 
535 ///
536 final class AnonymousEnumMember : ASTNode
537 {
538     override void accept(ASTVisitor visitor) const
539     {
540         mixin(visitIfNotNull!(type, name, assignExpression));
541     }
542     /** */ Type type;
543     /** */ Token name;
544     /** */ ExpressionNode assignExpression;
545     /** */ string comment;
546 
547 
548     AtAttribute[] atAttributes;
549 
550     bool isDisabled;
551     Deprecated deprecated_;
552 
553     size_t line;
554 }
555 
556 ///
557 final class ArgumentList : ASTNode
558 {
559 public:
560     override void accept(ASTVisitor visitor) const
561     {
562         mixin(visitIfNotNull!(items));
563     }
564     mixin OpEquals;
565     /** */ ExpressionNode[] items;
566     /** */ size_t startLocation;
567     /** */ size_t endLocation;
568 }
569 
570 ///
571 final class Arguments : ASTNode
572 {
573 public:
574     override void accept(ASTVisitor visitor) const
575     {
576         mixin(visitIfNotNull!(argumentList));
577     }
578     mixin OpEquals;
579     /** */ ArgumentList argumentList;
580 }
581 
582 ///
583 final class ArrayInitializer : ASTNode
584 {
585 public:
586     override void accept(ASTVisitor visitor) const
587     {
588         mixin(visitIfNotNull!(arrayMemberInitializations));
589     }
590     mixin OpEquals;
591     /** */ size_t startLocation;
592     /** */ size_t endLocation;
593     /** */ ArrayMemberInitialization[] arrayMemberInitializations;
594 }
595 
596 ///
597 final class ArrayLiteral : ASTNode
598 {
599 public:
600     override void accept(ASTVisitor visitor) const
601     {
602         mixin(visitIfNotNull!(argumentList));
603     }
604     mixin OpEquals;
605     /** */ ArgumentList argumentList;
606 }
607 
608 ///
609 final class ArrayMemberInitialization : ASTNode
610 {
611 public:
612     override void accept(ASTVisitor visitor) const
613     {
614         mixin(visitIfNotNull!(assignExpression, nonVoidInitializer));
615     }
616     mixin OpEquals;
617     /** */ ExpressionNode assignExpression;
618     /** */ NonVoidInitializer nonVoidInitializer;
619 }
620 
621 ///
622 final class AsmAddExp : ExpressionNode
623 {
624 public:
625     override void accept(ASTVisitor visitor) const
626     {
627         mixin(visitIfNotNull!(left, right));
628     }
629     mixin OpEquals;
630     /** */ IdType operator;
631     mixin BinaryExpressionBody;
632 }
633 
634 ///
635 final class AsmAndExp : ExpressionNode
636 {
637 public:
638     override void accept(ASTVisitor visitor) const
639     {
640         mixin(visitIfNotNull!(left, right));
641     }
642     mixin OpEquals;
643     mixin BinaryExpressionBody;
644 }
645 
646 ///
647 final class AsmBrExp : ExpressionNode
648 {
649 public:
650     override void accept(ASTVisitor visitor) const
651     {
652         mixin(visitIfNotNull!(asmBrExp, asmExp, asmUnaExp));
653     }
654     mixin OpEquals;
655     size_t line;
656     size_t column;
657     /** */ AsmBrExp asmBrExp;
658     /** */ ExpressionNode asmExp;
659     /** */ AsmUnaExp asmUnaExp;
660 }
661 
662 ///
663 final class AsmEqualExp : ExpressionNode
664 {
665 public:
666     override void accept(ASTVisitor visitor) const
667     {
668         mixin(visitIfNotNull!(left, right));
669     }
670     mixin BinaryExpressionBody;
671     mixin OpEquals;
672     /** */ IdType operator;
673 }
674 
675 ///
676 final class AsmExp : ExpressionNode
677 {
678 public:
679     override void accept(ASTVisitor visitor) const
680     {
681         mixin(visitIfNotNull!(left, middle, right));
682     }
683     mixin OpEquals;
684     /** */ ExpressionNode left;
685     /** */ ExpressionNode middle;
686     /** */ ExpressionNode right;
687 }
688 
689 ///
690 final class AsmInstruction : ASTNode
691 {
692 public:
693     override void accept(ASTVisitor visitor) const
694     {
695         mixin(visitIfNotNull!(identifierOrIntegerOrOpcode, asmInstruction, operands));
696     }
697     mixin OpEquals;
698     /** */ Token identifierOrIntegerOrOpcode;
699     /** */ bool hasAlign;
700     /** */ AsmInstruction asmInstruction;
701     /** */ Operands operands;
702 }
703 
704 ///
705 final class AsmLogAndExp : ExpressionNode
706 {
707 public:
708     override void accept(ASTVisitor visitor) const
709     {
710         mixin(visitIfNotNull!(left, right));
711     }
712     mixin BinaryExpressionBody;
713     mixin OpEquals;
714 }
715 
716 ///
717 final class AsmLogOrExp : ExpressionNode
718 {
719 public:
720     override void accept(ASTVisitor visitor) const
721     {
722         mixin(visitIfNotNull!(left, right));
723     }
724     mixin BinaryExpressionBody;
725     mixin OpEquals;
726 }
727 
728 ///
729 final class AsmMulExp : ExpressionNode
730 {
731 public:
732     override void accept(ASTVisitor visitor) const
733     {
734         mixin(visitIfNotNull!(left, right));
735     }
736     /** */ IdType operator;
737     mixin BinaryExpressionBody;
738     mixin OpEquals;
739 
740 }
741 
742 ///
743 final class AsmOrExp : ExpressionNode
744 {
745 public:
746     override void accept(ASTVisitor visitor) const
747     {
748         mixin(visitIfNotNull!(left, right));
749     }
750     mixin BinaryExpressionBody;
751     mixin OpEquals;
752 }
753 
754 ///
755 final class AsmPrimaryExp : ASTNode
756 {
757 public:
758     override void accept(ASTVisitor visitor) const
759     {
760         mixin(visitIfNotNull!(token, register, asmExp, identifierChain));
761     }
762     /** */ ExpressionNode asmExp;
763     /** */ IdentifierChain identifierChain;
764     /** */ Register register;
765     /** */ Token token;
766     mixin OpEquals;
767 }
768 
769 ///
770 final class AsmRelExp : ExpressionNode
771 {
772 public:
773     override void accept(ASTVisitor visitor) const
774     {
775         mixin(visitIfNotNull!(left, right));
776     }
777     mixin BinaryExpressionBody;
778     /** */ IdType operator;
779     mixin OpEquals;
780 }
781 
782 ///
783 final class AsmShiftExp : ExpressionNode
784 {
785 public:
786     override void accept(ASTVisitor visitor) const
787     {
788         mixin(visitIfNotNull!(left, right));
789     }
790     mixin BinaryExpressionBody;
791     /** */ IdType operator;
792     mixin OpEquals;
793 }
794 
795 ///
796 final class AsmStatement : ASTNode
797 {
798 public:
799     override void accept(ASTVisitor visitor) const
800     {
801         mixin(visitIfNotNull!asmInstructions);
802     }
803     /** */ AsmInstruction[] asmInstructions;
804     /** */ FunctionAttribute[] functionAttributes;
805     mixin OpEquals;
806 }
807 
808 ///
809 final class AsmTypePrefix : ASTNode
810 {
811 public:
812     override void accept(ASTVisitor visitor) const
813     {
814         mixin(visitIfNotNull!(left, right));
815     }
816     /** */ Token left;
817     /** */ Token right;
818     mixin OpEquals;
819 }
820 
821 ///
822 final class AsmUnaExp : ASTNode
823 {
824 public:
825     override void accept(ASTVisitor visitor) const
826     {
827         mixin(visitIfNotNull!(prefix, asmTypePrefix, asmExp, asmPrimaryExp, asmUnaExp));
828     }
829     /** */ AsmTypePrefix asmTypePrefix;
830     /** */ ExpressionNode asmExp;
831     /** */ Token prefix;
832     /** */ AsmPrimaryExp asmPrimaryExp;
833     /** */ AsmUnaExp asmUnaExp;
834     mixin OpEquals;
835 }
836 
837 ///
838 final class AsmXorExp : ExpressionNode
839 {
840 public:
841     override void accept(ASTVisitor visitor) const
842     {
843         mixin(visitIfNotNull!(left, right));
844     }
845     mixin BinaryExpressionBody;
846     mixin OpEquals;
847 }
848 
849 ///
850 final class AssertExpression : ExpressionNode
851 {
852 public:
853     override void accept(ASTVisitor visitor) const
854     {
855         mixin(visitIfNotNull!(assertion, message));
856     }
857     /** */ size_t line;
858     /** */ size_t column;
859     /** */ ExpressionNode assertion;
860     /** */ ExpressionNode message;
861     mixin OpEquals;
862 }
863 
864 ///
865 final class AssignExpression : ExpressionNode
866 {
867 public:
868     override void accept(ASTVisitor visitor) const
869     {
870         mixin(visitIfNotNull!(ternaryExpression, expression));
871     }
872     /** */ ExpressionNode ternaryExpression;
873     /** */ ExpressionNode expression;
874     /** */ IdType operator;
875     /** */ size_t line;
876     /** */ size_t column;
877     mixin OpEquals;
878 }
879 
880 ///
881 final class AssocArrayLiteral : ASTNode
882 {
883 public:
884     override void accept(ASTVisitor visitor) const
885     {
886         mixin(visitIfNotNull!(keyValuePairs));
887     }
888     /** */ KeyValuePairs keyValuePairs;
889     mixin OpEquals;
890 }
891 
892 ///
893 final class AtAttribute : ASTNode
894 {
895 public:
896     override void accept(ASTVisitor visitor) const
897     {
898         mixin(visitIfNotNull!(argumentList));
899     }
900     /** */ ArgumentList argumentList;
901     /** */ Token identifier;
902     /** */ size_t startLocation;
903     /** */ size_t endLocation;
904     mixin OpEquals;
905 }
906 
907 ///
908 final class Attribute : ASTNode
909 {
910 public:
911     override void accept(ASTVisitor visitor) const
912     {
913         mixin(visitIfNotNull!(pragmaExpression, deprecated_, atAttribute,
914             alignAttribute, identifierChain));
915     }
916     /** */ PragmaExpression pragmaExpression;
917     /** */ Deprecated deprecated_;
918     /** */ AtAttribute atAttribute;
919     /** */ AlignAttribute alignAttribute;
920     /** */ LinkageAttribute linkageAttribute;
921     /** */ Token attribute;
922     /** */ IdentifierChain identifierChain;
923     mixin OpEquals;
924 }
925 
926 ///
927 final class AttributeDeclaration : ASTNode
928 {
929     override void accept(ASTVisitor visitor) const
930     {
931         mixin(visitIfNotNull!(attribute));
932     }
933     /** */ Attribute attribute;
934     /** */ size_t line;
935     mixin OpEquals;
936 }
937 
938 ///
939 final class AutoDeclaration : ASTNode
940 {
941 public:
942     override void accept(ASTVisitor visitor) const
943     {
944         foreach (sc; storageClasses)
945             visitor.visit(sc);
946         foreach (i; 0 .. initializers.length)
947         {
948             visitor.visit(initializers[i]);
949         }
950     }
951     /** */ Token[] identifiers;
952     /** */ Initializer[] initializers;
953     /** */ StorageClass[] storageClasses;
954     /** */ string comment;
955     mixin OpEquals;
956 }
957 
958 ///
959 final class BlockStatement : ASTNode
960 {
961 public:
962     override void accept(ASTVisitor visitor) const
963     {
964         mixin(visitIfNotNull!(declarationsAndStatements));
965     }
966 
967     /**
968      * Byte position of the opening brace
969      */
970     size_t startLocation;
971 
972     /**
973      * Byte position of the closing brace
974      */
975     size_t endLocation;
976 
977     /** */ DeclarationsAndStatements declarationsAndStatements;
978     mixin OpEquals;
979 }
980 
981 ///
982 final class BodyStatement : ASTNode
983 {
984 public:
985     override void accept(ASTVisitor visitor) const
986     {
987         mixin(visitIfNotNull!(blockStatement));
988     }
989     /** */ BlockStatement blockStatement;
990     mixin OpEquals;
991 }
992 
993 ///
994 final class BreakStatement : ASTNode
995 {
996 public:
997     override void accept(ASTVisitor visitor) const
998     {
999         mixin(visitIfNotNull!(label));
1000     }
1001     /** */ Token label;
1002     mixin OpEquals;
1003 }
1004 
1005 ///
1006 final class BaseClass : ASTNode
1007 {
1008 public:
1009     override void accept(ASTVisitor visitor) const
1010     {
1011         mixin(visitIfNotNull!(type2));
1012     }
1013     /** */ Type2 type2;
1014     mixin OpEquals;
1015 }
1016 
1017 ///
1018 final class BaseClassList : ASTNode
1019 {
1020 public:
1021     override void accept(ASTVisitor visitor) const
1022     {
1023         mixin(visitIfNotNull!(items));
1024     }
1025     /** */ BaseClass[] items;
1026     mixin OpEquals;
1027 }
1028 
1029 ///
1030 final class CaseRangeStatement : ASTNode
1031 {
1032 public:
1033     override void accept(ASTVisitor visitor) const
1034     {
1035         mixin(visitIfNotNull!(low, high, declarationsAndStatements));
1036     }
1037     /** */ ExpressionNode low;
1038     /** */ ExpressionNode high;
1039     /** */ DeclarationsAndStatements declarationsAndStatements;
1040 	/** */ size_t colonLocation;
1041     mixin OpEquals;
1042 }
1043 
1044 ///
1045 final class CaseStatement: ASTNode
1046 {
1047 public:
1048     override void accept(ASTVisitor visitor) const
1049     {
1050         mixin(visitIfNotNull!(argumentList, declarationsAndStatements));
1051     }
1052     /** */ ArgumentList argumentList;
1053     /** */ DeclarationsAndStatements declarationsAndStatements;
1054 	/** */ size_t colonLocation;
1055     mixin OpEquals;
1056 }
1057 
1058 ///
1059 final class CastExpression: ASTNode
1060 {
1061 public:
1062     override void accept(ASTVisitor visitor) const
1063     {
1064         mixin(visitIfNotNull!(type, castQualifier, unaryExpression));
1065     }
1066     /** */ Type type;
1067     /** */ CastQualifier castQualifier;
1068     /** */ UnaryExpression unaryExpression;
1069     mixin OpEquals;
1070 }
1071 
1072 ///
1073 final class CastQualifier: ASTNode
1074 {
1075 public:
1076     override void accept(ASTVisitor visitor) const
1077     {
1078         mixin(visitIfNotNull!(first, second));
1079     }
1080     /** */ Token first;
1081     /** */ Token second;
1082     mixin OpEquals;
1083 }
1084 
1085 ///
1086 final class Catches: ASTNode
1087 {
1088 public:
1089     override void accept(ASTVisitor visitor) const
1090     {
1091         mixin(visitIfNotNull!(catches, lastCatch));
1092     }
1093     /** */ Catch[] catches;
1094     /** */ LastCatch lastCatch;
1095     mixin OpEquals;
1096 }
1097 
1098 ///
1099 final class Catch: ASTNode
1100 {
1101 public:
1102     override void accept(ASTVisitor visitor) const
1103     {
1104         mixin(visitIfNotNull!(type, identifier, declarationOrStatement));
1105     }
1106     /** */ Type type;
1107     /** */ Token identifier;
1108     /** */ DeclarationOrStatement declarationOrStatement;
1109     mixin OpEquals;
1110 }
1111 
1112 ///
1113 final class ClassDeclaration: ASTNode
1114 {
1115 public:
1116     override void accept(ASTVisitor visitor) const
1117     {
1118         mixin(visitIfNotNull!(templateParameters, constraint, baseClassList,
1119             structBody));
1120     }
1121 
1122     /** */ Token name;
1123     /** */ TemplateParameters templateParameters;
1124     /** */ Constraint constraint;
1125     /** */ BaseClassList baseClassList;
1126     /** */ StructBody structBody;
1127     /** */ string comment;
1128     mixin OpEquals;
1129 }
1130 
1131 ///
1132 final class CmpExpression : ExpressionNode
1133 {
1134 public:
1135     override void accept(ASTVisitor visitor) const
1136     {
1137         mixin(visitIfNotNull!(shiftExpression, equalExpression,
1138             identityExpression, relExpression, inExpression));
1139     }
1140     /** */ ExpressionNode shiftExpression;
1141     /** */ ExpressionNode equalExpression;
1142     /** */ ExpressionNode identityExpression;
1143     /** */ ExpressionNode relExpression;
1144     /** */ ExpressionNode inExpression;
1145     mixin OpEquals;
1146 }
1147 
1148 ///
1149 final class CompileCondition : ASTNode
1150 {
1151 public:
1152     override void accept(ASTVisitor visitor) const
1153     {
1154         mixin(visitIfNotNull!(versionCondition, debugCondition, staticIfCondition));
1155     }
1156     /** */ VersionCondition versionCondition;
1157     /** */ DebugCondition debugCondition;
1158     /** */ StaticIfCondition staticIfCondition;
1159     mixin OpEquals;
1160 }
1161 
1162 ///
1163 final class ConditionalDeclaration : ASTNode
1164 {
1165 public:
1166     override void accept(ASTVisitor visitor) const
1167     {
1168         mixin(visitIfNotNull!(compileCondition, trueDeclarations, falseDeclaration));
1169     }
1170     /** */ CompileCondition compileCondition;
1171     /** */ Declaration[] trueDeclarations;
1172     /** */ Declaration falseDeclaration;
1173     mixin OpEquals;
1174 }
1175 
1176 ///
1177 final class ConditionalStatement : ASTNode
1178 {
1179 public:
1180     override void accept(ASTVisitor visitor) const
1181     {
1182         mixin(visitIfNotNull!(compileCondition, trueStatement, falseStatement));
1183     }
1184     /** */ CompileCondition compileCondition;
1185     /** */ DeclarationOrStatement trueStatement;
1186     /** */ DeclarationOrStatement falseStatement;
1187     mixin OpEquals;
1188 }
1189 
1190 ///
1191 final class Constraint : ASTNode
1192 {
1193 public:
1194     override void accept(ASTVisitor visitor) const
1195     {
1196         mixin(visitIfNotNull!(expression));
1197     }
1198     /** */ Expression expression;
1199     mixin OpEquals;
1200 }
1201 
1202 ///
1203 final class Constructor : ASTNode
1204 {
1205 public:
1206     override void accept(ASTVisitor visitor) const
1207     {
1208         mixin(visitIfNotNull!(parameters, templateParameters, constraint,
1209             memberFunctionAttributes, functionBody));
1210     }
1211     /** */ Parameters parameters;
1212     /** */ FunctionBody functionBody;
1213     /** */ Constraint constraint;
1214     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
1215     /** */ TemplateParameters templateParameters;
1216     /** */ size_t location;
1217     /** */ size_t line;
1218     /** */ size_t column;
1219     /** */ string comment;
1220     mixin OpEquals;
1221 }
1222 
1223 ///
1224 final class ContinueStatement : ASTNode
1225 {
1226 public:
1227     override void accept(ASTVisitor visitor) const
1228     {
1229         mixin(visitIfNotNull!(label));
1230     }
1231     /** */ Token label;
1232     mixin OpEquals;
1233 }
1234 
1235 ///
1236 final class DebugCondition : ASTNode
1237 {
1238 public:
1239     override void accept(ASTVisitor visitor) const
1240     {
1241         mixin(visitIfNotNull!(identifierOrInteger));
1242     }
1243     /** */ size_t debugIndex;
1244     /** */ Token identifierOrInteger;
1245     mixin OpEquals;
1246 }
1247 
1248 ///
1249 final class DebugSpecification : ASTNode
1250 {
1251 public:
1252     override void accept(ASTVisitor visitor) const
1253     {
1254         mixin(visitIfNotNull!(identifierOrInteger));
1255     }
1256     /** */ Token identifierOrInteger;
1257     mixin OpEquals;
1258 }
1259 
1260 ///
1261 final class Declaration : ASTNode
1262 {
1263 public:
1264 
1265     override void accept(ASTVisitor visitor) const
1266     {
1267 
1268         foreach (attr; attributes)
1269             visitor.visit(attr);
1270         foreach (dec; declarations)
1271             visitor.visit(dec);
1272         foreach (Type; DeclarationTypes)
1273         {
1274             const(Type)* value = storage.peek!Type;
1275             if (value)
1276             {
1277                 static if (isArray!Type)
1278                     foreach (item; *(cast(Type*) value))
1279                         visitor.visit(item);
1280                 else if (*value !is null)
1281                     visitor.visit(*(cast(Type*) value));
1282             }
1283         }
1284     }
1285 
1286     private import std.variant:Algebraic;
1287     private import std.typetuple:TypeTuple;
1288 
1289     alias DeclarationTypes = TypeTuple!(AliasDeclaration, AliasThisDeclaration,
1290         AnonymousEnumDeclaration, Attribute[], AttributeDeclaration,
1291         ClassDeclaration, ConditionalDeclaration, Constructor, DebugSpecification,
1292         /+Declaration[],+/ Destructor, EnumDeclaration, EponymousTemplateDeclaration,
1293         FunctionDeclaration, ImportDeclaration, InterfaceDeclaration, Invariant,
1294         MixinDeclaration, MixinTemplateDeclaration, Postblit, PragmaDeclaration,
1295         SharedStaticConstructor, SharedStaticDestructor, StaticAssertDeclaration,
1296 	StaticForeachDeclaration,
1297         StaticConstructor, StaticDestructor, StructDeclaration,
1298         TemplateDeclaration, UnionDeclaration, Unittest, VariableDeclaration,
1299         VersionSpecification);
1300 
1301     private Algebraic!(DeclarationTypes) storage;
1302 
1303     private static string generateProperty(string type, string name)
1304     {
1305         return "const(" ~ type ~ ") " ~ name ~ "() const @property { auto p = storage.peek!" ~ type ~ "; return p is null? null : *p;}\n"
1306             ~ "const(" ~ type ~ ") " ~ name ~ "(" ~ type ~ " node) @property { storage = node; return node; }";
1307     }
1308 
1309     /** */ Attribute[] attributes;
1310     /** */ Declaration[] declarations;
1311 
1312     mixin(generateProperty("AliasDeclaration", "aliasDeclaration"));
1313     mixin(generateProperty("AliasThisDeclaration", "aliasThisDeclaration"));
1314     mixin(generateProperty("AnonymousEnumDeclaration", "anonymousEnumDeclaration"));
1315     mixin(generateProperty("AttributeDeclaration", "attributeDeclaration"));
1316     mixin(generateProperty("ClassDeclaration", "classDeclaration"));
1317     mixin(generateProperty("ConditionalDeclaration", "conditionalDeclaration"));
1318     mixin(generateProperty("Constructor", "constructor"));
1319     mixin(generateProperty("DebugSpecification", "debugSpecification"));
1320     /+mixin(generateProperty("Declaration[]", "declarations"));+/
1321     mixin(generateProperty("Destructor", "destructor"));
1322     mixin(generateProperty("EnumDeclaration", "enumDeclaration"));
1323     mixin(generateProperty("EponymousTemplateDeclaration", "eponymousTemplateDeclaration"));
1324     mixin(generateProperty("FunctionDeclaration", "functionDeclaration"));
1325     mixin(generateProperty("ImportDeclaration", "importDeclaration"));
1326     mixin(generateProperty("InterfaceDeclaration", "interfaceDeclaration"));
1327     mixin(generateProperty("Invariant", "invariant_"));
1328     mixin(generateProperty("MixinDeclaration", "mixinDeclaration"));
1329     mixin(generateProperty("MixinTemplateDeclaration", "mixinTemplateDeclaration"));
1330     mixin(generateProperty("Postblit", "postblit"));
1331     mixin(generateProperty("PragmaDeclaration", "pragmaDeclaration"));
1332     mixin(generateProperty("SharedStaticConstructor", "sharedStaticConstructor"));
1333     mixin(generateProperty("SharedStaticDestructor", "sharedStaticDestructor"));
1334     mixin(generateProperty("StaticAssertDeclaration", "staticAssertDeclaration"));
1335     mixin(generateProperty("StaticForeachDeclaration", "staticForeachDeclaration"));
1336     mixin(generateProperty("StaticConstructor", "staticConstructor"));
1337     mixin(generateProperty("StaticDestructor", "staticDestructor"));
1338     mixin(generateProperty("StructDeclaration", "structDeclaration"));
1339     mixin(generateProperty("TemplateDeclaration", "templateDeclaration"));
1340     mixin(generateProperty("UnionDeclaration", "unionDeclaration"));
1341     mixin(generateProperty("Unittest", "unittest_"));
1342     mixin(generateProperty("VariableDeclaration", "variableDeclaration"));
1343     mixin(generateProperty("VersionSpecification", "versionSpecification"));
1344 
1345 
1346     override bool opEquals(const Object other) const
1347     {
1348         auto otherDeclaration = cast(Declaration) other;
1349         if (otherDeclaration is null)
1350             return false;
1351         return attributes == otherDeclaration.attributes
1352             && declarations == otherDeclaration.declarations
1353             && storage == otherDeclaration.storage;
1354     }
1355 }
1356 
1357 ///
1358 final class DeclarationsAndStatements : ASTNode
1359 {
1360     override void accept(ASTVisitor visitor) const
1361     {
1362         mixin(visitIfNotNull!(declarationsAndStatements));
1363     }
1364 
1365     /** */ DeclarationOrStatement[] declarationsAndStatements;
1366     mixin OpEquals;
1367 }
1368 
1369 ///
1370 final class DeclarationOrStatement : ASTNode
1371 {
1372 public:
1373     override void accept(ASTVisitor visitor) const
1374     {
1375         mixin(visitIfNotNull!(declaration, statement));
1376     }
1377 
1378     /** */ Declaration declaration;
1379     /** */ Statement statement;
1380     mixin OpEquals;
1381 }
1382 
1383 ///
1384 final class Declarator : ASTNode
1385 {
1386 public:
1387     override void accept(ASTVisitor visitor) const
1388     {
1389         mixin(visitIfNotNull!(templateParameters, initializer));
1390     }
1391     /** */ Token name;
1392     /** */ TemplateParameters templateParameters;
1393     /** */ Initializer initializer;
1394     /** */ TypeSuffix[] cstyle;
1395     /** */ string comment;
1396     mixin OpEquals;
1397 }
1398 
1399 ///
1400 final class DefaultStatement : ASTNode
1401 {
1402 public:
1403     override void accept(ASTVisitor visitor) const
1404     {
1405         mixin(visitIfNotNull!(declarationsAndStatements));
1406     }
1407     /** */ DeclarationsAndStatements declarationsAndStatements;
1408 	/** */ size_t colonLocation;
1409     mixin OpEquals;
1410 }
1411 
1412 ///
1413 final class DeleteExpression : ExpressionNode
1414 {
1415 public:
1416     override void accept(ASTVisitor visitor) const
1417     {
1418         mixin(visitIfNotNull!(unaryExpression));
1419     }
1420     /** */ UnaryExpression unaryExpression;
1421     /** */ size_t line;
1422     /** */ size_t column;
1423     mixin OpEquals;
1424 }
1425 
1426 ///
1427 final class DeleteStatement : ASTNode
1428 {
1429 public:
1430     override void accept(ASTVisitor visitor) const
1431     {
1432         mixin(visitIfNotNull!(deleteExpression));
1433     }
1434     /** */ DeleteExpression deleteExpression;
1435     mixin OpEquals;
1436 }
1437 
1438 ///
1439 final class Deprecated : ASTNode
1440 {
1441 public:
1442     override void accept(ASTVisitor visitor) const
1443     {
1444         mixin(visitIfNotNull!(stringLiterals));
1445     }
1446     /** */ Token[] stringLiterals;
1447     mixin OpEquals;
1448 }
1449 
1450 ///
1451 final class Destructor : ASTNode
1452 {
1453 public:
1454     override void accept(ASTVisitor visitor) const
1455     {
1456         mixin(visitIfNotNull!(memberFunctionAttributes, functionBody));
1457     }
1458     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
1459     /** */ FunctionBody functionBody;
1460     /** */ size_t line;
1461     /** */ size_t column;
1462     /** */ size_t index;
1463     /** */ string comment;
1464     mixin OpEquals;
1465 }
1466 
1467 ///
1468 final class DoStatement : ASTNode
1469 {
1470 public:
1471     override void accept(ASTVisitor visitor) const
1472     {
1473         mixin(visitIfNotNull!(expression, statementNoCaseNoDefault));
1474     }
1475     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
1476     /** */ Expression expression;
1477     mixin OpEquals;
1478 }
1479 
1480 ///
1481 final class EnumBody : ASTNode
1482 {
1483 public:
1484     override void accept(ASTVisitor visitor) const
1485     {
1486         mixin(visitIfNotNull!(enumMembers));
1487     }
1488     /** */ EnumMember[] enumMembers;
1489 
1490     /**
1491      * Byte position of the opening brace
1492      */
1493     size_t startLocation;
1494 
1495     /**
1496      * Byte position of the closing brace
1497      */
1498     size_t endLocation;
1499     mixin OpEquals;
1500 }
1501 
1502 ///
1503 final class EnumDeclaration : ASTNode
1504 {
1505 public:
1506     override void accept(ASTVisitor visitor) const
1507     {
1508         mixin(visitIfNotNull!(type, enumBody));
1509     }
1510     /** */ Token name;
1511     /** */ Type type;
1512     /** */ EnumBody enumBody;
1513     /** */ string comment;
1514     mixin OpEquals;
1515 }
1516 
1517 ///
1518 final class EnumMember : ASTNode
1519 {
1520 public:
1521     override void accept(ASTVisitor visitor) const
1522     {
1523         mixin(visitIfNotNull!(name, type, assignExpression));
1524     }
1525     /** */ Token name;
1526     /** */ Type type;
1527     /** */ ExpressionNode assignExpression;
1528     /** */ string comment;
1529     AtAttribute[] atAttributes;
1530 
1531     bool isDisabled;
1532     Deprecated deprecated_;
1533 
1534     mixin OpEquals;
1535 }
1536 
1537 ///
1538 final class EponymousTemplateDeclaration : ASTNode
1539 {
1540 public:
1541     override void accept(ASTVisitor visitor) const
1542     {
1543         mixin(visitIfNotNull!(name, templateParameters, assignExpression, constraint));
1544     }
1545     /** */ Token name;
1546     /** */ TemplateParameters templateParameters;
1547     /** */ ExpressionNode assignExpression;
1548     /** */ Type type;
1549     string comment;
1550     Constraint constraint;
1551     mixin OpEquals;
1552 }
1553 
1554 ///
1555 final class EqualExpression : ExpressionNode
1556 {
1557 public:
1558     override void accept(ASTVisitor visitor) const
1559     {
1560         mixin(visitIfNotNull!(left, right));
1561     }
1562     /** */ IdType operator;
1563     mixin BinaryExpressionBody;
1564     mixin OpEquals;
1565 }
1566 
1567 ///
1568 final class Expression : ExpressionNode
1569 {
1570 public:
1571     override void accept(ASTVisitor visitor) const
1572     {
1573         mixin(visitIfNotNull!(items));
1574     }
1575     /** */ ExpressionNode[] items;
1576     /** */ size_t line;
1577     /** */ size_t column;
1578     mixin OpEquals;
1579 }
1580 
1581 ///
1582 final class ExpressionStatement : ASTNode
1583 {
1584 public:
1585     override void accept(ASTVisitor visitor) const
1586     {
1587         mixin(visitIfNotNull!(expression));
1588     }
1589     /** */ Expression expression;
1590     mixin OpEquals;
1591 }
1592 
1593 ///
1594 final class FinalSwitchStatement : ASTNode
1595 {
1596 public:
1597     override void accept(ASTVisitor visitor) const
1598     {
1599         mixin(visitIfNotNull!(switchStatement));
1600     }
1601     /** */ SwitchStatement switchStatement;
1602     mixin OpEquals;
1603 }
1604 
1605 ///
1606 final class Finally : ASTNode
1607 {
1608 public:
1609     override void accept(ASTVisitor visitor) const
1610     {
1611         mixin(visitIfNotNull!(declarationOrStatement));
1612     }
1613     /** */ DeclarationOrStatement declarationOrStatement;
1614     mixin OpEquals;
1615 }
1616 
1617 ///
1618 final class ForStatement : ASTNode
1619 {
1620 public:
1621     override void accept(ASTVisitor visitor) const
1622     {
1623         mixin(visitIfNotNull!(initialization, test, increment,
1624             declarationOrStatement));
1625     }
1626     /** */ DeclarationOrStatement initialization;
1627     /** */ Expression test;
1628     /** */ Expression increment;
1629     /** */ DeclarationOrStatement declarationOrStatement;
1630     /** */ size_t startIndex;
1631     mixin OpEquals;
1632 }
1633 
1634 ///
1635 final class ForeachStatement : ASTNode
1636 {
1637 public:
1638     override void accept(ASTVisitor visitor) const
1639     {
1640         mixin(visitIfNotNull!(foreachType, foreachTypeList, low, high,
1641             declarationOrStatement));
1642     }
1643     /** */ IdType type;
1644     /** */ ForeachTypeList foreachTypeList;
1645     /** */ ForeachType foreachType;
1646     /** */ Expression low;
1647     /** */ Expression high;
1648     /** */ DeclarationOrStatement declarationOrStatement;
1649     /** */ size_t startIndex;
1650     mixin OpEquals;
1651 }
1652 
1653 ///
1654 final class ForeachType : ASTNode
1655 {
1656 public:
1657     override void accept(ASTVisitor visitor) const
1658     {
1659         mixin(visitIfNotNull!(type, identifier));
1660     }
1661     /** */ bool isRef;
1662     /** */ IdType[] typeConstructors;
1663     /** */ Type type;
1664     /** */ Token identifier;
1665     mixin OpEquals;
1666 }
1667 
1668 ///
1669 final class ForeachTypeList : ASTNode
1670 {
1671 public:
1672     override void accept(ASTVisitor visitor) const
1673     {
1674         mixin(visitIfNotNull!(items));
1675     }
1676     /** */ ForeachType[] items;
1677     mixin OpEquals;
1678 }
1679 
1680 ///
1681 final class FunctionAttribute : ASTNode
1682 {
1683 public:
1684     override void accept(ASTVisitor visitor) const
1685     {
1686         mixin(visitIfNotNull!(token, atAttribute));
1687     }
1688     /** */ Token token;
1689     /** */ AtAttribute atAttribute;
1690     mixin OpEquals;
1691 }
1692 
1693 ///
1694 final class FunctionBody : ASTNode
1695 {
1696 public:
1697     override void accept(ASTVisitor visitor) const
1698     {
1699         mixin(visitIfNotNull!(inStatement, outStatement, bodyStatement,
1700             blockStatement));
1701     }
1702 
1703     /** */ BlockStatement blockStatement;
1704     /** */ BodyStatement bodyStatement;
1705     /** */ OutStatement outStatement;
1706     /** */ InStatement inStatement;
1707 
1708 
1709 	bool hadABody;
1710 
1711     mixin OpEquals;
1712 }
1713 
1714 ///
1715 final class FunctionCallExpression : ExpressionNode
1716 {
1717 public:
1718     override void accept(ASTVisitor visitor) const
1719     {
1720         mixin(visitIfNotNull!(type, unaryExpression, templateArguments, arguments));
1721     }
1722     /** */ Type type;
1723     /** */ UnaryExpression unaryExpression;
1724     /** */ TemplateArguments templateArguments;
1725     /** */ Arguments arguments;
1726     mixin OpEquals;
1727 }
1728 
1729 ///
1730 final class FunctionDeclaration : ASTNode
1731 {
1732 public:
1733     override void accept(ASTVisitor visitor) const
1734     {
1735         mixin(visitIfNotNull!(storageClasses, returnType, parameters,
1736             templateParameters, constraint, memberFunctionAttributes,
1737             functionBody));
1738     }
1739     /** */ bool hasAuto;
1740     /** */ bool hasRef;
1741     /** */ Type returnType;
1742     /** */ Token name;
1743     /** */ TemplateParameters templateParameters;
1744     /** */ Parameters parameters;
1745     /** */ Constraint constraint;
1746     /** */ FunctionBody functionBody;
1747     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
1748     /** */ string comment;
1749     /** */ Attribute[] attributes;
1750     /** */ StorageClass[] storageClasses;
1751     mixin OpEquals;
1752 }
1753 
1754 ///
1755 final class FunctionLiteralExpression : ExpressionNode
1756 {
1757 public:
1758     override void accept(ASTVisitor visitor) const
1759     {
1760         mixin(visitIfNotNull!(type, parameters, memberFunctionAttributes,
1761             functionBody));
1762     }
1763     /** */ IdType functionOrDelegate;
1764     /** */ Type type;
1765     /** */ Parameters parameters;
1766     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
1767     /** */ FunctionBody functionBody;
1768     mixin OpEquals;
1769 }
1770 
1771 ///
1772 final class GotoStatement : ASTNode
1773 {
1774 public:
1775     override void accept(ASTVisitor visitor) const
1776     {
1777         mixin(visitIfNotNull!(label, expression));
1778     }
1779     /** */ Expression expression;
1780     /** */ Token label;
1781     mixin OpEquals;
1782 }
1783 
1784 ///
1785 final class IdentifierChain : ASTNode
1786 {
1787 public:
1788     override void accept(ASTVisitor visitor) const
1789     {
1790         mixin(visitIfNotNull!(identifiers));
1791     }
1792     /** */ Token[] identifiers;
1793     mixin OpEquals;
1794 }
1795 
1796 ///
1797 final class IdentifierList : ASTNode
1798 {
1799 public:
1800     override void accept(ASTVisitor visitor) const
1801     {
1802         mixin(visitIfNotNull!(identifiers));
1803     }
1804     /** */ Token[] identifiers;
1805     mixin OpEquals;
1806 }
1807 
1808 ///
1809 final class IdentifierOrTemplateChain : ASTNode
1810 {
1811 public:
1812     override void accept(ASTVisitor visitor) const
1813     {
1814         mixin(visitIfNotNull!(identifiersOrTemplateInstances));
1815     }
1816 
1817     /** */ IdentifierOrTemplateInstance[] identifiersOrTemplateInstances;
1818     mixin OpEquals;
1819 }
1820 
1821 ///
1822 final class IdentifierOrTemplateInstance : ASTNode
1823 {
1824 public:
1825     override void accept(ASTVisitor visitor) const
1826     {
1827         mixin(visitIfNotNull!(identifier, templateInstance));
1828     }
1829 
1830     /** */ Token identifier;
1831     /** */ TemplateInstance templateInstance;
1832     mixin OpEquals;
1833 }
1834 
1835 ///
1836 final class IdentityExpression : ExpressionNode
1837 {
1838 public:
1839     override void accept(ASTVisitor visitor) const
1840     {
1841         mixin(visitIfNotNull!(left, right));
1842     }
1843     /** */ bool negated;
1844     mixin BinaryExpressionBody;
1845     mixin OpEquals;
1846 }
1847 
1848 ///
1849 final class IfStatement : ASTNode
1850 {
1851 public:
1852     override void accept(ASTVisitor visitor) const
1853     {
1854         mixin(visitIfNotNull!(identifier, type, expression, thenStatement,
1855             elseStatement));
1856     }
1857     /** */ Token identifier;
1858     /** */ Type type;
1859     /** */ Expression expression;
1860     /** */ DeclarationOrStatement thenStatement;
1861     /** */ DeclarationOrStatement elseStatement;
1862     /** */ size_t startIndex;
1863     /** */ size_t line;
1864     /** */ size_t column;
1865     mixin OpEquals;
1866 }
1867 
1868 ///
1869 final class ImportBind : ASTNode
1870 {
1871 public:
1872     override void accept(ASTVisitor visitor) const
1873     {
1874         mixin(visitIfNotNull!(left, right));
1875     }
1876     /** */ Token left;
1877     /** */ Token right;
1878     mixin OpEquals;
1879 }
1880 
1881 ///
1882 final class ImportBindings : ASTNode
1883 {
1884 public:
1885     override void accept(ASTVisitor visitor) const
1886     {
1887         mixin(visitIfNotNull!(singleImport, importBinds));
1888     }
1889     /** */ SingleImport singleImport;
1890     /** */ ImportBind[] importBinds;
1891     mixin OpEquals;
1892 }
1893 
1894 ///
1895 final class ImportDeclaration : ASTNode
1896 {
1897 public:
1898     override void accept(ASTVisitor visitor) const
1899     {
1900         mixin(visitIfNotNull!(singleImports, importBindings));
1901     }
1902     /** */ string comment;
1903     size_t line;
1904     /** */ SingleImport[] singleImports;
1905     /** */ ImportBindings importBindings;
1906     mixin OpEquals;
1907 }
1908 
1909 ///
1910 final class ImportExpression : ExpressionNode
1911 {
1912 public:
1913     override void accept(ASTVisitor visitor) const
1914     {
1915         mixin(visitIfNotNull!(assignExpression));
1916     }
1917     /** */ ExpressionNode assignExpression;
1918     mixin OpEquals;
1919 }
1920 
1921 ///
1922 final class Index : ASTNode
1923 {
1924 public:
1925     override void accept(ASTVisitor visitor) const
1926     {
1927         mixin(visitIfNotNull!(low, high));
1928     }
1929     /** */ ExpressionNode low;
1930     /** */ ExpressionNode high;
1931     mixin OpEquals;
1932 }
1933 
1934 ///
1935 final class IndexExpression : ExpressionNode
1936 {
1937 public:
1938     override void accept(ASTVisitor visitor) const
1939     {
1940         mixin(visitIfNotNull!(unaryExpression, indexes));
1941     }
1942     /** */ UnaryExpression unaryExpression;
1943     /** */ Index[] indexes;
1944     mixin OpEquals;
1945 }
1946 
1947 ///
1948 final class InExpression : ExpressionNode
1949 {
1950 public:
1951     override void accept(ASTVisitor visitor) const
1952     {
1953         mixin(visitIfNotNull!(left, right));
1954     }
1955     mixin BinaryExpressionBody;
1956     bool negated;
1957     mixin OpEquals;
1958 }
1959 
1960 ///
1961 final class InStatement : ASTNode
1962 {
1963 public:
1964     override void accept(ASTVisitor visitor) const
1965     {
1966         mixin(visitIfNotNull!(blockStatement));
1967     }
1968     /** */ size_t inTokenLocation;
1969     /** */ BlockStatement blockStatement;
1970     /** */ Expression expression;
1971     mixin OpEquals;
1972 }
1973 
1974 ///
1975 final class Initialize : ASTNode
1976 {
1977 public:
1978     override void accept(ASTVisitor visitor) const
1979     {
1980         mixin(visitIfNotNull!(statementNoCaseNoDefault));
1981     }
1982     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
1983     mixin OpEquals;
1984 }
1985 
1986 ///
1987 final class Initializer : ASTNode
1988 {
1989 public:
1990     override void accept(ASTVisitor visitor) const
1991     {
1992         mixin(visitIfNotNull!(nonVoidInitializer));
1993     }
1994     /** */ NonVoidInitializer nonVoidInitializer;
1995     mixin OpEquals;
1996 }
1997 
1998 ///
1999 final class InterfaceDeclaration : ASTNode
2000 {
2001 public:
2002     override void accept(ASTVisitor visitor) const
2003     {
2004         mixin(visitIfNotNull!(templateParameters, constraint, baseClassList,
2005             structBody));
2006     }
2007     /** */ Token name;
2008     /** */ TemplateParameters templateParameters;
2009     /** */ Constraint constraint;
2010     /** */ BaseClassList baseClassList;
2011     /** */ StructBody structBody;
2012     /** */ string comment;
2013     mixin OpEquals;
2014 }
2015 
2016 ///
2017 final class Invariant : ASTNode
2018 {
2019 public:
2020     override void accept(ASTVisitor visitor) const
2021     {
2022         mixin(visitIfNotNull!(blockStatement));
2023     }
2024     /** */ BlockStatement blockStatement;
2025     /** */ string comment;
2026     size_t line;
2027     size_t index;
2028     mixin OpEquals;
2029 }
2030 
2031 ///
2032 final class IsExpression : ExpressionNode
2033 {
2034 public:
2035     override void accept(ASTVisitor visitor) const
2036     {
2037         mixin(visitIfNotNull!(type, identifier, typeSpecialization,
2038             templateParameterList));
2039     }
2040     /** */ Type type;
2041     /** */ Token identifier;
2042     /** */ TypeSpecialization typeSpecialization;
2043     /** */ TemplateParameterList templateParameterList;
2044     /** */ IdType equalsOrColon;
2045     mixin OpEquals;
2046 }
2047 
2048 ///
2049 final class KeyValuePair : ASTNode
2050 {
2051 public:
2052     override void accept(ASTVisitor visitor) const
2053     {
2054         mixin(visitIfNotNull!(key, value));
2055     }
2056     /** */ ExpressionNode key;
2057     /** */ ExpressionNode value;
2058     mixin OpEquals;
2059 }
2060 
2061 ///
2062 final class KeyValuePairs : ASTNode
2063 {
2064 public:
2065     override void accept(ASTVisitor visitor) const
2066     {
2067         mixin(visitIfNotNull!(keyValuePairs));
2068     }
2069     /** */ KeyValuePair[] keyValuePairs;
2070     mixin OpEquals;
2071 }
2072 
2073 ///
2074 final class LabeledStatement : ASTNode
2075 {
2076 public:
2077     override void accept(ASTVisitor visitor) const
2078     {
2079         mixin(visitIfNotNull!(identifier, declarationOrStatement));
2080     }
2081     Token identifier;
2082     /** */ DeclarationOrStatement declarationOrStatement;
2083     mixin OpEquals;
2084 }
2085 
2086 ///
2087 final class LambdaExpression : ExpressionNode
2088 {
2089 public:
2090     override void accept(ASTVisitor visitor) const
2091     {
2092         mixin(visitIfNotNull!(identifier, returnType, parameters, functionAttributes,
2093             assignExpression));
2094     }
2095     /** */ IdType functionType;
2096     /** */ Token identifier;
2097     /** */ Parameters parameters;
2098     /** */ FunctionAttribute[] functionAttributes;
2099     /** */ ExpressionNode assignExpression;
2100     /** */ Type returnType;
2101     mixin OpEquals;
2102 }
2103 
2104 ///
2105 final class LastCatch : ASTNode
2106 {
2107 public:
2108     override void accept(ASTVisitor visitor) const
2109     {
2110         mixin(visitIfNotNull!(statementNoCaseNoDefault));
2111     }
2112     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
2113     size_t line;
2114     size_t column;
2115     mixin OpEquals;
2116 }
2117 
2118 ///
2119 final class LinkageAttribute : ASTNode
2120 {
2121 public:
2122     override void accept(ASTVisitor visitor) const
2123     {
2124         mixin(visitIfNotNull!(identifier, identifierChain));
2125     }
2126     /** */ Token identifier;
2127     /** */ bool hasPlusPlus;
2128     /** */ IdentifierChain identifierChain;
2129     mixin OpEquals;
2130 }
2131 
2132 ///
2133 final class MemberFunctionAttribute : ASTNode
2134 {
2135 public:
2136     override void accept(ASTVisitor visitor) const
2137     {
2138         mixin(visitIfNotNull!(atAttribute));
2139     }
2140     /** */ IdType tokenType;
2141     /** */ AtAttribute atAttribute;
2142     mixin OpEquals;
2143 }
2144 
2145 ///
2146 final class MixinDeclaration : ASTNode
2147 {
2148 public:
2149     override void accept(ASTVisitor visitor) const
2150     {
2151         mixin(visitIfNotNull!(mixinExpression, templateMixinExpression));
2152 	foreach(decl; trivialDeclarations) {
2153 		decl.accept(visitor);
2154 	}
2155     }
2156     /** */ MixinExpression mixinExpression;
2157     /** */ TemplateMixinExpression templateMixinExpression;
2158 
2159     Declaration[] trivialDeclarations;
2160 
2161     mixin OpEquals;
2162 }
2163 
2164 ///
2165 final class MixinExpression : ExpressionNode
2166 {
2167 public:
2168     override void accept(ASTVisitor visitor) const
2169     {
2170         mixin(visitIfNotNull!(assignExpression));
2171     }
2172     /** */ ExpressionNode assignExpression;
2173     mixin OpEquals;
2174 }
2175 
2176 ///
2177 final class MixinTemplateDeclaration : ASTNode
2178 {
2179 public:
2180     override void accept(ASTVisitor visitor) const
2181     {
2182         mixin(visitIfNotNull!(templateDeclaration));
2183     }
2184     /** */ TemplateDeclaration templateDeclaration;
2185     mixin OpEquals;
2186 }
2187 
2188 ///
2189 final class MixinTemplateName : ASTNode
2190 {
2191 public:
2192     override void accept(ASTVisitor visitor) const
2193     {
2194         mixin(visitIfNotNull!(symbol, typeofExpression, identifierOrTemplateChain));
2195     }
2196     /** */ Symbol symbol;
2197     /** */ IdentifierOrTemplateChain identifierOrTemplateChain;
2198     /** */ TypeofExpression typeofExpression;
2199     mixin OpEquals;
2200 }
2201 
2202 ///
2203 final class Module : ASTNode
2204 {
2205 public:
2206     override void accept(ASTVisitor visitor) const
2207     {
2208         mixin(visitIfNotNull!(scriptLine, moduleDeclaration, declarations));
2209     }
2210     /** */ Token scriptLine;
2211     /** */ ModuleDeclaration moduleDeclaration;
2212     /** */ Declaration[] declarations;
2213     mixin OpEquals;
2214 }
2215 
2216 ///
2217 final class ModuleDeclaration : ASTNode
2218 {
2219 public:
2220     override void accept(ASTVisitor visitor) const
2221     {
2222         mixin(visitIfNotNull!(moduleName, deprecated_));
2223     }
2224     /** */ Deprecated deprecated_;
2225     /** */ IdentifierChain moduleName;
2226     /** */ size_t startLocation;
2227     /** */ size_t endLocation;
2228     /** */ string comment;
2229     mixin OpEquals;
2230 }
2231 
2232 
2233 ///
2234 final class MulExpression : ExpressionNode
2235 {
2236 public:
2237     override void accept(ASTVisitor visitor) const
2238     {
2239         mixin(visitIfNotNull!(left, right));
2240     }
2241     /** */ IdType operator;
2242     mixin BinaryExpressionBody;
2243     mixin OpEquals;
2244 }
2245 
2246 ///
2247 final class NewAnonClassExpression : ExpressionNode
2248 {
2249 public:
2250     override void accept(ASTVisitor visitor) const
2251     {
2252         mixin(visitIfNotNull!(allocatorArguments, constructorArguments,
2253             baseClassList, structBody));
2254     }
2255     /** */ Arguments allocatorArguments;
2256     /** */ Arguments constructorArguments;
2257     /** */ BaseClassList baseClassList;
2258     /** */ StructBody structBody;
2259     mixin OpEquals;
2260 }
2261 
2262 ///
2263 final class NewExpression : ExpressionNode
2264 {
2265 public:
2266     override void accept(ASTVisitor visitor) const
2267     {
2268         mixin(visitIfNotNull!(newAnonClassExpression, type, arguments,
2269             assignExpression));
2270     }
2271     /** */ Type type;
2272     /** */ NewAnonClassExpression newAnonClassExpression;
2273     /** */ Arguments arguments;
2274     /** */ ExpressionNode assignExpression;
2275     mixin OpEquals;
2276 }
2277 
2278 
2279 ///
2280 final class StatementNoCaseNoDefault : ASTNode
2281 {
2282 public:
2283     override void accept(ASTVisitor visitor) const
2284     {
2285         mixin(visitIfNotNull!(labeledStatement, blockStatement, ifStatement,
2286             whileStatement, doStatement, forStatement, foreachStatement,
2287             switchStatement, finalSwitchStatement, continueStatement,
2288             breakStatement, returnStatement, gotoStatement, withStatement,
2289             synchronizedStatement, tryStatement, throwStatement,
2290             scopeGuardStatement, asmStatement, conditionalStatement,
2291             staticAssertStatement, versionSpecification, debugSpecification,
2292             expressionStatement));
2293     }
2294     /** */ LabeledStatement labeledStatement;
2295     /** */ BlockStatement blockStatement;
2296     /** */ IfStatement ifStatement;
2297     /** */ WhileStatement whileStatement;
2298     /** */ DoStatement doStatement;
2299     /** */ ForStatement forStatement;
2300     /** */ ForeachStatement foreachStatement;
2301     /** */ SwitchStatement switchStatement;
2302     /** */ FinalSwitchStatement finalSwitchStatement;
2303     /** */ ContinueStatement continueStatement;
2304     /** */ BreakStatement breakStatement;
2305     /** */ ReturnStatement returnStatement;
2306     /** */ GotoStatement gotoStatement;
2307     /** */ WithStatement withStatement;
2308     /** */ SynchronizedStatement synchronizedStatement;
2309     /** */ TryStatement tryStatement;
2310     /** */ ThrowStatement throwStatement;
2311     /** */ ScopeGuardStatement scopeGuardStatement;
2312     /** */ AsmStatement asmStatement;
2313     /** */ ConditionalStatement conditionalStatement;
2314     /** */ StaticAssertStatement staticAssertStatement;
2315     /** */ StaticForeachStatement staticForeachStatement;
2316     /** */ VersionSpecification versionSpecification;
2317     /** */ DebugSpecification debugSpecification;
2318     /** */ ExpressionStatement expressionStatement;
2319     /** */ size_t startLocation;
2320     /** */ size_t endLocation;
2321     mixin OpEquals;
2322 }
2323 
2324 ///
2325 final class NonVoidInitializer : ASTNode
2326 {
2327 public:
2328     override void accept(ASTVisitor visitor) const
2329     {
2330         mixin(visitIfNotNull!(assignExpression, arrayInitializer,
2331             structInitializer));
2332     }
2333     /** */ ExpressionNode assignExpression;
2334     /** */ ArrayInitializer arrayInitializer;
2335     /** */ StructInitializer structInitializer;
2336 
2337     mixin OpEquals;
2338 }
2339 
2340 ///
2341 final class Operands : ASTNode
2342 {
2343 public:
2344     override void accept(ASTVisitor visitor) const
2345     {
2346         mixin(visitIfNotNull!(operands));
2347     }
2348     /** */ ExpressionNode[] operands;
2349     mixin OpEquals;
2350 }
2351 
2352 ///
2353 final class OrExpression : ExpressionNode
2354 {
2355 public:
2356     override void accept(ASTVisitor visitor) const
2357     {
2358         mixin(visitIfNotNull!(left, right));
2359     }
2360     mixin BinaryExpressionBody;
2361     mixin OpEquals;
2362 }
2363 
2364 ///
2365 final class OrOrExpression : ExpressionNode
2366 {
2367 public:
2368     override void accept(ASTVisitor visitor) const
2369     {
2370         mixin(visitIfNotNull!(left, right));
2371     }
2372     mixin BinaryExpressionBody;
2373     mixin OpEquals;
2374 }
2375 
2376 ///
2377 final class OutStatement : ASTNode
2378 {
2379 public:
2380     override void accept(ASTVisitor visitor) const
2381     {
2382         mixin(visitIfNotNull!(parameter, blockStatement));
2383     }
2384     /** */ size_t outTokenLocation;
2385     /** */ Token parameter;
2386     /** */ BlockStatement blockStatement;
2387     Expression expression;
2388     mixin OpEquals;
2389 }
2390 
2391 ///
2392 final class Parameter : ASTNode
2393 {
2394 public:
2395     override void accept(ASTVisitor visitor) const
2396     {
2397         mixin(visitIfNotNull!(type, name, default_));
2398     }
2399 
2400     /** */ IdType[] parameterAttributes;
2401     /** */ Type type;
2402     /** */ Token name;
2403     /** */ bool vararg;
2404     /** */ ExpressionNode default_;
2405     /** */ TypeSuffix[] cstyle;
2406     AtAttribute[] atAttributes;
2407 
2408     string comment;
2409 
2410     mixin OpEquals;
2411 }
2412 
2413 ///
2414 final class Parameters : ASTNode
2415 {
2416 public:
2417     override void accept(ASTVisitor visitor) const
2418     {
2419         mixin(visitIfNotNull!(parameters));
2420     }
2421 
2422     /** */ Parameter[] parameters;
2423     /** */ bool hasVarargs;
2424     mixin OpEquals;
2425 }
2426 
2427 ///
2428 final class Postblit : ASTNode
2429 {
2430 public:
2431     override void accept(ASTVisitor visitor) const
2432     {
2433         mixin(visitIfNotNull!(functionBody));
2434     }
2435     /** */ FunctionBody functionBody;
2436     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
2437     /** */ string comment;
2438     size_t line;
2439     mixin OpEquals;
2440 }
2441 
2442 ///
2443 final class PowExpression : ExpressionNode
2444 {
2445 public:
2446     override void accept(ASTVisitor visitor) const
2447     {
2448         mixin(visitIfNotNull!(left, right));
2449     }
2450     mixin BinaryExpressionBody;
2451     mixin OpEquals;
2452 }
2453 
2454 ///
2455 final class PragmaDeclaration : ASTNode
2456 {
2457 public:
2458     override void accept(ASTVisitor visitor) const
2459     {
2460         mixin(visitIfNotNull!(pragmaExpression));
2461     }
2462     /** */ PragmaExpression pragmaExpression;
2463     mixin OpEquals;
2464 }
2465 
2466 ///
2467 final class PragmaExpression : ExpressionNode
2468 {
2469 public:
2470     override void accept(ASTVisitor visitor) const
2471     {
2472         mixin(visitIfNotNull!(identifier, argumentList));
2473     }
2474     /** */ Token identifier;
2475     /** */ ArgumentList argumentList;
2476     mixin OpEquals;
2477 }
2478 
2479 ///
2480 final class PrimaryExpression : ExpressionNode
2481 {
2482 public:
2483     override void accept(ASTVisitor visitor) const
2484     {
2485         mixin(visitIfNotNull!(basicType, typeConstructor, type, primary,
2486             typeofExpression, typeidExpression, arrayLiteral, assocArrayLiteral,
2487             expression, dot, identifierOrTemplateInstance, isExpression,
2488             lambdaExpression, functionLiteralExpression, traitsExpression,
2489             mixinExpression, importExpression, vector, arguments));
2490     }
2491     /** */ Token dot;
2492     /** */ Token primary;
2493     /** */ IdentifierOrTemplateInstance identifierOrTemplateInstance;
2494     /** */ Token basicType;
2495     /** */ TypeofExpression typeofExpression;
2496     /** */ TypeidExpression typeidExpression;
2497     /** */ ArrayLiteral arrayLiteral;
2498     /** */ AssocArrayLiteral assocArrayLiteral;
2499     /** */ Expression expression;
2500     /** */ IsExpression isExpression;
2501     /** */ LambdaExpression lambdaExpression;
2502     /** */ FunctionLiteralExpression functionLiteralExpression;
2503     /** */ TraitsExpression traitsExpression;
2504     /** */ MixinExpression mixinExpression;
2505     /** */ ImportExpression importExpression;
2506     /** */ Vector vector;
2507     /** */ Type type;
2508     /** */ Token typeConstructor;
2509     /** */ Arguments arguments;
2510     mixin OpEquals;
2511 }
2512 
2513 ///
2514 final class Register : ASTNode
2515 {
2516 public:
2517     override void accept(ASTVisitor visitor) const
2518     {
2519         mixin(visitIfNotNull!(identifier, intLiteral));
2520     }
2521     /** */ Token identifier;
2522     /** */ Token intLiteral;
2523     /** */ bool hasIntegerLiteral;
2524     mixin OpEquals;
2525 }
2526 
2527 ///
2528 final class RelExpression : ExpressionNode
2529 {
2530 public:
2531     override void accept(ASTVisitor visitor) const
2532     {
2533         mixin(visitIfNotNull!(left, right));
2534     }
2535     /** */ IdType operator;
2536     mixin BinaryExpressionBody;
2537     mixin OpEquals;
2538 }
2539 
2540 ///
2541 final class ReturnStatement : ASTNode
2542 {
2543 public:
2544     override void accept(ASTVisitor visitor) const
2545     {
2546         mixin(visitIfNotNull!(expression));
2547     }
2548     /** */ Expression expression;
2549     /** */ size_t startLocation;
2550     /** */ size_t endLocation;
2551     mixin OpEquals;
2552 }
2553 
2554 ///
2555 final class ScopeGuardStatement : ASTNode
2556 {
2557 public:
2558     override void accept(ASTVisitor visitor) const
2559     {
2560         mixin(visitIfNotNull!(identifier, statementNoCaseNoDefault));
2561     }
2562     /** */ Token identifier;
2563     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
2564     mixin OpEquals;
2565 }
2566 
2567 ///
2568 final class SharedStaticConstructor : ASTNode
2569 {
2570 public:
2571     override void accept(ASTVisitor visitor) const
2572     {
2573         mixin(visitIfNotNull!(functionBody));
2574     }
2575     /** */ FunctionBody functionBody;
2576     /** */ size_t location;
2577     /** */ string comment;
2578     mixin OpEquals;
2579 }
2580 
2581 ///
2582 final class SharedStaticDestructor : ASTNode
2583 {
2584 public:
2585     override void accept(ASTVisitor visitor) const
2586     {
2587         mixin(visitIfNotNull!(functionBody));
2588     }
2589     /** */ FunctionBody functionBody;
2590     /** */ size_t location;
2591     /** */ string comment;
2592     mixin OpEquals;
2593 }
2594 
2595 ///
2596 final class ShiftExpression : ExpressionNode
2597 {
2598 public:
2599     override void accept(ASTVisitor visitor) const
2600     {
2601         mixin(visitIfNotNull!(left, right));
2602     }
2603     /** */ IdType operator;
2604     mixin BinaryExpressionBody;
2605     mixin OpEquals;
2606 }
2607 
2608 ///
2609 final class SingleImport : ASTNode
2610 {
2611 public:
2612     override void accept(ASTVisitor visitor) const
2613     {
2614         mixin(visitIfNotNull!(rename, identifierChain));
2615     }
2616     /** */ Token rename;
2617     /** */ IdentifierChain identifierChain;
2618     mixin OpEquals;
2619 }
2620 
2621 ///
2622 final class Statement : ASTNode
2623 {
2624 public:
2625     override void accept(ASTVisitor visitor) const
2626     {
2627         mixin(visitIfNotNull!(statementNoCaseNoDefault, caseStatement,
2628             caseRangeStatement, defaultStatement));
2629     }
2630     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
2631     /** */ CaseStatement caseStatement;
2632     /** */ CaseRangeStatement caseRangeStatement;
2633     /** */ DefaultStatement defaultStatement;
2634     mixin OpEquals;
2635 }
2636 
2637 ///
2638 final class StaticAssertDeclaration : ASTNode
2639 {
2640 public:
2641     override void accept(ASTVisitor visitor) const
2642     {
2643         mixin(visitIfNotNull!(staticAssertStatement));
2644     }
2645     /** */ StaticAssertStatement staticAssertStatement;
2646     mixin OpEquals;
2647 }
2648 
2649 final class StaticForeachDeclaration : ASTNode
2650 {
2651 public:
2652     override void accept(ASTVisitor visitor) const
2653     {
2654         mixin(visitIfNotNull!(declarations));
2655     }
2656     /** */ Declaration[] declarations;
2657 }
2658 
2659 final class StaticForeachStatement : ASTNode
2660 {
2661 	// FIXME
2662     override void accept(ASTVisitor visitor) const
2663     {
2664     }
2665 }
2666 
2667 ///
2668 final class StaticAssertStatement : ASTNode
2669 {
2670 public:
2671     override void accept(ASTVisitor visitor) const
2672     {
2673         mixin(visitIfNotNull!(assertExpression));
2674     }
2675     /** */ AssertExpression assertExpression;
2676     mixin OpEquals;
2677 }
2678 
2679 ///
2680 final class StaticConstructor : ASTNode
2681 {
2682 public:
2683     override void accept(ASTVisitor visitor) const
2684     {
2685         mixin(visitIfNotNull!(functionBody));
2686     }
2687     /** */ FunctionBody functionBody;
2688     /** */ size_t location;
2689     /** */ size_t line;
2690     /** */ size_t column;
2691     /** */ string comment;
2692     mixin OpEquals;
2693 }
2694 
2695 ///
2696 final class StaticDestructor : ASTNode
2697 {
2698 public:
2699     override void accept(ASTVisitor visitor) const
2700     {
2701         mixin(visitIfNotNull!(functionBody));
2702     }
2703     /** */ FunctionBody functionBody;
2704     /** */ size_t location;
2705     /** */ size_t line;
2706     /** */ size_t column;
2707     /** */ string comment;
2708     mixin OpEquals;
2709 }
2710 
2711 ///
2712 final class StaticIfCondition : ASTNode
2713 {
2714 public:
2715     override void accept(ASTVisitor visitor) const
2716     {
2717         mixin(visitIfNotNull!(assignExpression));
2718     }
2719     /** */ ExpressionNode assignExpression;
2720     mixin OpEquals;
2721 }
2722 
2723 ///
2724 final class StorageClass : ASTNode
2725 {
2726 public:
2727     override void accept(ASTVisitor visitor) const
2728     {
2729         mixin(visitIfNotNull!(token, alignAttribute, linkageAttribute,
2730             atAttribute, deprecated_));
2731     }
2732     /** */ AlignAttribute alignAttribute;
2733     /** */ LinkageAttribute linkageAttribute;
2734     /** */ AtAttribute atAttribute;
2735     /** */ Deprecated deprecated_;
2736     /** */ Token token;
2737     mixin OpEquals;
2738 }
2739 
2740 ///
2741 final class StructBody : ASTNode
2742 {
2743 public:
2744     override void accept(ASTVisitor visitor) const
2745     {
2746         mixin(visitIfNotNull!(declarations));
2747     }
2748 
2749     /**
2750      * Byte position of the opening brace
2751      */
2752     size_t startLocation;
2753 
2754     /**
2755      * Byte position of the closing brace
2756      */
2757     size_t endLocation;
2758     /** */ Declaration[] declarations;
2759     mixin OpEquals;
2760 }
2761 
2762 ///
2763 final class StructDeclaration : ASTNode
2764 {
2765 public:
2766     override void accept(ASTVisitor visitor) const
2767     {
2768         mixin(visitIfNotNull!(templateParameters, constraint, structBody));
2769     }
2770     /** */ Token name;
2771     /** */ TemplateParameters templateParameters;
2772     /** */ Constraint constraint;
2773     /** */ StructBody structBody;
2774     /** */ string comment;
2775     mixin OpEquals;
2776 }
2777 
2778 ///
2779 final class StructInitializer : ASTNode
2780 {
2781 public:
2782     override void accept(ASTVisitor visitor) const
2783     {
2784         mixin(visitIfNotNull!(structMemberInitializers));
2785     }
2786     /** */ StructMemberInitializers structMemberInitializers;
2787     /** */ size_t startLocation;
2788     /** */ size_t endLocation;
2789     mixin OpEquals;
2790 }
2791 
2792 ///
2793 final class StructMemberInitializer : ASTNode
2794 {
2795 public:
2796     override void accept(ASTVisitor visitor) const
2797     {
2798         mixin(visitIfNotNull!(identifier, nonVoidInitializer));
2799     }
2800     /** */ Token identifier;
2801     /** */ NonVoidInitializer nonVoidInitializer;
2802     mixin OpEquals;
2803 }
2804 
2805 ///
2806 final class StructMemberInitializers : ASTNode
2807 {
2808 public:
2809     override void accept(ASTVisitor visitor) const
2810     {
2811         mixin(visitIfNotNull!(structMemberInitializers));
2812     }
2813     /** */ StructMemberInitializer[] structMemberInitializers;
2814     mixin OpEquals;
2815 }
2816 
2817 ///
2818 final class SwitchStatement : ASTNode
2819 {
2820 public:
2821     override void accept(ASTVisitor visitor) const
2822     {
2823         mixin(visitIfNotNull!(expression, statement));
2824     }
2825     /** */ Expression expression;
2826     /** */ Statement statement;
2827     mixin OpEquals;
2828 }
2829 
2830 ///
2831 final class Symbol : ASTNode
2832 {
2833 public:
2834     override void accept(ASTVisitor visitor) const
2835     {
2836         mixin(visitIfNotNull!(identifierOrTemplateChain));
2837     }
2838 
2839     /** */ IdentifierOrTemplateChain identifierOrTemplateChain;
2840     /** */ bool dot;
2841     mixin OpEquals;
2842 }
2843 
2844 ///
2845 final class SynchronizedStatement : ASTNode
2846 {
2847 public:
2848     override void accept(ASTVisitor visitor) const
2849     {
2850         mixin(visitIfNotNull!(expression, statementNoCaseNoDefault));
2851     }
2852     /** */ Expression expression;
2853     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
2854     mixin OpEquals;
2855 }
2856 
2857 ///
2858 final class TemplateAliasParameter : ASTNode
2859 {
2860 public:
2861     override void accept(ASTVisitor visitor) const
2862     {
2863         mixin(visitIfNotNull!(type, identifier, colonType, colonExpression,
2864             assignType, assignExpression));
2865     }
2866     /** */ Type type;
2867     /** */ Token identifier;
2868     /** */ Type colonType;
2869     /** */ ExpressionNode colonExpression;
2870     /** */ Type assignType;
2871     /** */ ExpressionNode assignExpression;
2872     mixin OpEquals;
2873 }
2874 
2875 ///
2876 final class TemplateArgument : ASTNode
2877 {
2878 public:
2879     override void accept(ASTVisitor visitor) const
2880     {
2881         mixin(visitIfNotNull!(type, assignExpression));
2882     }
2883     /** */ Type type;
2884     /** */ ExpressionNode assignExpression;
2885     mixin OpEquals;
2886 }
2887 
2888 ///
2889 final class TemplateArgumentList : ASTNode
2890 {
2891 public:
2892     override void accept(ASTVisitor visitor) const
2893     {
2894         mixin(visitIfNotNull!(items));
2895     }
2896     /** */ TemplateArgument[] items;
2897     mixin OpEquals;
2898 }
2899 
2900 ///
2901 final class TemplateArguments : ASTNode
2902 {
2903 public:
2904     override void accept(ASTVisitor visitor) const
2905     {
2906         mixin(visitIfNotNull!(templateArgumentList, templateSingleArgument));
2907     }
2908     /** */ TemplateArgumentList templateArgumentList;
2909     /** */ TemplateSingleArgument templateSingleArgument;
2910     mixin OpEquals;
2911 }
2912 
2913 ///
2914 final class TemplateDeclaration : ASTNode
2915 {
2916 public:
2917     override void accept(ASTVisitor visitor) const
2918     {
2919         mixin(visitIfNotNull!(name, templateParameters, constraint,
2920             declarations));
2921     }
2922     /** */ Token name;
2923     /** */ TemplateParameters templateParameters;
2924     /** */ Constraint constraint;
2925     /** */ Declaration[] declarations;
2926     /** */ string comment;
2927     /**
2928      * Byte position of the opening brace
2929      */
2930     size_t startLocation;
2931 
2932     /**
2933      * Byte position of the closing brace
2934      */
2935     size_t endLocation;
2936     mixin OpEquals;
2937 }
2938 
2939 ///
2940 final class TemplateInstance : ASTNode
2941 {
2942 public:
2943     override void accept(ASTVisitor visitor) const
2944     {
2945         mixin(visitIfNotNull!(identifier, templateArguments));
2946     }
2947     /** */ Token identifier;
2948     /** */ TemplateArguments templateArguments;
2949     mixin OpEquals;
2950 }
2951 
2952 ///
2953 final class TemplateMixinExpression : ExpressionNode
2954 {
2955 public:
2956     override void accept(ASTVisitor visitor) const
2957     {
2958         mixin(visitIfNotNull!(identifier, templateArguments, mixinTemplateName));
2959     }
2960     /** */ Token identifier;
2961     /** */ TemplateArguments templateArguments;
2962     /** */ MixinTemplateName mixinTemplateName;
2963     /** */ string comment;
2964     size_t line;
2965     mixin OpEquals;
2966 }
2967 
2968 ///
2969 final class TemplateParameter : ASTNode
2970 {
2971 public:
2972     override void accept(ASTVisitor visitor) const
2973     {
2974         mixin(visitIfNotNull!(templateTypeParameter, templateValueParameter,
2975             templateAliasParameter, templateTupleParameter,
2976             templateThisParameter));
2977     }
2978     /** */ TemplateTypeParameter templateTypeParameter;
2979     /** */ TemplateValueParameter templateValueParameter;
2980     /** */ TemplateAliasParameter templateAliasParameter;
2981     /** */ TemplateTupleParameter templateTupleParameter;
2982     /** */ TemplateThisParameter templateThisParameter;
2983     string comment;
2984     mixin OpEquals;
2985 }
2986 
2987 ///
2988 final class TemplateParameterList : ASTNode
2989 {
2990 public:
2991     override void accept(ASTVisitor visitor) const
2992     {
2993         mixin(visitIfNotNull!(items));
2994     }
2995     /** */ TemplateParameter[] items;
2996     mixin OpEquals;
2997 }
2998 
2999 ///
3000 final class TemplateParameters : ASTNode
3001 {
3002 public:
3003     override void accept(ASTVisitor visitor) const
3004     {
3005         mixin(visitIfNotNull!(templateParameterList));
3006     }
3007     /** */ TemplateParameterList templateParameterList;
3008     mixin OpEquals;
3009 }
3010 
3011 ///
3012 final class TemplateSingleArgument : ASTNode
3013 {
3014 public:
3015     override void accept(ASTVisitor visitor) const
3016     {
3017         mixin(visitIfNotNull!(token));
3018     }
3019     /** */ Token token;
3020     mixin OpEquals;
3021 }
3022 
3023 ///
3024 final class TemplateThisParameter : ASTNode
3025 {
3026 public:
3027     override void accept(ASTVisitor visitor) const
3028     {
3029         mixin(visitIfNotNull!(templateTypeParameter));
3030     }
3031     /** */ TemplateTypeParameter templateTypeParameter;
3032     mixin OpEquals;
3033 }
3034 
3035 ///
3036 final class TemplateTupleParameter : ASTNode
3037 {
3038 public:
3039     override void accept(ASTVisitor visitor) const
3040     {
3041         mixin(visitIfNotNull!(identifier));
3042     }
3043     /** */ Token identifier;
3044     mixin OpEquals;
3045 }
3046 
3047 ///
3048 final class TemplateTypeParameter : ASTNode
3049 {
3050 public:
3051     override void accept(ASTVisitor visitor) const
3052     {
3053         mixin(visitIfNotNull!(identifier, colonType, assignType));
3054     }
3055     /** */ Token identifier;
3056     /** */ Type colonType;
3057     /** */ Type assignType;
3058     mixin OpEquals;
3059 }
3060 
3061 ///
3062 final class TemplateValueParameter : ASTNode
3063 {
3064 public:
3065     override void accept(ASTVisitor visitor) const
3066     {
3067         mixin(visitIfNotNull!(type, identifier, assignExpression,
3068             templateValueParameterDefault));
3069     }
3070     /** */ Type type;
3071     /** */ Token identifier;
3072     /** */ ExpressionNode assignExpression;
3073     /** */ TemplateValueParameterDefault templateValueParameterDefault;
3074     mixin OpEquals;
3075 }
3076 
3077 ///
3078 final class TemplateValueParameterDefault : ASTNode
3079 {
3080 public:
3081     override void accept(ASTVisitor visitor) const
3082     {
3083         mixin(visitIfNotNull!(token, assignExpression));
3084     }
3085     /** */ ExpressionNode assignExpression;
3086     /** */ Token token;
3087     mixin OpEquals;
3088 }
3089 
3090 ///
3091 final class TernaryExpression : ExpressionNode
3092 {
3093 public:
3094     override void accept(ASTVisitor visitor) const
3095     {
3096         mixin(visitIfNotNull!(orOrExpression, expression, ternaryExpression));
3097     }
3098     /** */ ExpressionNode orOrExpression;
3099     /** */ ExpressionNode expression;
3100     /** */ ExpressionNode ternaryExpression;
3101     /// Store this so that we know where the ':' is
3102     Token colon;
3103     mixin OpEquals;
3104 }
3105 
3106 ///
3107 final class ThrowStatement : ASTNode
3108 {
3109 public:
3110     override void accept(ASTVisitor visitor) const
3111     {
3112         mixin(visitIfNotNull!(expression));
3113     }
3114     /** */ Expression expression;
3115     mixin OpEquals;
3116 }
3117 
3118 ///
3119 final class TraitsExpression : ExpressionNode
3120 {
3121 public:
3122     override void accept(ASTVisitor visitor) const
3123     {
3124         mixin(visitIfNotNull!(identifier, templateArgumentList));
3125     }
3126     /** */ Token identifier;
3127     /** */ TemplateArgumentList templateArgumentList;
3128     mixin OpEquals;
3129 }
3130 
3131 ///
3132 final class TryStatement : ASTNode
3133 {
3134 public:
3135     override void accept(ASTVisitor visitor) const
3136     {
3137         mixin(visitIfNotNull!(declarationOrStatement, catches, finally_));
3138     }
3139     /** */ DeclarationOrStatement declarationOrStatement;
3140     /** */ Catches catches;
3141     /** */ Finally finally_;
3142     mixin OpEquals;
3143 }
3144 
3145 ///
3146 final class Type : ASTNode
3147 {
3148 public:
3149     override void accept(ASTVisitor visitor) const
3150     {
3151         mixin(visitIfNotNull!(type2, typeSuffixes));
3152     }
3153 
3154     /** */ IdType[] typeConstructors;
3155     /** */ TypeSuffix[] typeSuffixes;
3156     /** */ Type2 type2;
3157     mixin OpEquals;
3158 }
3159 
3160 ///
3161 final class Type2 : ASTNode
3162 {
3163 public:
3164     override void accept(ASTVisitor visitor) const
3165     {
3166         mixin(visitIfNotNull!(symbol, typeofExpression,
3167             identifierOrTemplateChain, type, vector));
3168     }
3169 
3170     /** */ IdType builtinType;
3171     /** */ Symbol symbol;
3172     /** */ TypeofExpression typeofExpression;
3173     /** */ IdentifierOrTemplateChain identifierOrTemplateChain;
3174     /** */ IdType typeConstructor;
3175     /** */ Type type;
3176     /** */ Vector vector;
3177     mixin OpEquals;
3178 }
3179 
3180 ///
3181 final class TypeSpecialization : ASTNode
3182 {
3183 public:
3184     override void accept(ASTVisitor visitor) const
3185     {
3186         mixin(visitIfNotNull!(token, type));
3187     }
3188     /** */ Token token;
3189     /** */ Type type;
3190     mixin OpEquals;
3191 }
3192 
3193 ///
3194 final class TypeSuffix : ASTNode
3195 {
3196 public:
3197     override void accept(ASTVisitor visitor) const
3198     {
3199         mixin(visitIfNotNull!(type, low, high, delegateOrFunction, parameters,
3200             memberFunctionAttributes));
3201     }
3202 
3203     /** */ Token delegateOrFunction;
3204     /** */ Token star;
3205     /** */ bool array;
3206     /** */ Type type;
3207     /** */ ExpressionNode low;
3208     /** */ ExpressionNode high;
3209     /** */ Parameters parameters;
3210     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
3211     mixin OpEquals;
3212 }
3213 
3214 ///
3215 final class TypeidExpression : ExpressionNode
3216 {
3217 public:
3218     override void accept(ASTVisitor visitor) const
3219     {
3220         mixin(visitIfNotNull!(type, expression));
3221     }
3222     /** */ Type type;
3223     /** */ Expression expression;
3224     mixin OpEquals;
3225 }
3226 
3227 ///
3228 final class TypeofExpression : ExpressionNode
3229 {
3230 public:
3231     override void accept(ASTVisitor visitor) const
3232     {
3233         mixin(visitIfNotNull!(expression, return_));
3234     }
3235     /** */ Expression expression;
3236     /** */ Token return_;
3237     mixin OpEquals;
3238 }
3239 
3240 ///
3241 final class UnaryExpression : ExpressionNode
3242 {
3243 public:
3244     override void accept(ASTVisitor visitor) const
3245     {
3246         // TODO prefix, postfix, unary
3247         mixin(visitIfNotNull!(primaryExpression, newExpression, deleteExpression,
3248             castExpression, functionCallExpression, argumentList, unaryExpression,
3249             type, identifierOrTemplateInstance, assertExpression, indexExpression));
3250     }
3251 
3252     /** */ Type type;
3253     /** */ PrimaryExpression primaryExpression;
3254     /** */ Token prefix;
3255     /** */ Token suffix;
3256     /** */ UnaryExpression unaryExpression;
3257     /** */ NewExpression newExpression;
3258     /** */ DeleteExpression deleteExpression;
3259     /** */ CastExpression castExpression;
3260     /** */ FunctionCallExpression functionCallExpression;
3261     /** */ ArgumentList argumentList;
3262     /** */ IdentifierOrTemplateInstance identifierOrTemplateInstance;
3263     /** */ AssertExpression assertExpression;
3264     /** */ IndexExpression indexExpression;
3265     mixin OpEquals;
3266 }
3267 
3268 ///
3269 final class UnionDeclaration : ASTNode
3270 {
3271 public:
3272     override void accept(ASTVisitor visitor) const
3273     {
3274         mixin(visitIfNotNull!(name, templateParameters, constraint, structBody));
3275     }
3276 
3277     /** */ Token name;
3278     /** */ TemplateParameters templateParameters;
3279     /** */ Constraint constraint;
3280     /** */ StructBody structBody;
3281     /** */ string comment;
3282     mixin OpEquals;
3283 }
3284 
3285 ///
3286 final class Unittest : ASTNode
3287 {
3288 public:
3289     override void accept(ASTVisitor visitor) const
3290     {
3291         mixin(visitIfNotNull!(blockStatement));
3292     }
3293     /** */ BlockStatement blockStatement;
3294     /** */ string comment;
3295     mixin OpEquals;
3296 }
3297 
3298 ///
3299 final class VariableDeclaration : ASTNode
3300 {
3301 public:
3302     override void accept(ASTVisitor visitor) const
3303     {
3304         mixin(visitIfNotNull!(attributes, storageClasses, type, declarators, autoDeclaration));
3305     }
3306     /** */ Type type;
3307     /** */ Declarator[] declarators;
3308     /** */ StorageClass[] storageClasses;
3309     /** */ Attribute[] attributes;
3310     /** */ AutoDeclaration autoDeclaration;
3311     /** */ string comment;
3312     bool isEnum;
3313     mixin OpEquals;
3314 }
3315 
3316 ///
3317 final class Vector : ASTNode
3318 {
3319 public:
3320     override void accept(ASTVisitor visitor) const
3321     {
3322         mixin(visitIfNotNull!(type));
3323     }
3324     /** */ Type type;
3325     mixin OpEquals;
3326 }
3327 
3328 ///
3329 final class VersionCondition : ASTNode
3330 {
3331 public:
3332     override void accept(ASTVisitor visitor) const
3333     {
3334         mixin(visitIfNotNull!(token));
3335     }
3336     /** */ size_t versionIndex;
3337     /** */ Token token;
3338     mixin OpEquals;
3339 }
3340 
3341 ///
3342 final class VersionSpecification : ASTNode
3343 {
3344 public:
3345     override void accept(ASTVisitor visitor) const
3346     {
3347         mixin(visitIfNotNull!(token));
3348     }
3349     /** */ Token token;
3350     mixin OpEquals;
3351 }
3352 
3353 ///
3354 final class WhileStatement : ASTNode
3355 {
3356 public:
3357     override void accept(ASTVisitor visitor) const
3358     {
3359         mixin(visitIfNotNull!(expression, declarationOrStatement));
3360     }
3361 
3362     /** */ Expression expression;
3363     /** */ DeclarationOrStatement declarationOrStatement;
3364     /** */ size_t startIndex;
3365     mixin OpEquals;
3366 }
3367 
3368 ///
3369 final class WithStatement : ASTNode
3370 {
3371 public:
3372     override void accept(ASTVisitor visitor) const
3373     {
3374         mixin(visitIfNotNull!(expression, statementNoCaseNoDefault));
3375     }
3376 
3377     /** */ Expression expression;
3378     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
3379     mixin OpEquals;
3380 }
3381 
3382 ///
3383 final class XorExpression : ExpressionNode
3384 {
3385 public:
3386     override void accept(ASTVisitor visitor) const
3387     {
3388         mixin(visitIfNotNull!(left, right));
3389     }
3390     mixin BinaryExpressionBody;
3391     mixin OpEquals;
3392 }