|
|
|||
File indexing completed on 2026-05-10 08:36:34
0001 //===--- DynamicRecursiveASTVisitor.h - Virtual AST Visitor -----*- C++ -*-===// 0002 // 0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 0004 // See https://llvm.org/LICENSE.txt for license information. 0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 0006 // 0007 //===----------------------------------------------------------------------===// 0008 // 0009 // This file defines the DynamicRecursiveASTVisitor interface, which acts 0010 // identically to RecursiveASTVisitor, except that it uses virtual dispatch 0011 // instead of CRTP, which greatly improves compile times and binary size. 0012 // 0013 // Prefer to use this over RecursiveASTVisitor whenever possible. 0014 // 0015 //===----------------------------------------------------------------------===// 0016 #ifndef LLVM_CLANG_AST_DYNAMIC_RECURSIVE_AST_VISITOR_H 0017 #define LLVM_CLANG_AST_DYNAMIC_RECURSIVE_AST_VISITOR_H 0018 0019 #include "clang/AST/Attr.h" 0020 #include "clang/AST/ExprConcepts.h" 0021 #include "clang/AST/TypeLoc.h" 0022 0023 namespace clang { 0024 class ASTContext; 0025 0026 /// Recursive AST visitor that supports extension via dynamic dispatch. 0027 /// 0028 /// Like RecursiveASTVisitor, this class allows for traversal of arbitrarily 0029 /// complex ASTs. The main difference is that this uses virtual functions 0030 /// instead of CRTP, which greatly improves compile times of Clang itself, 0031 /// as well as binary size. 0032 /// 0033 /// Instead of functions (e.g. shouldVisitImplicitCode()), this class 0034 /// uses member variables (e.g. ShouldVisitImplicitCode) to control 0035 /// visitation behaviour. 0036 /// 0037 /// However, there is no support for overriding some of the less commonly 0038 /// used features of the RAV, such as WalkUpFromX or attribute traversal 0039 /// (attributes can still be traversed, but you can't change what happens 0040 /// when we traverse one). 0041 /// 0042 /// The following is a list of RAV features that are NOT customisable: 0043 /// 0044 /// - Visiting attributes, 0045 /// - Overriding WalkUpFromX, 0046 /// - Overriding getStmtChildren(). 0047 /// 0048 /// Furthermore, post-order traversal is not supported at all. 0049 /// 0050 /// Prefer to use this over RecursiveASTVisitor unless you absolutely 0051 /// need to use one of the features listed above (e.g. overriding 0052 /// WalkUpFromX or post-order traversal). 0053 /// 0054 /// \see RecursiveASTVisitor. 0055 class DynamicRecursiveASTVisitor { 0056 public: 0057 /// Whether this visitor should recurse into template instantiations. 0058 bool ShouldVisitTemplateInstantiations = false; 0059 0060 /// Whether this visitor should recurse into the types of TypeLocs. 0061 bool ShouldWalkTypesOfTypeLocs = true; 0062 0063 /// Whether this visitor should recurse into implicit code, e.g. 0064 /// implicit constructors and destructors. 0065 bool ShouldVisitImplicitCode = false; 0066 0067 /// Whether this visitor should recurse into lambda body. 0068 bool ShouldVisitLambdaBody = true; 0069 0070 protected: 0071 DynamicRecursiveASTVisitor() = default; 0072 DynamicRecursiveASTVisitor(DynamicRecursiveASTVisitor &&) = default; 0073 DynamicRecursiveASTVisitor(const DynamicRecursiveASTVisitor &) = default; 0074 DynamicRecursiveASTVisitor & 0075 operator=(DynamicRecursiveASTVisitor &&) = default; 0076 DynamicRecursiveASTVisitor & 0077 operator=(const DynamicRecursiveASTVisitor &) = default; 0078 0079 public: 0080 virtual void anchor(); 0081 virtual ~DynamicRecursiveASTVisitor() = default; 0082 0083 /// Recursively visits an entire AST, starting from the TranslationUnitDecl. 0084 /// \returns false if visitation was terminated early. 0085 virtual bool TraverseAST(ASTContext &AST); 0086 0087 /// Recursively visit an attribute, by dispatching to 0088 /// Traverse*Attr() based on the argument's dynamic type. 0089 /// 0090 /// \returns false if the visitation was terminated early, true 0091 /// otherwise (including when the argument is a Null type location). 0092 virtual bool TraverseAttr(Attr *At); 0093 0094 /// Recursively visit a constructor initializer. This 0095 /// automatically dispatches to another visitor for the initializer 0096 /// expression, but not for the name of the initializer, so may 0097 /// be overridden for clients that need access to the name. 0098 /// 0099 /// \returns false if the visitation was terminated early, true otherwise. 0100 virtual bool TraverseConstructorInitializer(CXXCtorInitializer *Init); 0101 0102 /// Recursively visit a base specifier. This can be overridden by a 0103 /// subclass. 0104 /// 0105 /// \returns false if the visitation was terminated early, true otherwise. 0106 virtual bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base); 0107 0108 /// Recursively visit a declaration, by dispatching to 0109 /// Traverse*Decl() based on the argument's dynamic type. 0110 /// 0111 /// \returns false if the visitation was terminated early, true 0112 /// otherwise (including when the argument is NULL). 0113 virtual bool TraverseDecl(Decl *D); 0114 0115 /// Recursively visit a name with its location information. 0116 /// 0117 /// \returns false if the visitation was terminated early, true otherwise. 0118 virtual bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo); 0119 0120 /// Recursively visit a lambda capture. \c Init is the expression that 0121 /// will be used to initialize the capture. 0122 /// 0123 /// \returns false if the visitation was terminated early, true otherwise. 0124 virtual bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C, 0125 Expr *Init); 0126 0127 /// Recursively visit a C++ nested-name-specifier. 0128 /// 0129 /// \returns false if the visitation was terminated early, true otherwise. 0130 virtual bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS); 0131 0132 /// Recursively visit a C++ nested-name-specifier with location 0133 /// information. 0134 /// 0135 /// \returns false if the visitation was terminated early, true otherwise. 0136 virtual bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS); 0137 0138 /// Recursively visit a statement or expression, by 0139 /// dispatching to Traverse*() based on the argument's dynamic type. 0140 /// 0141 /// \returns false if the visitation was terminated early, true 0142 /// otherwise (including when the argument is nullptr). 0143 virtual bool TraverseStmt(Stmt *S); 0144 0145 /// Recursively visit a template argument and dispatch to the 0146 /// appropriate method for the argument type. 0147 /// 0148 /// \returns false if the visitation was terminated early, true otherwise. 0149 // FIXME: migrate callers to TemplateArgumentLoc instead. 0150 virtual bool TraverseTemplateArgument(const TemplateArgument &Arg); 0151 0152 /// Recursively visit a template argument location and dispatch to the 0153 /// appropriate method for the argument type. 0154 /// 0155 /// \returns false if the visitation was terminated early, true otherwise. 0156 virtual bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc); 0157 0158 /// Recursively visit a set of template arguments. 0159 /// 0160 /// \returns false if the visitation was terminated early, true otherwise. 0161 // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead. 0162 // Not virtual for now because no-one overrides it. 0163 bool TraverseTemplateArguments(ArrayRef<TemplateArgument> Args); 0164 0165 /// Recursively visit a template name and dispatch to the 0166 /// appropriate method. 0167 /// 0168 /// \returns false if the visitation was terminated early, true otherwise. 0169 virtual bool TraverseTemplateName(TemplateName Template); 0170 0171 /// Recursively visit a type, by dispatching to 0172 /// Traverse*Type() based on the argument's getTypeClass() property. 0173 /// 0174 /// \returns false if the visitation was terminated early, true 0175 /// otherwise (including when the argument is a Null type). 0176 virtual bool TraverseType(QualType T); 0177 0178 /// Recursively visit a type with location, by dispatching to 0179 /// Traverse*TypeLoc() based on the argument type's getTypeClass() property. 0180 /// 0181 /// \returns false if the visitation was terminated early, true 0182 /// otherwise (including when the argument is a Null type location). 0183 virtual bool TraverseTypeLoc(TypeLoc TL); 0184 0185 /// Recursively visit an Objective-C protocol reference with location 0186 /// information. 0187 /// 0188 /// \returns false if the visitation was terminated early, true otherwise. 0189 virtual bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLoc); 0190 0191 /// Traverse a concept (requirement). 0192 virtual bool TraverseTypeConstraint(const TypeConstraint *C); 0193 virtual bool TraverseConceptRequirement(concepts::Requirement *R); 0194 virtual bool TraverseConceptTypeRequirement(concepts::TypeRequirement *R); 0195 virtual bool TraverseConceptExprRequirement(concepts::ExprRequirement *R); 0196 virtual bool TraverseConceptNestedRequirement(concepts::NestedRequirement *R); 0197 virtual bool TraverseConceptReference(ConceptReference *CR); 0198 virtual bool VisitConceptReference(ConceptReference *CR) { return true; } 0199 0200 /// Visit a node. 0201 virtual bool VisitAttr(Attr *A) { return true; } 0202 virtual bool VisitDecl(Decl *D) { return true; } 0203 virtual bool VisitStmt(Stmt *S) { return true; } 0204 virtual bool VisitType(Type *T) { return true; } 0205 virtual bool VisitTypeLoc(TypeLoc TL) { return true; } 0206 0207 /// Walk up from a node. 0208 bool WalkUpFromDecl(Decl *D) { return VisitDecl(D); } 0209 bool WalkUpFromStmt(Stmt *S) { return VisitStmt(S); } 0210 bool WalkUpFromType(Type *T) { return VisitType(T); } 0211 bool WalkUpFromTypeLoc(TypeLoc TL) { return VisitTypeLoc(TL); } 0212 0213 /// Invoked before visiting a statement or expression via data recursion. 0214 /// 0215 /// \returns false to skip visiting the node, true otherwise. 0216 virtual bool dataTraverseStmtPre(Stmt *S) { return true; } 0217 0218 /// Invoked after visiting a statement or expression via data recursion. 0219 /// This is not invoked if the previously invoked \c dataTraverseStmtPre 0220 /// returned false. 0221 /// 0222 /// \returns false if the visitation was terminated early, true otherwise. 0223 virtual bool dataTraverseStmtPost(Stmt *S) { return true; } 0224 virtual bool dataTraverseNode(Stmt *S); 0225 0226 #define DEF_TRAVERSE_TMPL_INST(kind) \ 0227 virtual bool TraverseTemplateInstantiations(kind##TemplateDecl *D); 0228 DEF_TRAVERSE_TMPL_INST(Class) 0229 DEF_TRAVERSE_TMPL_INST(Var) 0230 DEF_TRAVERSE_TMPL_INST(Function) 0231 #undef DEF_TRAVERSE_TMPL_INST 0232 0233 // Decls. 0234 #define ABSTRACT_DECL(DECL) 0235 #define DECL(CLASS, BASE) virtual bool Traverse##CLASS##Decl(CLASS##Decl *D); 0236 #include "clang/AST/DeclNodes.inc" 0237 0238 #define DECL(CLASS, BASE) \ 0239 bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D); \ 0240 virtual bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; } 0241 #include "clang/AST/DeclNodes.inc" 0242 0243 // Stmts. 0244 #define ABSTRACT_STMT(STMT) 0245 #define STMT(CLASS, PARENT) virtual bool Traverse##CLASS(CLASS *S); 0246 #include "clang/AST/StmtNodes.inc" 0247 0248 #define STMT(CLASS, PARENT) \ 0249 bool WalkUpFrom##CLASS(CLASS *S); \ 0250 virtual bool Visit##CLASS(CLASS *S) { return true; } 0251 #include "clang/AST/StmtNodes.inc" 0252 0253 // Types. 0254 #define ABSTRACT_TYPE(CLASS, BASE) 0255 #define TYPE(CLASS, BASE) virtual bool Traverse##CLASS##Type(CLASS##Type *T); 0256 #include "clang/AST/TypeNodes.inc" 0257 0258 #define TYPE(CLASS, BASE) \ 0259 bool WalkUpFrom##CLASS##Type(CLASS##Type *T); \ 0260 virtual bool Visit##CLASS##Type(CLASS##Type *T) { return true; } 0261 #include "clang/AST/TypeNodes.inc" 0262 0263 // TypeLocs. 0264 #define ABSTRACT_TYPELOC(CLASS, BASE) 0265 #define TYPELOC(CLASS, BASE) \ 0266 virtual bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL); 0267 #include "clang/AST/TypeLocNodes.def" 0268 0269 #define TYPELOC(CLASS, BASE) \ 0270 bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL); \ 0271 virtual bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; } 0272 #include "clang/AST/TypeLocNodes.def" 0273 }; 0274 } // namespace clang 0275 0276 #endif // LLVM_CLANG_AST_DYNAMIC_RECURSIVE_AST_VISITOR_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|