clang 22.0.0git
DynamicRecursiveASTVisitor.h
Go to the documentation of this file.
1//===--- DynamicRecursiveASTVisitor.h - Virtual AST Visitor -----*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the DynamicRecursiveASTVisitor interface, which acts
10// identically to RecursiveASTVisitor, except that it uses virtual dispatch
11// instead of CRTP, which greatly improves compile times and binary size.
12//
13// Prefer to use this over RecursiveASTVisitor whenever possible.
14//
15//===----------------------------------------------------------------------===//
16#ifndef LLVM_CLANG_AST_DYNAMIC_RECURSIVE_AST_VISITOR_H
17#define LLVM_CLANG_AST_DYNAMIC_RECURSIVE_AST_VISITOR_H
18
19#include "clang/AST/Attr.h"
21#include "clang/AST/TypeLoc.h"
22
23namespace clang {
24class ASTContext;
25
26/// Recursive AST visitor that supports extension via dynamic dispatch.
27///
28/// Like RecursiveASTVisitor, this class allows for traversal of arbitrarily
29/// complex ASTs. The main difference is that this uses virtual functions
30/// instead of CRTP, which greatly improves compile times of Clang itself,
31/// as well as binary size.
32///
33/// Instead of functions (e.g. shouldVisitImplicitCode()), this class
34/// uses member variables (e.g. ShouldVisitImplicitCode) to control
35/// visitation behaviour.
36///
37/// However, there is no support for overriding some of the less commonly
38/// used features of the RAV, such as WalkUpFromX or attribute traversal
39/// (attributes can still be traversed, but you can't change what happens
40/// when we traverse one).
41///
42/// The following is a list of RAV features that are NOT customisable:
43///
44/// - Visiting attributes,
45/// - Overriding WalkUpFromX,
46/// - Overriding getStmtChildren().
47///
48/// Furthermore, post-order traversal is not supported at all.
49///
50/// Prefer to use this over RecursiveASTVisitor unless you absolutely
51/// need to use one of the features listed above (e.g. overriding
52/// WalkUpFromX or post-order traversal).
53///
54/// \see RecursiveASTVisitor.
55template <bool IsConst> class DynamicRecursiveASTVisitorBase {
56protected:
57 template <typename ASTNode>
58 using MaybeConst = std::conditional_t<IsConst, const ASTNode, ASTNode>;
59
60public:
61 /// Whether this visitor should recurse into template instantiations.
63
64 /// Whether this visitor should recurse into the types of TypeLocs.
66
67 /// Whether this visitor should recurse into implicit code, e.g.
68 /// implicit constructors and destructors.
70
71 /// Whether this visitor should recurse into lambda body.
73
74protected:
78 default;
83
84public:
85 virtual void anchor();
87
88 /// Recursively visits an entire AST, starting from the TranslationUnitDecl.
89 /// \returns false if visitation was terminated early.
91
92 /// Recursively visit an attribute, by dispatching to
93 /// Traverse*Attr() based on the argument's dynamic type.
94 ///
95 /// \returns false if the visitation was terminated early, true
96 /// otherwise (including when the argument is a Null type location).
97 virtual bool TraverseAttr(MaybeConst<Attr> *At);
98
99 /// Recursively visit a constructor initializer. This
100 /// automatically dispatches to another visitor for the initializer
101 /// expression, but not for the name of the initializer, so may
102 /// be overridden for clients that need access to the name.
103 ///
104 /// \returns false if the visitation was terminated early, true otherwise.
105 virtual bool
107
108 /// Recursively visit a base specifier. This can be overridden by a
109 /// subclass.
110 ///
111 /// \returns false if the visitation was terminated early, true otherwise.
113
114 /// Recursively visit a declaration, by dispatching to
115 /// Traverse*Decl() based on the argument's dynamic type.
116 ///
117 /// \returns false if the visitation was terminated early, true
118 /// otherwise (including when the argument is NULL).
120
121 /// Recursively visit a name with its location information.
122 ///
123 /// \returns false if the visitation was terminated early, true otherwise.
125
126 /// Recursively visit a lambda capture. \c Init is the expression that
127 /// will be used to initialize the capture.
128 ///
129 /// \returns false if the visitation was terminated early, true otherwise.
131 const LambdaCapture *C,
133
134 /// Recursively visit a C++ nested-name-specifier.
135 ///
136 /// \returns false if the visitation was terminated early, true otherwise.
138
139 /// Recursively visit a C++ nested-name-specifier with location
140 /// information.
141 ///
142 /// \returns false if the visitation was terminated early, true otherwise.
144
145 /// Recursively visit a statement or expression, by
146 /// dispatching to Traverse*() based on the argument's dynamic type.
147 ///
148 /// \returns false if the visitation was terminated early, true
149 /// otherwise (including when the argument is nullptr).
151
152 /// Recursively visit a template argument and dispatch to the
153 /// appropriate method for the argument type.
154 ///
155 /// \returns false if the visitation was terminated early, true otherwise.
156 // FIXME: migrate callers to TemplateArgumentLoc instead.
158
159 /// Recursively visit a template argument location and dispatch to the
160 /// appropriate method for the argument type.
161 ///
162 /// \returns false if the visitation was terminated early, true otherwise.
164
165 /// Recursively visit a set of template arguments.
166 ///
167 /// \returns false if the visitation was terminated early, true otherwise.
168 // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead.
169 // Not virtual for now because no-one overrides it.
171
172 /// Recursively visit a template name and dispatch to the
173 /// appropriate method.
174 ///
175 /// \returns false if the visitation was terminated early, true otherwise.
177
178 /// Recursively visit a type, by dispatching to
179 /// Traverse*Type() based on the argument's getTypeClass() property.
180 ///
181 /// \returns false if the visitation was terminated early, true
182 /// otherwise (including when the argument is a Null type).
183 virtual bool TraverseType(QualType T, bool TraverseQualifier = true);
184
185 /// Recursively visit a type with location, by dispatching to
186 /// Traverse*TypeLoc() based on the argument type's getTypeClass() property.
187 ///
188 /// \returns false if the visitation was terminated early, true
189 /// otherwise (including when the argument is a Null type location).
190 virtual bool TraverseTypeLoc(TypeLoc TL, bool TraverseQualifier = true);
191
192 /// Recursively visit an Objective-C protocol reference with location
193 /// information.
194 ///
195 /// \returns false if the visitation was terminated early, true otherwise.
196 virtual bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLoc);
197
198 /// Traverse a concept (requirement).
201
202 virtual bool
204
205 virtual bool
207
208 virtual bool
210
213 return true;
214 }
215
216 /// Visit a node.
217 virtual bool VisitAttr(MaybeConst<Attr> *A) { return true; }
218 virtual bool VisitDecl(MaybeConst<Decl> *D) { return true; }
219 virtual bool VisitStmt(MaybeConst<Stmt> *S) { return true; }
220 virtual bool VisitType(MaybeConst<Type> *T) { return true; }
221 virtual bool VisitTypeLoc(TypeLoc TL) { return true; }
222
223 /// Walk up from a node.
227 bool WalkUpFromTypeLoc(TypeLoc TL) { return VisitTypeLoc(TL); }
228
229 /// Invoked before visiting a statement or expression via data recursion.
230 ///
231 /// \returns false to skip visiting the node, true otherwise.
232 virtual bool dataTraverseStmtPre(MaybeConst<Stmt> *S) { return true; }
233
234 /// Invoked after visiting a statement or expression via data recursion.
235 /// This is not invoked if the previously invoked \c dataTraverseStmtPre
236 /// returned false.
237 ///
238 /// \returns false if the visitation was terminated early, true otherwise.
239 virtual bool dataTraverseStmtPost(MaybeConst<Stmt> *S) { return true; }
240 virtual bool dataTraverseNode(MaybeConst<Stmt> *S);
241
242#define DEF_TRAVERSE_TMPL_INST(kind) \
243 virtual bool TraverseTemplateInstantiations( \
244 MaybeConst<kind##TemplateDecl> *D);
248#undef DEF_TRAVERSE_TMPL_INST
249
250 // Decls.
251#define ABSTRACT_DECL(DECL)
252#define DECL(CLASS, BASE) \
253 bool WalkUpFrom##CLASS##Decl(MaybeConst<CLASS##Decl> *D); \
254 virtual bool Traverse##CLASS##Decl(MaybeConst<CLASS##Decl> *D);
255#include "clang/AST/DeclNodes.inc"
256
257#define DECL(CLASS, BASE) \
258 virtual bool Visit##CLASS##Decl(MaybeConst<CLASS##Decl> *D) { return true; }
259#include "clang/AST/DeclNodes.inc"
260
261 // Stmts.
262#define ABSTRACT_STMT(STMT)
263#define STMT(CLASS, PARENT) virtual bool Traverse##CLASS(MaybeConst<CLASS> *S);
264#include "clang/AST/StmtNodes.inc"
265
266#define STMT(CLASS, PARENT) \
267 bool WalkUpFrom##CLASS(MaybeConst<CLASS> *S); \
268 virtual bool Visit##CLASS(MaybeConst<CLASS> *S) { return true; }
269#include "clang/AST/StmtNodes.inc"
270
271 // Types.
272#define ABSTRACT_TYPE(CLASS, BASE)
273#define TYPE(CLASS, BASE) \
274 bool WalkUpFrom##CLASS##Type(MaybeConst<CLASS##Type> *T); \
275 virtual bool Traverse##CLASS##Type(MaybeConst<CLASS##Type> *T, \
276 bool TraverseQualifier = true);
277#include "clang/AST/TypeNodes.inc"
278
279#define TYPE(CLASS, BASE) \
280 virtual bool Visit##CLASS##Type(MaybeConst<CLASS##Type> *T) { return true; }
281#include "clang/AST/TypeNodes.inc"
282
283 // TypeLocs.
284#define ABSTRACT_TYPELOC(CLASS, BASE)
285#define TYPELOC(CLASS, BASE) \
286 virtual bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL, \
287 bool TraverseQualifier);
288#include "clang/AST/TypeLocNodes.def"
289
290#define TYPELOC(CLASS, BASE) \
291 bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL); \
292 virtual bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
293#include "clang/AST/TypeLocNodes.def"
294};
295
296extern template class DynamicRecursiveASTVisitorBase<false>;
297extern template class DynamicRecursiveASTVisitorBase<true>;
298
300 DynamicRecursiveASTVisitorBase</*Const=*/false>;
302 DynamicRecursiveASTVisitorBase</*Const=*/true>;
303} // namespace clang
304
305#endif // LLVM_CLANG_AST_DYNAMIC_RECURSIVE_AST_VISITOR_H
const Decl * D
#define DEF_TRAVERSE_TMPL_INST(kind)
Defines Expressions and AST nodes for C++2a concepts.
Defines the clang::TypeLoc interface and its subclasses.
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
Recursive AST visitor that supports extension via dynamic dispatch.
virtual bool TraverseConceptNestedRequirement(MaybeConst< concepts::NestedRequirement > *R)
virtual ~DynamicRecursiveASTVisitorBase()=default
virtual bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc)
Recursively visit a template argument location and dispatch to the appropriate method for the argumen...
virtual bool TraverseConstructorInitializer(MaybeConst< CXXCtorInitializer > *Init)
Recursively visit a constructor initializer.
virtual bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS)
Recursively visit a C++ nested-name-specifier with location information.
bool ShouldVisitLambdaBody
Whether this visitor should recurse into lambda body.
DynamicRecursiveASTVisitorBase & operator=(const DynamicRecursiveASTVisitorBase &)=default
virtual bool TraverseDecl(MaybeConst< Decl > *D)
Recursively visit a declaration, by dispatching to Traverse*Decl() based on the argument's dynamic ty...
DynamicRecursiveASTVisitorBase(DynamicRecursiveASTVisitorBase &&)=default
bool ShouldVisitTemplateInstantiations
Whether this visitor should recurse into template instantiations.
std::conditional_t< IsConst, const ASTNode, ASTNode > MaybeConst
virtual bool TraverseTypeLoc(TypeLoc TL, bool TraverseQualifier=true)
Recursively visit a type with location, by dispatching to Traverse*TypeLoc() based on the argument ty...
virtual bool TraverseConceptRequirement(MaybeConst< concepts::Requirement > *R)
virtual bool dataTraverseStmtPre(MaybeConst< Stmt > *S)
Invoked before visiting a statement or expression via data recursion.
virtual bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base)
Recursively visit a base specifier.
virtual bool TraverseConceptExprRequirement(MaybeConst< concepts::ExprRequirement > *R)
virtual bool VisitDecl(MaybeConst< Decl > *D)
bool ShouldVisitImplicitCode
Whether this visitor should recurse into implicit code, e.g.
virtual bool VisitStmt(MaybeConst< Stmt > *S)
virtual bool VisitAttr(MaybeConst< Attr > *A)
Visit a node.
virtual bool TraverseStmt(MaybeConst< Stmt > *S)
Recursively visit a statement or expression, by dispatching to Traverse*() based on the argument's dy...
virtual bool TraverseAttr(MaybeConst< Attr > *At)
Recursively visit an attribute, by dispatching to Traverse*Attr() based on the argument's dynamic typ...
virtual bool TraverseNestedNameSpecifier(NestedNameSpecifier NNS)
Recursively visit a C++ nested-name-specifier.
virtual bool TraverseConceptTypeRequirement(MaybeConst< concepts::TypeRequirement > *R)
DynamicRecursiveASTVisitorBase & operator=(DynamicRecursiveASTVisitorBase &&)=default
virtual bool TraverseTypeConstraint(const TypeConstraint *C)
Traverse a concept (requirement).
bool WalkUpFromDecl(MaybeConst< Decl > *D)
Walk up from a node.
virtual bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo)
Recursively visit a name with its location information.
virtual bool VisitConceptReference(MaybeConst< ConceptReference > *CR)
bool ShouldWalkTypesOfTypeLocs
Whether this visitor should recurse into the types of TypeLocs.
DynamicRecursiveASTVisitorBase(const DynamicRecursiveASTVisitorBase &)=default
virtual bool TraverseLambdaCapture(MaybeConst< LambdaExpr > *LE, const LambdaCapture *C, MaybeConst< Expr > *Init)
Recursively visit a lambda capture.
virtual bool TraverseTemplateName(TemplateName Template)
Recursively visit a template name and dispatch to the appropriate method.
virtual bool dataTraverseStmtPost(MaybeConst< Stmt > *S)
Invoked after visiting a statement or expression via data recursion.
virtual bool dataTraverseNode(MaybeConst< Stmt > *S)
virtual bool VisitType(MaybeConst< Type > *T)
virtual bool TraverseAST(MaybeConst< ASTContext > &AST)
Recursively visits an entire AST, starting from the TranslationUnitDecl.
virtual bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLoc)
Recursively visit an Objective-C protocol reference with location information.
bool TraverseTemplateArguments(ArrayRef< TemplateArgument > Args)
Recursively visit a set of template arguments.
virtual bool TraverseConceptReference(MaybeConst< ConceptReference > *CR)
virtual bool TraverseType(QualType T, bool TraverseQualifier=true)
Recursively visit a type, by dispatching to Traverse*Type() based on the argument's getTypeClass() pr...
virtual bool TraverseTemplateArgument(const TemplateArgument &Arg)
Recursively visit a template argument and dispatch to the appropriate method for the argument type.
Describes the capture of a variable or of this, or of a C++1y init-capture.
Definition: LambdaCapture.h:25
A C++ nested-name-specifier augmented with source location information.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
A (possibly-)qualified type.
Definition: TypeBase.h:937
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:528
Represents a template argument.
Definition: TemplateBase.h:61
Represents a C++ template name within the type system.
Definition: TemplateName.h:222
Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...
Definition: ASTConcept.h:223
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:59
The JSON file list parser is used to communicate input to InstallAPI.
@ Template
We are parsing a template declaration.
const FunctionProtoType * T
@ Class
The "class" keyword introduces the elaborated-type-specifier.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...