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