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     void setSupplementalComment(string supplementalComment) {
1287     	if(supplementalComment is null)
1288 		return;
1289 
1290 	foreach(decl; declarations)
1291 		decl.setSupplementalComment(supplementalComment);
1292 
1293         foreach (Type; DeclarationTypes)
1294         {
1295 		static if(__traits(compiles, Type.init.comment)) {
1296             const(Type)* value = storage.peek!Type;
1297             if (value)
1298             {
1299                 static if (isArray!Type)
1300                     foreach (item; *(cast(Type*) value)) {
1301 			if(item.comment is null)
1302                         item.comment = supplementalComment;// ~ item.comment;
1303 		    }
1304                 else if (*value !is null) {
1305                     auto v = *(cast(Type*) value);
1306 		    if(v.comment is null)
1307 		    v.comment = supplementalComment;// ~ v.comment;
1308 		}
1309             }
1310 	    }
1311         }
1312     }
1313 
1314     private import std.variant:Algebraic;
1315     private import std.typetuple:TypeTuple;
1316 
1317     alias DeclarationTypes = TypeTuple!(AliasDeclaration, AliasThisDeclaration,
1318         AnonymousEnumDeclaration, Attribute[], AttributeDeclaration,
1319         ClassDeclaration, ConditionalDeclaration, Constructor, DebugSpecification,
1320         /+Declaration[],+/ Destructor, EnumDeclaration, EponymousTemplateDeclaration,
1321         FunctionDeclaration, ImportDeclaration, InterfaceDeclaration, Invariant,
1322         MixinDeclaration, MixinTemplateDeclaration, Postblit, PragmaDeclaration,
1323         SharedStaticConstructor, SharedStaticDestructor, StaticAssertDeclaration,
1324 	StaticForeachDeclaration,
1325         StaticConstructor, StaticDestructor, StructDeclaration,
1326         TemplateDeclaration, UnionDeclaration, Unittest, VariableDeclaration,
1327         VersionSpecification);
1328 
1329     private Algebraic!(DeclarationTypes) storage;
1330 
1331     private static string generateProperty(string type, string name)
1332     {
1333         return "const(" ~ type ~ ") " ~ name ~ "() const @property { auto p = storage.peek!" ~ type ~ "; return p is null? null : *p;}\n"
1334             ~ "const(" ~ type ~ ") " ~ name ~ "(" ~ type ~ " node) @property { storage = node; return node; }";
1335     }
1336 
1337     /** */ Attribute[] attributes;
1338     /** */ Declaration[] declarations;
1339 
1340     mixin(generateProperty("AliasDeclaration", "aliasDeclaration"));
1341     mixin(generateProperty("AliasThisDeclaration", "aliasThisDeclaration"));
1342     mixin(generateProperty("AnonymousEnumDeclaration", "anonymousEnumDeclaration"));
1343     mixin(generateProperty("AttributeDeclaration", "attributeDeclaration"));
1344     mixin(generateProperty("ClassDeclaration", "classDeclaration"));
1345     mixin(generateProperty("ConditionalDeclaration", "conditionalDeclaration"));
1346     mixin(generateProperty("Constructor", "constructor"));
1347     mixin(generateProperty("DebugSpecification", "debugSpecification"));
1348     /+mixin(generateProperty("Declaration[]", "declarations"));+/
1349     mixin(generateProperty("Destructor", "destructor"));
1350     mixin(generateProperty("EnumDeclaration", "enumDeclaration"));
1351     mixin(generateProperty("EponymousTemplateDeclaration", "eponymousTemplateDeclaration"));
1352     mixin(generateProperty("FunctionDeclaration", "functionDeclaration"));
1353     mixin(generateProperty("ImportDeclaration", "importDeclaration"));
1354     mixin(generateProperty("InterfaceDeclaration", "interfaceDeclaration"));
1355     mixin(generateProperty("Invariant", "invariant_"));
1356     mixin(generateProperty("MixinDeclaration", "mixinDeclaration"));
1357     mixin(generateProperty("MixinTemplateDeclaration", "mixinTemplateDeclaration"));
1358     mixin(generateProperty("Postblit", "postblit"));
1359     mixin(generateProperty("PragmaDeclaration", "pragmaDeclaration"));
1360     mixin(generateProperty("SharedStaticConstructor", "sharedStaticConstructor"));
1361     mixin(generateProperty("SharedStaticDestructor", "sharedStaticDestructor"));
1362     mixin(generateProperty("StaticAssertDeclaration", "staticAssertDeclaration"));
1363     mixin(generateProperty("StaticForeachDeclaration", "staticForeachDeclaration"));
1364     mixin(generateProperty("StaticConstructor", "staticConstructor"));
1365     mixin(generateProperty("StaticDestructor", "staticDestructor"));
1366     mixin(generateProperty("StructDeclaration", "structDeclaration"));
1367     mixin(generateProperty("TemplateDeclaration", "templateDeclaration"));
1368     mixin(generateProperty("UnionDeclaration", "unionDeclaration"));
1369     mixin(generateProperty("Unittest", "unittest_"));
1370     mixin(generateProperty("VariableDeclaration", "variableDeclaration"));
1371     mixin(generateProperty("VersionSpecification", "versionSpecification"));
1372 
1373 
1374     override bool opEquals(const Object other) const
1375     {
1376         auto otherDeclaration = cast(Declaration) other;
1377         if (otherDeclaration is null)
1378             return false;
1379         return attributes == otherDeclaration.attributes
1380             && declarations == otherDeclaration.declarations
1381             && storage == otherDeclaration.storage;
1382     }
1383 }
1384 
1385 ///
1386 final class DeclarationsAndStatements : ASTNode
1387 {
1388     override void accept(ASTVisitor visitor) const
1389     {
1390         mixin(visitIfNotNull!(declarationsAndStatements));
1391     }
1392 
1393     /** */ DeclarationOrStatement[] declarationsAndStatements;
1394     mixin OpEquals;
1395 }
1396 
1397 ///
1398 final class DeclarationOrStatement : ASTNode
1399 {
1400 public:
1401     override void accept(ASTVisitor visitor) const
1402     {
1403         mixin(visitIfNotNull!(declaration, statement));
1404     }
1405 
1406     /** */ Declaration declaration;
1407     /** */ Statement statement;
1408     mixin OpEquals;
1409 }
1410 
1411 ///
1412 final class Declarator : ASTNode
1413 {
1414 public:
1415     override void accept(ASTVisitor visitor) const
1416     {
1417         mixin(visitIfNotNull!(templateParameters, initializer));
1418     }
1419     /** */ Token name;
1420     /** */ TemplateParameters templateParameters;
1421     /** */ Initializer initializer;
1422     /** */ TypeSuffix[] cstyle;
1423     /** */ string comment;
1424     mixin OpEquals;
1425 }
1426 
1427 ///
1428 final class DefaultStatement : ASTNode
1429 {
1430 public:
1431     override void accept(ASTVisitor visitor) const
1432     {
1433         mixin(visitIfNotNull!(declarationsAndStatements));
1434     }
1435     /** */ DeclarationsAndStatements declarationsAndStatements;
1436 	/** */ size_t colonLocation;
1437     mixin OpEquals;
1438 }
1439 
1440 ///
1441 final class DeleteExpression : ExpressionNode
1442 {
1443 public:
1444     override void accept(ASTVisitor visitor) const
1445     {
1446         mixin(visitIfNotNull!(unaryExpression));
1447     }
1448     /** */ UnaryExpression unaryExpression;
1449     /** */ size_t line;
1450     /** */ size_t column;
1451     mixin OpEquals;
1452 }
1453 
1454 ///
1455 final class DeleteStatement : ASTNode
1456 {
1457 public:
1458     override void accept(ASTVisitor visitor) const
1459     {
1460         mixin(visitIfNotNull!(deleteExpression));
1461     }
1462     /** */ DeleteExpression deleteExpression;
1463     mixin OpEquals;
1464 }
1465 
1466 ///
1467 final class Deprecated : ASTNode
1468 {
1469 public:
1470     override void accept(ASTVisitor visitor) const
1471     {
1472         mixin(visitIfNotNull!(stringLiterals));
1473     }
1474     /** */ Token[] stringLiterals;
1475     mixin OpEquals;
1476 }
1477 
1478 ///
1479 final class Destructor : ASTNode
1480 {
1481 public:
1482     override void accept(ASTVisitor visitor) const
1483     {
1484         mixin(visitIfNotNull!(memberFunctionAttributes, functionBody));
1485     }
1486     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
1487     /** */ FunctionBody functionBody;
1488     /** */ size_t line;
1489     /** */ size_t column;
1490     /** */ size_t index;
1491     /** */ string comment;
1492     mixin OpEquals;
1493 }
1494 
1495 ///
1496 final class DoStatement : ASTNode
1497 {
1498 public:
1499     override void accept(ASTVisitor visitor) const
1500     {
1501         mixin(visitIfNotNull!(expression, statementNoCaseNoDefault));
1502     }
1503     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
1504     /** */ Expression expression;
1505     mixin OpEquals;
1506 }
1507 
1508 ///
1509 final class EnumBody : ASTNode
1510 {
1511 public:
1512     override void accept(ASTVisitor visitor) const
1513     {
1514         mixin(visitIfNotNull!(enumMembers));
1515     }
1516     /** */ EnumMember[] enumMembers;
1517 
1518     /**
1519      * Byte position of the opening brace
1520      */
1521     size_t startLocation;
1522 
1523     /**
1524      * Byte position of the closing brace
1525      */
1526     size_t endLocation;
1527     mixin OpEquals;
1528 }
1529 
1530 ///
1531 final class EnumDeclaration : ASTNode
1532 {
1533 public:
1534     override void accept(ASTVisitor visitor) const
1535     {
1536         mixin(visitIfNotNull!(type, enumBody));
1537     }
1538     /** */ Token name;
1539     /** */ Type type;
1540     /** */ EnumBody enumBody;
1541     /** */ string comment;
1542     mixin OpEquals;
1543 }
1544 
1545 ///
1546 final class EnumMember : ASTNode
1547 {
1548 public:
1549     override void accept(ASTVisitor visitor) const
1550     {
1551         mixin(visitIfNotNull!(name, type, assignExpression));
1552     }
1553     /** */ Token name;
1554     /** */ Type type;
1555     /** */ ExpressionNode assignExpression;
1556     /** */ string comment;
1557     AtAttribute[] atAttributes;
1558 
1559     bool isDisabled;
1560     Deprecated deprecated_;
1561 
1562     mixin OpEquals;
1563 }
1564 
1565 ///
1566 final class EponymousTemplateDeclaration : ASTNode
1567 {
1568 public:
1569     override void accept(ASTVisitor visitor) const
1570     {
1571         mixin(visitIfNotNull!(name, templateParameters, assignExpression, constraint));
1572     }
1573     /** */ Token name;
1574     /** */ TemplateParameters templateParameters;
1575     /** */ ExpressionNode assignExpression;
1576     /** */ Type type;
1577     string comment;
1578     Constraint constraint;
1579     mixin OpEquals;
1580 }
1581 
1582 ///
1583 final class EqualExpression : ExpressionNode
1584 {
1585 public:
1586     override void accept(ASTVisitor visitor) const
1587     {
1588         mixin(visitIfNotNull!(left, right));
1589     }
1590     /** */ IdType operator;
1591     mixin BinaryExpressionBody;
1592     mixin OpEquals;
1593 }
1594 
1595 ///
1596 final class Expression : ExpressionNode
1597 {
1598 public:
1599     override void accept(ASTVisitor visitor) const
1600     {
1601         mixin(visitIfNotNull!(items));
1602     }
1603     /** */ ExpressionNode[] items;
1604     /** */ size_t line;
1605     /** */ size_t column;
1606     mixin OpEquals;
1607 }
1608 
1609 ///
1610 final class ExpressionStatement : ASTNode
1611 {
1612 public:
1613     override void accept(ASTVisitor visitor) const
1614     {
1615         mixin(visitIfNotNull!(expression));
1616     }
1617     /** */ Expression expression;
1618     mixin OpEquals;
1619 }
1620 
1621 ///
1622 final class FinalSwitchStatement : ASTNode
1623 {
1624 public:
1625     override void accept(ASTVisitor visitor) const
1626     {
1627         mixin(visitIfNotNull!(switchStatement));
1628     }
1629     /** */ SwitchStatement switchStatement;
1630     mixin OpEquals;
1631 }
1632 
1633 ///
1634 final class Finally : ASTNode
1635 {
1636 public:
1637     override void accept(ASTVisitor visitor) const
1638     {
1639         mixin(visitIfNotNull!(declarationOrStatement));
1640     }
1641     /** */ DeclarationOrStatement declarationOrStatement;
1642     mixin OpEquals;
1643 }
1644 
1645 ///
1646 final class ForStatement : ASTNode
1647 {
1648 public:
1649     override void accept(ASTVisitor visitor) const
1650     {
1651         mixin(visitIfNotNull!(initialization, test, increment,
1652             declarationOrStatement));
1653     }
1654     /** */ DeclarationOrStatement initialization;
1655     /** */ Expression test;
1656     /** */ Expression increment;
1657     /** */ DeclarationOrStatement declarationOrStatement;
1658     /** */ size_t startIndex;
1659     mixin OpEquals;
1660 }
1661 
1662 ///
1663 final class ForeachStatement : ASTNode
1664 {
1665 public:
1666     override void accept(ASTVisitor visitor) const
1667     {
1668         mixin(visitIfNotNull!(foreachType, foreachTypeList, low, high,
1669             declarationOrStatement));
1670     }
1671     /** */ IdType type;
1672     /** */ ForeachTypeList foreachTypeList;
1673     /** */ ForeachType foreachType;
1674     /** */ Expression low;
1675     /** */ Expression high;
1676     /** */ DeclarationOrStatement declarationOrStatement;
1677     /** */ size_t startIndex;
1678     mixin OpEquals;
1679 }
1680 
1681 ///
1682 final class ForeachType : ASTNode
1683 {
1684 public:
1685     override void accept(ASTVisitor visitor) const
1686     {
1687         mixin(visitIfNotNull!(type, identifier));
1688     }
1689     /** */ bool isRef;
1690     /** */ IdType[] typeConstructors;
1691     /** */ Type type;
1692     /** */ Token identifier;
1693     mixin OpEquals;
1694 }
1695 
1696 ///
1697 final class ForeachTypeList : ASTNode
1698 {
1699 public:
1700     override void accept(ASTVisitor visitor) const
1701     {
1702         mixin(visitIfNotNull!(items));
1703     }
1704     /** */ ForeachType[] items;
1705     mixin OpEquals;
1706 }
1707 
1708 ///
1709 final class FunctionAttribute : ASTNode
1710 {
1711 public:
1712     override void accept(ASTVisitor visitor) const
1713     {
1714         mixin(visitIfNotNull!(token, atAttribute));
1715     }
1716     /** */ Token token;
1717     /** */ AtAttribute atAttribute;
1718     mixin OpEquals;
1719 }
1720 
1721 ///
1722 final class FunctionBody : ASTNode
1723 {
1724 public:
1725     override void accept(ASTVisitor visitor) const
1726     {
1727         mixin(visitIfNotNull!(inStatement, outStatement, bodyStatement,
1728             blockStatement));
1729     }
1730 
1731     /** */ BlockStatement blockStatement;
1732     /** */ BodyStatement bodyStatement;
1733     /** */ OutStatement outStatement;
1734     /** */ InStatement inStatement;
1735 
1736 
1737 	bool hadABody;
1738 
1739     mixin OpEquals;
1740 }
1741 
1742 ///
1743 final class FunctionCallExpression : ExpressionNode
1744 {
1745 public:
1746     override void accept(ASTVisitor visitor) const
1747     {
1748         mixin(visitIfNotNull!(type, unaryExpression, templateArguments, arguments));
1749     }
1750     /** */ Type type;
1751     /** */ UnaryExpression unaryExpression;
1752     /** */ TemplateArguments templateArguments;
1753     /** */ Arguments arguments;
1754     mixin OpEquals;
1755 }
1756 
1757 ///
1758 final class FunctionDeclaration : ASTNode
1759 {
1760 public:
1761     override void accept(ASTVisitor visitor) const
1762     {
1763         mixin(visitIfNotNull!(storageClasses, returnType, parameters,
1764             templateParameters, constraint, memberFunctionAttributes,
1765             functionBody));
1766     }
1767     /** */ bool hasAuto;
1768     /** */ bool hasRef;
1769     /** */ Type returnType;
1770     /** */ Token name;
1771     /** */ TemplateParameters templateParameters;
1772     /** */ Parameters parameters;
1773     /** */ Constraint constraint;
1774     /** */ FunctionBody functionBody;
1775     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
1776     /** */ string comment;
1777     /** */ Attribute[] attributes;
1778     /** */ StorageClass[] storageClasses;
1779     mixin OpEquals;
1780 }
1781 
1782 ///
1783 final class FunctionLiteralExpression : ExpressionNode
1784 {
1785 public:
1786     override void accept(ASTVisitor visitor) const
1787     {
1788         mixin(visitIfNotNull!(type, parameters, memberFunctionAttributes,
1789             functionBody));
1790     }
1791     /** */ IdType functionOrDelegate;
1792     /** */ Type type;
1793     /** */ Parameters parameters;
1794     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
1795     /** */ FunctionBody functionBody;
1796     mixin OpEquals;
1797 }
1798 
1799 ///
1800 final class GotoStatement : ASTNode
1801 {
1802 public:
1803     override void accept(ASTVisitor visitor) const
1804     {
1805         mixin(visitIfNotNull!(label, expression));
1806     }
1807     /** */ Expression expression;
1808     /** */ Token label;
1809     mixin OpEquals;
1810 }
1811 
1812 ///
1813 final class IdentifierChain : ASTNode
1814 {
1815 public:
1816     override void accept(ASTVisitor visitor) const
1817     {
1818         mixin(visitIfNotNull!(identifiers));
1819     }
1820     /** */ Token[] identifiers;
1821     mixin OpEquals;
1822 }
1823 
1824 ///
1825 final class IdentifierList : ASTNode
1826 {
1827 public:
1828     override void accept(ASTVisitor visitor) const
1829     {
1830         mixin(visitIfNotNull!(identifiers));
1831     }
1832     /** */ Token[] identifiers;
1833     mixin OpEquals;
1834 }
1835 
1836 ///
1837 final class IdentifierOrTemplateChain : ASTNode
1838 {
1839 public:
1840     override void accept(ASTVisitor visitor) const
1841     {
1842         mixin(visitIfNotNull!(identifiersOrTemplateInstances));
1843     }
1844 
1845     /** */ IdentifierOrTemplateInstance[] identifiersOrTemplateInstances;
1846     mixin OpEquals;
1847 }
1848 
1849 ///
1850 final class IdentifierOrTemplateInstance : ASTNode
1851 {
1852 public:
1853     override void accept(ASTVisitor visitor) const
1854     {
1855         mixin(visitIfNotNull!(identifier, templateInstance));
1856     }
1857 
1858     /** */ Token identifier;
1859     /** */ TemplateInstance templateInstance;
1860     mixin OpEquals;
1861 }
1862 
1863 ///
1864 final class IdentityExpression : ExpressionNode
1865 {
1866 public:
1867     override void accept(ASTVisitor visitor) const
1868     {
1869         mixin(visitIfNotNull!(left, right));
1870     }
1871     /** */ bool negated;
1872     mixin BinaryExpressionBody;
1873     mixin OpEquals;
1874 }
1875 
1876 ///
1877 final class IfStatement : ASTNode
1878 {
1879 public:
1880     override void accept(ASTVisitor visitor) const
1881     {
1882         mixin(visitIfNotNull!(identifier, type, expression, thenStatement,
1883             elseStatement));
1884     }
1885     /** */ Token identifier;
1886     /** */ Type type;
1887     /** */ Expression expression;
1888     /** */ DeclarationOrStatement thenStatement;
1889     /** */ DeclarationOrStatement elseStatement;
1890     /** */ size_t startIndex;
1891     /** */ size_t line;
1892     /** */ size_t column;
1893     mixin OpEquals;
1894 }
1895 
1896 ///
1897 final class ImportBind : ASTNode
1898 {
1899 public:
1900     override void accept(ASTVisitor visitor) const
1901     {
1902         mixin(visitIfNotNull!(left, right));
1903     }
1904     /** */ Token left;
1905     /** */ Token right;
1906     mixin OpEquals;
1907 }
1908 
1909 ///
1910 final class ImportBindings : ASTNode
1911 {
1912 public:
1913     override void accept(ASTVisitor visitor) const
1914     {
1915         mixin(visitIfNotNull!(singleImport, importBinds));
1916     }
1917     /** */ SingleImport singleImport;
1918     /** */ ImportBind[] importBinds;
1919     mixin OpEquals;
1920 }
1921 
1922 ///
1923 final class ImportDeclaration : ASTNode
1924 {
1925 public:
1926     override void accept(ASTVisitor visitor) const
1927     {
1928         mixin(visitIfNotNull!(singleImports, importBindings));
1929     }
1930     /** */ string comment;
1931     size_t line;
1932     /** */ SingleImport[] singleImports;
1933     /** */ ImportBindings importBindings;
1934     mixin OpEquals;
1935 }
1936 
1937 ///
1938 final class ImportExpression : ExpressionNode
1939 {
1940 public:
1941     override void accept(ASTVisitor visitor) const
1942     {
1943         mixin(visitIfNotNull!(assignExpression));
1944     }
1945     /** */ ExpressionNode assignExpression;
1946     mixin OpEquals;
1947 }
1948 
1949 ///
1950 final class Index : ASTNode
1951 {
1952 public:
1953     override void accept(ASTVisitor visitor) const
1954     {
1955         mixin(visitIfNotNull!(low, high));
1956     }
1957     /** */ ExpressionNode low;
1958     /** */ ExpressionNode high;
1959     mixin OpEquals;
1960 }
1961 
1962 ///
1963 final class IndexExpression : ExpressionNode
1964 {
1965 public:
1966     override void accept(ASTVisitor visitor) const
1967     {
1968         mixin(visitIfNotNull!(unaryExpression, indexes));
1969     }
1970     /** */ UnaryExpression unaryExpression;
1971     /** */ Index[] indexes;
1972     mixin OpEquals;
1973 }
1974 
1975 ///
1976 final class InExpression : ExpressionNode
1977 {
1978 public:
1979     override void accept(ASTVisitor visitor) const
1980     {
1981         mixin(visitIfNotNull!(left, right));
1982     }
1983     mixin BinaryExpressionBody;
1984     bool negated;
1985     mixin OpEquals;
1986 }
1987 
1988 ///
1989 final class InStatement : ASTNode
1990 {
1991 public:
1992     override void accept(ASTVisitor visitor) const
1993     {
1994         mixin(visitIfNotNull!(blockStatement));
1995     }
1996     /** */ size_t inTokenLocation;
1997     /** */ BlockStatement blockStatement;
1998     /** */ Expression expression;
1999     mixin OpEquals;
2000 }
2001 
2002 ///
2003 final class Initialize : ASTNode
2004 {
2005 public:
2006     override void accept(ASTVisitor visitor) const
2007     {
2008         mixin(visitIfNotNull!(statementNoCaseNoDefault));
2009     }
2010     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
2011     mixin OpEquals;
2012 }
2013 
2014 ///
2015 final class Initializer : ASTNode
2016 {
2017 public:
2018     override void accept(ASTVisitor visitor) const
2019     {
2020         mixin(visitIfNotNull!(nonVoidInitializer));
2021     }
2022     /** */ NonVoidInitializer nonVoidInitializer;
2023     mixin OpEquals;
2024 }
2025 
2026 ///
2027 final class InterfaceDeclaration : ASTNode
2028 {
2029 public:
2030     override void accept(ASTVisitor visitor) const
2031     {
2032         mixin(visitIfNotNull!(templateParameters, constraint, baseClassList,
2033             structBody));
2034     }
2035     /** */ Token name;
2036     /** */ TemplateParameters templateParameters;
2037     /** */ Constraint constraint;
2038     /** */ BaseClassList baseClassList;
2039     /** */ StructBody structBody;
2040     /** */ string comment;
2041     mixin OpEquals;
2042 }
2043 
2044 ///
2045 final class Invariant : ASTNode
2046 {
2047 public:
2048     override void accept(ASTVisitor visitor) const
2049     {
2050         mixin(visitIfNotNull!(blockStatement));
2051     }
2052     /** */ BlockStatement blockStatement;
2053     /** */ string comment;
2054     size_t line;
2055     size_t index;
2056     mixin OpEquals;
2057 }
2058 
2059 ///
2060 final class IsExpression : ExpressionNode
2061 {
2062 public:
2063     override void accept(ASTVisitor visitor) const
2064     {
2065         mixin(visitIfNotNull!(type, identifier, typeSpecialization,
2066             templateParameterList));
2067     }
2068     /** */ Type type;
2069     /** */ Token identifier;
2070     /** */ TypeSpecialization typeSpecialization;
2071     /** */ TemplateParameterList templateParameterList;
2072     /** */ IdType equalsOrColon;
2073     mixin OpEquals;
2074 }
2075 
2076 ///
2077 final class KeyValuePair : ASTNode
2078 {
2079 public:
2080     override void accept(ASTVisitor visitor) const
2081     {
2082         mixin(visitIfNotNull!(key, value));
2083     }
2084     /** */ ExpressionNode key;
2085     /** */ ExpressionNode value;
2086     mixin OpEquals;
2087 }
2088 
2089 ///
2090 final class KeyValuePairs : ASTNode
2091 {
2092 public:
2093     override void accept(ASTVisitor visitor) const
2094     {
2095         mixin(visitIfNotNull!(keyValuePairs));
2096     }
2097     /** */ KeyValuePair[] keyValuePairs;
2098     mixin OpEquals;
2099 }
2100 
2101 ///
2102 final class LabeledStatement : ASTNode
2103 {
2104 public:
2105     override void accept(ASTVisitor visitor) const
2106     {
2107         mixin(visitIfNotNull!(identifier, declarationOrStatement));
2108     }
2109     Token identifier;
2110     /** */ DeclarationOrStatement declarationOrStatement;
2111     mixin OpEquals;
2112 }
2113 
2114 ///
2115 final class LambdaExpression : ExpressionNode
2116 {
2117 public:
2118     override void accept(ASTVisitor visitor) const
2119     {
2120         mixin(visitIfNotNull!(identifier, returnType, parameters, functionAttributes,
2121             assignExpression));
2122     }
2123     /** */ IdType functionType;
2124     /** */ Token identifier;
2125     /** */ Parameters parameters;
2126     /** */ FunctionAttribute[] functionAttributes;
2127     /** */ ExpressionNode assignExpression;
2128     /** */ Type returnType;
2129     mixin OpEquals;
2130 }
2131 
2132 ///
2133 final class LastCatch : ASTNode
2134 {
2135 public:
2136     override void accept(ASTVisitor visitor) const
2137     {
2138         mixin(visitIfNotNull!(statementNoCaseNoDefault));
2139     }
2140     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
2141     size_t line;
2142     size_t column;
2143     mixin OpEquals;
2144 }
2145 
2146 ///
2147 final class LinkageAttribute : ASTNode
2148 {
2149 public:
2150     override void accept(ASTVisitor visitor) const
2151     {
2152         mixin(visitIfNotNull!(identifier, identifierChain));
2153     }
2154     /** */ Token identifier;
2155     /** */ bool hasPlusPlus;
2156     /** */ IdentifierChain identifierChain;
2157     mixin OpEquals;
2158 }
2159 
2160 ///
2161 final class MemberFunctionAttribute : ASTNode
2162 {
2163 public:
2164     override void accept(ASTVisitor visitor) const
2165     {
2166         mixin(visitIfNotNull!(atAttribute));
2167     }
2168     /** */ IdType tokenType;
2169     /** */ AtAttribute atAttribute;
2170     mixin OpEquals;
2171 }
2172 
2173 ///
2174 final class MixinDeclaration : ASTNode
2175 {
2176 public:
2177     override void accept(ASTVisitor visitor) const
2178     {
2179         mixin(visitIfNotNull!(mixinExpression, templateMixinExpression));
2180 	foreach(decl; trivialDeclarations) {
2181 		decl.accept(visitor);
2182 	}
2183     }
2184     /** */ MixinExpression mixinExpression;
2185     /** */ TemplateMixinExpression templateMixinExpression;
2186 
2187     Declaration[] trivialDeclarations;
2188 
2189     mixin OpEquals;
2190 }
2191 
2192 ///
2193 final class MixinExpression : ExpressionNode
2194 {
2195 public:
2196     override void accept(ASTVisitor visitor) const
2197     {
2198         mixin(visitIfNotNull!(assignExpression));
2199     }
2200     /** */ ExpressionNode assignExpression;
2201     mixin OpEquals;
2202 }
2203 
2204 ///
2205 final class MixinTemplateDeclaration : ASTNode
2206 {
2207 public:
2208     override void accept(ASTVisitor visitor) const
2209     {
2210         mixin(visitIfNotNull!(templateDeclaration));
2211     }
2212     /** */ TemplateDeclaration templateDeclaration;
2213     mixin OpEquals;
2214 }
2215 
2216 ///
2217 final class MixinTemplateName : ASTNode
2218 {
2219 public:
2220     override void accept(ASTVisitor visitor) const
2221     {
2222         mixin(visitIfNotNull!(symbol, typeofExpression, identifierOrTemplateChain));
2223     }
2224     /** */ Symbol symbol;
2225     /** */ IdentifierOrTemplateChain identifierOrTemplateChain;
2226     /** */ TypeofExpression typeofExpression;
2227     mixin OpEquals;
2228 }
2229 
2230 ///
2231 final class Module : ASTNode
2232 {
2233 public:
2234     override void accept(ASTVisitor visitor) const
2235     {
2236         mixin(visitIfNotNull!(scriptLine, moduleDeclaration, declarations));
2237     }
2238     /** */ Token scriptLine;
2239     /** */ ModuleDeclaration moduleDeclaration;
2240     /** */ Declaration[] declarations;
2241     mixin OpEquals;
2242 }
2243 
2244 ///
2245 final class ModuleDeclaration : ASTNode
2246 {
2247 public:
2248     override void accept(ASTVisitor visitor) const
2249     {
2250         mixin(visitIfNotNull!(moduleName, deprecated_));
2251     }
2252     /** */ Deprecated deprecated_;
2253     /** */ IdentifierChain moduleName;
2254     /** */ size_t startLocation;
2255     /** */ size_t endLocation;
2256     /** */ string comment;
2257     mixin OpEquals;
2258 }
2259 
2260 
2261 ///
2262 final class MulExpression : ExpressionNode
2263 {
2264 public:
2265     override void accept(ASTVisitor visitor) const
2266     {
2267         mixin(visitIfNotNull!(left, right));
2268     }
2269     /** */ IdType operator;
2270     mixin BinaryExpressionBody;
2271     mixin OpEquals;
2272 }
2273 
2274 ///
2275 final class NewAnonClassExpression : ExpressionNode
2276 {
2277 public:
2278     override void accept(ASTVisitor visitor) const
2279     {
2280         mixin(visitIfNotNull!(allocatorArguments, constructorArguments,
2281             baseClassList, structBody));
2282     }
2283     /** */ Arguments allocatorArguments;
2284     /** */ Arguments constructorArguments;
2285     /** */ BaseClassList baseClassList;
2286     /** */ StructBody structBody;
2287     mixin OpEquals;
2288 }
2289 
2290 ///
2291 final class NewExpression : ExpressionNode
2292 {
2293 public:
2294     override void accept(ASTVisitor visitor) const
2295     {
2296         mixin(visitIfNotNull!(newAnonClassExpression, type, arguments,
2297             assignExpression));
2298     }
2299     /** */ Type type;
2300     /** */ NewAnonClassExpression newAnonClassExpression;
2301     /** */ Arguments arguments;
2302     /** */ ExpressionNode assignExpression;
2303     mixin OpEquals;
2304 }
2305 
2306 
2307 ///
2308 final class StatementNoCaseNoDefault : ASTNode
2309 {
2310 public:
2311     override void accept(ASTVisitor visitor) const
2312     {
2313         mixin(visitIfNotNull!(labeledStatement, blockStatement, ifStatement,
2314             whileStatement, doStatement, forStatement, foreachStatement,
2315             switchStatement, finalSwitchStatement, continueStatement,
2316             breakStatement, returnStatement, gotoStatement, withStatement,
2317             synchronizedStatement, tryStatement, throwStatement,
2318             scopeGuardStatement, asmStatement, conditionalStatement,
2319             staticAssertStatement, versionSpecification, debugSpecification,
2320             expressionStatement));
2321     }
2322     /** */ LabeledStatement labeledStatement;
2323     /** */ BlockStatement blockStatement;
2324     /** */ IfStatement ifStatement;
2325     /** */ WhileStatement whileStatement;
2326     /** */ DoStatement doStatement;
2327     /** */ ForStatement forStatement;
2328     /** */ ForeachStatement foreachStatement;
2329     /** */ SwitchStatement switchStatement;
2330     /** */ FinalSwitchStatement finalSwitchStatement;
2331     /** */ ContinueStatement continueStatement;
2332     /** */ BreakStatement breakStatement;
2333     /** */ ReturnStatement returnStatement;
2334     /** */ GotoStatement gotoStatement;
2335     /** */ WithStatement withStatement;
2336     /** */ SynchronizedStatement synchronizedStatement;
2337     /** */ TryStatement tryStatement;
2338     /** */ ThrowStatement throwStatement;
2339     /** */ ScopeGuardStatement scopeGuardStatement;
2340     /** */ AsmStatement asmStatement;
2341     /** */ ConditionalStatement conditionalStatement;
2342     /** */ StaticAssertStatement staticAssertStatement;
2343     /** */ StaticForeachStatement staticForeachStatement;
2344     /** */ VersionSpecification versionSpecification;
2345     /** */ DebugSpecification debugSpecification;
2346     /** */ ExpressionStatement expressionStatement;
2347     /** */ size_t startLocation;
2348     /** */ size_t endLocation;
2349     mixin OpEquals;
2350 }
2351 
2352 ///
2353 final class NonVoidInitializer : ASTNode
2354 {
2355 public:
2356     override void accept(ASTVisitor visitor) const
2357     {
2358         mixin(visitIfNotNull!(assignExpression, arrayInitializer,
2359             structInitializer));
2360     }
2361     /** */ ExpressionNode assignExpression;
2362     /** */ ArrayInitializer arrayInitializer;
2363     /** */ StructInitializer structInitializer;
2364 
2365     mixin OpEquals;
2366 }
2367 
2368 ///
2369 final class Operands : ASTNode
2370 {
2371 public:
2372     override void accept(ASTVisitor visitor) const
2373     {
2374         mixin(visitIfNotNull!(operands));
2375     }
2376     /** */ ExpressionNode[] operands;
2377     mixin OpEquals;
2378 }
2379 
2380 ///
2381 final class OrExpression : ExpressionNode
2382 {
2383 public:
2384     override void accept(ASTVisitor visitor) const
2385     {
2386         mixin(visitIfNotNull!(left, right));
2387     }
2388     mixin BinaryExpressionBody;
2389     mixin OpEquals;
2390 }
2391 
2392 ///
2393 final class OrOrExpression : ExpressionNode
2394 {
2395 public:
2396     override void accept(ASTVisitor visitor) const
2397     {
2398         mixin(visitIfNotNull!(left, right));
2399     }
2400     mixin BinaryExpressionBody;
2401     mixin OpEquals;
2402 }
2403 
2404 ///
2405 final class OutStatement : ASTNode
2406 {
2407 public:
2408     override void accept(ASTVisitor visitor) const
2409     {
2410         mixin(visitIfNotNull!(parameter, blockStatement));
2411     }
2412     /** */ size_t outTokenLocation;
2413     /** */ Token parameter;
2414     /** */ BlockStatement blockStatement;
2415     Expression expression;
2416     mixin OpEquals;
2417 }
2418 
2419 ///
2420 final class Parameter : ASTNode
2421 {
2422 public:
2423     override void accept(ASTVisitor visitor) const
2424     {
2425         mixin(visitIfNotNull!(type, name, default_));
2426     }
2427 
2428     /** */ IdType[] parameterAttributes;
2429     /** */ Type type;
2430     /** */ Token name;
2431     /** */ bool vararg;
2432     /** */ ExpressionNode default_;
2433     /** */ TypeSuffix[] cstyle;
2434     AtAttribute[] atAttributes;
2435 
2436     string comment;
2437 
2438     mixin OpEquals;
2439 }
2440 
2441 ///
2442 final class Parameters : ASTNode
2443 {
2444 public:
2445     override void accept(ASTVisitor visitor) const
2446     {
2447         mixin(visitIfNotNull!(parameters));
2448     }
2449 
2450     /** */ Parameter[] parameters;
2451     /** */ bool hasVarargs;
2452     mixin OpEquals;
2453 }
2454 
2455 ///
2456 final class Postblit : ASTNode
2457 {
2458 public:
2459     override void accept(ASTVisitor visitor) const
2460     {
2461         mixin(visitIfNotNull!(functionBody));
2462     }
2463     /** */ FunctionBody functionBody;
2464     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
2465     /** */ string comment;
2466     size_t line;
2467     mixin OpEquals;
2468 }
2469 
2470 ///
2471 final class PowExpression : ExpressionNode
2472 {
2473 public:
2474     override void accept(ASTVisitor visitor) const
2475     {
2476         mixin(visitIfNotNull!(left, right));
2477     }
2478     mixin BinaryExpressionBody;
2479     mixin OpEquals;
2480 }
2481 
2482 ///
2483 final class PragmaDeclaration : ASTNode
2484 {
2485 public:
2486     override void accept(ASTVisitor visitor) const
2487     {
2488         mixin(visitIfNotNull!(pragmaExpression));
2489     }
2490     /** */ PragmaExpression pragmaExpression;
2491     mixin OpEquals;
2492 }
2493 
2494 ///
2495 final class PragmaExpression : ExpressionNode
2496 {
2497 public:
2498     override void accept(ASTVisitor visitor) const
2499     {
2500         mixin(visitIfNotNull!(identifier, argumentList));
2501     }
2502     /** */ Token identifier;
2503     /** */ ArgumentList argumentList;
2504     mixin OpEquals;
2505 }
2506 
2507 ///
2508 final class PrimaryExpression : ExpressionNode
2509 {
2510 public:
2511     override void accept(ASTVisitor visitor) const
2512     {
2513         mixin(visitIfNotNull!(basicType, typeConstructor, type, primary,
2514             typeofExpression, typeidExpression, arrayLiteral, assocArrayLiteral,
2515             expression, dot, identifierOrTemplateInstance, isExpression,
2516             lambdaExpression, functionLiteralExpression, traitsExpression,
2517             mixinExpression, importExpression, vector, arguments));
2518     }
2519     /** */ Token dot;
2520     /** */ Token primary;
2521     /** */ IdentifierOrTemplateInstance identifierOrTemplateInstance;
2522     /** */ Token basicType;
2523     /** */ TypeofExpression typeofExpression;
2524     /** */ TypeidExpression typeidExpression;
2525     /** */ ArrayLiteral arrayLiteral;
2526     /** */ AssocArrayLiteral assocArrayLiteral;
2527     /** */ Expression expression;
2528     /** */ IsExpression isExpression;
2529     /** */ LambdaExpression lambdaExpression;
2530     /** */ FunctionLiteralExpression functionLiteralExpression;
2531     /** */ TraitsExpression traitsExpression;
2532     /** */ MixinExpression mixinExpression;
2533     /** */ ImportExpression importExpression;
2534     /** */ Vector vector;
2535     /** */ Type type;
2536     /** */ Token typeConstructor;
2537     /** */ Arguments arguments;
2538     mixin OpEquals;
2539 }
2540 
2541 ///
2542 final class Register : ASTNode
2543 {
2544 public:
2545     override void accept(ASTVisitor visitor) const
2546     {
2547         mixin(visitIfNotNull!(identifier, intLiteral));
2548     }
2549     /** */ Token identifier;
2550     /** */ Token intLiteral;
2551     /** */ bool hasIntegerLiteral;
2552     mixin OpEquals;
2553 }
2554 
2555 ///
2556 final class RelExpression : ExpressionNode
2557 {
2558 public:
2559     override void accept(ASTVisitor visitor) const
2560     {
2561         mixin(visitIfNotNull!(left, right));
2562     }
2563     /** */ IdType operator;
2564     mixin BinaryExpressionBody;
2565     mixin OpEquals;
2566 }
2567 
2568 ///
2569 final class ReturnStatement : ASTNode
2570 {
2571 public:
2572     override void accept(ASTVisitor visitor) const
2573     {
2574         mixin(visitIfNotNull!(expression));
2575     }
2576     /** */ Expression expression;
2577     /** */ size_t startLocation;
2578     /** */ size_t endLocation;
2579     mixin OpEquals;
2580 }
2581 
2582 ///
2583 final class ScopeGuardStatement : ASTNode
2584 {
2585 public:
2586     override void accept(ASTVisitor visitor) const
2587     {
2588         mixin(visitIfNotNull!(identifier, statementNoCaseNoDefault));
2589     }
2590     /** */ Token identifier;
2591     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
2592     mixin OpEquals;
2593 }
2594 
2595 ///
2596 final class SharedStaticConstructor : ASTNode
2597 {
2598 public:
2599     override void accept(ASTVisitor visitor) const
2600     {
2601         mixin(visitIfNotNull!(functionBody));
2602     }
2603     /** */ FunctionBody functionBody;
2604     /** */ size_t location;
2605     /** */ string comment;
2606     mixin OpEquals;
2607 }
2608 
2609 ///
2610 final class SharedStaticDestructor : ASTNode
2611 {
2612 public:
2613     override void accept(ASTVisitor visitor) const
2614     {
2615         mixin(visitIfNotNull!(functionBody));
2616     }
2617     /** */ FunctionBody functionBody;
2618     /** */ size_t location;
2619     /** */ string comment;
2620     mixin OpEquals;
2621 }
2622 
2623 ///
2624 final class ShiftExpression : ExpressionNode
2625 {
2626 public:
2627     override void accept(ASTVisitor visitor) const
2628     {
2629         mixin(visitIfNotNull!(left, right));
2630     }
2631     /** */ IdType operator;
2632     mixin BinaryExpressionBody;
2633     mixin OpEquals;
2634 }
2635 
2636 ///
2637 final class SingleImport : ASTNode
2638 {
2639 public:
2640     override void accept(ASTVisitor visitor) const
2641     {
2642         mixin(visitIfNotNull!(rename, identifierChain));
2643     }
2644     /** */ Token rename;
2645     /** */ IdentifierChain identifierChain;
2646     mixin OpEquals;
2647 }
2648 
2649 ///
2650 final class Statement : ASTNode
2651 {
2652 public:
2653     override void accept(ASTVisitor visitor) const
2654     {
2655         mixin(visitIfNotNull!(statementNoCaseNoDefault, caseStatement,
2656             caseRangeStatement, defaultStatement));
2657     }
2658     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
2659     /** */ CaseStatement caseStatement;
2660     /** */ CaseRangeStatement caseRangeStatement;
2661     /** */ DefaultStatement defaultStatement;
2662     mixin OpEquals;
2663 }
2664 
2665 ///
2666 final class StaticAssertDeclaration : ASTNode
2667 {
2668 public:
2669     override void accept(ASTVisitor visitor) const
2670     {
2671         mixin(visitIfNotNull!(staticAssertStatement));
2672     }
2673     /** */ StaticAssertStatement staticAssertStatement;
2674     mixin OpEquals;
2675 }
2676 
2677 final class StaticForeachDeclaration : ASTNode
2678 {
2679 public:
2680     override void accept(ASTVisitor visitor) const
2681     {
2682         mixin(visitIfNotNull!(declarations));
2683     }
2684     /** */ Declaration[] declarations;
2685 }
2686 
2687 final class StaticForeachStatement : ASTNode
2688 {
2689 	// FIXME
2690     override void accept(ASTVisitor visitor) const
2691     {
2692     }
2693 }
2694 
2695 ///
2696 final class StaticAssertStatement : ASTNode
2697 {
2698 public:
2699     override void accept(ASTVisitor visitor) const
2700     {
2701         mixin(visitIfNotNull!(assertExpression));
2702     }
2703     /** */ AssertExpression assertExpression;
2704     mixin OpEquals;
2705 }
2706 
2707 ///
2708 final class StaticConstructor : ASTNode
2709 {
2710 public:
2711     override void accept(ASTVisitor visitor) const
2712     {
2713         mixin(visitIfNotNull!(functionBody));
2714     }
2715     /** */ FunctionBody functionBody;
2716     /** */ size_t location;
2717     /** */ size_t line;
2718     /** */ size_t column;
2719     /** */ string comment;
2720     mixin OpEquals;
2721 }
2722 
2723 ///
2724 final class StaticDestructor : ASTNode
2725 {
2726 public:
2727     override void accept(ASTVisitor visitor) const
2728     {
2729         mixin(visitIfNotNull!(functionBody));
2730     }
2731     /** */ FunctionBody functionBody;
2732     /** */ size_t location;
2733     /** */ size_t line;
2734     /** */ size_t column;
2735     /** */ string comment;
2736     mixin OpEquals;
2737 }
2738 
2739 ///
2740 final class StaticIfCondition : ASTNode
2741 {
2742 public:
2743     override void accept(ASTVisitor visitor) const
2744     {
2745         mixin(visitIfNotNull!(assignExpression));
2746     }
2747     /** */ ExpressionNode assignExpression;
2748     mixin OpEquals;
2749 }
2750 
2751 ///
2752 final class StorageClass : ASTNode
2753 {
2754 public:
2755     override void accept(ASTVisitor visitor) const
2756     {
2757         mixin(visitIfNotNull!(token, alignAttribute, linkageAttribute,
2758             atAttribute, deprecated_));
2759     }
2760     /** */ AlignAttribute alignAttribute;
2761     /** */ LinkageAttribute linkageAttribute;
2762     /** */ AtAttribute atAttribute;
2763     /** */ Deprecated deprecated_;
2764     /** */ Token token;
2765     mixin OpEquals;
2766 }
2767 
2768 ///
2769 final class StructBody : ASTNode
2770 {
2771 public:
2772     override void accept(ASTVisitor visitor) const
2773     {
2774         mixin(visitIfNotNull!(declarations));
2775     }
2776 
2777     /**
2778      * Byte position of the opening brace
2779      */
2780     size_t startLocation;
2781 
2782     /**
2783      * Byte position of the closing brace
2784      */
2785     size_t endLocation;
2786     /** */ Declaration[] declarations;
2787     mixin OpEquals;
2788 }
2789 
2790 ///
2791 final class StructDeclaration : ASTNode
2792 {
2793 public:
2794     override void accept(ASTVisitor visitor) const
2795     {
2796         mixin(visitIfNotNull!(templateParameters, constraint, structBody));
2797     }
2798     /** */ Token name;
2799     /** */ TemplateParameters templateParameters;
2800     /** */ Constraint constraint;
2801     /** */ StructBody structBody;
2802     /** */ string comment;
2803     mixin OpEquals;
2804 }
2805 
2806 ///
2807 final class StructInitializer : ASTNode
2808 {
2809 public:
2810     override void accept(ASTVisitor visitor) const
2811     {
2812         mixin(visitIfNotNull!(structMemberInitializers));
2813     }
2814     /** */ StructMemberInitializers structMemberInitializers;
2815     /** */ size_t startLocation;
2816     /** */ size_t endLocation;
2817     mixin OpEquals;
2818 }
2819 
2820 ///
2821 final class StructMemberInitializer : ASTNode
2822 {
2823 public:
2824     override void accept(ASTVisitor visitor) const
2825     {
2826         mixin(visitIfNotNull!(identifier, nonVoidInitializer));
2827     }
2828     /** */ Token identifier;
2829     /** */ NonVoidInitializer nonVoidInitializer;
2830     mixin OpEquals;
2831 }
2832 
2833 ///
2834 final class StructMemberInitializers : ASTNode
2835 {
2836 public:
2837     override void accept(ASTVisitor visitor) const
2838     {
2839         mixin(visitIfNotNull!(structMemberInitializers));
2840     }
2841     /** */ StructMemberInitializer[] structMemberInitializers;
2842     mixin OpEquals;
2843 }
2844 
2845 ///
2846 final class SwitchStatement : ASTNode
2847 {
2848 public:
2849     override void accept(ASTVisitor visitor) const
2850     {
2851         mixin(visitIfNotNull!(expression, statement));
2852     }
2853     /** */ Expression expression;
2854     /** */ Statement statement;
2855     mixin OpEquals;
2856 }
2857 
2858 ///
2859 final class Symbol : ASTNode
2860 {
2861 public:
2862     override void accept(ASTVisitor visitor) const
2863     {
2864         mixin(visitIfNotNull!(identifierOrTemplateChain));
2865     }
2866 
2867     /** */ IdentifierOrTemplateChain identifierOrTemplateChain;
2868     /** */ bool dot;
2869     mixin OpEquals;
2870 }
2871 
2872 ///
2873 final class SynchronizedStatement : ASTNode
2874 {
2875 public:
2876     override void accept(ASTVisitor visitor) const
2877     {
2878         mixin(visitIfNotNull!(expression, statementNoCaseNoDefault));
2879     }
2880     /** */ Expression expression;
2881     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
2882     mixin OpEquals;
2883 }
2884 
2885 ///
2886 final class TemplateAliasParameter : ASTNode
2887 {
2888 public:
2889     override void accept(ASTVisitor visitor) const
2890     {
2891         mixin(visitIfNotNull!(type, identifier, colonType, colonExpression,
2892             assignType, assignExpression));
2893     }
2894     /** */ Type type;
2895     /** */ Token identifier;
2896     /** */ Type colonType;
2897     /** */ ExpressionNode colonExpression;
2898     /** */ Type assignType;
2899     /** */ ExpressionNode assignExpression;
2900     mixin OpEquals;
2901 }
2902 
2903 ///
2904 final class TemplateArgument : ASTNode
2905 {
2906 public:
2907     override void accept(ASTVisitor visitor) const
2908     {
2909         mixin(visitIfNotNull!(type, assignExpression));
2910     }
2911     /** */ Type type;
2912     /** */ ExpressionNode assignExpression;
2913     mixin OpEquals;
2914 }
2915 
2916 ///
2917 final class TemplateArgumentList : ASTNode
2918 {
2919 public:
2920     override void accept(ASTVisitor visitor) const
2921     {
2922         mixin(visitIfNotNull!(items));
2923     }
2924     /** */ TemplateArgument[] items;
2925     mixin OpEquals;
2926 }
2927 
2928 ///
2929 final class TemplateArguments : ASTNode
2930 {
2931 public:
2932     override void accept(ASTVisitor visitor) const
2933     {
2934         mixin(visitIfNotNull!(templateArgumentList, templateSingleArgument));
2935     }
2936     /** */ TemplateArgumentList templateArgumentList;
2937     /** */ TemplateSingleArgument templateSingleArgument;
2938     mixin OpEquals;
2939 }
2940 
2941 ///
2942 final class TemplateDeclaration : ASTNode
2943 {
2944 public:
2945     override void accept(ASTVisitor visitor) const
2946     {
2947         mixin(visitIfNotNull!(name, templateParameters, constraint,
2948             declarations));
2949     }
2950     /** */ Token name;
2951     /** */ TemplateParameters templateParameters;
2952     /** */ Constraint constraint;
2953     /** */ Declaration[] declarations;
2954     /** */ string comment;
2955     /**
2956      * Byte position of the opening brace
2957      */
2958     size_t startLocation;
2959 
2960     /**
2961      * Byte position of the closing brace
2962      */
2963     size_t endLocation;
2964     mixin OpEquals;
2965 }
2966 
2967 ///
2968 final class TemplateInstance : ASTNode
2969 {
2970 public:
2971     override void accept(ASTVisitor visitor) const
2972     {
2973         mixin(visitIfNotNull!(identifier, templateArguments));
2974     }
2975     /** */ Token identifier;
2976     /** */ TemplateArguments templateArguments;
2977     mixin OpEquals;
2978 }
2979 
2980 ///
2981 final class TemplateMixinExpression : ExpressionNode
2982 {
2983 public:
2984     override void accept(ASTVisitor visitor) const
2985     {
2986         mixin(visitIfNotNull!(identifier, templateArguments, mixinTemplateName));
2987     }
2988     /** */ Token identifier;
2989     /** */ TemplateArguments templateArguments;
2990     /** */ MixinTemplateName mixinTemplateName;
2991     /** */ string comment;
2992     size_t line;
2993     mixin OpEquals;
2994 }
2995 
2996 ///
2997 final class TemplateParameter : ASTNode
2998 {
2999 public:
3000     override void accept(ASTVisitor visitor) const
3001     {
3002         mixin(visitIfNotNull!(templateTypeParameter, templateValueParameter,
3003             templateAliasParameter, templateTupleParameter,
3004             templateThisParameter));
3005     }
3006     /** */ TemplateTypeParameter templateTypeParameter;
3007     /** */ TemplateValueParameter templateValueParameter;
3008     /** */ TemplateAliasParameter templateAliasParameter;
3009     /** */ TemplateTupleParameter templateTupleParameter;
3010     /** */ TemplateThisParameter templateThisParameter;
3011     string comment;
3012     mixin OpEquals;
3013 }
3014 
3015 ///
3016 final class TemplateParameterList : ASTNode
3017 {
3018 public:
3019     override void accept(ASTVisitor visitor) const
3020     {
3021         mixin(visitIfNotNull!(items));
3022     }
3023     /** */ TemplateParameter[] items;
3024     mixin OpEquals;
3025 }
3026 
3027 ///
3028 final class TemplateParameters : ASTNode
3029 {
3030 public:
3031     override void accept(ASTVisitor visitor) const
3032     {
3033         mixin(visitIfNotNull!(templateParameterList));
3034     }
3035     /** */ TemplateParameterList templateParameterList;
3036     mixin OpEquals;
3037 }
3038 
3039 ///
3040 final class TemplateSingleArgument : ASTNode
3041 {
3042 public:
3043     override void accept(ASTVisitor visitor) const
3044     {
3045         mixin(visitIfNotNull!(token));
3046     }
3047     /** */ Token token;
3048     mixin OpEquals;
3049 }
3050 
3051 ///
3052 final class TemplateThisParameter : ASTNode
3053 {
3054 public:
3055     override void accept(ASTVisitor visitor) const
3056     {
3057         mixin(visitIfNotNull!(templateTypeParameter));
3058     }
3059     /** */ TemplateTypeParameter templateTypeParameter;
3060     mixin OpEquals;
3061 }
3062 
3063 ///
3064 final class TemplateTupleParameter : ASTNode
3065 {
3066 public:
3067     override void accept(ASTVisitor visitor) const
3068     {
3069         mixin(visitIfNotNull!(identifier));
3070     }
3071     /** */ Token identifier;
3072     mixin OpEquals;
3073 }
3074 
3075 ///
3076 final class TemplateTypeParameter : ASTNode
3077 {
3078 public:
3079     override void accept(ASTVisitor visitor) const
3080     {
3081         mixin(visitIfNotNull!(identifier, colonType, assignType));
3082     }
3083     /** */ Token identifier;
3084     /** */ Type colonType;
3085     /** */ Type assignType;
3086     mixin OpEquals;
3087 }
3088 
3089 ///
3090 final class TemplateValueParameter : ASTNode
3091 {
3092 public:
3093     override void accept(ASTVisitor visitor) const
3094     {
3095         mixin(visitIfNotNull!(type, identifier, assignExpression,
3096             templateValueParameterDefault));
3097     }
3098     /** */ Type type;
3099     /** */ Token identifier;
3100     /** */ ExpressionNode assignExpression;
3101     /** */ TemplateValueParameterDefault templateValueParameterDefault;
3102     mixin OpEquals;
3103 }
3104 
3105 ///
3106 final class TemplateValueParameterDefault : ASTNode
3107 {
3108 public:
3109     override void accept(ASTVisitor visitor) const
3110     {
3111         mixin(visitIfNotNull!(token, assignExpression));
3112     }
3113     /** */ ExpressionNode assignExpression;
3114     /** */ Token token;
3115     mixin OpEquals;
3116 }
3117 
3118 ///
3119 final class TernaryExpression : ExpressionNode
3120 {
3121 public:
3122     override void accept(ASTVisitor visitor) const
3123     {
3124         mixin(visitIfNotNull!(orOrExpression, expression, ternaryExpression));
3125     }
3126     /** */ ExpressionNode orOrExpression;
3127     /** */ ExpressionNode expression;
3128     /** */ ExpressionNode ternaryExpression;
3129     /// Store this so that we know where the ':' is
3130     Token colon;
3131     mixin OpEquals;
3132 }
3133 
3134 ///
3135 final class ThrowStatement : ASTNode
3136 {
3137 public:
3138     override void accept(ASTVisitor visitor) const
3139     {
3140         mixin(visitIfNotNull!(expression));
3141     }
3142     /** */ Expression expression;
3143     mixin OpEquals;
3144 }
3145 
3146 ///
3147 final class TraitsExpression : ExpressionNode
3148 {
3149 public:
3150     override void accept(ASTVisitor visitor) const
3151     {
3152         mixin(visitIfNotNull!(identifier, templateArgumentList));
3153     }
3154     /** */ Token identifier;
3155     /** */ TemplateArgumentList templateArgumentList;
3156     mixin OpEquals;
3157 }
3158 
3159 ///
3160 final class TryStatement : ASTNode
3161 {
3162 public:
3163     override void accept(ASTVisitor visitor) const
3164     {
3165         mixin(visitIfNotNull!(declarationOrStatement, catches, finally_));
3166     }
3167     /** */ DeclarationOrStatement declarationOrStatement;
3168     /** */ Catches catches;
3169     /** */ Finally finally_;
3170     mixin OpEquals;
3171 }
3172 
3173 ///
3174 final class Type : ASTNode
3175 {
3176 public:
3177     override void accept(ASTVisitor visitor) const
3178     {
3179         mixin(visitIfNotNull!(type2, typeSuffixes));
3180     }
3181 
3182     /** */ IdType[] typeConstructors;
3183     /** */ TypeSuffix[] typeSuffixes;
3184     /** */ Type2 type2;
3185     mixin OpEquals;
3186 }
3187 
3188 ///
3189 final class Type2 : ASTNode
3190 {
3191 public:
3192     override void accept(ASTVisitor visitor) const
3193     {
3194         mixin(visitIfNotNull!(symbol, typeofExpression,
3195             identifierOrTemplateChain, type, vector));
3196     }
3197 
3198     /** */ IdType builtinType;
3199     /** */ Symbol symbol;
3200     /** */ TypeofExpression typeofExpression;
3201     /** */ IdentifierOrTemplateChain identifierOrTemplateChain;
3202     /** */ IdType typeConstructor;
3203     /** */ Type type;
3204     /** */ Vector vector;
3205     mixin OpEquals;
3206 }
3207 
3208 ///
3209 final class TypeSpecialization : ASTNode
3210 {
3211 public:
3212     override void accept(ASTVisitor visitor) const
3213     {
3214         mixin(visitIfNotNull!(token, type));
3215     }
3216     /** */ Token token;
3217     /** */ Type type;
3218     mixin OpEquals;
3219 }
3220 
3221 ///
3222 final class TypeSuffix : ASTNode
3223 {
3224 public:
3225     override void accept(ASTVisitor visitor) const
3226     {
3227         mixin(visitIfNotNull!(type, low, high, delegateOrFunction, parameters,
3228             memberFunctionAttributes));
3229     }
3230 
3231     /** */ Token delegateOrFunction;
3232     /** */ Token star;
3233     /** */ bool array;
3234     /** */ Type type;
3235     /** */ ExpressionNode low;
3236     /** */ ExpressionNode high;
3237     /** */ Parameters parameters;
3238     /** */ MemberFunctionAttribute[] memberFunctionAttributes;
3239     mixin OpEquals;
3240 }
3241 
3242 ///
3243 final class TypeidExpression : ExpressionNode
3244 {
3245 public:
3246     override void accept(ASTVisitor visitor) const
3247     {
3248         mixin(visitIfNotNull!(type, expression));
3249     }
3250     /** */ Type type;
3251     /** */ Expression expression;
3252     mixin OpEquals;
3253 }
3254 
3255 ///
3256 final class TypeofExpression : ExpressionNode
3257 {
3258 public:
3259     override void accept(ASTVisitor visitor) const
3260     {
3261         mixin(visitIfNotNull!(expression, return_));
3262     }
3263     /** */ Expression expression;
3264     /** */ Token return_;
3265     mixin OpEquals;
3266 }
3267 
3268 ///
3269 final class UnaryExpression : ExpressionNode
3270 {
3271 public:
3272     override void accept(ASTVisitor visitor) const
3273     {
3274         // TODO prefix, postfix, unary
3275         mixin(visitIfNotNull!(primaryExpression, newExpression, deleteExpression,
3276             castExpression, functionCallExpression, argumentList, unaryExpression,
3277             type, identifierOrTemplateInstance, assertExpression, indexExpression));
3278     }
3279 
3280     /** */ Type type;
3281     /** */ PrimaryExpression primaryExpression;
3282     /** */ Token prefix;
3283     /** */ Token suffix;
3284     /** */ UnaryExpression unaryExpression;
3285     /** */ NewExpression newExpression;
3286     /** */ DeleteExpression deleteExpression;
3287     /** */ CastExpression castExpression;
3288     /** */ FunctionCallExpression functionCallExpression;
3289     /** */ ArgumentList argumentList;
3290     /** */ IdentifierOrTemplateInstance identifierOrTemplateInstance;
3291     /** */ AssertExpression assertExpression;
3292     /** */ IndexExpression indexExpression;
3293     mixin OpEquals;
3294 }
3295 
3296 ///
3297 final class UnionDeclaration : ASTNode
3298 {
3299 public:
3300     override void accept(ASTVisitor visitor) const
3301     {
3302         mixin(visitIfNotNull!(name, templateParameters, constraint, structBody));
3303     }
3304 
3305     /** */ Token name;
3306     /** */ TemplateParameters templateParameters;
3307     /** */ Constraint constraint;
3308     /** */ StructBody structBody;
3309     /** */ string comment;
3310     mixin OpEquals;
3311 }
3312 
3313 ///
3314 final class Unittest : ASTNode
3315 {
3316 public:
3317     override void accept(ASTVisitor visitor) const
3318     {
3319         mixin(visitIfNotNull!(blockStatement));
3320     }
3321     /** */ BlockStatement blockStatement;
3322     /** */ string comment;
3323     mixin OpEquals;
3324 }
3325 
3326 ///
3327 final class VariableDeclaration : ASTNode
3328 {
3329 public:
3330     override void accept(ASTVisitor visitor) const
3331     {
3332         mixin(visitIfNotNull!(attributes, storageClasses, type, declarators, autoDeclaration));
3333     }
3334     /** */ Type type;
3335     /** */ Declarator[] declarators;
3336     /** */ StorageClass[] storageClasses;
3337     /** */ Attribute[] attributes;
3338     /** */ AutoDeclaration autoDeclaration;
3339     /** */ string comment;
3340     bool isEnum;
3341     mixin OpEquals;
3342 }
3343 
3344 ///
3345 final class Vector : ASTNode
3346 {
3347 public:
3348     override void accept(ASTVisitor visitor) const
3349     {
3350         mixin(visitIfNotNull!(type));
3351     }
3352     /** */ Type type;
3353     mixin OpEquals;
3354 }
3355 
3356 ///
3357 final class VersionCondition : ASTNode
3358 {
3359 public:
3360     override void accept(ASTVisitor visitor) const
3361     {
3362         mixin(visitIfNotNull!(token));
3363     }
3364     /** */ size_t versionIndex;
3365     /** */ Token token;
3366 
3367     mixin OpEquals;
3368 }
3369 
3370 ///
3371 final class VersionSpecification : ASTNode
3372 {
3373 public:
3374     override void accept(ASTVisitor visitor) const
3375     {
3376         mixin(visitIfNotNull!(token));
3377     }
3378     /** */ Token token;
3379     mixin OpEquals;
3380 }
3381 
3382 ///
3383 final class WhileStatement : ASTNode
3384 {
3385 public:
3386     override void accept(ASTVisitor visitor) const
3387     {
3388         mixin(visitIfNotNull!(expression, declarationOrStatement));
3389     }
3390 
3391     /** */ Expression expression;
3392     /** */ DeclarationOrStatement declarationOrStatement;
3393     /** */ size_t startIndex;
3394     mixin OpEquals;
3395 }
3396 
3397 ///
3398 final class WithStatement : ASTNode
3399 {
3400 public:
3401     override void accept(ASTVisitor visitor) const
3402     {
3403         mixin(visitIfNotNull!(expression, statementNoCaseNoDefault));
3404     }
3405 
3406     /** */ Expression expression;
3407     /** */ StatementNoCaseNoDefault statementNoCaseNoDefault;
3408     mixin OpEquals;
3409 }
3410 
3411 ///
3412 final class XorExpression : ExpressionNode
3413 {
3414 public:
3415     override void accept(ASTVisitor visitor) const
3416     {
3417         mixin(visitIfNotNull!(left, right));
3418     }
3419     mixin BinaryExpressionBody;
3420     mixin OpEquals;
3421 }