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 }