clang 21.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.
137 virtual bool
139
140 /// Recursively visit a C++ nested-name-specifier with location
141 /// information.
142 ///
143 /// \returns false if the visitation was terminated early, true otherwise.
145
146 /// Recursively visit a statement or expression, by
147 /// dispatching to Traverse*() based on the argument's dynamic type.
148 ///
149 /// \returns false if the visitation was terminated early, true
150 /// otherwise (including when the argument is nullptr).
152
153 /// Recursively visit a template argument and dispatch to the
154 /// appropriate method for the argument type.
155 ///
156 /// \returns false if the visitation was terminated early, true otherwise.
157 // FIXME: migrate callers to TemplateArgumentLoc instead.
159
160 /// Recursively visit a template argument location and dispatch to the
161 /// appropriate method for the argument type.
162 ///
163 /// \returns false if the visitation was terminated early, true otherwise.
165
166 /// Recursively visit a set of template arguments.
167 ///
168 /// \returns false if the visitation was terminated early, true otherwise.
169 // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead.
170 // Not virtual for now because no-one overrides it.
172
173 /// Recursively visit a template name and dispatch to the
174 /// appropriate method.
175 ///
176 /// \returns false if the visitation was terminated early, true otherwise.
177 virtual bool TraverseTemplateName(TemplateName Template);
178
179 /// Recursively visit a type, by dispatching to
180 /// Traverse*Type() based on the argument's getTypeClass() property.
181 ///
182 /// \returns false if the visitation was terminated early, true
183 /// otherwise (including when the argument is a Null type).
184 virtual bool TraverseType(QualType T);
185
186 /// Recursively visit a type with location, by dispatching to
187 /// Traverse*TypeLoc() based on the argument type's getTypeClass() property.
188 ///
189 /// \returns false if the visitation was terminated early, true
190 /// otherwise (including when the argument is a Null type location).
191 virtual bool TraverseTypeLoc(TypeLoc TL);
192
193 /// Recursively visit an Objective-C protocol reference with location
194 /// information.
195 ///
196 /// \returns false if the visitation was terminated early, true otherwise.
197 virtual bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLoc);
198
199 /// Traverse a concept (requirement).
202
203 virtual bool
205
206 virtual bool
208
209 virtual bool
211
214 return true;
215 }
216
217 /// Visit a node.
218 virtual bool VisitAttr(MaybeConst<Attr> *A) { return true; }
219 virtual bool VisitDecl(MaybeConst<Decl> *D) { return true; }
220 virtual bool VisitStmt(MaybeConst<Stmt> *S) { return true; }
221 virtual bool VisitType(MaybeConst<Type> *T) { return true; }
222 virtual bool VisitTypeLoc(TypeLoc TL) { return true; }
223
224 /// Walk up from a node.
228 bool WalkUpFromTypeLoc(TypeLoc TL) { return VisitTypeLoc(TL); }
229
230 /// Invoked before visiting a statement or expression via data recursion.
231 ///
232 /// \returns false to skip visiting the node, true otherwise.
233 virtual bool dataTraverseStmtPre(MaybeConst<Stmt> *S) { return true; }
234
235 /// Invoked after visiting a statement or expression via data recursion.
236 /// This is not invoked if the previously invoked \c dataTraverseStmtPre
237 /// returned false.
238 ///
239 /// \returns false if the visitation was terminated early, true otherwise.
240 virtual bool dataTraverseStmtPost(MaybeConst<Stmt> *S) { return true; }
241 virtual bool dataTraverseNode(MaybeConst<Stmt> *S);
242
243#define DEF_TRAVERSE_TMPL_INST(kind) \
244 virtual bool TraverseTemplateInstantiations( \
245 MaybeConst<kind##TemplateDecl> *D);
249#undef DEF_TRAVERSE_TMPL_INST
250
251 // Decls.
252#define ABSTRACT_DECL(DECL)
253#define DECL(CLASS, BASE) \
254 virtual bool Traverse##CLASS##Decl(MaybeConst<CLASS##Decl> *D);
255#include "clang/AST/DeclNodes.inc"
256
257#define DECL(CLASS, BASE) \
258 bool WalkUpFrom##CLASS##Decl(MaybeConst<CLASS##Decl> *D); \
259 virtual bool Visit##CLASS##Decl(MaybeConst<CLASS##Decl> *D) { return true; }
260#include "clang/AST/DeclNodes.inc"
261
262 // Stmts.
263#define ABSTRACT_STMT(STMT)
264#define STMT(CLASS, PARENT) virtual bool Traverse##CLASS(MaybeConst<CLASS> *S);
265#include "clang/AST/StmtNodes.inc"
266
267#define STMT(CLASS, PARENT) \
268 bool WalkUpFrom##CLASS(MaybeConst<CLASS> *S); \
269 virtual bool Visit##CLASS(MaybeConst<CLASS> *S) { return true; }
270#include "clang/AST/StmtNodes.inc"
271
272 // Types.
273#define ABSTRACT_TYPE(CLASS, BASE)
274#define TYPE(CLASS, BASE) \
275 virtual bool Traverse##CLASS##Type(MaybeConst<CLASS##Type> *T);
276#include "clang/AST/TypeNodes.inc"
277
278#define TYPE(CLASS, BASE) \
279 bool WalkUpFrom##CLASS##Type(MaybeConst<CLASS##Type> *T); \
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#include "clang/AST/TypeLocNodes.def"
288
289#define TYPELOC(CLASS, BASE) \
290 bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL); \
291 virtual bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
292#include "clang/AST/TypeLocNodes.def"
293};
294
295extern template class DynamicRecursiveASTVisitorBase<false>;
296extern template class DynamicRecursiveASTVisitorBase<true>;
297
299 DynamicRecursiveASTVisitorBase</*Const=*/false>;
301 DynamicRecursiveASTVisitorBase</*Const=*/true>;
302} // namespace clang
303
304#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 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 TraverseNestedNameSpecifier(MaybeConst< NestedNameSpecifier > *NNS)
Recursively visit a C++ nested-name-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 TraverseConceptTypeRequirement(MaybeConst< concepts::TypeRequirement > *R)
virtual bool TraverseTypeLoc(TypeLoc TL)
Recursively visit a type with location, by dispatching to Traverse*TypeLoc() based on the argument ty...
DynamicRecursiveASTVisitorBase & operator=(DynamicRecursiveASTVisitorBase &&)=default
virtual bool TraverseTypeConstraint(const TypeConstraint *C)
Traverse a concept (requirement).
virtual bool TraverseType(QualType T)
Recursively visit a type, by dispatching to Traverse*Type() based on the argument's getTypeClass() pr...
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 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 TraverseLambdaCapture(MaybeConst< LambdaExpr > *LE, const LambdaCapture *C, MaybeConst< Expr > *Init)
Recursively visit a lambda capture.
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.
A (possibly-)qualified type.
Definition: Type.h:929
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:524
Represents a template argument.
Definition: TemplateBase.h:61
Represents a C++ template name within the type system.
Definition: TemplateName.h:220
Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...
Definition: ASTConcept.h:227
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.
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...