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