1 /**
2 * Provides a visitor class visiting all AST nodes present in the compiler.
3 *
4 * Copyright: Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved
5 * Authors: $(LINK2 http://www.digitalmars.com, Walter Bright)
6 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
7 * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/visitor.d, _visitor.d)
8 * Documentation: https://dlang.org/phobos/dmd_visitor.html
9 * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/visitor.d
10 */
11
12 module dmd.visitor;
13
14 import dmd.astcodegen;
15 import dmd.parsetimevisitor;
16 import dmd.tokens;
17 import dmd.transitivevisitor;
18 import dmd.expression;
19 import dmd.root.rootobject;
20
21 /**
22 * Classic Visitor class which implements visit methods for all the AST
23 * nodes present in the compiler. The visit methods for AST nodes
24 * created at parse time are inherited while the visiting methods
25 * for AST nodes created at semantic time are implemented.
26 */
27 extern (C++) class Visitor : ParseTimeVisitor!ASTCodegen
28 {
29 alias visit = ParseTimeVisitor!ASTCodegen.visit;
30 public:
31 void visit(ASTCodegen.ErrorStatement s) { visit(cast(ASTCodegen.Statement)s); }
32 void visit(ASTCodegen.PeelStatement s) { visit(cast(ASTCodegen.Statement)s); }
33 void visit(ASTCodegen.UnrolledLoopStatement s) { visit(cast(ASTCodegen.Statement)s); }
34 void visit(ASTCodegen.SwitchErrorStatement s) { visit(cast(ASTCodegen.Statement)s); }
35 void visit(ASTCodegen.DebugStatement s) { visit(cast(ASTCodegen.Statement)s); }
36 void visit(ASTCodegen.DtorExpStatement s) { visit(cast(ASTCodegen.ExpStatement)s); }
37 void visit(ASTCodegen.ForwardingStatement s) { visit(cast(ASTCodegen.Statement)s); }
38 void visit(ASTCodegen.OverloadSet s) { visit(cast(ASTCodegen.Dsymbol)s); }
39 void visit(ASTCodegen.LabelDsymbol s) { visit(cast(ASTCodegen.Dsymbol)s); }
40 void visit(ASTCodegen.WithScopeSymbol s) { visit(cast(ASTCodegen.ScopeDsymbol)s); }
41 void visit(ASTCodegen.ArrayScopeSymbol s) { visit(cast(ASTCodegen.ScopeDsymbol)s); }
42 void visit(ASTCodegen.OverDeclaration s) { visit(cast(ASTCodegen.Declaration)s); }
43 void visit(ASTCodegen.SymbolDeclaration s) { visit(cast(ASTCodegen.Declaration)s); }
44 void visit(ASTCodegen.ForwardingAttribDeclaration s) { visit(cast(ASTCodegen.AttribDeclaration)s); }
45 void visit(ASTCodegen.ThisDeclaration s) { visit(cast(ASTCodegen.VarDeclaration)s); }
46 void visit(ASTCodegen.TypeInfoDeclaration s) { visit(cast(ASTCodegen.VarDeclaration)s); }
47 void visit(ASTCodegen.TypeInfoStructDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }
48 void visit(ASTCodegen.TypeInfoClassDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }
49 void visit(ASTCodegen.TypeInfoInterfaceDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }
50 void visit(ASTCodegen.TypeInfoPointerDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }
51 void visit(ASTCodegen.TypeInfoArrayDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }
52 void visit(ASTCodegen.TypeInfoStaticArrayDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }
53 void visit(ASTCodegen.TypeInfoAssociativeArrayDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }
54 void visit(ASTCodegen.TypeInfoEnumDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }
55 void visit(ASTCodegen.TypeInfoFunctionDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }
56 void visit(ASTCodegen.TypeInfoDelegateDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }
57 void visit(ASTCodegen.TypeInfoTupleDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }
58 void visit(ASTCodegen.TypeInfoConstDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }
59 void visit(ASTCodegen.TypeInfoInvariantDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }
60 void visit(ASTCodegen.TypeInfoSharedDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }
61 void visit(ASTCodegen.TypeInfoWildDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }
62 void visit(ASTCodegen.TypeInfoVectorDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); }
63 void visit(ASTCodegen.FuncAliasDeclaration s) { visit(cast(ASTCodegen.FuncDeclaration)s); }
64 void visit(ASTCodegen.ErrorInitializer i) { visit(cast(ASTCodegen.Initializer)i); }
65 void visit(ASTCodegen.ErrorExp e) { visit(cast(ASTCodegen.Expression)e); }
66 void visit(ASTCodegen.ComplexExp e) { visit(cast(ASTCodegen.Expression)e); }
67 void visit(ASTCodegen.StructLiteralExp e) { visit(cast(ASTCodegen.Expression)e); }
68 void visit(ASTCodegen.ObjcClassReferenceExp e) { visit(cast(ASTCodegen.Expression)e); }
69 void visit(ASTCodegen.SymOffExp e) { visit(cast(ASTCodegen.SymbolExp)e); }
70 void visit(ASTCodegen.OverExp e) { visit(cast(ASTCodegen.Expression)e); }
71 void visit(ASTCodegen.HaltExp e) { visit(cast(ASTCodegen.Expression)e); }
72 void visit(ASTCodegen.DotTemplateExp e) { visit(cast(ASTCodegen.UnaExp)e); }
73 void visit(ASTCodegen.DotVarExp e) { visit(cast(ASTCodegen.UnaExp)e); }
74 void visit(ASTCodegen.DelegateExp e) { visit(cast(ASTCodegen.UnaExp)e); }
75 void visit(ASTCodegen.DotTypeExp e) { visit(cast(ASTCodegen.UnaExp)e); }
76 void visit(ASTCodegen.VectorExp e) { visit(cast(ASTCodegen.UnaExp)e); }
77 void visit(ASTCodegen.VectorArrayExp e) { visit(cast(ASTCodegen.UnaExp)e); }
78 void visit(ASTCodegen.SliceExp e) { visit(cast(ASTCodegen.UnaExp)e); }
79 void visit(ASTCodegen.ArrayLengthExp e) { visit(cast(ASTCodegen.UnaExp)e); }
80 void visit(ASTCodegen.DelegatePtrExp e) { visit(cast(ASTCodegen.UnaExp)e); }
81 void visit(ASTCodegen.DelegateFuncptrExp e) { visit(cast(ASTCodegen.UnaExp)e); }
82 void visit(ASTCodegen.DotExp e) { visit(cast(ASTCodegen.BinExp)e); }
83 void visit(ASTCodegen.IndexExp e) { visit(cast(ASTCodegen.BinExp)e); }
84 void visit(ASTCodegen.ConstructExp e) { visit(cast(ASTCodegen.AssignExp)e); }
85 void visit(ASTCodegen.BlitExp e) { visit(cast(ASTCodegen.AssignExp)e); }
86 void visit(ASTCodegen.RemoveExp e) { visit(cast(ASTCodegen.BinExp)e); }
87 void visit(ASTCodegen.ClassReferenceExp e) { visit(cast(ASTCodegen.Expression)e); }
88 void visit(ASTCodegen.VoidInitExp e) { visit(cast(ASTCodegen.Expression)e); }
89 void visit(ASTCodegen.ThrownExceptionExp e) { visit(cast(ASTCodegen.Expression)e); }
90 }
91
92 /**
93 * The PermissiveVisitor overrides the root AST nodes with
94 * empty visiting methods.
95 */
96 extern (C++) class SemanticTimePermissiveVisitor : Visitor
97 {
98 alias visit = Visitor.visit;
99
100 override void visit(ASTCodegen.Dsymbol){}
101 override void visit(ASTCodegen.Parameter){}
102 override void visit(ASTCodegen.Statement){}
103 override void visit(ASTCodegen.Type){}
104 override void visit(ASTCodegen.Expression){}
105 override void visit(ASTCodegen.TemplateParameter){}
106 override void visit(ASTCodegen.Condition){}
107 override void visit(ASTCodegen.Initializer){}
108 }
109
110 /**
111 * The TransitiveVisitor implements the AST traversal logic for all AST nodes.
112 */
113 extern (C++) class SemanticTimeTransitiveVisitor : SemanticTimePermissiveVisitor
114 {
115 alias visit = SemanticTimePermissiveVisitor.visit;
116
117 mixin ParseVisitMethods!ASTCodegen __methods;
118 alias visit = __methods.visit;
119
120 override void visit(ASTCodegen.PeelStatement s)
121 {
122 if (s.s)
123 s.s.accept(this);
124 }
125
126 override void visit(ASTCodegen.UnrolledLoopStatement s)
127 {
128 foreach(sx; *s.statements)
129 {
130 if (sx)
131 sx.accept(this);
132 }
133 }
134
135 override void visit(ASTCodegen.DebugStatement s)
136 {
137 if (s.statement)
138 s.statement.accept(this);
139 }
140
141 override void visit(ASTCodegen.ForwardingStatement s)
142 {
143 if (s.statement)
144 s.statement.accept(this);
145 }
146
147 override void visit(ASTCodegen.StructLiteralExp e)
148 {
149 // CTFE can generate struct literals that contain an AddrExp pointing to themselves,
150 // need to avoid infinite recursion.
151 if (!(e.stageflags & stageToCBuffer))
152 {
153 int old = e.stageflags;
154 e.stageflags |= stageToCBuffer;
155 foreach (el; *e.elements)
156 if (el)
157 el.accept(this);
158 e.stageflags = old;
159 }
160 }
161
162 override void visit(ASTCodegen.DotTemplateExp e)
163 {
164 e.e1.accept(this);
165 }
166
167 override void visit(ASTCodegen.DotVarExp e)
168 {
169 e.e1.accept(this);
170 }
171
172 override void visit(ASTCodegen.DelegateExp e)
173 {
174 if (!e.func.isNested() || e.func.needThis())
175 e.e1.accept(this);
176 }
177
178 override void visit(ASTCodegen.DotTypeExp e)
179 {
180 e.e1.accept(this);
181 }
182
183 override void visit(ASTCodegen.VectorExp e)
184 {
185 visitType(e.to);
186 e.e1.accept(this);
187 }
188
189 override void visit(ASTCodegen.VectorArrayExp e)
190 {
191 e.e1.accept(this);
192 }
193
194 override void visit(ASTCodegen.SliceExp e)
195 {
196 e.e1.accept(this);
197 if (e.upr)
198 e.upr.accept(this);
199 if (e.lwr)
200 e.lwr.accept(this);
201 }
202
203 override void visit(ASTCodegen.ArrayLengthExp e)
204 {
205 e.e1.accept(this);
206 }
207
208 override void visit(ASTCodegen.DelegatePtrExp e)
209 {
210 e.e1.accept(this);
211 }
212
213 override void visit(ASTCodegen.DelegateFuncptrExp e)
214 {
215 e.e1.accept(this);
216 }
217
218 override void visit(ASTCodegen.DotExp e)
219 {
220 e.e1.accept(this);
221 e.e2.accept(this);
222 }
223
224 override void visit(ASTCodegen.IndexExp e)
225 {
226 e.e1.accept(this);
227 e.e2.accept(this);
228 }
229
230 override void visit(ASTCodegen.RemoveExp e)
231 {
232 e.e1.accept(this);
233 e.e2.accept(this);
234 }
235 }
236
237 extern (C++) class StoppableVisitor : Visitor
238 {
239 alias visit = Visitor.visit;
240 public:
241 bool stop;
242
243 final extern (D) this()
244 {
245 }
246 }