clang 20.0.0git
DynamicRecursiveASTVisitor.cpp
Go to the documentation of this file.
1//=== DynamicRecursiveASTVisitor.cpp - Dynamic AST Visitor Implementation -===//
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 implements DynamicRecursiveASTVisitor in terms of the CRTP-based
10// RecursiveASTVisitor.
11//
12//===----------------------------------------------------------------------===//
15
16using namespace clang;
17
18// The implementation of DRAV deserves some explanation:
19//
20// We want to implement DynamicRecursiveASTVisitor without having to inherit or
21// reference RecursiveASTVisitor in any way in the header: if we instantiate
22// RAV in the header, then every user of (or rather every file that uses) DRAV
23// still has to instantiate a RAV, which gets us nowhere. Moreover, even just
24// including RecursiveASTVisitor.h would probably cause some amount of slowdown
25// because we'd have to parse a huge template. For these reasons, the fact that
26// DRAV is implemented using a RAV is solely an implementation detail.
27//
28// As for the implementation itself, DRAV by default acts exactly like a RAV
29// that overrides none of RAV's functions. There are two parts to this:
30//
31// 1. Any function in DRAV has to act like the corresponding function in RAV,
32// unless overridden by a derived class, of course.
33//
34// 2. Any call to a function by the RAV implementation that DRAV allows to be
35// overridden must be transformed to a virtual call on the user-provided
36// DRAV object: if some function in RAV calls e.g. TraverseCallExpr()
37// during traversal, then the derived class's TraverseCallExpr() must be
38// called (provided it overrides TraverseCallExpr()).
39//
40// The 'Impl' class is a helper that connects the two implementations; it is
41// a wrapper around a reference to a DRAV that is itself a RecursiveASTVisitor.
42// It overrides every function in RAV *that is virtual in DRAV* to perform a
43// virtual call on its DRAV reference. This accomplishes point 2 above.
44//
45// Point 1 is accomplished by, first, having the base class implementation of
46// each of the virtual functions construct an Impl object (which is actually
47// just a no-op), passing in itself so that any virtual calls use the right
48// vtable. Secondly, it then calls RAV's implementation of that same function
49// *on Impl* (using a qualified call so that we actually call into the RAV
50// implementation instead of Impl's version of that same function); this way,
51// we both execute RAV's implementation for this function only and ensure that
52// calls to subsequent functions call into Impl via CRTP (and Impl then calls
53// back into DRAV and so on).
54//
55// While this ends up constructing a lot of Impl instances (almost one per
56// function call), this doesn't really matter since Impl just holds a single
57// pointer, and everything in this file should get inlined into all the DRAV
58// functions here anyway.
59//
60//===----------------------------------------------------------------------===//
61//
62// The following illustrates how a call to an (overridden) function is actually
63// resolved: given some class 'Derived' that derives from DRAV and overrides
64// TraverseStmt(), if we are traversing some AST, and TraverseStmt() is called
65// by the RAV implementation, the following happens:
66//
67// 1. Impl::TraverseStmt() overrides RAV::TraverseStmt() via CRTP, so the
68// former is called.
69//
70// 2. Impl::TraverseStmt() performs a virtual call to the visitor (which is
71// an instance to Derived), so Derived::TraverseStmt() is called.
72//
73// End result: Derived::TraverseStmt() is executed.
74//
75// Suppose some other function, e.g. TraverseCallExpr(), which is NOT overridden
76// by Derived is called, we get:
77//
78// 1. Impl::TraverseCallExpr() overrides RAV::TraverseCallExpr() via CRTP,
79// so the former is called.
80//
81// 2. Impl::TraverseCallExpr() performs a virtual call, but since Derived
82// does not override that function, DRAV::TraverseCallExpr() is called.
83//
84// 3. DRAV::TraverseCallExpr() creates a new instance of Impl, passing in
85// itself (this doesn't change that the pointer is an instance of Derived);
86// it then calls RAV::TraverseCallExpr() on the Impl object, which actually
87// ends up executing RAV's implementation because we used a qualified
88// function call.
89//
90// End result: RAV::TraverseCallExpr() is executed,
91namespace {
92struct Impl : RecursiveASTVisitor<Impl> {
94 Impl(DynamicRecursiveASTVisitor &Visitor) : Visitor(Visitor) {}
95
98 }
99
100 bool shouldWalkTypesOfTypeLocs() const {
101 return Visitor.ShouldWalkTypesOfTypeLocs;
102 }
103
104 bool shouldVisitImplicitCode() const {
105 return Visitor.ShouldVisitImplicitCode;
106 }
107
108 bool shouldVisitLambdaBody() const { return Visitor.ShouldVisitLambdaBody; }
109
110 // Supporting post-order would be very hard because of quirks of the
111 // RAV implementation that only work with CRTP. It also is only used
112 // by less than 5 visitors in the entire code base.
113 bool shouldTraversePostOrder() const { return false; }
114
115 bool TraverseAST(ASTContext &AST) { return Visitor.TraverseAST(AST); }
116 bool TraverseAttr(Attr *At) { return Visitor.TraverseAttr(At); }
117 bool TraverseDecl(Decl *D) { return Visitor.TraverseDecl(D); }
118 bool TraverseType(QualType T) { return Visitor.TraverseType(T); }
119 bool TraverseTypeLoc(TypeLoc TL) { return Visitor.TraverseTypeLoc(TL); }
120 bool TraverseStmt(Stmt *S) { return Visitor.TraverseStmt(S); }
121
123 return Visitor.TraverseConstructorInitializer(Init);
124 }
125
127 return Visitor.TraverseTemplateArgument(Arg);
128 }
129
131 return Visitor.TraverseTemplateArgumentLoc(ArgLoc);
132 }
133
134 bool TraverseTemplateName(TemplateName Template) {
135 return Visitor.TraverseTemplateName(Template);
136 }
137
138 bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLoc) {
139 return Visitor.TraverseObjCProtocolLoc(ProtocolLoc);
140 }
141
143 return Visitor.TraverseTypeConstraint(C);
144 }
146 return Visitor.TraverseConceptRequirement(R);
147 }
149 return Visitor.TraverseConceptTypeRequirement(R);
150 }
152 return Visitor.TraverseConceptExprRequirement(R);
153 }
155 return Visitor.TraverseConceptNestedRequirement(R);
156 }
157
159 return Visitor.TraverseConceptReference(CR);
160 }
161
163 return Visitor.TraverseCXXBaseSpecifier(Base);
164 }
165
167 return Visitor.TraverseDeclarationNameInfo(NameInfo);
168 }
169
171 Expr *Init) {
172 return Visitor.TraverseLambdaCapture(LE, C, Init);
173 }
174
176 return Visitor.TraverseNestedNameSpecifier(NNS);
177 }
178
180 return Visitor.TraverseNestedNameSpecifierLoc(NNS);
181 }
182
184 return Visitor.VisitConceptReference(CR);
185 }
186
187 bool dataTraverseStmtPre(Stmt *S) { return Visitor.dataTraverseStmtPre(S); }
188 bool dataTraverseStmtPost(Stmt *S) { return Visitor.dataTraverseStmtPost(S); }
189
190 // TraverseStmt() always passes in a queue, so we have no choice but to
191 // accept it as a parameter here.
192 bool dataTraverseNode(Stmt *S, DataRecursionQueue * = nullptr) {
193 // But since don't support postorder traversal, we don't need it, so
194 // simply discard it here. This way, derived classes don't need to worry
195 // about including it as a parameter that they never use.
196 return Visitor.dataTraverseNode(S);
197 }
198
199 /// Visit a node.
200 bool VisitAttr(Attr *A) { return Visitor.VisitAttr(A); }
201 bool VisitDecl(Decl *D) { return Visitor.VisitDecl(D); }
202 bool VisitStmt(Stmt *S) { return Visitor.VisitStmt(S); }
203 bool VisitType(Type *T) { return Visitor.VisitType(T); }
204 bool VisitTypeLoc(TypeLoc TL) { return Visitor.VisitTypeLoc(TL); }
205
206#define DEF_TRAVERSE_TMPL_INST(kind) \
207 bool TraverseTemplateInstantiations(kind##TemplateDecl *D) { \
208 return Visitor.TraverseTemplateInstantiations(D); \
209 }
212 DEF_TRAVERSE_TMPL_INST(Function)
213#undef DEF_TRAVERSE_TMPL_INST
214
215 // Decls.
216#define ABSTRACT_DECL(DECL)
217#define DECL(CLASS, BASE) \
218 bool Traverse##CLASS##Decl(CLASS##Decl *D) { \
219 return Visitor.Traverse##CLASS##Decl(D); \
220 }
221#include "clang/AST/DeclNodes.inc"
222
223#define DECL(CLASS, BASE) \
224 bool Visit##CLASS##Decl(CLASS##Decl *D) { \
225 return Visitor.Visit##CLASS##Decl(D); \
226 }
227#include "clang/AST/DeclNodes.inc"
228
229 // Stmts.
230#define ABSTRACT_STMT(STMT)
231#define STMT(CLASS, PARENT) \
232 bool Traverse##CLASS(CLASS *S) { return Visitor.Traverse##CLASS(S); }
233#include "clang/AST/StmtNodes.inc"
234
235#define STMT(CLASS, PARENT) \
236 bool Visit##CLASS(CLASS *S) { return Visitor.Visit##CLASS(S); }
237#include "clang/AST/StmtNodes.inc"
238
239 // Types.
240#define ABSTRACT_TYPE(CLASS, BASE)
241#define TYPE(CLASS, BASE) \
242 bool Traverse##CLASS##Type(CLASS##Type *T) { \
243 return Visitor.Traverse##CLASS##Type(T); \
244 }
245#include "clang/AST/TypeNodes.inc"
246
247#define TYPE(CLASS, BASE) \
248 bool Visit##CLASS##Type(CLASS##Type *T) { \
249 return Visitor.Visit##CLASS##Type(T); \
250 }
251#include "clang/AST/TypeNodes.inc"
252
253 // TypeLocs.
254#define ABSTRACT_TYPELOC(CLASS, BASE)
255#define TYPELOC(CLASS, BASE) \
256 bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
257 return Visitor.Traverse##CLASS##TypeLoc(TL); \
258 }
259#include "clang/AST/TypeLocNodes.def"
260
261#define TYPELOC(CLASS, BASE) \
262 bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
263 return Visitor.Visit##CLASS##TypeLoc(TL); \
264 }
265#include "clang/AST/TypeLocNodes.def"
266};
267} // namespace
268
270
272 return Impl(*this).RecursiveASTVisitor<Impl>::TraverseAST(AST);
273}
274
276 return Impl(*this).RecursiveASTVisitor<Impl>::TraverseAttr(At);
277}
278
281 return Impl(*this).RecursiveASTVisitor<Impl>::TraverseConstructorInitializer(
282 Init);
283}
284
286 return Impl(*this).RecursiveASTVisitor<Impl>::TraverseDecl(D);
287}
288
290 const LambdaCapture *C,
291 Expr *Init) {
292 return Impl(*this).RecursiveASTVisitor<Impl>::TraverseLambdaCapture(LE, C,
293 Init);
294}
295
297 return Impl(*this).RecursiveASTVisitor<Impl>::TraverseStmt(S);
298}
299
301 const TemplateArgument &Arg) {
302 return Impl(*this).RecursiveASTVisitor<Impl>::TraverseTemplateArgument(Arg);
303}
304
307 return Impl(*this).RecursiveASTVisitor<Impl>::TraverseTemplateArguments(Args);
308}
309
311 const TemplateArgumentLoc &ArgLoc) {
312 return Impl(*this).RecursiveASTVisitor<Impl>::TraverseTemplateArgumentLoc(
313 ArgLoc);
314}
315
317 return Impl(*this).RecursiveASTVisitor<Impl>::TraverseTemplateName(Template);
318}
319
321 return Impl(*this).RecursiveASTVisitor<Impl>::TraverseType(T);
322}
323
325 return Impl(*this).RecursiveASTVisitor<Impl>::TraverseTypeLoc(TL);
326}
327
329 const TypeConstraint *C) {
330 return Impl(*this).RecursiveASTVisitor<Impl>::TraverseTypeConstraint(C);
331}
333 ObjCProtocolLoc ProtocolLoc) {
334 return Impl(*this).RecursiveASTVisitor<Impl>::TraverseObjCProtocolLoc(
335 ProtocolLoc);
336}
337
340 return Impl(*this).RecursiveASTVisitor<Impl>::TraverseConceptRequirement(R);
341}
344 return Impl(*this).RecursiveASTVisitor<Impl>::TraverseConceptTypeRequirement(
345 R);
346}
349 return Impl(*this).RecursiveASTVisitor<Impl>::TraverseConceptExprRequirement(
350 R);
351}
354 return Impl(*this)
355 .RecursiveASTVisitor<Impl>::TraverseConceptNestedRequirement(R);
356}
357
359 ConceptReference *CR) {
360 return Impl(*this).RecursiveASTVisitor<Impl>::TraverseConceptReference(CR);
361}
362
364 const CXXBaseSpecifier &Base) {
365 return Impl(*this).RecursiveASTVisitor<Impl>::TraverseCXXBaseSpecifier(Base);
366}
367
369 DeclarationNameInfo NameInfo) {
370 return Impl(*this).RecursiveASTVisitor<Impl>::TraverseDeclarationNameInfo(
371 NameInfo);
372}
373
375 NestedNameSpecifier *NNS) {
376 return Impl(*this).RecursiveASTVisitor<Impl>::TraverseNestedNameSpecifier(
377 NNS);
378}
379
382 return Impl(*this).RecursiveASTVisitor<Impl>::TraverseNestedNameSpecifierLoc(
383 NNS);
384}
385
387 return Impl(*this).RecursiveASTVisitor<Impl>::dataTraverseNode(S, nullptr);
388}
389
390#define DEF_TRAVERSE_TMPL_INST(kind) \
391 bool DynamicRecursiveASTVisitor::TraverseTemplateInstantiations( \
392 kind##TemplateDecl *D) { \
393 return Impl(*this) \
394 .RecursiveASTVisitor<Impl>::TraverseTemplateInstantiations(D); \
395 }
399#undef DEF_TRAVERSE_TMPL_INST
400
401// Declare Traverse*() for and friends all concrete Decl classes.
402#define ABSTRACT_DECL(DECL)
403#define DECL(CLASS, BASE) \
404 bool DynamicRecursiveASTVisitor::Traverse##CLASS##Decl(CLASS##Decl *D) { \
405 return Impl(*this).RecursiveASTVisitor<Impl>::Traverse##CLASS##Decl(D); \
406 } \
407 bool DynamicRecursiveASTVisitor::WalkUpFrom##CLASS##Decl(CLASS##Decl *D) { \
408 return Impl(*this).RecursiveASTVisitor<Impl>::WalkUpFrom##CLASS##Decl(D); \
409 }
410#include "clang/AST/DeclNodes.inc"
411
412// Declare Traverse*() and friends for all concrete Stmt classes.
413#define ABSTRACT_STMT(STMT)
414#define STMT(CLASS, PARENT) \
415 bool DynamicRecursiveASTVisitor::Traverse##CLASS(CLASS *S) { \
416 return Impl(*this).RecursiveASTVisitor<Impl>::Traverse##CLASS(S); \
417 }
418#include "clang/AST/StmtNodes.inc"
419
420#define STMT(CLASS, PARENT) \
421 bool DynamicRecursiveASTVisitor::WalkUpFrom##CLASS(CLASS *S) { \
422 return Impl(*this).RecursiveASTVisitor<Impl>::WalkUpFrom##CLASS(S); \
423 }
424#include "clang/AST/StmtNodes.inc"
425
426// Declare Traverse*() and friends for all concrete Typeclasses.
427#define ABSTRACT_TYPE(CLASS, BASE)
428#define TYPE(CLASS, BASE) \
429 bool DynamicRecursiveASTVisitor::Traverse##CLASS##Type(CLASS##Type *T) { \
430 return Impl(*this).RecursiveASTVisitor<Impl>::Traverse##CLASS##Type(T); \
431 } \
432 bool DynamicRecursiveASTVisitor::WalkUpFrom##CLASS##Type(CLASS##Type *T) { \
433 return Impl(*this).RecursiveASTVisitor<Impl>::WalkUpFrom##CLASS##Type(T); \
434 }
435#include "clang/AST/TypeNodes.inc"
436
437#define ABSTRACT_TYPELOC(CLASS, BASE)
438#define TYPELOC(CLASS, BASE) \
439 bool DynamicRecursiveASTVisitor::Traverse##CLASS##TypeLoc( \
440 CLASS##TypeLoc TL) { \
441 return Impl(*this).RecursiveASTVisitor<Impl>::Traverse##CLASS##TypeLoc( \
442 TL); \
443 }
444#include "clang/AST/TypeLocNodes.def"
445
446#define TYPELOC(CLASS, BASE) \
447 bool DynamicRecursiveASTVisitor::WalkUpFrom##CLASS##TypeLoc( \
448 CLASS##TypeLoc TL) { \
449 return Impl(*this).RecursiveASTVisitor<Impl>::WalkUpFrom##CLASS##TypeLoc( \
450 TL); \
451 }
452#include "clang/AST/TypeLocNodes.def"
const Decl * D
#define DEF_TRAVERSE_TMPL_INST(kind)
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:188
Attr - This represents one attribute.
Definition: Attr.h:43
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
Represents a C++ base or member initializer.
Definition: DeclCXX.h:2318
A reference to a concept and its template args, as it appears in the code.
Definition: ASTConcept.h:124
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
Recursive AST visitor that supports extension via dynamic dispatch.
virtual bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo)
Recursively visit a name with its location information.
virtual bool dataTraverseStmtPost(Stmt *S)
Invoked after visiting a statement or expression via data recursion.
virtual bool TraverseDecl(Decl *D)
Recursively visit a declaration, by dispatching to Traverse*Decl() based on the argument's dynamic ty...
virtual bool TraverseConceptTypeRequirement(concepts::TypeRequirement *R)
virtual bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS)
Recursively visit a C++ nested-name-specifier.
virtual bool VisitAttr(Attr *A)
Visit a node.
bool ShouldVisitLambdaBody
Whether this visitor should recurse into lambda body.
virtual bool TraverseTypeLoc(TypeLoc TL)
Recursively visit a type with location, by dispatching to Traverse*TypeLoc() based on the argument ty...
virtual bool dataTraverseStmtPre(Stmt *S)
Invoked before visiting a statement or expression via data recursion.
virtual bool TraverseConceptRequirement(concepts::Requirement *R)
virtual bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLoc)
Recursively visit an Objective-C protocol reference with location information.
virtual bool VisitConceptReference(ConceptReference *CR)
virtual bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS)
Recursively visit a C++ nested-name-specifier with location information.
virtual bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C, Expr *Init)
Recursively visit a lambda capture.
virtual bool TraverseAttr(Attr *At)
Recursively visit an attribute, by dispatching to Traverse*Attr() based on the argument's dynamic typ...
virtual bool TraverseStmt(Stmt *S)
Recursively visit a statement or expression, by dispatching to Traverse*() based on the argument's dy...
virtual bool TraverseConceptReference(ConceptReference *CR)
virtual bool TraverseTemplateArgument(const TemplateArgument &Arg)
Recursively visit a template argument and dispatch to the appropriate method for the argument type.
virtual bool TraverseConstructorInitializer(CXXCtorInitializer *Init)
Recursively visit a constructor initializer.
bool TraverseTemplateArguments(ArrayRef< TemplateArgument > Args)
Recursively visit a set of template arguments.
virtual bool TraverseConceptExprRequirement(concepts::ExprRequirement *R)
virtual bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc)
Recursively visit a template argument location and dispatch to the appropriate method for the argumen...
virtual bool TraverseAST(ASTContext &AST)
Recursively visits an entire AST, starting from the TranslationUnitDecl.
virtual bool TraverseType(QualType T)
Recursively visit a type, by dispatching to Traverse*Type() based on the argument's getTypeClass() pr...
virtual bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base)
Recursively visit a base specifier.
virtual bool TraverseTypeConstraint(const TypeConstraint *C)
Traverse a concept (requirement).
bool ShouldWalkTypesOfTypeLocs
Whether this visitor should recurse into the types of TypeLocs.
bool ShouldVisitImplicitCode
Whether this visitor should recurse into implicit code, e.g.
virtual bool TraverseConceptNestedRequirement(concepts::NestedRequirement *R)
bool ShouldVisitTemplateInstantiations
Whether this visitor should recurse into template instantiations.
virtual bool TraverseTemplateName(TemplateName Template)
Recursively visit a template name and dispatch to the appropriate method.
This represents one expression.
Definition: Expr.h:110
Describes the capture of a variable or of this, or of a C++1y init-capture.
Definition: LambdaCapture.h:25
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition: ExprCXX.h:1954
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: Type.h:929
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue=nullptr)
Recursively visit a statement or expression, by dispatching to Traverse*() based on the argument's dy...
bool TraverseTemplateArgument(const TemplateArgument &Arg)
Recursively visit a template argument and dispatch to the appropriate method for the argument type.
bool TraverseConceptRequirement(concepts::Requirement *R)
bool TraverseType(QualType T)
Recursively visit a type, by dispatching to Traverse*Type() based on the argument's getTypeClass() pr...
bool dataTraverseStmtPre(Stmt *S)
Invoked before visiting a statement or expression via data recursion.
bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLoc)
Recursively visit an Objective-C protocol reference with location information.
bool TraverseConceptExprRequirement(concepts::ExprRequirement *R)
bool TraverseAST(ASTContext &AST)
Recursively visits an entire AST, starting from the TranslationUnitDecl.
bool shouldVisitTemplateInstantiations() const
Return whether this visitor should recurse into template instantiations.
bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc)
Recursively visit a template argument location and dispatch to the appropriate method for the argumen...
bool dataTraverseStmtPost(Stmt *S)
Invoked after visiting a statement or expression via data recursion.
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS)
Recursively visit a C++ nested-name-specifier with location information.
bool TraverseTemplateName(TemplateName Template)
Recursively visit a template name and dispatch to the appropriate method.
bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS)
Recursively visit a C++ nested-name-specifier.
bool shouldVisitImplicitCode() const
Return whether this visitor should recurse into implicit code, e.g., implicit constructors and destru...
bool TraverseConceptReference(ConceptReference *CR)
Recursively visit concept reference with location information.
bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue)
bool TraverseDecl(Decl *D)
Recursively visit a declaration, by dispatching to Traverse*Decl() based on the argument's dynamic ty...
bool TraverseTypeLoc(TypeLoc TL)
Recursively visit a type with location, by dispatching to Traverse*TypeLoc() based on the argument ty...
bool TraverseTypeConstraint(const TypeConstraint *C)
bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C, Expr *Init)
Recursively visit a lambda capture.
bool VisitConceptReference(ConceptReference *CR)
bool shouldTraversePostOrder() const
Return whether this visitor should traverse post-order.
bool shouldVisitLambdaBody() const
Return whether this visitor should recurse into lambda body.
bool TraverseAttr(Attr *At)
Recursively visit an attribute, by dispatching to Traverse*Attr() based on the argument's dynamic typ...
bool TraverseConceptNestedRequirement(concepts::NestedRequirement *R)
bool shouldWalkTypesOfTypeLocs() const
Return whether this visitor should recurse into the types of TypeLocs.
bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo)
Recursively visit a name with its location information.
bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base)
Recursively visit a base specifier.
bool TraverseConceptTypeRequirement(concepts::TypeRequirement *R)
bool TraverseConstructorInitializer(CXXCtorInitializer *Init)
Recursively visit a constructor initializer.
Stmt - This represents one statement.
Definition: Stmt.h:84
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 base class of the type hierarchy.
Definition: Type.h:1828
A requires-expression requirement which queries the validity and properties of an expression ('simple...
Definition: ExprConcepts.h:280
A requires-expression requirement which is satisfied when a general constraint expression is satisfie...
Definition: ExprConcepts.h:429
A static requirement that can be used in a requires-expression to check properties of types and expre...
Definition: ExprConcepts.h:168
A requires-expression requirement which queries the existence of a type name or type template special...
Definition: ExprConcepts.h:225
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...