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     mixin OpEquals;
1708 }
1709 
1710 ///
1711 final class FunctionCallExpression : ExpressionNode
1712 {
1713 public:
1714     override void accept(ASTVisitor visitor) const
1715     {
1716         mixin(visitIfNotNull!(type, unaryExpression, templateArguments, arguments));
1717     }
1718     /** */ Type type;
1719     /** */ UnaryExpression unaryExpression;
1720     /** */ TemplateArguments templateArguments;
1721     /** */ Arguments arguments;
1722     mixin OpEquals;
1723 }
1724 
1725 ///
1726 final class FunctionDeclaration : ASTNode
1727 {
1728 public:
1729     override void accept(ASTVisitor visitor) const
1730     {
1731         mixin(visitIfNotNull!(storageClasses, returnType, parameters,
1732             templateParameters, constraint, memberFunctionAttributes,
1733             functionBody));
1734     }
1735     /** */ bool hasAuto;
1736     /** */ bool hasRef;
1737     /** */ Type returnType;
1738     /** */ Token name;
1739     /** */ TemplateParameters templateParameters;
1740     /** */ Parameters parameters;
1741     /** */ Constraint constraint;
1742     /** */ FunctionBody functionBody;
1743     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
1744     /** */ string comment;
1745     /** */ Attribute[] attributes;
1746     /** */ StorageClass[] storageClasses;
1747     mixin OpEquals;
1748 }
1749 
1750 ///
1751 final class FunctionLiteralExpression : ExpressionNode
1752 {
1753 public:
1754     override void accept(ASTVisitor visitor) const
1755     {
1756         mixin(visitIfNotNull!(type, parameters, memberFunctionAttributes,
1757             functionBody));
1758     }
1759     /** */ IdType functionOrDelegate;
1760     /** */ Type type;
1761     /** */ Parameters parameters;
1762     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
1763     /** */ FunctionBody functionBody;
1764     mixin OpEquals;
1765 }
1766 
1767 ///
1768 final class GotoStatement : ASTNode
1769 {
1770 public:
1771     override void accept(ASTVisitor visitor) const
1772     {
1773         mixin(visitIfNotNull!(label, expression));
1774     }
1775     /** */ Expression expression;
1776     /** */ Token label;
1777     mixin OpEquals;
1778 }
1779 
1780 ///
1781 final class IdentifierChain : ASTNode
1782 {
1783 public:
1784     override void accept(ASTVisitor visitor) const
1785     {
1786         mixin(visitIfNotNull!(identifiers));
1787     }
1788     /** */ Token[] identifiers;
1789     mixin OpEquals;
1790 }
1791 
1792 ///
1793 final class IdentifierList : ASTNode
1794 {
1795 public:
1796     override void accept(ASTVisitor visitor) const
1797     {
1798         mixin(visitIfNotNull!(identifiers));
1799     }
1800     /** */ Token[] identifiers;
1801     mixin OpEquals;
1802 }
1803 
1804 ///
1805 final class IdentifierOrTemplateChain : ASTNode
1806 {
1807 public:
1808     override void accept(ASTVisitor visitor) const
1809     {
1810         mixin(visitIfNotNull!(identifiersOrTemplateInstances));
1811     }
1812 
1813     /** */ IdentifierOrTemplateInstance[] identifiersOrTemplateInstances;
1814     mixin OpEquals;
1815 }
1816 
1817 ///
1818 final class IdentifierOrTemplateInstance : ASTNode
1819 {
1820 public:
1821     override void accept(ASTVisitor visitor) const
1822     {
1823         mixin(visitIfNotNull!(identifier, templateInstance));
1824     }
1825 
1826     /** */ Token identifier;
1827     /** */ TemplateInstance templateInstance;
1828     mixin OpEquals;
1829 }
1830 
1831 ///
1832 final class IdentityExpression : ExpressionNode
1833 {
1834 public:
1835     override void accept(ASTVisitor visitor) const
1836     {
1837         mixin(visitIfNotNull!(left, right));
1838     }
1839     /** */ bool negated;
1840     mixin BinaryExpressionBody;
1841     mixin OpEquals;
1842 }
1843 
1844 ///
1845 final class IfStatement : ASTNode
1846 {
1847 public:
1848     override void accept(ASTVisitor visitor) const
1849     {
1850         mixin(visitIfNotNull!(identifier, type, expression, thenStatement,
1851             elseStatement));
1852     }
1853     /** */ Token identifier;
1854     /** */ Type type;
1855     /** */ Expression expression;
1856     /** */ DeclarationOrStatement thenStatement;
1857     /** */ DeclarationOrStatement elseStatement;
1858     /** */ size_t startIndex;
1859     /** */ size_t line;
1860     /** */ size_t column;
1861     mixin OpEquals;
1862 }
1863 
1864 ///
1865 final class ImportBind : ASTNode
1866 {
1867 public:
1868     override void accept(ASTVisitor visitor) const
1869     {
1870         mixin(visitIfNotNull!(left, right));
1871     }
1872     /** */ Token left;
1873     /** */ Token right;
1874     mixin OpEquals;
1875 }
1876 
1877 ///
1878 final class ImportBindings : ASTNode
1879 {
1880 public:
1881     override void accept(ASTVisitor visitor) const
1882     {
1883         mixin(visitIfNotNull!(singleImport, importBinds));
1884     }
1885     /** */ SingleImport singleImport;
1886     /** */ ImportBind[] importBinds;
1887     mixin OpEquals;
1888 }
1889 
1890 ///
1891 final class ImportDeclaration : ASTNode
1892 {
1893 public:
1894     override void accept(ASTVisitor visitor) const
1895     {
1896         mixin(visitIfNotNull!(singleImports, importBindings));
1897     }
1898     /** */ string comment;
1899     size_t line;
1900     /** */ SingleImport[] singleImports;
1901     /** */ ImportBindings importBindings;
1902     mixin OpEquals;
1903 }
1904 
1905 ///
1906 final class ImportExpression : ExpressionNode
1907 {
1908 public:
1909     override void accept(ASTVisitor visitor) const
1910     {
1911         mixin(visitIfNotNull!(assignExpression));
1912     }
1913     /** */ ExpressionNode assignExpression;
1914     mixin OpEquals;
1915 }
1916 
1917 ///
1918 final class Index : ASTNode
1919 {
1920 public:
1921     override void accept(ASTVisitor visitor) const
1922     {
1923         mixin(visitIfNotNull!(low, high));
1924     }
1925     /** */ ExpressionNode low;
1926     /** */ ExpressionNode high;
1927     mixin OpEquals;
1928 }
1929 
1930 ///
1931 final class IndexExpression : ExpressionNode
1932 {
1933 public:
1934     override void accept(ASTVisitor visitor) const
1935     {
1936         mixin(visitIfNotNull!(unaryExpression, indexes));
1937     }
1938     /** */ UnaryExpression unaryExpression;
1939     /** */ Index[] indexes;
1940     mixin OpEquals;
1941 }
1942 
1943 ///
1944 final class InExpression : ExpressionNode
1945 {
1946 public:
1947     override void accept(ASTVisitor visitor) const
1948     {
1949         mixin(visitIfNotNull!(left, right));
1950     }
1951     mixin BinaryExpressionBody;
1952     bool negated;
1953     mixin OpEquals;
1954 }
1955 
1956 ///
1957 final class InStatement : ASTNode
1958 {
1959 public:
1960     override void accept(ASTVisitor visitor) const
1961     {
1962         mixin(visitIfNotNull!(blockStatement));
1963     }
1964     /** */ size_t inTokenLocation;
1965     /** */ BlockStatement blockStatement;
1966     /** */ Expression expression;
1967     mixin OpEquals;
1968 }
1969 
1970 ///
1971 final class Initialize : ASTNode
1972 {
1973 public:
1974     override void accept(ASTVisitor visitor) const
1975     {
1976         mixin(visitIfNotNull!(statementNoCaseNoDefault));
1977     }
1978     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
1979     mixin OpEquals;
1980 }
1981 
1982 ///
1983 final class Initializer : ASTNode
1984 {
1985 public:
1986     override void accept(ASTVisitor visitor) const
1987     {
1988         mixin(visitIfNotNull!(nonVoidInitializer));
1989     }
1990     /** */ NonVoidInitializer nonVoidInitializer;
1991     mixin OpEquals;
1992 }
1993 
1994 ///
1995 final class InterfaceDeclaration : ASTNode
1996 {
1997 public:
1998     override void accept(ASTVisitor visitor) const
1999     {
2000         mixin(visitIfNotNull!(templateParameters, constraint, baseClassList,
2001             structBody));
2002     }
2003     /** */ Token name;
2004     /** */ TemplateParameters templateParameters;
2005     /** */ Constraint constraint;
2006     /** */ BaseClassList baseClassList;
2007     /** */ StructBody structBody;
2008     /** */ string comment;
2009     mixin OpEquals;
2010 }
2011 
2012 ///
2013 final class Invariant : ASTNode
2014 {
2015 public:
2016     override void accept(ASTVisitor visitor) const
2017     {
2018         mixin(visitIfNotNull!(blockStatement));
2019     }
2020     /** */ BlockStatement blockStatement;
2021     /** */ string comment;
2022     size_t line;
2023     size_t index;
2024     mixin OpEquals;
2025 }
2026 
2027 ///
2028 final class IsExpression : ExpressionNode
2029 {
2030 public:
2031     override void accept(ASTVisitor visitor) const
2032     {
2033         mixin(visitIfNotNull!(type, identifier, typeSpecialization,
2034             templateParameterList));
2035     }
2036     /** */ Type type;
2037     /** */ Token identifier;
2038     /** */ TypeSpecialization typeSpecialization;
2039     /** */ TemplateParameterList templateParameterList;
2040     /** */ IdType equalsOrColon;
2041     mixin OpEquals;
2042 }
2043 
2044 ///
2045 final class KeyValuePair : ASTNode
2046 {
2047 public:
2048     override void accept(ASTVisitor visitor) const
2049     {
2050         mixin(visitIfNotNull!(key, value));
2051     }
2052     /** */ ExpressionNode key;
2053     /** */ ExpressionNode value;
2054     mixin OpEquals;
2055 }
2056 
2057 ///
2058 final class KeyValuePairs : ASTNode
2059 {
2060 public:
2061     override void accept(ASTVisitor visitor) const
2062     {
2063         mixin(visitIfNotNull!(keyValuePairs));
2064     }
2065     /** */ KeyValuePair[] keyValuePairs;
2066     mixin OpEquals;
2067 }
2068 
2069 ///
2070 final class LabeledStatement : ASTNode
2071 {
2072 public:
2073     override void accept(ASTVisitor visitor) const
2074     {
2075         mixin(visitIfNotNull!(identifier, declarationOrStatement));
2076     }
2077     Token identifier;
2078     /** */ DeclarationOrStatement declarationOrStatement;
2079     mixin OpEquals;
2080 }
2081 
2082 ///
2083 final class LambdaExpression : ExpressionNode
2084 {
2085 public:
2086     override void accept(ASTVisitor visitor) const
2087     {
2088         mixin(visitIfNotNull!(identifier, returnType, parameters, functionAttributes,
2089             assignExpression));
2090     }
2091     /** */ IdType functionType;
2092     /** */ Token identifier;
2093     /** */ Parameters parameters;
2094     /** */ FunctionAttribute[] functionAttributes;
2095     /** */ ExpressionNode assignExpression;
2096     /** */ Type returnType;
2097     mixin OpEquals;
2098 }
2099 
2100 ///
2101 final class LastCatch : ASTNode
2102 {
2103 public:
2104     override void accept(ASTVisitor visitor) const
2105     {
2106         mixin(visitIfNotNull!(statementNoCaseNoDefault));
2107     }
2108     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
2109     size_t line;
2110     size_t column;
2111     mixin OpEquals;
2112 }
2113 
2114 ///
2115 final class LinkageAttribute : ASTNode
2116 {
2117 public:
2118     override void accept(ASTVisitor visitor) const
2119     {
2120         mixin(visitIfNotNull!(identifier, identifierChain));
2121     }
2122     /** */ Token identifier;
2123     /** */ bool hasPlusPlus;
2124     /** */ IdentifierChain identifierChain;
2125     mixin OpEquals;
2126 }
2127 
2128 ///
2129 final class MemberFunctionAttribute : ASTNode
2130 {
2131 public:
2132     override void accept(ASTVisitor visitor) const
2133     {
2134         mixin(visitIfNotNull!(atAttribute));
2135     }
2136     /** */ IdType tokenType;
2137     /** */ AtAttribute atAttribute;
2138     mixin OpEquals;
2139 }
2140 
2141 ///
2142 final class MixinDeclaration : ASTNode
2143 {
2144 public:
2145     override void accept(ASTVisitor visitor) const
2146     {
2147         mixin(visitIfNotNull!(mixinExpression, templateMixinExpression));
2148 	foreach(decl; trivialDeclarations) {
2149 		decl.accept(visitor);
2150 	}
2151     }
2152     /** */ MixinExpression mixinExpression;
2153     /** */ TemplateMixinExpression templateMixinExpression;
2154 
2155     Declaration[] trivialDeclarations;
2156 
2157     mixin OpEquals;
2158 }
2159 
2160 ///
2161 final class MixinExpression : ExpressionNode
2162 {
2163 public:
2164     override void accept(ASTVisitor visitor) const
2165     {
2166         mixin(visitIfNotNull!(assignExpression));
2167     }
2168     /** */ ExpressionNode assignExpression;
2169     mixin OpEquals;
2170 }
2171 
2172 ///
2173 final class MixinTemplateDeclaration : ASTNode
2174 {
2175 public:
2176     override void accept(ASTVisitor visitor) const
2177     {
2178         mixin(visitIfNotNull!(templateDeclaration));
2179     }
2180     /** */ TemplateDeclaration templateDeclaration;
2181     mixin OpEquals;
2182 }
2183 
2184 ///
2185 final class MixinTemplateName : ASTNode
2186 {
2187 public:
2188     override void accept(ASTVisitor visitor) const
2189     {
2190         mixin(visitIfNotNull!(symbol, typeofExpression, identifierOrTemplateChain));
2191     }
2192     /** */ Symbol symbol;
2193     /** */ IdentifierOrTemplateChain identifierOrTemplateChain;
2194     /** */ TypeofExpression typeofExpression;
2195     mixin OpEquals;
2196 }
2197 
2198 ///
2199 final class Module : ASTNode
2200 {
2201 public:
2202     override void accept(ASTVisitor visitor) const
2203     {
2204         mixin(visitIfNotNull!(scriptLine, moduleDeclaration, declarations));
2205     }
2206     /** */ Token scriptLine;
2207     /** */ ModuleDeclaration moduleDeclaration;
2208     /** */ Declaration[] declarations;
2209     mixin OpEquals;
2210 }
2211 
2212 ///
2213 final class ModuleDeclaration : ASTNode
2214 {
2215 public:
2216     override void accept(ASTVisitor visitor) const
2217     {
2218         mixin(visitIfNotNull!(moduleName, deprecated_));
2219     }
2220     /** */ Deprecated deprecated_;
2221     /** */ IdentifierChain moduleName;
2222     /** */ size_t startLocation;
2223     /** */ size_t endLocation;
2224     /** */ string comment;
2225     mixin OpEquals;
2226 }
2227 
2228 
2229 ///
2230 final class MulExpression : ExpressionNode
2231 {
2232 public:
2233     override void accept(ASTVisitor visitor) const
2234     {
2235         mixin(visitIfNotNull!(left, right));
2236     }
2237     /** */ IdType operator;
2238     mixin BinaryExpressionBody;
2239     mixin OpEquals;
2240 }
2241 
2242 ///
2243 final class NewAnonClassExpression : ExpressionNode
2244 {
2245 public:
2246     override void accept(ASTVisitor visitor) const
2247     {
2248         mixin(visitIfNotNull!(allocatorArguments, constructorArguments,
2249             baseClassList, structBody));
2250     }
2251     /** */ Arguments allocatorArguments;
2252     /** */ Arguments constructorArguments;
2253     /** */ BaseClassList baseClassList;
2254     /** */ StructBody structBody;
2255     mixin OpEquals;
2256 }
2257 
2258 ///
2259 final class NewExpression : ExpressionNode
2260 {
2261 public:
2262     override void accept(ASTVisitor visitor) const
2263     {
2264         mixin(visitIfNotNull!(newAnonClassExpression, type, arguments,
2265             assignExpression));
2266     }
2267     /** */ Type type;
2268     /** */ NewAnonClassExpression newAnonClassExpression;
2269     /** */ Arguments arguments;
2270     /** */ ExpressionNode assignExpression;
2271     mixin OpEquals;
2272 }
2273 
2274 
2275 ///
2276 final class StatementNoCaseNoDefault : ASTNode
2277 {
2278 public:
2279     override void accept(ASTVisitor visitor) const
2280     {
2281         mixin(visitIfNotNull!(labeledStatement, blockStatement, ifStatement,
2282             whileStatement, doStatement, forStatement, foreachStatement,
2283             switchStatement, finalSwitchStatement, continueStatement,
2284             breakStatement, returnStatement, gotoStatement, withStatement,
2285             synchronizedStatement, tryStatement, throwStatement,
2286             scopeGuardStatement, asmStatement, conditionalStatement,
2287             staticAssertStatement, versionSpecification, debugSpecification,
2288             expressionStatement));
2289     }
2290     /** */ LabeledStatement labeledStatement;
2291     /** */ BlockStatement blockStatement;
2292     /** */ IfStatement ifStatement;
2293     /** */ WhileStatement whileStatement;
2294     /** */ DoStatement doStatement;
2295     /** */ ForStatement forStatement;
2296     /** */ ForeachStatement foreachStatement;
2297     /** */ SwitchStatement switchStatement;
2298     /** */ FinalSwitchStatement finalSwitchStatement;
2299     /** */ ContinueStatement continueStatement;
2300     /** */ BreakStatement breakStatement;
2301     /** */ ReturnStatement returnStatement;
2302     /** */ GotoStatement gotoStatement;
2303     /** */ WithStatement withStatement;
2304     /** */ SynchronizedStatement synchronizedStatement;
2305     /** */ TryStatement tryStatement;
2306     /** */ ThrowStatement throwStatement;
2307     /** */ ScopeGuardStatement scopeGuardStatement;
2308     /** */ AsmStatement asmStatement;
2309     /** */ ConditionalStatement conditionalStatement;
2310     /** */ StaticAssertStatement staticAssertStatement;
2311     /** */ StaticForeachStatement staticForeachStatement;
2312     /** */ VersionSpecification versionSpecification;
2313     /** */ DebugSpecification debugSpecification;
2314     /** */ ExpressionStatement expressionStatement;
2315     /** */ size_t startLocation;
2316     /** */ size_t endLocation;
2317     mixin OpEquals;
2318 }
2319 
2320 ///
2321 final class NonVoidInitializer : ASTNode
2322 {
2323 public:
2324     override void accept(ASTVisitor visitor) const
2325     {
2326         mixin(visitIfNotNull!(assignExpression, arrayInitializer,
2327             structInitializer));
2328     }
2329     /** */ ExpressionNode assignExpression;
2330     /** */ ArrayInitializer arrayInitializer;
2331     /** */ StructInitializer structInitializer;
2332 
2333     mixin OpEquals;
2334 }
2335 
2336 ///
2337 final class Operands : ASTNode
2338 {
2339 public:
2340     override void accept(ASTVisitor visitor) const
2341     {
2342         mixin(visitIfNotNull!(operands));
2343     }
2344     /** */ ExpressionNode[] operands;
2345     mixin OpEquals;
2346 }
2347 
2348 ///
2349 final class OrExpression : ExpressionNode
2350 {
2351 public:
2352     override void accept(ASTVisitor visitor) const
2353     {
2354         mixin(visitIfNotNull!(left, right));
2355     }
2356     mixin BinaryExpressionBody;
2357     mixin OpEquals;
2358 }
2359 
2360 ///
2361 final class OrOrExpression : ExpressionNode
2362 {
2363 public:
2364     override void accept(ASTVisitor visitor) const
2365     {
2366         mixin(visitIfNotNull!(left, right));
2367     }
2368     mixin BinaryExpressionBody;
2369     mixin OpEquals;
2370 }
2371 
2372 ///
2373 final class OutStatement : ASTNode
2374 {
2375 public:
2376     override void accept(ASTVisitor visitor) const
2377     {
2378         mixin(visitIfNotNull!(parameter, blockStatement));
2379     }
2380     /** */ size_t outTokenLocation;
2381     /** */ Token parameter;
2382     /** */ BlockStatement blockStatement;
2383     Expression expression;
2384     mixin OpEquals;
2385 }
2386 
2387 ///
2388 final class Parameter : ASTNode
2389 {
2390 public:
2391     override void accept(ASTVisitor visitor) const
2392     {
2393         mixin(visitIfNotNull!(type, name, default_));
2394     }
2395 
2396     /** */ IdType[] parameterAttributes;
2397     /** */ Type type;
2398     /** */ Token name;
2399     /** */ bool vararg;
2400     /** */ ExpressionNode default_;
2401     /** */ TypeSuffix[] cstyle;
2402     AtAttribute[] atAttributes;
2403 
2404     mixin OpEquals;
2405 }
2406 
2407 ///
2408 final class Parameters : ASTNode
2409 {
2410 public:
2411     override void accept(ASTVisitor visitor) const
2412     {
2413         mixin(visitIfNotNull!(parameters));
2414     }
2415 
2416     /** */ Parameter[] parameters;
2417     /** */ bool hasVarargs;
2418     mixin OpEquals;
2419 }
2420 
2421 ///
2422 final class Postblit : ASTNode
2423 {
2424 public:
2425     override void accept(ASTVisitor visitor) const
2426     {
2427         mixin(visitIfNotNull!(functionBody));
2428     }
2429     /** */ FunctionBody functionBody;
2430     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
2431     /** */ string comment;
2432     size_t line;
2433     mixin OpEquals;
2434 }
2435 
2436 ///
2437 final class PowExpression : ExpressionNode
2438 {
2439 public:
2440     override void accept(ASTVisitor visitor) const
2441     {
2442         mixin(visitIfNotNull!(left, right));
2443     }
2444     mixin BinaryExpressionBody;
2445     mixin OpEquals;
2446 }
2447 
2448 ///
2449 final class PragmaDeclaration : ASTNode
2450 {
2451 public:
2452     override void accept(ASTVisitor visitor) const
2453     {
2454         mixin(visitIfNotNull!(pragmaExpression));
2455     }
2456     /** */ PragmaExpression pragmaExpression;
2457     mixin OpEquals;
2458 }
2459 
2460 ///
2461 final class PragmaExpression : ExpressionNode
2462 {
2463 public:
2464     override void accept(ASTVisitor visitor) const
2465     {
2466         mixin(visitIfNotNull!(identifier, argumentList));
2467     }
2468     /** */ Token identifier;
2469     /** */ ArgumentList argumentList;
2470     mixin OpEquals;
2471 }
2472 
2473 ///
2474 final class PrimaryExpression : ExpressionNode
2475 {
2476 public:
2477     override void accept(ASTVisitor visitor) const
2478     {
2479         mixin(visitIfNotNull!(basicType, typeConstructor, type, primary,
2480             typeofExpression, typeidExpression, arrayLiteral, assocArrayLiteral,
2481             expression, dot, identifierOrTemplateInstance, isExpression,
2482             lambdaExpression, functionLiteralExpression, traitsExpression,
2483             mixinExpression, importExpression, vector, arguments));
2484     }
2485     /** */ Token dot;
2486     /** */ Token primary;
2487     /** */ IdentifierOrTemplateInstance identifierOrTemplateInstance;
2488     /** */ Token basicType;
2489     /** */ TypeofExpression typeofExpression;
2490     /** */ TypeidExpression typeidExpression;
2491     /** */ ArrayLiteral arrayLiteral;
2492     /** */ AssocArrayLiteral assocArrayLiteral;
2493     /** */ Expression expression;
2494     /** */ IsExpression isExpression;
2495     /** */ LambdaExpression lambdaExpression;
2496     /** */ FunctionLiteralExpression functionLiteralExpression;
2497     /** */ TraitsExpression traitsExpression;
2498     /** */ MixinExpression mixinExpression;
2499     /** */ ImportExpression importExpression;
2500     /** */ Vector vector;
2501     /** */ Type type;
2502     /** */ Token typeConstructor;
2503     /** */ Arguments arguments;
2504     mixin OpEquals;
2505 }
2506 
2507 ///
2508 final class Register : ASTNode
2509 {
2510 public:
2511     override void accept(ASTVisitor visitor) const
2512     {
2513         mixin(visitIfNotNull!(identifier, intLiteral));
2514     }
2515     /** */ Token identifier;
2516     /** */ Token intLiteral;
2517     /** */ bool hasIntegerLiteral;
2518     mixin OpEquals;
2519 }
2520 
2521 ///
2522 final class RelExpression : ExpressionNode
2523 {
2524 public:
2525     override void accept(ASTVisitor visitor) const
2526     {
2527         mixin(visitIfNotNull!(left, right));
2528     }
2529     /** */ IdType operator;
2530     mixin BinaryExpressionBody;
2531     mixin OpEquals;
2532 }
2533 
2534 ///
2535 final class ReturnStatement : ASTNode
2536 {
2537 public:
2538     override void accept(ASTVisitor visitor) const
2539     {
2540         mixin(visitIfNotNull!(expression));
2541     }
2542     /** */ Expression expression;
2543     /** */ size_t startLocation;
2544     /** */ size_t endLocation;
2545     mixin OpEquals;
2546 }
2547 
2548 ///
2549 final class ScopeGuardStatement : ASTNode
2550 {
2551 public:
2552     override void accept(ASTVisitor visitor) const
2553     {
2554         mixin(visitIfNotNull!(identifier, statementNoCaseNoDefault));
2555     }
2556     /** */ Token identifier;
2557     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
2558     mixin OpEquals;
2559 }
2560 
2561 ///
2562 final class SharedStaticConstructor : ASTNode
2563 {
2564 public:
2565     override void accept(ASTVisitor visitor) const
2566     {
2567         mixin(visitIfNotNull!(functionBody));
2568     }
2569     /** */ FunctionBody functionBody;
2570     /** */ size_t location;
2571     /** */ string comment;
2572     mixin OpEquals;
2573 }
2574 
2575 ///
2576 final class SharedStaticDestructor : ASTNode
2577 {
2578 public:
2579     override void accept(ASTVisitor visitor) const
2580     {
2581         mixin(visitIfNotNull!(functionBody));
2582     }
2583     /** */ FunctionBody functionBody;
2584     /** */ size_t location;
2585     /** */ string comment;
2586     mixin OpEquals;
2587 }
2588 
2589 ///
2590 final class ShiftExpression : ExpressionNode
2591 {
2592 public:
2593     override void accept(ASTVisitor visitor) const
2594     {
2595         mixin(visitIfNotNull!(left, right));
2596     }
2597     /** */ IdType operator;
2598     mixin BinaryExpressionBody;
2599     mixin OpEquals;
2600 }
2601 
2602 ///
2603 final class SingleImport : ASTNode
2604 {
2605 public:
2606     override void accept(ASTVisitor visitor) const
2607     {
2608         mixin(visitIfNotNull!(rename, identifierChain));
2609     }
2610     /** */ Token rename;
2611     /** */ IdentifierChain identifierChain;
2612     mixin OpEquals;
2613 }
2614 
2615 ///
2616 final class Statement : ASTNode
2617 {
2618 public:
2619     override void accept(ASTVisitor visitor) const
2620     {
2621         mixin(visitIfNotNull!(statementNoCaseNoDefault, caseStatement,
2622             caseRangeStatement, defaultStatement));
2623     }
2624     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
2625     /** */ CaseStatement caseStatement;
2626     /** */ CaseRangeStatement caseRangeStatement;
2627     /** */ DefaultStatement defaultStatement;
2628     mixin OpEquals;
2629 }
2630 
2631 ///
2632 final class StaticAssertDeclaration : ASTNode
2633 {
2634 public:
2635     override void accept(ASTVisitor visitor) const
2636     {
2637         mixin(visitIfNotNull!(staticAssertStatement));
2638     }
2639     /** */ StaticAssertStatement staticAssertStatement;
2640     mixin OpEquals;
2641 }
2642 
2643 final class StaticForeachDeclaration : ASTNode
2644 {
2645 public:
2646     override void accept(ASTVisitor visitor) const
2647     {
2648         mixin(visitIfNotNull!(declarations));
2649     }
2650     /** */ Declaration[] declarations;
2651 }
2652 
2653 final class StaticForeachStatement : ASTNode
2654 {
2655 	// FIXME
2656     override void accept(ASTVisitor visitor) const
2657     {
2658     }
2659 }
2660 
2661 ///
2662 final class StaticAssertStatement : ASTNode
2663 {
2664 public:
2665     override void accept(ASTVisitor visitor) const
2666     {
2667         mixin(visitIfNotNull!(assertExpression));
2668     }
2669     /** */ AssertExpression assertExpression;
2670     mixin OpEquals;
2671 }
2672 
2673 ///
2674 final class StaticConstructor : ASTNode
2675 {
2676 public:
2677     override void accept(ASTVisitor visitor) const
2678     {
2679         mixin(visitIfNotNull!(functionBody));
2680     }
2681     /** */ FunctionBody functionBody;
2682     /** */ size_t location;
2683     /** */ size_t line;
2684     /** */ size_t column;
2685     /** */ string comment;
2686     mixin OpEquals;
2687 }
2688 
2689 ///
2690 final class StaticDestructor : ASTNode
2691 {
2692 public:
2693     override void accept(ASTVisitor visitor) const
2694     {
2695         mixin(visitIfNotNull!(functionBody));
2696     }
2697     /** */ FunctionBody functionBody;
2698     /** */ size_t location;
2699     /** */ size_t line;
2700     /** */ size_t column;
2701     /** */ string comment;
2702     mixin OpEquals;
2703 }
2704 
2705 ///
2706 final class StaticIfCondition : ASTNode
2707 {
2708 public:
2709     override void accept(ASTVisitor visitor) const
2710     {
2711         mixin(visitIfNotNull!(assignExpression));
2712     }
2713     /** */ ExpressionNode assignExpression;
2714     mixin OpEquals;
2715 }
2716 
2717 ///
2718 final class StorageClass : ASTNode
2719 {
2720 public:
2721     override void accept(ASTVisitor visitor) const
2722     {
2723         mixin(visitIfNotNull!(token, alignAttribute, linkageAttribute,
2724             atAttribute, deprecated_));
2725     }
2726     /** */ AlignAttribute alignAttribute;
2727     /** */ LinkageAttribute linkageAttribute;
2728     /** */ AtAttribute atAttribute;
2729     /** */ Deprecated deprecated_;
2730     /** */ Token token;
2731     mixin OpEquals;
2732 }
2733 
2734 ///
2735 final class StructBody : ASTNode
2736 {
2737 public:
2738     override void accept(ASTVisitor visitor) const
2739     {
2740         mixin(visitIfNotNull!(declarations));
2741     }
2742 
2743     /**
2744      * Byte position of the opening brace
2745      */
2746     size_t startLocation;
2747 
2748     /**
2749      * Byte position of the closing brace
2750      */
2751     size_t endLocation;
2752     /** */ Declaration[] declarations;
2753     mixin OpEquals;
2754 }
2755 
2756 ///
2757 final class StructDeclaration : ASTNode
2758 {
2759 public:
2760     override void accept(ASTVisitor visitor) const
2761     {
2762         mixin(visitIfNotNull!(templateParameters, constraint, structBody));
2763     }
2764     /** */ Token name;
2765     /** */ TemplateParameters templateParameters;
2766     /** */ Constraint constraint;
2767     /** */ StructBody structBody;
2768     /** */ string comment;
2769     mixin OpEquals;
2770 }
2771 
2772 ///
2773 final class StructInitializer : ASTNode
2774 {
2775 public:
2776     override void accept(ASTVisitor visitor) const
2777     {
2778         mixin(visitIfNotNull!(structMemberInitializers));
2779     }
2780     /** */ StructMemberInitializers structMemberInitializers;
2781     /** */ size_t startLocation;
2782     /** */ size_t endLocation;
2783     mixin OpEquals;
2784 }
2785 
2786 ///
2787 final class StructMemberInitializer : ASTNode
2788 {
2789 public:
2790     override void accept(ASTVisitor visitor) const
2791     {
2792         mixin(visitIfNotNull!(identifier, nonVoidInitializer));
2793     }
2794     /** */ Token identifier;
2795     /** */ NonVoidInitializer nonVoidInitializer;
2796     mixin OpEquals;
2797 }
2798 
2799 ///
2800 final class StructMemberInitializers : ASTNode
2801 {
2802 public:
2803     override void accept(ASTVisitor visitor) const
2804     {
2805         mixin(visitIfNotNull!(structMemberInitializers));
2806     }
2807     /** */ StructMemberInitializer[] structMemberInitializers;
2808     mixin OpEquals;
2809 }
2810 
2811 ///
2812 final class SwitchStatement : ASTNode
2813 {
2814 public:
2815     override void accept(ASTVisitor visitor) const
2816     {
2817         mixin(visitIfNotNull!(expression, statement));
2818     }
2819     /** */ Expression expression;
2820     /** */ Statement statement;
2821     mixin OpEquals;
2822 }
2823 
2824 ///
2825 final class Symbol : ASTNode
2826 {
2827 public:
2828     override void accept(ASTVisitor visitor) const
2829     {
2830         mixin(visitIfNotNull!(identifierOrTemplateChain));
2831     }
2832 
2833     /** */ IdentifierOrTemplateChain identifierOrTemplateChain;
2834     /** */ bool dot;
2835     mixin OpEquals;
2836 }
2837 
2838 ///
2839 final class SynchronizedStatement : ASTNode
2840 {
2841 public:
2842     override void accept(ASTVisitor visitor) const
2843     {
2844         mixin(visitIfNotNull!(expression, statementNoCaseNoDefault));
2845     }
2846     /** */ Expression expression;
2847     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
2848     mixin OpEquals;
2849 }
2850 
2851 ///
2852 final class TemplateAliasParameter : ASTNode
2853 {
2854 public:
2855     override void accept(ASTVisitor visitor) const
2856     {
2857         mixin(visitIfNotNull!(type, identifier, colonType, colonExpression,
2858             assignType, assignExpression));
2859     }
2860     /** */ Type type;
2861     /** */ Token identifier;
2862     /** */ Type colonType;
2863     /** */ ExpressionNode colonExpression;
2864     /** */ Type assignType;
2865     /** */ ExpressionNode assignExpression;
2866     mixin OpEquals;
2867 }
2868 
2869 ///
2870 final class TemplateArgument : ASTNode
2871 {
2872 public:
2873     override void accept(ASTVisitor visitor) const
2874     {
2875         mixin(visitIfNotNull!(type, assignExpression));
2876     }
2877     /** */ Type type;
2878     /** */ ExpressionNode assignExpression;
2879     mixin OpEquals;
2880 }
2881 
2882 ///
2883 final class TemplateArgumentList : ASTNode
2884 {
2885 public:
2886     override void accept(ASTVisitor visitor) const
2887     {
2888         mixin(visitIfNotNull!(items));
2889     }
2890     /** */ TemplateArgument[] items;
2891     mixin OpEquals;
2892 }
2893 
2894 ///
2895 final class TemplateArguments : ASTNode
2896 {
2897 public:
2898     override void accept(ASTVisitor visitor) const
2899     {
2900         mixin(visitIfNotNull!(templateArgumentList, templateSingleArgument));
2901     }
2902     /** */ TemplateArgumentList templateArgumentList;
2903     /** */ TemplateSingleArgument templateSingleArgument;
2904     mixin OpEquals;
2905 }
2906 
2907 ///
2908 final class TemplateDeclaration : ASTNode
2909 {
2910 public:
2911     override void accept(ASTVisitor visitor) const
2912     {
2913         mixin(visitIfNotNull!(name, templateParameters, constraint,
2914             declarations));
2915     }
2916     /** */ Token name;
2917     /** */ TemplateParameters templateParameters;
2918     /** */ Constraint constraint;
2919     /** */ Declaration[] declarations;
2920     /** */ string comment;
2921     /**
2922      * Byte position of the opening brace
2923      */
2924     size_t startLocation;
2925 
2926     /**
2927      * Byte position of the closing brace
2928      */
2929     size_t endLocation;
2930     mixin OpEquals;
2931 }
2932 
2933 ///
2934 final class TemplateInstance : ASTNode
2935 {
2936 public:
2937     override void accept(ASTVisitor visitor) const
2938     {
2939         mixin(visitIfNotNull!(identifier, templateArguments));
2940     }
2941     /** */ Token identifier;
2942     /** */ TemplateArguments templateArguments;
2943     mixin OpEquals;
2944 }
2945 
2946 ///
2947 final class TemplateMixinExpression : ExpressionNode
2948 {
2949 public:
2950     override void accept(ASTVisitor visitor) const
2951     {
2952         mixin(visitIfNotNull!(identifier, templateArguments, mixinTemplateName));
2953     }
2954     /** */ Token identifier;
2955     /** */ TemplateArguments templateArguments;
2956     /** */ MixinTemplateName mixinTemplateName;
2957     /** */ string comment;
2958     size_t line;
2959     mixin OpEquals;
2960 }
2961 
2962 ///
2963 final class TemplateParameter : ASTNode
2964 {
2965 public:
2966     override void accept(ASTVisitor visitor) const
2967     {
2968         mixin(visitIfNotNull!(templateTypeParameter, templateValueParameter,
2969             templateAliasParameter, templateTupleParameter,
2970             templateThisParameter));
2971     }
2972     /** */ TemplateTypeParameter templateTypeParameter;
2973     /** */ TemplateValueParameter templateValueParameter;
2974     /** */ TemplateAliasParameter templateAliasParameter;
2975     /** */ TemplateTupleParameter templateTupleParameter;
2976     /** */ TemplateThisParameter templateThisParameter;
2977     mixin OpEquals;
2978 }
2979 
2980 ///
2981 final class TemplateParameterList : ASTNode
2982 {
2983 public:
2984     override void accept(ASTVisitor visitor) const
2985     {
2986         mixin(visitIfNotNull!(items));
2987     }
2988     /** */ TemplateParameter[] items;
2989     mixin OpEquals;
2990 }
2991 
2992 ///
2993 final class TemplateParameters : ASTNode
2994 {
2995 public:
2996     override void accept(ASTVisitor visitor) const
2997     {
2998         mixin(visitIfNotNull!(templateParameterList));
2999     }
3000     /** */ TemplateParameterList templateParameterList;
3001     mixin OpEquals;
3002 }
3003 
3004 ///
3005 final class TemplateSingleArgument : ASTNode
3006 {
3007 public:
3008     override void accept(ASTVisitor visitor) const
3009     {
3010         mixin(visitIfNotNull!(token));
3011     }
3012     /** */ Token token;
3013     mixin OpEquals;
3014 }
3015 
3016 ///
3017 final class TemplateThisParameter : ASTNode
3018 {
3019 public:
3020     override void accept(ASTVisitor visitor) const
3021     {
3022         mixin(visitIfNotNull!(templateTypeParameter));
3023     }
3024     /** */ TemplateTypeParameter templateTypeParameter;
3025     mixin OpEquals;
3026 }
3027 
3028 ///
3029 final class TemplateTupleParameter : ASTNode
3030 {
3031 public:
3032     override void accept(ASTVisitor visitor) const
3033     {
3034         mixin(visitIfNotNull!(identifier));
3035     }
3036     /** */ Token identifier;
3037     mixin OpEquals;
3038 }
3039 
3040 ///
3041 final class TemplateTypeParameter : ASTNode
3042 {
3043 public:
3044     override void accept(ASTVisitor visitor) const
3045     {
3046         mixin(visitIfNotNull!(identifier, colonType, assignType));
3047     }
3048     /** */ Token identifier;
3049     /** */ Type colonType;
3050     /** */ Type assignType;
3051     mixin OpEquals;
3052 }
3053 
3054 ///
3055 final class TemplateValueParameter : ASTNode
3056 {
3057 public:
3058     override void accept(ASTVisitor visitor) const
3059     {
3060         mixin(visitIfNotNull!(type, identifier, assignExpression,
3061             templateValueParameterDefault));
3062     }
3063     /** */ Type type;
3064     /** */ Token identifier;
3065     /** */ ExpressionNode assignExpression;
3066     /** */ TemplateValueParameterDefault templateValueParameterDefault;
3067     mixin OpEquals;
3068 }
3069 
3070 ///
3071 final class TemplateValueParameterDefault : ASTNode
3072 {
3073 public:
3074     override void accept(ASTVisitor visitor) const
3075     {
3076         mixin(visitIfNotNull!(token, assignExpression));
3077     }
3078     /** */ ExpressionNode assignExpression;
3079     /** */ Token token;
3080     mixin OpEquals;
3081 }
3082 
3083 ///
3084 final class TernaryExpression : ExpressionNode
3085 {
3086 public:
3087     override void accept(ASTVisitor visitor) const
3088     {
3089         mixin(visitIfNotNull!(orOrExpression, expression, ternaryExpression));
3090     }
3091     /** */ ExpressionNode orOrExpression;
3092     /** */ ExpressionNode expression;
3093     /** */ ExpressionNode ternaryExpression;
3094     /// Store this so that we know where the ':' is
3095     Token colon;
3096     mixin OpEquals;
3097 }
3098 
3099 ///
3100 final class ThrowStatement : ASTNode
3101 {
3102 public:
3103     override void accept(ASTVisitor visitor) const
3104     {
3105         mixin(visitIfNotNull!(expression));
3106     }
3107     /** */ Expression expression;
3108     mixin OpEquals;
3109 }
3110 
3111 ///
3112 final class TraitsExpression : ExpressionNode
3113 {
3114 public:
3115     override void accept(ASTVisitor visitor) const
3116     {
3117         mixin(visitIfNotNull!(identifier, templateArgumentList));
3118     }
3119     /** */ Token identifier;
3120     /** */ TemplateArgumentList templateArgumentList;
3121     mixin OpEquals;
3122 }
3123 
3124 ///
3125 final class TryStatement : ASTNode
3126 {
3127 public:
3128     override void accept(ASTVisitor visitor) const
3129     {
3130         mixin(visitIfNotNull!(declarationOrStatement, catches, finally_));
3131     }
3132     /** */ DeclarationOrStatement declarationOrStatement;
3133     /** */ Catches catches;
3134     /** */ Finally finally_;
3135     mixin OpEquals;
3136 }
3137 
3138 ///
3139 final class Type : ASTNode
3140 {
3141 public:
3142     override void accept(ASTVisitor visitor) const
3143     {
3144         mixin(visitIfNotNull!(type2, typeSuffixes));
3145     }
3146 
3147     /** */ IdType[] typeConstructors;
3148     /** */ TypeSuffix[] typeSuffixes;
3149     /** */ Type2 type2;
3150     mixin OpEquals;
3151 }
3152 
3153 ///
3154 final class Type2 : ASTNode
3155 {
3156 public:
3157     override void accept(ASTVisitor visitor) const
3158     {
3159         mixin(visitIfNotNull!(symbol, typeofExpression,
3160             identifierOrTemplateChain, type, vector));
3161     }
3162 
3163     /** */ IdType builtinType;
3164     /** */ Symbol symbol;
3165     /** */ TypeofExpression typeofExpression;
3166     /** */ IdentifierOrTemplateChain identifierOrTemplateChain;
3167     /** */ IdType typeConstructor;
3168     /** */ Type type;
3169     /** */ Vector vector;
3170     mixin OpEquals;
3171 }
3172 
3173 ///
3174 final class TypeSpecialization : ASTNode
3175 {
3176 public:
3177     override void accept(ASTVisitor visitor) const
3178     {
3179         mixin(visitIfNotNull!(token, type));
3180     }
3181     /** */ Token token;
3182     /** */ Type type;
3183     mixin OpEquals;
3184 }
3185 
3186 ///
3187 final class TypeSuffix : ASTNode
3188 {
3189 public:
3190     override void accept(ASTVisitor visitor) const
3191     {
3192         mixin(visitIfNotNull!(type, low, high, delegateOrFunction, parameters,
3193             memberFunctionAttributes));
3194     }
3195 
3196     /** */ Token delegateOrFunction;
3197     /** */ Token star;
3198     /** */ bool array;
3199     /** */ Type type;
3200     /** */ ExpressionNode low;
3201     /** */ ExpressionNode high;
3202     /** */ Parameters parameters;
3203     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
3204     mixin OpEquals;
3205 }
3206 
3207 ///
3208 final class TypeidExpression : ExpressionNode
3209 {
3210 public:
3211     override void accept(ASTVisitor visitor) const
3212     {
3213         mixin(visitIfNotNull!(type, expression));
3214     }
3215     /** */ Type type;
3216     /** */ Expression expression;
3217     mixin OpEquals;
3218 }
3219 
3220 ///
3221 final class TypeofExpression : ExpressionNode
3222 {
3223 public:
3224     override void accept(ASTVisitor visitor) const
3225     {
3226         mixin(visitIfNotNull!(expression, return_));
3227     }
3228     /** */ Expression expression;
3229     /** */ Token return_;
3230     mixin OpEquals;
3231 }
3232 
3233 ///
3234 final class UnaryExpression : ExpressionNode
3235 {
3236 public:
3237     override void accept(ASTVisitor visitor) const
3238     {
3239         // TODO prefix, postfix, unary
3240         mixin(visitIfNotNull!(primaryExpression, newExpression, deleteExpression,
3241             castExpression, functionCallExpression, argumentList, unaryExpression,
3242             type, identifierOrTemplateInstance, assertExpression, indexExpression));
3243     }
3244 
3245     /** */ Type type;
3246     /** */ PrimaryExpression primaryExpression;
3247     /** */ Token prefix;
3248     /** */ Token suffix;
3249     /** */ UnaryExpression unaryExpression;
3250     /** */ NewExpression newExpression;
3251     /** */ DeleteExpression deleteExpression;
3252     /** */ CastExpression castExpression;
3253     /** */ FunctionCallExpression functionCallExpression;
3254     /** */ ArgumentList argumentList;
3255     /** */ IdentifierOrTemplateInstance identifierOrTemplateInstance;
3256     /** */ AssertExpression assertExpression;
3257     /** */ IndexExpression indexExpression;
3258     mixin OpEquals;
3259 }
3260 
3261 ///
3262 final class UnionDeclaration : ASTNode
3263 {
3264 public:
3265     override void accept(ASTVisitor visitor) const
3266     {
3267         mixin(visitIfNotNull!(name, templateParameters, constraint, structBody));
3268     }
3269 
3270     /** */ Token name;
3271     /** */ TemplateParameters templateParameters;
3272     /** */ Constraint constraint;
3273     /** */ StructBody structBody;
3274     /** */ string comment;
3275     mixin OpEquals;
3276 }
3277 
3278 ///
3279 final class Unittest : ASTNode
3280 {
3281 public:
3282     override void accept(ASTVisitor visitor) const
3283     {
3284         mixin(visitIfNotNull!(blockStatement));
3285     }
3286     /** */ BlockStatement blockStatement;
3287     /** */ string comment;
3288     mixin OpEquals;
3289 }
3290 
3291 ///
3292 final class VariableDeclaration : ASTNode
3293 {
3294 public:
3295     override void accept(ASTVisitor visitor) const
3296     {
3297         mixin(visitIfNotNull!(attributes, storageClasses, type, declarators, autoDeclaration));
3298     }
3299     /** */ Type type;
3300     /** */ Declarator[] declarators;
3301     /** */ StorageClass[] storageClasses;
3302     /** */ Attribute[] attributes;
3303     /** */ AutoDeclaration autoDeclaration;
3304     /** */ string comment;
3305     bool isEnum;
3306     mixin OpEquals;
3307 }
3308 
3309 ///
3310 final class Vector : ASTNode
3311 {
3312 public:
3313     override void accept(ASTVisitor visitor) const
3314     {
3315         mixin(visitIfNotNull!(type));
3316     }
3317     /** */ Type type;
3318     mixin OpEquals;
3319 }
3320 
3321 ///
3322 final class VersionCondition : ASTNode
3323 {
3324 public:
3325     override void accept(ASTVisitor visitor) const
3326     {
3327         mixin(visitIfNotNull!(token));
3328     }
3329     /** */ size_t versionIndex;
3330     /** */ Token token;
3331     mixin OpEquals;
3332 }
3333 
3334 ///
3335 final class VersionSpecification : ASTNode
3336 {
3337 public:
3338     override void accept(ASTVisitor visitor) const
3339     {
3340         mixin(visitIfNotNull!(token));
3341     }
3342     /** */ Token token;
3343     mixin OpEquals;
3344 }
3345 
3346 ///
3347 final class WhileStatement : ASTNode
3348 {
3349 public:
3350     override void accept(ASTVisitor visitor) const
3351     {
3352         mixin(visitIfNotNull!(expression, declarationOrStatement));
3353     }
3354 
3355     /** */ Expression expression;
3356     /** */ DeclarationOrStatement declarationOrStatement;
3357     /** */ size_t startIndex;
3358     mixin OpEquals;
3359 }
3360 
3361 ///
3362 final class WithStatement : ASTNode
3363 {
3364 public:
3365     override void accept(ASTVisitor visitor) const
3366     {
3367         mixin(visitIfNotNull!(expression, statementNoCaseNoDefault));
3368     }
3369 
3370     /** */ Expression expression;
3371     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
3372     mixin OpEquals;
3373 }
3374 
3375 ///
3376 final class XorExpression : ExpressionNode
3377 {
3378 public:
3379     override void accept(ASTVisitor visitor) const
3380     {
3381         mixin(visitIfNotNull!(left, right));
3382     }
3383     mixin BinaryExpressionBody;
3384     mixin OpEquals;
3385 }