Internally these would treat the cast same as a normal conversion from int[7] to int[], which allows code at CTFE to erroneously succeed where it would raise a SEGV at run-time.
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 | 1 |
void visit(ASTCodegen.SwitchErrorStatement s) { visit(cast(ASTCodegen.Statement)s); } |
35 |
void visit(ASTCodegen.DebugStatement s) { visit(cast(ASTCodegen.Statement)s); } |
|
36 | 1 |
void visit(ASTCodegen.DtorExpStatement s) { visit(cast(ASTCodegen.ExpStatement)s); } |
37 |
void visit(ASTCodegen.ForwardingStatement s) { visit(cast(ASTCodegen.Statement)s); } |
|
38 | 1 |
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 | 1 |
void visit(ASTCodegen.ForwardingAttribDeclaration s) { visit(cast(ASTCodegen.AttribDeclaration)s); } |
45 | 1 |
void visit(ASTCodegen.ThisDeclaration s) { visit(cast(ASTCodegen.VarDeclaration)s); } |
46 | 1 |
void visit(ASTCodegen.TypeInfoDeclaration s) { visit(cast(ASTCodegen.VarDeclaration)s); } |
47 | 1 |
void visit(ASTCodegen.TypeInfoStructDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); } |
48 |
void visit(ASTCodegen.TypeInfoClassDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); } |
|
49 | 1 |
void visit(ASTCodegen.TypeInfoInterfaceDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); } |
50 | 1 |
void visit(ASTCodegen.TypeInfoPointerDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); } |
51 | 1 |
void visit(ASTCodegen.TypeInfoArrayDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); } |
52 | 1 |
void visit(ASTCodegen.TypeInfoStaticArrayDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); } |
53 | 1 |
void visit(ASTCodegen.TypeInfoAssociativeArrayDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); } |
54 | 1 |
void visit(ASTCodegen.TypeInfoEnumDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); } |
55 | 1 |
void visit(ASTCodegen.TypeInfoFunctionDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); } |
56 | 1 |
void visit(ASTCodegen.TypeInfoDelegateDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); } |
57 | 1 |
void visit(ASTCodegen.TypeInfoTupleDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); } |
58 | 1 |
void visit(ASTCodegen.TypeInfoConstDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); } |
59 | 1 |
void visit(ASTCodegen.TypeInfoInvariantDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); } |
60 | 1 |
void visit(ASTCodegen.TypeInfoSharedDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); } |
61 | 1 |
void visit(ASTCodegen.TypeInfoWildDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); } |
62 | 1 |
void visit(ASTCodegen.TypeInfoVectorDeclaration s) { visit(cast(ASTCodegen.TypeInfoDeclaration)s); } |
63 | 1 |
void visit(ASTCodegen.FuncAliasDeclaration s) { visit(cast(ASTCodegen.FuncDeclaration)s); } |
64 |
void visit(ASTCodegen.ErrorInitializer i) { visit(cast(ASTCodegen.Initializer)i); } |
|
65 | 1 |
void visit(ASTCodegen.ErrorExp e) { visit(cast(ASTCodegen.Expression)e); } |
66 | 1 |
void visit(ASTCodegen.ComplexExp e) { visit(cast(ASTCodegen.Expression)e); } |
67 | 1 |
void visit(ASTCodegen.StructLiteralExp e) { visit(cast(ASTCodegen.Expression)e); } |
68 |
void visit(ASTCodegen.ObjcClassReferenceExp e) { visit(cast(ASTCodegen.Expression)e); } |
|
69 | 1 |
void visit(ASTCodegen.SymOffExp e) { visit(cast(ASTCodegen.SymbolExp)e); } |
70 | 1 |
void visit(ASTCodegen.OverExp e) { visit(cast(ASTCodegen.Expression)e); } |
71 | 1 |
void visit(ASTCodegen.HaltExp e) { visit(cast(ASTCodegen.Expression)e); } |
72 |
void visit(ASTCodegen.DotTemplateExp e) { visit(cast(ASTCodegen.UnaExp)e); } |
|
73 | 1 |
void visit(ASTCodegen.DotVarExp e) { visit(cast(ASTCodegen.UnaExp)e); } |
74 | 1 |
void visit(ASTCodegen.DelegateExp e) { visit(cast(ASTCodegen.UnaExp)e); } |
75 | 1 |
void visit(ASTCodegen.DotTypeExp e) { visit(cast(ASTCodegen.UnaExp)e); } |
76 | 1 |
void visit(ASTCodegen.VectorExp e) { visit(cast(ASTCodegen.UnaExp)e); } |
77 | 1 |
void visit(ASTCodegen.VectorArrayExp e) { visit(cast(ASTCodegen.UnaExp)e); } |
78 | 1 |
void visit(ASTCodegen.SliceExp e) { visit(cast(ASTCodegen.UnaExp)e); } |
79 | 1 |
void visit(ASTCodegen.ArrayLengthExp e) { visit(cast(ASTCodegen.UnaExp)e); } |
80 | 1 |
void visit(ASTCodegen.DelegatePtrExp e) { visit(cast(ASTCodegen.UnaExp)e); } |
81 | 1 |
void visit(ASTCodegen.DelegateFuncptrExp e) { visit(cast(ASTCodegen.UnaExp)e); } |
82 |
void visit(ASTCodegen.DotExp e) { visit(cast(ASTCodegen.BinExp)e); } |
|
83 | 1 |
void visit(ASTCodegen.IndexExp e) { visit(cast(ASTCodegen.BinExp)e); } |
84 | 1 |
void visit(ASTCodegen.ConstructExp e) { visit(cast(ASTCodegen.AssignExp)e); } |
85 | 1 |
void visit(ASTCodegen.BlitExp e) { visit(cast(ASTCodegen.AssignExp)e); } |
86 | 1 |
void visit(ASTCodegen.RemoveExp e) { visit(cast(ASTCodegen.BinExp)e); } |
87 | 1 |
void visit(ASTCodegen.ClassReferenceExp e) { visit(cast(ASTCodegen.Expression)e); } |
88 | 1 |
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 | 1 |
final extern (D) this() |
244 |
{
|
|
245 |
}
|
|
246 |
}
|
Read our documentation on viewing source code .