1//===--- RecursiveASTVisitor.h - Recursive 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 RecursiveASTVisitor interface, which recursively
10// traverses the entire AST.
11//
12//===----------------------------------------------------------------------===//
13#ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
14#define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
15
16#include "clang/AST/ASTConcept.h"
17#include "clang/AST/Attr.h"
18#include "clang/AST/Decl.h"
19#include "clang/AST/DeclBase.h"
20#include "clang/AST/DeclCXX.h"
21#include "clang/AST/DeclFriend.h"
22#include "clang/AST/DeclObjC.h"
23#include "clang/AST/DeclOpenACC.h"
24#include "clang/AST/DeclOpenMP.h"
25#include "clang/AST/DeclTemplate.h"
26#include "clang/AST/DeclarationName.h"
27#include "clang/AST/Expr.h"
28#include "clang/AST/ExprCXX.h"
29#include "clang/AST/ExprConcepts.h"
30#include "clang/AST/ExprObjC.h"
31#include "clang/AST/ExprOpenMP.h"
32#include "clang/AST/LambdaCapture.h"
33#include "clang/AST/NestedNameSpecifier.h"
34#include "clang/AST/OpenACCClause.h"
35#include "clang/AST/OpenMPClause.h"
36#include "clang/AST/Stmt.h"
37#include "clang/AST/StmtCXX.h"
38#include "clang/AST/StmtObjC.h"
39#include "clang/AST/StmtOpenACC.h"
40#include "clang/AST/StmtOpenMP.h"
41#include "clang/AST/StmtSYCL.h"
42#include "clang/AST/TemplateBase.h"
43#include "clang/AST/TemplateName.h"
44#include "clang/AST/Type.h"
45#include "clang/AST/TypeLoc.h"
46#include "clang/Basic/LLVM.h"
47#include "clang/Basic/OpenMPKinds.h"
48#include "clang/Basic/Specifiers.h"
49#include "llvm/ADT/PointerIntPair.h"
50#include "llvm/ADT/SmallVector.h"
51#include "llvm/Support/Casting.h"
52#include <algorithm>
53#include <cstddef>
54#include <type_traits>
55
56namespace clang {
57
58// A helper macro to implement short-circuiting when recursing. It
59// invokes CALL_EXPR, which must be a method call, on the derived
60// object (s.t. a user of RecursiveASTVisitor can override the method
61// in CALL_EXPR).
62#define TRY_TO(CALL_EXPR) \
63 do { \
64 if (!getDerived().CALL_EXPR) \
65 return false; \
66 } while (false)
67
68namespace detail {
69
70template <typename T, typename U>
71struct has_same_member_pointer_type : std::false_type {};
72template <typename T, typename U, typename R, typename... P>
73struct has_same_member_pointer_type<R (T::*)(P...), R (U::*)(P...)>
74 : std::true_type {};
75
76/// Returns true if and only if \p FirstMethodPtr and \p SecondMethodPtr
77/// are pointers to the same non-static member function.
78template <typename FirstMethodPtrTy, typename SecondMethodPtrTy>
79LLVM_ATTRIBUTE_ALWAYS_INLINE LLVM_ATTRIBUTE_NODEBUG auto
80isSameMethod([[maybe_unused]] FirstMethodPtrTy FirstMethodPtr,
81 [[maybe_unused]] SecondMethodPtrTy SecondMethodPtr)
82 -> bool {
83 if constexpr (has_same_member_pointer_type<FirstMethodPtrTy,
84 SecondMethodPtrTy>::value)
85 return FirstMethodPtr == SecondMethodPtr;
86 return false;
87}
88
89} // end namespace detail
90
91/// A class that does preorder or postorder
92/// depth-first traversal on the entire Clang AST and visits each node.
93///
94/// This class performs three distinct tasks:
95/// 1. traverse the AST (i.e. go to each node);
96/// 2. at a given node, walk up the class hierarchy, starting from
97/// the node's dynamic type, until the top-most class (e.g. Stmt,
98/// Decl, or Type) is reached.
99/// 3. given a (node, class) combination, where 'class' is some base
100/// class of the dynamic type of 'node', call a user-overridable
101/// function to actually visit the node.
102///
103/// These tasks are done by three groups of methods, respectively:
104/// 1. TraverseDecl(Decl *x) does task #1. It is the entry point
105/// for traversing an AST rooted at x. This method simply
106/// dispatches (i.e. forwards) to TraverseFoo(Foo *x) where Foo
107/// is the dynamic type of *x, which calls WalkUpFromFoo(x) and
108/// then recursively visits the child nodes of x.
109/// TraverseStmt(Stmt *x) and TraverseType(QualType x) work
110/// similarly.
111/// 2. WalkUpFromFoo(Foo *x) does task #2. It does not try to visit
112/// any child node of x. Instead, it first calls WalkUpFromBar(x)
113/// where Bar is the direct parent class of Foo (unless Foo has
114/// no parent), and then calls VisitFoo(x) (see the next list item).
115/// 3. VisitFoo(Foo *x) does task #3.
116///
117/// These three method groups are tiered (Traverse* > WalkUpFrom* >
118/// Visit*). A method (e.g. Traverse*) may call methods from the same
119/// tier (e.g. other Traverse*) or one tier lower (e.g. WalkUpFrom*).
120/// It may not call methods from a higher tier.
121///
122/// Note that since WalkUpFromFoo() calls WalkUpFromBar() (where Bar
123/// is Foo's super class) before calling VisitFoo(), the result is
124/// that the Visit*() methods for a given node are called in the
125/// top-down order (e.g. for a node of type NamespaceDecl, the order will
126/// be VisitDecl(), VisitNamedDecl(), and then VisitNamespaceDecl()).
127///
128/// This scheme guarantees that all Visit*() calls for the same AST
129/// node are grouped together. In other words, Visit*() methods for
130/// different nodes are never interleaved.
131///
132/// Clients of this visitor should subclass the visitor (providing
133/// themselves as the template argument, using the curiously recurring
134/// template pattern) and override any of the Traverse*, WalkUpFrom*,
135/// and Visit* methods for declarations, types, statements,
136/// expressions, or other AST nodes where the visitor should customize
137/// behavior. Most users only need to override Visit*. Advanced
138/// users may override Traverse* and WalkUpFrom* to implement custom
139/// traversal strategies. Returning false from one of these overridden
140/// functions will abort the entire traversal.
141///
142/// By default, this visitor tries to visit every part of the explicit
143/// source code exactly once. The default policy towards templates
144/// is to descend into the 'pattern' class or function body, not any
145/// explicit or implicit instantiations. Explicit specializations
146/// are still visited, and the patterns of partial specializations
147/// are visited separately. This behavior can be changed by
148/// overriding shouldVisitTemplateInstantiations() in the derived class
149/// to return true, in which case all known implicit and explicit
150/// instantiations will be visited at the same time as the pattern
151/// from which they were produced.
152///
153/// By default, this visitor preorder traverses the AST. If postorder traversal
154/// is needed, the \c shouldTraversePostOrder method needs to be overridden
155/// to return \c true.
156template <typename Derived> class RecursiveASTVisitor {
157public:
158 /// A queue used for performing data recursion over statements.
159 /// Parameters involving this type are used to implement data
160 /// recursion over Stmts and Exprs within this class, and should
161 /// typically not be explicitly specified by derived classes.
162 /// The bool bit indicates whether the statement has been traversed or not.
163 typedef SmallVectorImpl<llvm::PointerIntPair<Stmt *, 1, bool>>
164 DataRecursionQueue;
165
166 /// Return a reference to the derived class.
167 Derived &getDerived() { return *static_cast<Derived *>(this); }
168
169 /// Return whether this visitor should recurse into
170 /// template instantiations.
171 bool shouldVisitTemplateInstantiations() const { return false; }
172
173 /// Return whether this visitor should recurse into the types of
174 /// TypeLocs.
175 bool shouldWalkTypesOfTypeLocs() const { return true; }
176
177 /// Return whether this visitor should recurse into implicit
178 /// code, e.g., implicit constructors and destructors.
179 bool shouldVisitImplicitCode() const { return false; }
180
181 /// Return whether this visitor should recurse into lambda body
182 bool shouldVisitLambdaBody() const { return true; }
183
184 /// Return whether this visitor should traverse post-order.
185 bool shouldTraversePostOrder() const { return false; }
186
187 /// Recursively visits an entire AST, starting from the TranslationUnitDecl.
188 /// \returns false if visitation was terminated early.
189 bool TraverseAST(ASTContext &AST) {
190 // Currently just an alias for TraverseDecl(TUDecl), but kept in case
191 // we change the implementation again.
192 return getDerived().TraverseDecl(AST.getTranslationUnitDecl());
193 }
194
195 /// Recursively visit a statement or expression, by
196 /// dispatching to Traverse*() based on the argument's dynamic type.
197 ///
198 /// \returns false if the visitation was terminated early, true
199 /// otherwise (including when the argument is nullptr).
200 bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue = nullptr);
201
202 /// Invoked before visiting a statement or expression via data recursion.
203 ///
204 /// \returns false to skip visiting the node, true otherwise.
205 bool dataTraverseStmtPre(Stmt *S) { return true; }
206
207 /// Invoked after visiting a statement or expression via data recursion.
208 /// This is not invoked if the previously invoked \c dataTraverseStmtPre
209 /// returned false.
210 ///
211 /// \returns false if the visitation was terminated early, true otherwise.
212 bool dataTraverseStmtPost(Stmt *S) { return true; }
213
214 /// Recursively visit a type, by dispatching to
215 /// Traverse*Type() based on the argument's getTypeClass() property.
216 ///
217 /// \returns false if the visitation was terminated early, true
218 /// otherwise (including when the argument is a Null type).
219 bool TraverseType(QualType T);
220
221 /// Recursively visit a type with location, by dispatching to
222 /// Traverse*TypeLoc() based on the argument type's getTypeClass() property.
223 ///
224 /// \returns false if the visitation was terminated early, true
225 /// otherwise (including when the argument is a Null type location).
226 bool TraverseTypeLoc(TypeLoc TL);
227
228 /// Recursively visit an attribute, by dispatching to
229 /// Traverse*Attr() based on the argument's dynamic type.
230 ///
231 /// \returns false if the visitation was terminated early, true
232 /// otherwise (including when the argument is a Null type location).
233 bool TraverseAttr(Attr *At);
234
235 /// Recursively visit a declaration, by dispatching to
236 /// Traverse*Decl() based on the argument's dynamic type.
237 ///
238 /// \returns false if the visitation was terminated early, true
239 /// otherwise (including when the argument is NULL).
240 bool TraverseDecl(Decl *D);
241
242 /// Recursively visit a C++ nested-name-specifier.
243 ///
244 /// \returns false if the visitation was terminated early, true otherwise.
245 bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
246
247 /// Recursively visit a C++ nested-name-specifier with location
248 /// information.
249 ///
250 /// \returns false if the visitation was terminated early, true otherwise.
251 bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
252
253 /// Recursively visit a name with its location information.
254 ///
255 /// \returns false if the visitation was terminated early, true otherwise.
256 bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo);
257
258 /// Recursively visit a template name and dispatch to the
259 /// appropriate method.
260 ///
261 /// \returns false if the visitation was terminated early, true otherwise.
262 bool TraverseTemplateName(TemplateName Template);
263
264 /// Recursively visit a template argument and dispatch to the
265 /// appropriate method for the argument type.
266 ///
267 /// \returns false if the visitation was terminated early, true otherwise.
268 // FIXME: migrate callers to TemplateArgumentLoc instead.
269 bool TraverseTemplateArgument(const TemplateArgument &Arg);
270
271 /// Recursively visit a template argument location and dispatch to the
272 /// appropriate method for the argument type.
273 ///
274 /// \returns false if the visitation was terminated early, true otherwise.
275 bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc);
276
277 /// Recursively visit a set of template arguments.
278 /// This can be overridden by a subclass, but it's not expected that
279 /// will be needed -- this visitor always dispatches to another.
280 ///
281 /// \returns false if the visitation was terminated early, true otherwise.
282 // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead.
283 bool TraverseTemplateArguments(ArrayRef<TemplateArgument> Args);
284
285 /// Recursively visit a base specifier. This can be overridden by a
286 /// subclass.
287 ///
288 /// \returns false if the visitation was terminated early, true otherwise.
289 bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base);
290
291 /// Recursively visit a constructor initializer. This
292 /// automatically dispatches to another visitor for the initializer
293 /// expression, but not for the name of the initializer, so may
294 /// be overridden for clients that need access to the name.
295 ///
296 /// \returns false if the visitation was terminated early, true otherwise.
297 bool TraverseConstructorInitializer(CXXCtorInitializer *Init);
298
299 /// Recursively visit a lambda capture. \c Init is the expression that
300 /// will be used to initialize the capture.
301 ///
302 /// \returns false if the visitation was terminated early, true otherwise.
303 bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C,
304 Expr *Init);
305
306 /// Recursively visit the syntactic or semantic form of an
307 /// initialization list.
308 ///
309 /// \returns false if the visitation was terminated early, true otherwise.
310 bool TraverseSynOrSemInitListExpr(InitListExpr *S,
311 DataRecursionQueue *Queue = nullptr);
312
313 /// Recursively visit an Objective-C protocol reference with location
314 /// information.
315 ///
316 /// \returns false if the visitation was terminated early, true otherwise.
317 bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLoc);
318
319 /// Recursively visit concept reference with location information.
320 ///
321 /// \returns false if the visitation was terminated early, true otherwise.
322 bool TraverseConceptReference(ConceptReference *CR);
323
324 // Visit concept reference.
325 bool VisitConceptReference(ConceptReference *CR) { return true; }
326 // ---- Methods on Attrs ----
327
328 // Visit an attribute.
329 bool VisitAttr(Attr *A) { return true; }
330
331// Declare Traverse* and empty Visit* for all Attr classes.
332#define ATTR_VISITOR_DECLS_ONLY
333#include "clang/AST/AttrVisitor.inc"
334#undef ATTR_VISITOR_DECLS_ONLY
335
336// ---- Methods on Stmts ----
337
338 Stmt::child_range getStmtChildren(Stmt *S) { return S->children(); }
339
340private:
341 // Traverse the given statement. If the most-derived traverse function takes a
342 // data recursion queue, pass it on; otherwise, discard it. Note that the
343 // first branch of this conditional must compile whether or not the derived
344 // class can take a queue, so if we're taking the second arm, make the first
345 // arm call our function rather than the derived class version.
346#define TRAVERSE_STMT_BASE(NAME, CLASS, VAR, QUEUE) \
347 (::clang::detail::has_same_member_pointer_type< \
348 decltype(&RecursiveASTVisitor::Traverse##NAME), \
349 decltype(&Derived::Traverse##NAME)>::value \
350 ? static_cast<std::conditional_t< \
351 ::clang::detail::has_same_member_pointer_type< \
352 decltype(&RecursiveASTVisitor::Traverse##NAME), \
353 decltype(&Derived::Traverse##NAME)>::value, \
354 Derived &, RecursiveASTVisitor &>>(*this) \
355 .Traverse##NAME(static_cast<CLASS *>(VAR), QUEUE) \
356 : getDerived().Traverse##NAME(static_cast<CLASS *>(VAR)))
357
358// Try to traverse the given statement, or enqueue it if we're performing data
359// recursion in the middle of traversing another statement. Can only be called
360// from within a DEF_TRAVERSE_STMT body or similar context.
361#define TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S) \
362 do { \
363 if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S, Queue)) \
364 return false; \
365 } while (false)
366
367public:
368// Declare Traverse*() for all concrete Stmt classes.
369#define ABSTRACT_STMT(STMT)
370#define STMT(CLASS, PARENT) \
371 bool Traverse##CLASS(CLASS *S, DataRecursionQueue *Queue = nullptr);
372#include "clang/AST/StmtNodes.inc"
373 // The above header #undefs ABSTRACT_STMT and STMT upon exit.
374
375 // Define WalkUpFrom*() and empty Visit*() for all Stmt classes.
376 bool WalkUpFromStmt(Stmt *S) { return getDerived().VisitStmt(S); }
377 bool VisitStmt(Stmt *S) { return true; }
378#define STMT(CLASS, PARENT) \
379 bool WalkUpFrom##CLASS(CLASS *S) { \
380 TRY_TO(WalkUpFrom##PARENT(S)); \
381 TRY_TO(Visit##CLASS(S)); \
382 return true; \
383 } \
384 bool Visit##CLASS(CLASS *S) { return true; }
385#include "clang/AST/StmtNodes.inc"
386
387// ---- Methods on Types ----
388// FIXME: revamp to take TypeLoc's rather than Types.
389
390// Declare Traverse*() for all concrete Type classes.
391#define ABSTRACT_TYPE(CLASS, BASE)
392#define TYPE(CLASS, BASE) bool Traverse##CLASS##Type(CLASS##Type *T);
393#include "clang/AST/TypeNodes.inc"
394 // The above header #undefs ABSTRACT_TYPE and TYPE upon exit.
395
396 // Define WalkUpFrom*() and empty Visit*() for all Type classes.
397 bool WalkUpFromType(Type *T) { return getDerived().VisitType(T); }
398 bool VisitType(Type *T) { return true; }
399#define TYPE(CLASS, BASE) \
400 bool WalkUpFrom##CLASS##Type(CLASS##Type *T) { \
401 TRY_TO(WalkUpFrom##BASE(T)); \
402 TRY_TO(Visit##CLASS##Type(T)); \
403 return true; \
404 } \
405 bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
406#include "clang/AST/TypeNodes.inc"
407
408// ---- Methods on TypeLocs ----
409// FIXME: this currently just calls the matching Type methods
410
411// Declare Traverse*() for all concrete TypeLoc classes.
412#define ABSTRACT_TYPELOC(CLASS, BASE)
413#define TYPELOC(CLASS, BASE) bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
414#include "clang/AST/TypeLocNodes.def"
415 // The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit.
416
417 // Define WalkUpFrom*() and empty Visit*() for all TypeLoc classes.
418 bool WalkUpFromTypeLoc(TypeLoc TL) { return getDerived().VisitTypeLoc(TL); }
419 bool VisitTypeLoc(TypeLoc TL) { return true; }
420
421 // QualifiedTypeLoc and UnqualTypeLoc are not declared in
422 // TypeNodes.inc and thus need to be handled specially.
423 bool WalkUpFromQualifiedTypeLoc(QualifiedTypeLoc TL) {
424 return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
425 }
426 bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { return true; }
427 bool WalkUpFromUnqualTypeLoc(UnqualTypeLoc TL) {
428 return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
429 }
430 bool VisitUnqualTypeLoc(UnqualTypeLoc TL) { return true; }
431
432// Note that BASE includes trailing 'Type' which CLASS doesn't.
433#define TYPE(CLASS, BASE) \
434 bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
435 TRY_TO(WalkUpFrom##BASE##Loc(TL)); \
436 TRY_TO(Visit##CLASS##TypeLoc(TL)); \
437 return true; \
438 } \
439 bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
440#include "clang/AST/TypeNodes.inc"
441
442// ---- Methods on Decls ----
443
444// Declare Traverse*() for all concrete Decl classes.
445#define ABSTRACT_DECL(DECL)
446#define DECL(CLASS, BASE) bool Traverse##CLASS##Decl(CLASS##Decl *D);
447#include "clang/AST/DeclNodes.inc"
448 // The above header #undefs ABSTRACT_DECL and DECL upon exit.
449
450 // Define WalkUpFrom*() and empty Visit*() for all Decl classes.
451 bool WalkUpFromDecl(Decl *D) { return getDerived().VisitDecl(D); }
452 bool VisitDecl(Decl *D) { return true; }
453#define DECL(CLASS, BASE) \
454 bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) { \
455 TRY_TO(WalkUpFrom##BASE(D)); \
456 TRY_TO(Visit##CLASS##Decl(D)); \
457 return true; \
458 } \
459 bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
460#include "clang/AST/DeclNodes.inc"
461
462 bool canIgnoreChildDeclWhileTraversingDeclContext(const Decl *Child);
463
464#define DEF_TRAVERSE_TMPL_INST(TMPLDECLKIND) \
465 bool TraverseTemplateInstantiations(TMPLDECLKIND##TemplateDecl *D);
466 DEF_TRAVERSE_TMPL_INST(Class)
467 DEF_TRAVERSE_TMPL_INST(Var)
468 DEF_TRAVERSE_TMPL_INST(Function)
469#undef DEF_TRAVERSE_TMPL_INST
470
471 bool TraverseTypeConstraint(const TypeConstraint *C);
472
473 bool TraverseConceptRequirement(concepts::Requirement *R);
474 bool TraverseConceptTypeRequirement(concepts::TypeRequirement *R);
475 bool TraverseConceptExprRequirement(concepts::ExprRequirement *R);
476 bool TraverseConceptNestedRequirement(concepts::NestedRequirement *R);
477
478 bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue);
479
480private:
481 // These are helper methods used by more than one Traverse* method.
482 bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
483
484 // Traverses template parameter lists of either a DeclaratorDecl or TagDecl.
485 template <typename T>
486 bool TraverseDeclTemplateParameterLists(T *D);
487
488 bool TraverseTemplateTypeParamDeclConstraints(const TemplateTypeParmDecl *D);
489
490 bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL,
491 unsigned Count);
492 bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL);
493 bool TraverseRecordHelper(RecordDecl *D);
494 bool TraverseCXXRecordHelper(CXXRecordDecl *D);
495 bool TraverseDeclaratorHelper(DeclaratorDecl *D);
496 bool TraverseDeclContextHelper(DeclContext *DC);
497 bool TraverseFunctionHelper(FunctionDecl *D);
498 bool TraverseVarHelper(VarDecl *D);
499 bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
500 bool TraverseOMPLoopDirective(OMPLoopDirective *S);
501 bool TraverseOMPClause(OMPClause *C);
502#define GEN_CLANG_CLAUSE_CLASS
503#define CLAUSE_CLASS(Enum, Str, Class) bool Visit##Class(Class *C);
504#include "llvm/Frontend/OpenMP/OMP.inc"
505 /// Process clauses with list of variables.
506 template <typename T> bool VisitOMPClauseList(T *Node);
507 /// Process clauses with pre-initis.
508 bool VisitOMPClauseWithPreInit(OMPClauseWithPreInit *Node);
509 bool VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *Node);
510
511 bool PostVisitStmt(Stmt *S);
512 bool TraverseOpenACCConstructStmt(OpenACCConstructStmt *S);
513 bool
514 TraverseOpenACCAssociatedStmtConstruct(OpenACCAssociatedStmtConstruct *S);
515 bool VisitOpenACCClauseList(ArrayRef<const OpenACCClause *>);
516 bool VisitOpenACCClause(const OpenACCClause *);
517};
518
519template <typename Derived>
520bool RecursiveASTVisitor<Derived>::TraverseTypeConstraint(
521 const TypeConstraint *C) {
522 if (!getDerived().shouldVisitImplicitCode()) {
523 TRY_TO(TraverseConceptReference(C->getConceptReference()));
524 return true;
525 }
526 if (Expr *IDC = C->getImmediatelyDeclaredConstraint()) {
527 TRY_TO(TraverseStmt(IDC));
528 } else {
529 // Avoid traversing the ConceptReference in the TypeConstraint
530 // if we have an immediately-declared-constraint, otherwise
531 // we'll end up visiting the concept and the arguments in
532 // the TC twice.
533 TRY_TO(TraverseConceptReference(C->getConceptReference()));
534 }
535 return true;
536}
537
538template <typename Derived>
539bool RecursiveASTVisitor<Derived>::TraverseConceptRequirement(
540 concepts::Requirement *R) {
541 switch (R->getKind()) {
542 case concepts::Requirement::RK_Type:
543 return getDerived().TraverseConceptTypeRequirement(
544 cast<concepts::TypeRequirement>(Val: R));
545 case concepts::Requirement::RK_Simple:
546 case concepts::Requirement::RK_Compound:
547 return getDerived().TraverseConceptExprRequirement(
548 cast<concepts::ExprRequirement>(Val: R));
549 case concepts::Requirement::RK_Nested:
550 return getDerived().TraverseConceptNestedRequirement(
551 cast<concepts::NestedRequirement>(Val: R));
552 }
553 llvm_unreachable("unexpected case");
554}
555
556template <typename Derived>
557bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
558 DataRecursionQueue *Queue) {
559 // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
560 switch (S->getStmtClass()) {
561 case Stmt::NoStmtClass:
562 break;
563#define ABSTRACT_STMT(STMT)
564#define STMT(CLASS, PARENT) \
565 case Stmt::CLASS##Class: \
566 return TRAVERSE_STMT_BASE(CLASS, CLASS, S, Queue);
567#include "clang/AST/StmtNodes.inc"
568 }
569
570 return true;
571}
572
573#undef DISPATCH_STMT
574
575template <typename Derived>
576bool RecursiveASTVisitor<Derived>::TraverseConceptTypeRequirement(
577 concepts::TypeRequirement *R) {
578 if (R->isSubstitutionFailure())
579 return true;
580 return getDerived().TraverseTypeLoc(R->getType()->getTypeLoc());
581}
582
583template <typename Derived>
584bool RecursiveASTVisitor<Derived>::TraverseConceptExprRequirement(
585 concepts::ExprRequirement *R) {
586 if (!R->isExprSubstitutionFailure())
587 TRY_TO(TraverseStmt(R->getExpr()));
588 auto &RetReq = R->getReturnTypeRequirement();
589 if (RetReq.isTypeConstraint()) {
590 if (getDerived().shouldVisitImplicitCode()) {
591 TRY_TO(TraverseTemplateParameterListHelper(
592 RetReq.getTypeConstraintTemplateParameterList()));
593 } else {
594 // Template parameter list is implicit, visit constraint directly.
595 TRY_TO(TraverseTypeConstraint(RetReq.getTypeConstraint()));
596 }
597 }
598 return true;
599}
600
601template <typename Derived>
602bool RecursiveASTVisitor<Derived>::TraverseConceptNestedRequirement(
603 concepts::NestedRequirement *R) {
604 if (!R->hasInvalidConstraint())
605 return getDerived().TraverseStmt(R->getConstraintExpr());
606 return true;
607}
608
609template <typename Derived>
610bool RecursiveASTVisitor<Derived>::PostVisitStmt(Stmt *S) {
611 // In pre-order traversal mode, each Traverse##STMT method is responsible for
612 // calling WalkUpFrom. Therefore, if the user overrides Traverse##STMT and
613 // does not call the default implementation, the WalkUpFrom callback is not
614 // called. Post-order traversal mode should provide the same behavior
615 // regarding method overrides.
616 //
617 // In post-order traversal mode the Traverse##STMT method, when it receives a
618 // DataRecursionQueue, can't call WalkUpFrom after traversing children because
619 // it only enqueues the children and does not traverse them. TraverseStmt
620 // traverses the enqueued children, and we call WalkUpFrom here.
621 //
622 // However, to make pre-order and post-order modes identical with regards to
623 // whether they call WalkUpFrom at all, we call WalkUpFrom if and only if the
624 // user did not override the Traverse##STMT method. We implement the override
625 // check with isSameMethod calls below.
626
627 switch (S->getStmtClass()) {
628 case Stmt::NoStmtClass:
629 break;
630#define ABSTRACT_STMT(STMT)
631#define STMT(CLASS, PARENT) \
632 case Stmt::CLASS##Class: \
633 if (::clang::detail::isSameMethod(&RecursiveASTVisitor::Traverse##CLASS, \
634 &Derived::Traverse##CLASS)) { \
635 TRY_TO(WalkUpFrom##CLASS(static_cast<CLASS *>(S))); \
636 } \
637 break;
638#define INITLISTEXPR(CLASS, PARENT) \
639 case Stmt::CLASS##Class: \
640 if (::clang::detail::isSameMethod(&RecursiveASTVisitor::Traverse##CLASS, \
641 &Derived::Traverse##CLASS)) { \
642 auto ILE = static_cast<CLASS *>(S); \
643 if (auto Syn = ILE->isSemanticForm() ? ILE->getSyntacticForm() : ILE) \
644 TRY_TO(WalkUpFrom##CLASS(Syn)); \
645 if (auto Sem = ILE->isSemanticForm() ? ILE : ILE->getSemanticForm()) \
646 TRY_TO(WalkUpFrom##CLASS(Sem)); \
647 } \
648 break;
649#include "clang/AST/StmtNodes.inc"
650 }
651
652 return true;
653}
654
655#undef DISPATCH_STMT
656
657// Inlining this method can lead to large code size and compile-time increases
658// without any benefit to runtime performance.
659template <typename Derived>
660LLVM_ATTRIBUTE_NOINLINE bool
661RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S, DataRecursionQueue *Queue) {
662 if (!S)
663 return true;
664
665 if (Queue) {
666 Queue->push_back(Elt: {S, false});
667 return true;
668 }
669
670 SmallVector<llvm::PointerIntPair<Stmt *, 1, bool>, 8> LocalQueue;
671 LocalQueue.push_back(Elt: {S, false});
672
673 while (!LocalQueue.empty()) {
674 auto &CurrSAndVisited = LocalQueue.back();
675 Stmt *CurrS = CurrSAndVisited.getPointer();
676 bool Visited = CurrSAndVisited.getInt();
677 if (Visited) {
678 LocalQueue.pop_back();
679 TRY_TO(dataTraverseStmtPost(CurrS));
680 if (getDerived().shouldTraversePostOrder()) {
681 TRY_TO(PostVisitStmt(CurrS));
682 }
683 continue;
684 }
685
686 if (getDerived().dataTraverseStmtPre(CurrS)) {
687 CurrSAndVisited.setInt(true);
688 size_t N = LocalQueue.size();
689 TRY_TO(dataTraverseNode(CurrS, &LocalQueue));
690 // Process new children in the order they were added.
691 std::reverse(first: LocalQueue.begin() + N, last: LocalQueue.end());
692 } else {
693 LocalQueue.pop_back();
694 }
695 }
696
697 return true;
698}
699
700template <typename Derived>
701bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) {
702 if (T.isNull())
703 return true;
704
705 switch (T->getTypeClass()) {
706#define ABSTRACT_TYPE(CLASS, BASE)
707#define TYPE(CLASS, BASE) \
708 case Type::CLASS: \
709 return getDerived().Traverse##CLASS##Type( \
710 static_cast<CLASS##Type *>(const_cast<Type *>(T.getTypePtr())));
711#include "clang/AST/TypeNodes.inc"
712 }
713
714 return true;
715}
716
717template <typename Derived>
718bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
719 if (TL.isNull())
720 return true;
721
722 switch (TL.getTypeLocClass()) {
723#define ABSTRACT_TYPELOC(CLASS, BASE)
724#define TYPELOC(CLASS, BASE) \
725 case TypeLoc::CLASS: \
726 return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>());
727#include "clang/AST/TypeLocNodes.def"
728 }
729
730 return true;
731}
732
733// Define the Traverse*Attr(Attr* A) methods
734#define VISITORCLASS RecursiveASTVisitor
735#include "clang/AST/AttrVisitor.inc"
736#undef VISITORCLASS
737
738template <typename Derived>
739bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
740 if (!D)
741 return true;
742
743 // As a syntax visitor, by default we want to ignore declarations for
744 // implicit declarations (ones not typed explicitly by the user).
745 if (!getDerived().shouldVisitImplicitCode()) {
746 if (D->isImplicit()) {
747 // For an implicit template type parameter, its type constraints are not
748 // implicit and are not represented anywhere else. We still need to visit
749 // them.
750 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(Val: D))
751 return TraverseTemplateTypeParamDeclConstraints(D: TTPD);
752 return true;
753 }
754
755 // Deduction guides for alias templates are always synthesized, so they
756 // should not be traversed unless shouldVisitImplicitCode() returns true.
757 //
758 // It's important to note that checking the implicit bit is not efficient
759 // for the alias case. For deduction guides synthesized from explicit
760 // user-defined deduction guides, we must maintain the explicit bit to
761 // ensure correct overload resolution.
762 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(Val: D))
763 if (llvm::isa_and_present<TypeAliasTemplateDecl>(
764 Val: FTD->getDeclName().getCXXDeductionGuideTemplate()))
765 return true;
766 }
767
768 switch (D->getKind()) {
769#define ABSTRACT_DECL(DECL)
770#define DECL(CLASS, BASE) \
771 case Decl::CLASS: \
772 if (!getDerived().Traverse##CLASS##Decl(static_cast<CLASS##Decl *>(D))) \
773 return false; \
774 break;
775#include "clang/AST/DeclNodes.inc"
776 }
777 return true;
778}
779
780template <typename Derived>
781bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
782 NestedNameSpecifier *NNS) {
783 if (!NNS)
784 return true;
785
786 if (NNS->getPrefix())
787 TRY_TO(TraverseNestedNameSpecifier(NNS->getPrefix()));
788
789 switch (NNS->getKind()) {
790 case NestedNameSpecifier::Identifier:
791 case NestedNameSpecifier::Namespace:
792 case NestedNameSpecifier::NamespaceAlias:
793 case NestedNameSpecifier::Global:
794 case NestedNameSpecifier::Super:
795 return true;
796
797 case NestedNameSpecifier::TypeSpec:
798 TRY_TO(TraverseType(QualType(NNS->getAsType(), 0)));
799 }
800
801 return true;
802}
803
804template <typename Derived>
805bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
806 NestedNameSpecifierLoc NNS) {
807 if (!NNS)
808 return true;
809
810 if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
811 TRY_TO(TraverseNestedNameSpecifierLoc(Prefix));
812
813 switch (NNS.getNestedNameSpecifier()->getKind()) {
814 case NestedNameSpecifier::Identifier:
815 case NestedNameSpecifier::Namespace:
816 case NestedNameSpecifier::NamespaceAlias:
817 case NestedNameSpecifier::Global:
818 case NestedNameSpecifier::Super:
819 return true;
820
821 case NestedNameSpecifier::TypeSpec:
822 TRY_TO(TraverseTypeLoc(NNS.getTypeLoc()));
823 break;
824 }
825
826 return true;
827}
828
829template <typename Derived>
830bool RecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo(
831 DeclarationNameInfo NameInfo) {
832 switch (NameInfo.getName().getNameKind()) {
833 case DeclarationName::CXXConstructorName:
834 case DeclarationName::CXXDestructorName:
835 case DeclarationName::CXXConversionFunctionName:
836 if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
837 TRY_TO(TraverseTypeLoc(TSInfo->getTypeLoc()));
838 break;
839
840 case DeclarationName::CXXDeductionGuideName:
841 TRY_TO(TraverseTemplateName(
842 TemplateName(NameInfo.getName().getCXXDeductionGuideTemplate())));
843 break;
844
845 case DeclarationName::Identifier:
846 case DeclarationName::ObjCZeroArgSelector:
847 case DeclarationName::ObjCOneArgSelector:
848 case DeclarationName::ObjCMultiArgSelector:
849 case DeclarationName::CXXOperatorName:
850 case DeclarationName::CXXLiteralOperatorName:
851 case DeclarationName::CXXUsingDirective:
852 break;
853 }
854
855 return true;
856}
857
858template <typename Derived>
859bool RecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) {
860 if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
861 TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier()));
862 } else if (QualifiedTemplateName *QTN =
863 Template.getAsQualifiedTemplateName()) {
864 if (QTN->getQualifier()) {
865 TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier()));
866 }
867 }
868
869 return true;
870}
871
872template <typename Derived>
873bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
874 const TemplateArgument &Arg) {
875 switch (Arg.getKind()) {
876 case TemplateArgument::Null:
877 case TemplateArgument::Declaration:
878 case TemplateArgument::Integral:
879 case TemplateArgument::NullPtr:
880 case TemplateArgument::StructuralValue:
881 return true;
882
883 case TemplateArgument::Type:
884 return getDerived().TraverseType(Arg.getAsType());
885
886 case TemplateArgument::Template:
887 case TemplateArgument::TemplateExpansion:
888 return getDerived().TraverseTemplateName(
889 Arg.getAsTemplateOrTemplatePattern());
890
891 case TemplateArgument::Expression:
892 return getDerived().TraverseStmt(Arg.getAsExpr());
893
894 case TemplateArgument::Pack:
895 return getDerived().TraverseTemplateArguments(Arg.pack_elements());
896 }
897
898 return true;
899}
900
901// FIXME: no template name location?
902// FIXME: no source locations for a template argument pack?
903template <typename Derived>
904bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
905 const TemplateArgumentLoc &ArgLoc) {
906 const TemplateArgument &Arg = ArgLoc.getArgument();
907
908 switch (Arg.getKind()) {
909 case TemplateArgument::Null:
910 case TemplateArgument::Declaration:
911 case TemplateArgument::Integral:
912 case TemplateArgument::NullPtr:
913 case TemplateArgument::StructuralValue:
914 return true;
915
916 case TemplateArgument::Type: {
917 // FIXME: how can TSI ever be NULL?
918 if (TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo())
919 return getDerived().TraverseTypeLoc(TSI->getTypeLoc());
920 else
921 return getDerived().TraverseType(Arg.getAsType());
922 }
923
924 case TemplateArgument::Template:
925 case TemplateArgument::TemplateExpansion:
926 if (ArgLoc.getTemplateQualifierLoc())
927 TRY_TO(getDerived().TraverseNestedNameSpecifierLoc(
928 ArgLoc.getTemplateQualifierLoc()));
929 return getDerived().TraverseTemplateName(
930 Arg.getAsTemplateOrTemplatePattern());
931
932 case TemplateArgument::Expression:
933 return getDerived().TraverseStmt(ArgLoc.getSourceExpression());
934
935 case TemplateArgument::Pack:
936 return getDerived().TraverseTemplateArguments(Arg.pack_elements());
937 }
938
939 return true;
940}
941
942template <typename Derived>
943bool RecursiveASTVisitor<Derived>::TraverseTemplateArguments(
944 ArrayRef<TemplateArgument> Args) {
945 for (const TemplateArgument &Arg : Args)
946 TRY_TO(TraverseTemplateArgument(Arg));
947
948 return true;
949}
950
951template <typename Derived>
952bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
953 CXXCtorInitializer *Init) {
954 if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo())
955 TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
956
957 if (Init->isWritten() || getDerived().shouldVisitImplicitCode())
958 TRY_TO(TraverseStmt(Init->getInit()));
959
960 return true;
961}
962
963template <typename Derived>
964bool
965RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
966 const LambdaCapture *C,
967 Expr *Init) {
968 if (LE->isInitCapture(Capture: C))
969 TRY_TO(TraverseDecl(C->getCapturedVar()));
970 else
971 TRY_TO(TraverseStmt(Init));
972 return true;
973}
974
975// ----------------- Type traversal -----------------
976
977// This macro makes available a variable T, the passed-in type.
978#define DEF_TRAVERSE_TYPE(TYPE, CODE) \
979 template <typename Derived> \
980 bool RecursiveASTVisitor<Derived>::Traverse##TYPE(TYPE *T) { \
981 if (!getDerived().shouldTraversePostOrder()) \
982 TRY_TO(WalkUpFrom##TYPE(T)); \
983 { CODE; } \
984 if (getDerived().shouldTraversePostOrder()) \
985 TRY_TO(WalkUpFrom##TYPE(T)); \
986 return true; \
987 }
988
989DEF_TRAVERSE_TYPE(BuiltinType, {})
990
991DEF_TRAVERSE_TYPE(ComplexType, { TRY_TO(TraverseType(T->getElementType())); })
992
993DEF_TRAVERSE_TYPE(PointerType, { TRY_TO(TraverseType(T->getPointeeType())); })
994
995DEF_TRAVERSE_TYPE(BlockPointerType,
996 { TRY_TO(TraverseType(T->getPointeeType())); })
997
998DEF_TRAVERSE_TYPE(LValueReferenceType,
999 { TRY_TO(TraverseType(T->getPointeeType())); })
1000
1001DEF_TRAVERSE_TYPE(RValueReferenceType,
1002 { TRY_TO(TraverseType(T->getPointeeType())); })
1003
1004DEF_TRAVERSE_TYPE(MemberPointerType, {
1005 TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
1006 if (T->isSugared())
1007 TRY_TO(TraverseType(
1008 QualType(T->getMostRecentCXXRecordDecl()->getTypeForDecl(), 0)));
1009 TRY_TO(TraverseType(T->getPointeeType()));
1010})
1011
1012DEF_TRAVERSE_TYPE(AdjustedType, { TRY_TO(TraverseType(T->getOriginalType())); })
1013
1014DEF_TRAVERSE_TYPE(DecayedType, { TRY_TO(TraverseType(T->getOriginalType())); })
1015
1016DEF_TRAVERSE_TYPE(ConstantArrayType, {
1017 TRY_TO(TraverseType(T->getElementType()));
1018 if (T->getSizeExpr())
1019 TRY_TO(TraverseStmt(const_cast<Expr*>(T->getSizeExpr())));
1020})
1021
1022DEF_TRAVERSE_TYPE(ArrayParameterType, {
1023 TRY_TO(TraverseType(T->getElementType()));
1024 if (T->getSizeExpr())
1025 TRY_TO(TraverseStmt(const_cast<Expr *>(T->getSizeExpr())));
1026})
1027
1028DEF_TRAVERSE_TYPE(IncompleteArrayType,
1029 { TRY_TO(TraverseType(T->getElementType())); })
1030
1031DEF_TRAVERSE_TYPE(VariableArrayType, {
1032 TRY_TO(TraverseType(T->getElementType()));
1033 TRY_TO(TraverseStmt(T->getSizeExpr()));
1034})
1035
1036DEF_TRAVERSE_TYPE(DependentSizedArrayType, {
1037 TRY_TO(TraverseType(T->getElementType()));
1038 if (T->getSizeExpr())
1039 TRY_TO(TraverseStmt(T->getSizeExpr()));
1040})
1041
1042DEF_TRAVERSE_TYPE(DependentAddressSpaceType, {
1043 TRY_TO(TraverseStmt(T->getAddrSpaceExpr()));
1044 TRY_TO(TraverseType(T->getPointeeType()));
1045})
1046
1047DEF_TRAVERSE_TYPE(DependentVectorType, {
1048 if (T->getSizeExpr())
1049 TRY_TO(TraverseStmt(T->getSizeExpr()));
1050 TRY_TO(TraverseType(T->getElementType()));
1051})
1052
1053DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
1054 if (T->getSizeExpr())
1055 TRY_TO(TraverseStmt(T->getSizeExpr()));
1056 TRY_TO(TraverseType(T->getElementType()));
1057})
1058
1059DEF_TRAVERSE_TYPE(VectorType, { TRY_TO(TraverseType(T->getElementType())); })
1060
1061DEF_TRAVERSE_TYPE(ExtVectorType, { TRY_TO(TraverseType(T->getElementType())); })
1062
1063DEF_TRAVERSE_TYPE(ConstantMatrixType,
1064 { TRY_TO(TraverseType(T->getElementType())); })
1065
1066DEF_TRAVERSE_TYPE(DependentSizedMatrixType, {
1067 if (T->getRowExpr())
1068 TRY_TO(TraverseStmt(T->getRowExpr()));
1069 if (T->getColumnExpr())
1070 TRY_TO(TraverseStmt(T->getColumnExpr()));
1071 TRY_TO(TraverseType(T->getElementType()));
1072})
1073
1074DEF_TRAVERSE_TYPE(FunctionNoProtoType,
1075 { TRY_TO(TraverseType(T->getReturnType())); })
1076
1077DEF_TRAVERSE_TYPE(FunctionProtoType, {
1078 TRY_TO(TraverseType(T->getReturnType()));
1079
1080 for (const auto &A : T->param_types()) {
1081 TRY_TO(TraverseType(A));
1082 }
1083
1084 for (const auto &E : T->exceptions()) {
1085 TRY_TO(TraverseType(E));
1086 }
1087
1088 if (Expr *NE = T->getNoexceptExpr())
1089 TRY_TO(TraverseStmt(NE));
1090})
1091
1092DEF_TRAVERSE_TYPE(UsingType, {})
1093DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
1094DEF_TRAVERSE_TYPE(TypedefType, {})
1095
1096DEF_TRAVERSE_TYPE(TypeOfExprType,
1097 { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
1098
1099DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnmodifiedType())); })
1100
1101DEF_TRAVERSE_TYPE(DecltypeType,
1102 { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
1103
1104DEF_TRAVERSE_TYPE(PackIndexingType, {
1105 TRY_TO(TraverseType(T->getPattern()));
1106 TRY_TO(TraverseStmt(T->getIndexExpr()));
1107})
1108
1109DEF_TRAVERSE_TYPE(UnaryTransformType, {
1110 TRY_TO(TraverseType(T->getBaseType()));
1111 TRY_TO(TraverseType(T->getUnderlyingType()));
1112})
1113
1114DEF_TRAVERSE_TYPE(AutoType, {
1115 TRY_TO(TraverseType(T->getDeducedType()));
1116 if (T->isConstrained()) {
1117 TRY_TO(TraverseTemplateArguments(T->getTypeConstraintArguments()));
1118 }
1119})
1120DEF_TRAVERSE_TYPE(DeducedTemplateSpecializationType, {
1121 TRY_TO(TraverseTemplateName(T->getTemplateName()));
1122 TRY_TO(TraverseType(T->getDeducedType()));
1123})
1124
1125DEF_TRAVERSE_TYPE(RecordType, {})
1126DEF_TRAVERSE_TYPE(EnumType, {})
1127DEF_TRAVERSE_TYPE(TemplateTypeParmType, {})
1128DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, {
1129 TRY_TO(TraverseType(T->getReplacementType()));
1130})
1131DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, {
1132 TRY_TO(TraverseTemplateArgument(T->getArgumentPack()));
1133})
1134
1135DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
1136 TRY_TO(TraverseTemplateName(T->getTemplateName()));
1137 TRY_TO(TraverseTemplateArguments(T->template_arguments()));
1138})
1139
1140DEF_TRAVERSE_TYPE(InjectedClassNameType, {})
1141
1142DEF_TRAVERSE_TYPE(AttributedType,
1143 { TRY_TO(TraverseType(T->getModifiedType())); })
1144
1145DEF_TRAVERSE_TYPE(CountAttributedType, {
1146 if (T->getCountExpr())
1147 TRY_TO(TraverseStmt(T->getCountExpr()));
1148 TRY_TO(TraverseType(T->desugar()));
1149})
1150
1151DEF_TRAVERSE_TYPE(BTFTagAttributedType,
1152 { TRY_TO(TraverseType(T->getWrappedType())); })
1153
1154DEF_TRAVERSE_TYPE(HLSLAttributedResourceType,
1155 { TRY_TO(TraverseType(T->getWrappedType())); })
1156
1157DEF_TRAVERSE_TYPE(HLSLInlineSpirvType, {
1158 for (auto &Operand : T->getOperands()) {
1159 if (Operand.isConstant() || Operand.isType()) {
1160 TRY_TO(TraverseType(Operand.getResultType()));
1161 }
1162 }
1163})
1164
1165DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
1166
1167DEF_TRAVERSE_TYPE(MacroQualifiedType,
1168 { TRY_TO(TraverseType(T->getUnderlyingType())); })
1169
1170DEF_TRAVERSE_TYPE(ElaboratedType, {
1171 if (T->getQualifier()) {
1172 TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
1173 }
1174 TRY_TO(TraverseType(T->getNamedType()));
1175})
1176
1177DEF_TRAVERSE_TYPE(DependentNameType,
1178 { TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); })
1179
1180DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
1181 const DependentTemplateStorage &S = T->getDependentTemplateName();
1182 TRY_TO(TraverseNestedNameSpecifier(S.getQualifier()));
1183 TRY_TO(TraverseTemplateArguments(T->template_arguments()));
1184})
1185
1186DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); })
1187
1188DEF_TRAVERSE_TYPE(ObjCTypeParamType, {})
1189
1190DEF_TRAVERSE_TYPE(ObjCInterfaceType, {})
1191
1192DEF_TRAVERSE_TYPE(ObjCObjectType, {
1193 // We have to watch out here because an ObjCInterfaceType's base
1194 // type is itself.
1195 if (T->getBaseType().getTypePtr() != T)
1196 TRY_TO(TraverseType(T->getBaseType()));
1197 for (auto typeArg : T->getTypeArgsAsWritten()) {
1198 TRY_TO(TraverseType(typeArg));
1199 }
1200})
1201
1202DEF_TRAVERSE_TYPE(ObjCObjectPointerType,
1203 { TRY_TO(TraverseType(T->getPointeeType())); })
1204
1205DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); })
1206
1207DEF_TRAVERSE_TYPE(PipeType, { TRY_TO(TraverseType(T->getElementType())); })
1208
1209DEF_TRAVERSE_TYPE(BitIntType, {})
1210DEF_TRAVERSE_TYPE(DependentBitIntType,
1211 { TRY_TO(TraverseStmt(T->getNumBitsExpr())); })
1212
1213#undef DEF_TRAVERSE_TYPE
1214
1215// ----------------- TypeLoc traversal -----------------
1216
1217// This macro makes available a variable TL, the passed-in TypeLoc.
1218// If requested, it calls WalkUpFrom* for the Type in the given TypeLoc,
1219// in addition to WalkUpFrom* for the TypeLoc itself, such that existing
1220// clients that override the WalkUpFrom*Type() and/or Visit*Type() methods
1221// continue to work.
1222#define DEF_TRAVERSE_TYPELOC(TYPE, CODE) \
1223 template <typename Derived> \
1224 bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) { \
1225 if (!getDerived().shouldTraversePostOrder()) { \
1226 TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
1227 if (getDerived().shouldWalkTypesOfTypeLocs()) \
1228 TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \
1229 } \
1230 { CODE; } \
1231 if (getDerived().shouldTraversePostOrder()) { \
1232 TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
1233 if (getDerived().shouldWalkTypesOfTypeLocs()) \
1234 TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \
1235 } \
1236 return true; \
1237 }
1238
1239template <typename Derived>
1240bool
1241RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(QualifiedTypeLoc TL) {
1242 // Move this over to the 'main' typeloc tree. Note that this is a
1243 // move -- we pretend that we were really looking at the unqualified
1244 // typeloc all along -- rather than a recursion, so we don't follow
1245 // the normal CRTP plan of going through
1246 // getDerived().TraverseTypeLoc. If we did, we'd be traversing
1247 // twice for the same type (once as a QualifiedTypeLoc version of
1248 // the type, once as an UnqualifiedTypeLoc version of the type),
1249 // which in effect means we'd call VisitTypeLoc twice with the
1250 // 'same' type. This solves that problem, at the cost of never
1251 // seeing the qualified version of the type (unless the client
1252 // subclasses TraverseQualifiedTypeLoc themselves). It's not a
1253 // perfect solution. A perfect solution probably requires making
1254 // QualifiedTypeLoc a wrapper around TypeLoc -- like QualType is a
1255 // wrapper around Type* -- rather than being its own class in the
1256 // type hierarchy.
1257 return TraverseTypeLoc(TL: TL.getUnqualifiedLoc());
1258}
1259
1260DEF_TRAVERSE_TYPELOC(BuiltinType, {})
1261
1262// FIXME: ComplexTypeLoc is unfinished
1263DEF_TRAVERSE_TYPELOC(ComplexType, {
1264 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1265})
1266
1267DEF_TRAVERSE_TYPELOC(PointerType,
1268 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1269
1270DEF_TRAVERSE_TYPELOC(BlockPointerType,
1271 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1272
1273DEF_TRAVERSE_TYPELOC(LValueReferenceType,
1274 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1275
1276DEF_TRAVERSE_TYPELOC(RValueReferenceType,
1277 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1278
1279// We traverse this in the type case as well, but how is it not reached through
1280// the pointee type?
1281DEF_TRAVERSE_TYPELOC(MemberPointerType, {
1282 if (NestedNameSpecifierLoc QL = TL.getQualifierLoc())
1283 TRY_TO(TraverseNestedNameSpecifierLoc(QL));
1284 else
1285 TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
1286 TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
1287})
1288
1289DEF_TRAVERSE_TYPELOC(AdjustedType,
1290 { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
1291
1292DEF_TRAVERSE_TYPELOC(DecayedType,
1293 { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
1294
1295template <typename Derived>
1296bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
1297 // This isn't available for ArrayType, but is for the ArrayTypeLoc.
1298 TRY_TO(TraverseStmt(TL.getSizeExpr()));
1299 return true;
1300}
1301
1302DEF_TRAVERSE_TYPELOC(ConstantArrayType, {
1303 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1304 TRY_TO(TraverseArrayTypeLocHelper(TL));
1305})
1306
1307DEF_TRAVERSE_TYPELOC(ArrayParameterType, {
1308 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1309 TRY_TO(TraverseArrayTypeLocHelper(TL));
1310})
1311
1312DEF_TRAVERSE_TYPELOC(IncompleteArrayType, {
1313 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1314 TRY_TO(TraverseArrayTypeLocHelper(TL));
1315})
1316
1317DEF_TRAVERSE_TYPELOC(VariableArrayType, {
1318 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1319 TRY_TO(TraverseArrayTypeLocHelper(TL));
1320})
1321
1322DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, {
1323 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1324 TRY_TO(TraverseArrayTypeLocHelper(TL));
1325})
1326
1327DEF_TRAVERSE_TYPELOC(DependentAddressSpaceType, {
1328 TRY_TO(TraverseStmt(TL.getTypePtr()->getAddrSpaceExpr()));
1329 TRY_TO(TraverseType(TL.getTypePtr()->getPointeeType()));
1330})
1331
1332// FIXME: order? why not size expr first?
1333// FIXME: base VectorTypeLoc is unfinished
1334DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, {
1335 if (TL.getTypePtr()->getSizeExpr())
1336 TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
1337 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1338})
1339
1340// FIXME: VectorTypeLoc is unfinished
1341DEF_TRAVERSE_TYPELOC(VectorType, {
1342 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1343})
1344
1345DEF_TRAVERSE_TYPELOC(DependentVectorType, {
1346 if (TL.getTypePtr()->getSizeExpr())
1347 TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
1348 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1349})
1350
1351// FIXME: size and attributes
1352// FIXME: base VectorTypeLoc is unfinished
1353DEF_TRAVERSE_TYPELOC(ExtVectorType, {
1354 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1355})
1356
1357DEF_TRAVERSE_TYPELOC(ConstantMatrixType, {
1358 TRY_TO(TraverseStmt(TL.getAttrRowOperand()));
1359 TRY_TO(TraverseStmt(TL.getAttrColumnOperand()));
1360 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1361})
1362
1363DEF_TRAVERSE_TYPELOC(DependentSizedMatrixType, {
1364 TRY_TO(TraverseStmt(TL.getAttrRowOperand()));
1365 TRY_TO(TraverseStmt(TL.getAttrColumnOperand()));
1366 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1367})
1368
1369DEF_TRAVERSE_TYPELOC(FunctionNoProtoType,
1370 { TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); })
1371
1372// FIXME: location of exception specifications (attributes?)
1373DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
1374 TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
1375
1376 const FunctionProtoType *T = TL.getTypePtr();
1377
1378 for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) {
1379 if (TL.getParam(I)) {
1380 TRY_TO(TraverseDecl(TL.getParam(I)));
1381 } else if (I < T->getNumParams()) {
1382 TRY_TO(TraverseType(T->getParamType(I)));
1383 }
1384 }
1385
1386 for (const auto &E : T->exceptions()) {
1387 TRY_TO(TraverseType(E));
1388 }
1389
1390 if (Expr *NE = T->getNoexceptExpr())
1391 TRY_TO(TraverseStmt(NE));
1392})
1393
1394DEF_TRAVERSE_TYPELOC(UsingType, {})
1395DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
1396DEF_TRAVERSE_TYPELOC(TypedefType, {})
1397
1398DEF_TRAVERSE_TYPELOC(TypeOfExprType,
1399 { TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); })
1400
1401DEF_TRAVERSE_TYPELOC(TypeOfType, {
1402 TRY_TO(TraverseTypeLoc(TL.getUnmodifiedTInfo()->getTypeLoc()));
1403})
1404
1405// FIXME: location of underlying expr
1406DEF_TRAVERSE_TYPELOC(DecltypeType, {
1407 TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
1408})
1409
1410DEF_TRAVERSE_TYPELOC(PackIndexingType, {
1411 TRY_TO(TraverseType(TL.getPattern()));
1412 TRY_TO(TraverseStmt(TL.getTypePtr()->getIndexExpr()));
1413})
1414
1415DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
1416 TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
1417})
1418
1419DEF_TRAVERSE_TYPELOC(AutoType, {
1420 TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
1421 if (TL.isConstrained()) {
1422 TRY_TO(TraverseConceptReference(TL.getConceptReference()));
1423 }
1424})
1425
1426DEF_TRAVERSE_TYPELOC(DeducedTemplateSpecializationType, {
1427 TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
1428 TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
1429})
1430
1431DEF_TRAVERSE_TYPELOC(RecordType, {})
1432DEF_TRAVERSE_TYPELOC(EnumType, {})
1433DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {})
1434DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, {
1435 TRY_TO(TraverseType(TL.getTypePtr()->getReplacementType()));
1436})
1437DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, {
1438 TRY_TO(TraverseTemplateArgument(TL.getTypePtr()->getArgumentPack()));
1439})
1440
1441// FIXME: use the loc for the template name?
1442DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
1443 TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
1444 for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
1445 TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
1446 }
1447})
1448
1449DEF_TRAVERSE_TYPELOC(InjectedClassNameType, {})
1450
1451DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
1452
1453DEF_TRAVERSE_TYPELOC(MacroQualifiedType,
1454 { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
1455
1456DEF_TRAVERSE_TYPELOC(AttributedType,
1457 { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
1458
1459DEF_TRAVERSE_TYPELOC(CountAttributedType,
1460 { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
1461
1462DEF_TRAVERSE_TYPELOC(BTFTagAttributedType,
1463 { TRY_TO(TraverseTypeLoc(TL.getWrappedLoc())); })
1464
1465DEF_TRAVERSE_TYPELOC(HLSLAttributedResourceType,
1466 { TRY_TO(TraverseTypeLoc(TL.getWrappedLoc())); })
1467
1468DEF_TRAVERSE_TYPELOC(HLSLInlineSpirvType,
1469 { TRY_TO(TraverseType(TL.getType())); })
1470
1471DEF_TRAVERSE_TYPELOC(ElaboratedType, {
1472 if (TL.getQualifierLoc()) {
1473 TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
1474 }
1475 TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
1476})
1477
1478DEF_TRAVERSE_TYPELOC(DependentNameType, {
1479 TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
1480})
1481
1482DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
1483 if (TL.getQualifierLoc()) {
1484 TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
1485 }
1486
1487 for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
1488 TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
1489 }
1490})
1491
1492DEF_TRAVERSE_TYPELOC(PackExpansionType,
1493 { TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); })
1494
1495DEF_TRAVERSE_TYPELOC(ObjCTypeParamType, {
1496 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1497 ObjCProtocolLoc ProtocolLoc(TL.getProtocol(I), TL.getProtocolLoc(I));
1498 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1499 }
1500})
1501
1502DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, {})
1503
1504DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
1505 // We have to watch out here because an ObjCInterfaceType's base
1506 // type is itself.
1507 if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
1508 TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
1509 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
1510 TRY_TO(TraverseTypeLoc(TL.getTypeArgTInfo(i)->getTypeLoc()));
1511 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1512 ObjCProtocolLoc ProtocolLoc(TL.getProtocol(I), TL.getProtocolLoc(I));
1513 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1514 }
1515})
1516
1517DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType,
1518 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1519
1520DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
1521
1522DEF_TRAVERSE_TYPELOC(PipeType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
1523
1524DEF_TRAVERSE_TYPELOC(BitIntType, {})
1525DEF_TRAVERSE_TYPELOC(DependentBitIntType, {
1526 TRY_TO(TraverseStmt(TL.getTypePtr()->getNumBitsExpr()));
1527})
1528
1529#undef DEF_TRAVERSE_TYPELOC
1530
1531// ----------------- Decl traversal -----------------
1532//
1533// For a Decl, we automate (in the DEF_TRAVERSE_DECL macro) traversing
1534// the children that come from the DeclContext associated with it.
1535// Therefore each Traverse* only needs to worry about children other
1536// than those.
1537
1538template <typename Derived>
1539bool RecursiveASTVisitor<Derived>::canIgnoreChildDeclWhileTraversingDeclContext(
1540 const Decl *Child) {
1541 // BlockDecls are traversed through BlockExprs,
1542 // CapturedDecls are traversed through CapturedStmts.
1543 if (isa<BlockDecl>(Val: Child) || isa<CapturedDecl>(Val: Child))
1544 return true;
1545 // Lambda classes are traversed through LambdaExprs.
1546 if (const CXXRecordDecl* Cls = dyn_cast<CXXRecordDecl>(Val: Child))
1547 return Cls->isLambda();
1548 return false;
1549}
1550
1551template <typename Derived>
1552bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
1553 if (!DC)
1554 return true;
1555
1556 for (auto *Child : DC->decls()) {
1557 if (!canIgnoreChildDeclWhileTraversingDeclContext(Child))
1558 TRY_TO(TraverseDecl(Child));
1559 }
1560
1561 return true;
1562}
1563
1564// This macro makes available a variable D, the passed-in decl.
1565#define DEF_TRAVERSE_DECL(DECL, CODE) \
1566 template <typename Derived> \
1567 bool RecursiveASTVisitor<Derived>::Traverse##DECL(DECL *D) { \
1568 bool ShouldVisitChildren = true; \
1569 bool ReturnValue = true; \
1570 if (!getDerived().shouldTraversePostOrder()) \
1571 TRY_TO(WalkUpFrom##DECL(D)); \
1572 { CODE; } \
1573 if (ReturnValue && ShouldVisitChildren) \
1574 TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D))); \
1575 if (ReturnValue) { \
1576 /* Visit any attributes attached to this declaration. */ \
1577 for (auto *I : D->attrs()) \
1578 TRY_TO(getDerived().TraverseAttr(I)); \
1579 } \
1580 if (ReturnValue && getDerived().shouldTraversePostOrder()) \
1581 TRY_TO(WalkUpFrom##DECL(D)); \
1582 return ReturnValue; \
1583 }
1584
1585DEF_TRAVERSE_DECL(AccessSpecDecl, {})
1586
1587DEF_TRAVERSE_DECL(BlockDecl, {
1588 if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
1589 TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
1590 TRY_TO(TraverseStmt(D->getBody()));
1591 for (const auto &I : D->captures()) {
1592 if (I.hasCopyExpr()) {
1593 TRY_TO(TraverseStmt(I.getCopyExpr()));
1594 }
1595 }
1596 ShouldVisitChildren = false;
1597})
1598
1599DEF_TRAVERSE_DECL(OutlinedFunctionDecl, {
1600 TRY_TO(TraverseStmt(D->getBody()));
1601 ShouldVisitChildren = false;
1602})
1603
1604DEF_TRAVERSE_DECL(CapturedDecl, {
1605 TRY_TO(TraverseStmt(D->getBody()));
1606 ShouldVisitChildren = false;
1607})
1608
1609DEF_TRAVERSE_DECL(EmptyDecl, {})
1610
1611DEF_TRAVERSE_DECL(HLSLBufferDecl, {})
1612
1613DEF_TRAVERSE_DECL(HLSLRootSignatureDecl, {})
1614
1615DEF_TRAVERSE_DECL(LifetimeExtendedTemporaryDecl, {
1616 TRY_TO(TraverseStmt(D->getTemporaryExpr()));
1617})
1618
1619DEF_TRAVERSE_DECL(FileScopeAsmDecl,
1620 { TRY_TO(TraverseStmt(D->getAsmStringExpr())); })
1621
1622DEF_TRAVERSE_DECL(TopLevelStmtDecl, { TRY_TO(TraverseStmt(D->getStmt())); })
1623
1624DEF_TRAVERSE_DECL(ImportDecl, {})
1625
1626DEF_TRAVERSE_DECL(FriendDecl, {
1627 // Friend is either decl or a type.
1628 if (D->getFriendType()) {
1629 TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
1630 // Traverse any CXXRecordDecl owned by this type, since
1631 // it will not be in the parent context:
1632 if (auto *ET = D->getFriendType()->getType()->getAs<ElaboratedType>())
1633 TRY_TO(TraverseDecl(ET->getOwnedTagDecl()));
1634 } else {
1635 TRY_TO(TraverseDecl(D->getFriendDecl()));
1636 }
1637})
1638
1639DEF_TRAVERSE_DECL(FriendTemplateDecl, {
1640 if (D->getFriendType())
1641 TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
1642 else
1643 TRY_TO(TraverseDecl(D->getFriendDecl()));
1644 for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
1645 TemplateParameterList *TPL = D->getTemplateParameterList(I);
1646 for (TemplateParameterList::iterator ITPL = TPL->begin(), ETPL = TPL->end();
1647 ITPL != ETPL; ++ITPL) {
1648 TRY_TO(TraverseDecl(*ITPL));
1649 }
1650 }
1651})
1652
1653DEF_TRAVERSE_DECL(LinkageSpecDecl, {})
1654
1655DEF_TRAVERSE_DECL(ExportDecl, {})
1656
1657DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {// FIXME: implement this
1658 })
1659
1660DEF_TRAVERSE_DECL(StaticAssertDecl, {
1661 TRY_TO(TraverseStmt(D->getAssertExpr()));
1662 TRY_TO(TraverseStmt(D->getMessage()));
1663})
1664
1665DEF_TRAVERSE_DECL(TranslationUnitDecl, {
1666 // Code in an unnamed namespace shows up automatically in
1667 // decls_begin()/decls_end(). Thus we don't need to recurse on
1668 // D->getAnonymousNamespace().
1669
1670 // If the traversal scope is set, then consider them to be the children of
1671 // the TUDecl, rather than traversing (and loading?) all top-level decls.
1672 auto Scope = D->getASTContext().getTraversalScope();
1673 bool HasLimitedScope =
1674 Scope.size() != 1 || !isa<TranslationUnitDecl>(Scope.front());
1675 if (HasLimitedScope) {
1676 ShouldVisitChildren = false; // we'll do that here instead
1677 for (auto *Child : Scope) {
1678 if (!canIgnoreChildDeclWhileTraversingDeclContext(Child))
1679 TRY_TO(TraverseDecl(Child));
1680 }
1681 }
1682})
1683
1684DEF_TRAVERSE_DECL(PragmaCommentDecl, {})
1685
1686DEF_TRAVERSE_DECL(PragmaDetectMismatchDecl, {})
1687
1688DEF_TRAVERSE_DECL(ExternCContextDecl, {})
1689
1690DEF_TRAVERSE_DECL(NamespaceAliasDecl, {
1691 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1692
1693 // We shouldn't traverse an aliased namespace, since it will be
1694 // defined (and, therefore, traversed) somewhere else.
1695 ShouldVisitChildren = false;
1696})
1697
1698DEF_TRAVERSE_DECL(LabelDecl, {// There is no code in a LabelDecl.
1699 })
1700
1701DEF_TRAVERSE_DECL(
1702 NamespaceDecl,
1703 {// Code in an unnamed namespace shows up automatically in
1704 // decls_begin()/decls_end(). Thus we don't need to recurse on
1705 // D->getAnonymousNamespace().
1706 })
1707
1708DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement
1709 })
1710
1711DEF_TRAVERSE_DECL(ObjCCategoryDecl, {
1712 if (ObjCTypeParamList *typeParamList = D->getTypeParamList()) {
1713 for (auto typeParam : *typeParamList) {
1714 TRY_TO(TraverseObjCTypeParamDecl(typeParam));
1715 }
1716 }
1717 for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
1718 ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
1719 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1720 }
1721})
1722
1723DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement
1724 })
1725
1726DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement
1727 })
1728
1729DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {
1730 if (ObjCTypeParamList *typeParamList = D->getTypeParamListAsWritten()) {
1731 for (auto typeParam : *typeParamList) {
1732 TRY_TO(TraverseObjCTypeParamDecl(typeParam));
1733 }
1734 }
1735
1736 if (TypeSourceInfo *superTInfo = D->getSuperClassTInfo()) {
1737 TRY_TO(TraverseTypeLoc(superTInfo->getTypeLoc()));
1738 }
1739 if (D->isThisDeclarationADefinition()) {
1740 for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
1741 ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
1742 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1743 }
1744 }
1745})
1746
1747DEF_TRAVERSE_DECL(ObjCProtocolDecl, {
1748 if (D->isThisDeclarationADefinition()) {
1749 for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
1750 ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
1751 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1752 }
1753 }
1754})
1755
1756DEF_TRAVERSE_DECL(ObjCMethodDecl, {
1757 if (D->getReturnTypeSourceInfo()) {
1758 TRY_TO(TraverseTypeLoc(D->getReturnTypeSourceInfo()->getTypeLoc()));
1759 }
1760 for (ParmVarDecl *Parameter : D->parameters()) {
1761 TRY_TO(TraverseDecl(Parameter));
1762 }
1763 if (D->isThisDeclarationADefinition()) {
1764 TRY_TO(TraverseStmt(D->getBody()));
1765 }
1766 ShouldVisitChildren = false;
1767})
1768
1769DEF_TRAVERSE_DECL(ObjCTypeParamDecl, {
1770 if (D->hasExplicitBound()) {
1771 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
1772 // We shouldn't traverse D->getTypeForDecl(); it's a result of
1773 // declaring the type alias, not something that was written in the
1774 // source.
1775 }
1776})
1777
1778DEF_TRAVERSE_DECL(ObjCPropertyDecl, {
1779 if (D->getTypeSourceInfo())
1780 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
1781 else
1782 TRY_TO(TraverseType(D->getType()));
1783 ShouldVisitChildren = false;
1784})
1785
1786DEF_TRAVERSE_DECL(UsingDecl, {
1787 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1788 TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
1789})
1790
1791DEF_TRAVERSE_DECL(UsingEnumDecl,
1792 { TRY_TO(TraverseTypeLoc(D->getEnumTypeLoc())); })
1793
1794DEF_TRAVERSE_DECL(UsingPackDecl, {})
1795
1796DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
1797 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1798})
1799
1800DEF_TRAVERSE_DECL(UsingShadowDecl, {})
1801
1802DEF_TRAVERSE_DECL(ConstructorUsingShadowDecl, {})
1803
1804DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
1805 for (auto *I : D->varlist()) {
1806 TRY_TO(TraverseStmt(I));
1807 }
1808})
1809
1810DEF_TRAVERSE_DECL(OMPRequiresDecl, {
1811 for (auto *C : D->clauselists()) {
1812 TRY_TO(TraverseOMPClause(C));
1813 }
1814})
1815
1816DEF_TRAVERSE_DECL(OMPDeclareReductionDecl, {
1817 TRY_TO(TraverseStmt(D->getCombiner()));
1818 if (auto *Initializer = D->getInitializer())
1819 TRY_TO(TraverseStmt(Initializer));
1820 TRY_TO(TraverseType(D->getType()));
1821 return true;
1822})
1823
1824DEF_TRAVERSE_DECL(OMPDeclareMapperDecl, {
1825 for (auto *C : D->clauselists())
1826 TRY_TO(TraverseOMPClause(C));
1827 TRY_TO(TraverseType(D->getType()));
1828 return true;
1829})
1830
1831DEF_TRAVERSE_DECL(OMPCapturedExprDecl, { TRY_TO(TraverseVarHelper(D)); })
1832
1833DEF_TRAVERSE_DECL(OMPAllocateDecl, {
1834 for (auto *I : D->varlist())
1835 TRY_TO(TraverseStmt(I));
1836 for (auto *C : D->clauselists())
1837 TRY_TO(TraverseOMPClause(C));
1838})
1839
1840DEF_TRAVERSE_DECL(OpenACCDeclareDecl,
1841 { TRY_TO(VisitOpenACCClauseList(D->clauses())); })
1842
1843DEF_TRAVERSE_DECL(OpenACCRoutineDecl, {
1844 TRY_TO(TraverseStmt(D->getFunctionReference()));
1845 TRY_TO(VisitOpenACCClauseList(D->clauses()));
1846})
1847
1848// A helper method for TemplateDecl's children.
1849template <typename Derived>
1850bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
1851 TemplateParameterList *TPL) {
1852 if (TPL) {
1853 for (NamedDecl *D : *TPL) {
1854 TRY_TO(TraverseDecl(D));
1855 }
1856 if (Expr *RequiresClause = TPL->getRequiresClause()) {
1857 TRY_TO(TraverseStmt(RequiresClause));
1858 }
1859 }
1860 return true;
1861}
1862
1863template <typename Derived>
1864template <typename T>
1865bool RecursiveASTVisitor<Derived>::TraverseDeclTemplateParameterLists(T *D) {
1866 for (unsigned i = 0; i < D->getNumTemplateParameterLists(); i++) {
1867 TemplateParameterList *TPL = D->getTemplateParameterList(i);
1868 TraverseTemplateParameterListHelper(TPL);
1869 }
1870 return true;
1871}
1872
1873template <typename Derived>
1874bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
1875 ClassTemplateDecl *D) {
1876 for (auto *SD : D->specializations()) {
1877 for (auto *RD : SD->redecls()) {
1878 assert(!cast<CXXRecordDecl>(RD)->isInjectedClassName());
1879 switch (
1880 cast<ClassTemplateSpecializationDecl>(Val: RD)->getSpecializationKind()) {
1881 // Visit the implicit instantiations with the requested pattern.
1882 case TSK_Undeclared:
1883 case TSK_ImplicitInstantiation:
1884 TRY_TO(TraverseDecl(RD));
1885 break;
1886
1887 // We don't need to do anything on an explicit instantiation
1888 // or explicit specialization because there will be an explicit
1889 // node for it elsewhere.
1890 case TSK_ExplicitInstantiationDeclaration:
1891 case TSK_ExplicitInstantiationDefinition:
1892 case TSK_ExplicitSpecialization:
1893 break;
1894 }
1895 }
1896 }
1897
1898 return true;
1899}
1900
1901template <typename Derived>
1902bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
1903 VarTemplateDecl *D) {
1904 for (auto *SD : D->specializations()) {
1905 for (auto *RD : SD->redecls()) {
1906 switch (
1907 cast<VarTemplateSpecializationDecl>(Val: RD)->getSpecializationKind()) {
1908 case TSK_Undeclared:
1909 case TSK_ImplicitInstantiation:
1910 TRY_TO(TraverseDecl(RD));
1911 break;
1912
1913 case TSK_ExplicitInstantiationDeclaration:
1914 case TSK_ExplicitInstantiationDefinition:
1915 case TSK_ExplicitSpecialization:
1916 break;
1917 }
1918 }
1919 }
1920
1921 return true;
1922}
1923
1924// A helper method for traversing the instantiations of a
1925// function while skipping its specializations.
1926template <typename Derived>
1927bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
1928 FunctionTemplateDecl *D) {
1929 for (auto *FD : D->specializations()) {
1930 for (auto *RD : FD->redecls()) {
1931 switch (RD->getTemplateSpecializationKind()) {
1932 case TSK_Undeclared:
1933 case TSK_ImplicitInstantiation:
1934 // We don't know what kind of FunctionDecl this is.
1935 TRY_TO(TraverseDecl(RD));
1936 break;
1937
1938 // FIXME: For now traverse explicit instantiations here. Change that
1939 // once they are represented as dedicated nodes in the AST.
1940 case TSK_ExplicitInstantiationDeclaration:
1941 case TSK_ExplicitInstantiationDefinition:
1942 TRY_TO(TraverseDecl(RD));
1943 break;
1944
1945 case TSK_ExplicitSpecialization:
1946 break;
1947 }
1948 }
1949 }
1950
1951 return true;
1952}
1953
1954// This macro unifies the traversal of class, variable and function
1955// template declarations.
1956#define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND) \
1957 DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, { \
1958 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
1959 TRY_TO(TraverseDecl(D->getTemplatedDecl())); \
1960 \
1961 /* By default, we do not traverse the instantiations of \
1962 class templates since they do not appear in the user code. The \
1963 following code optionally traverses them. \
1964 \
1965 We only traverse the class instantiations when we see the canonical \
1966 declaration of the template, to ensure we only visit them once. */ \
1967 if (getDerived().shouldVisitTemplateInstantiations() && \
1968 D == D->getCanonicalDecl()) \
1969 TRY_TO(TraverseTemplateInstantiations(D)); \
1970 \
1971 /* Note that getInstantiatedFromMemberTemplate() is just a link \
1972 from a template instantiation back to the template from which \
1973 it was instantiated, and thus should not be traversed. */ \
1974 })
1975
1976DEF_TRAVERSE_TMPL_DECL(Class)
1977DEF_TRAVERSE_TMPL_DECL(Var)
1978DEF_TRAVERSE_TMPL_DECL(Function)
1979
1980DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, {
1981 // D is the "T" in something like
1982 // template <template <typename> class T> class container { };
1983 TRY_TO(TraverseDecl(D->getTemplatedDecl()));
1984 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
1985 TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
1986 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
1987})
1988
1989DEF_TRAVERSE_DECL(BuiltinTemplateDecl, {
1990 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
1991})
1992
1993template <typename Derived>
1994bool RecursiveASTVisitor<Derived>::TraverseTemplateTypeParamDeclConstraints(
1995 const TemplateTypeParmDecl *D) {
1996 if (const auto *TC = D->getTypeConstraint())
1997 TRY_TO(TraverseTypeConstraint(TC));
1998 return true;
1999}
2000
2001DEF_TRAVERSE_DECL(TemplateTypeParmDecl, {
2002 // D is the "T" in something like "template<typename T> class vector;"
2003 if (D->getTypeForDecl())
2004 TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
2005 TRY_TO(TraverseTemplateTypeParamDeclConstraints(D));
2006 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
2007 TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
2008})
2009
2010DEF_TRAVERSE_DECL(TypedefDecl, {
2011 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
2012 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2013 // declaring the typedef, not something that was written in the
2014 // source.
2015})
2016
2017DEF_TRAVERSE_DECL(TypeAliasDecl, {
2018 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
2019 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2020 // declaring the type alias, not something that was written in the
2021 // source.
2022})
2023
2024DEF_TRAVERSE_DECL(TypeAliasTemplateDecl, {
2025 TRY_TO(TraverseDecl(D->getTemplatedDecl()));
2026 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
2027})
2028
2029DEF_TRAVERSE_DECL(ConceptDecl, {
2030 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
2031 TRY_TO(TraverseStmt(D->getConstraintExpr()));
2032})
2033
2034DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, {
2035 // A dependent using declaration which was marked with 'typename'.
2036 // template<class T> class A : public B<T> { using typename B<T>::foo; };
2037 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2038 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2039 // declaring the type, not something that was written in the
2040 // source.
2041})
2042
2043DEF_TRAVERSE_DECL(UnresolvedUsingIfExistsDecl, {})
2044
2045DEF_TRAVERSE_DECL(EnumDecl, {
2046 TRY_TO(TraverseDeclTemplateParameterLists(D));
2047
2048 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2049 if (auto *TSI = D->getIntegerTypeSourceInfo())
2050 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
2051 // The enumerators are already traversed by
2052 // decls_begin()/decls_end().
2053})
2054
2055// Helper methods for RecordDecl and its children.
2056template <typename Derived>
2057bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) {
2058 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2059 // declaring the type, not something that was written in the source.
2060
2061 TRY_TO(TraverseDeclTemplateParameterLists(D));
2062 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2063 return true;
2064}
2065
2066template <typename Derived>
2067bool RecursiveASTVisitor<Derived>::TraverseCXXBaseSpecifier(
2068 const CXXBaseSpecifier &Base) {
2069 TRY_TO(TraverseTypeLoc(Base.getTypeSourceInfo()->getTypeLoc()));
2070 return true;
2071}
2072
2073template <typename Derived>
2074bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(CXXRecordDecl *D) {
2075 if (!TraverseRecordHelper(D))
2076 return false;
2077 if (D->isCompleteDefinition()) {
2078 for (const auto &I : D->bases()) {
2079 TRY_TO(TraverseCXXBaseSpecifier(I));
2080 }
2081 // We don't traverse the friends or the conversions, as they are
2082 // already in decls_begin()/decls_end().
2083 }
2084 return true;
2085}
2086
2087DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); })
2088
2089DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
2090
2091template <typename Derived>
2092bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
2093 const TemplateArgumentLoc *TAL, unsigned Count) {
2094 for (unsigned I = 0; I < Count; ++I) {
2095 TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
2096 }
2097 return true;
2098}
2099
2100#define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
2101 DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, { \
2102 /* For implicit instantiations ("set<int> x;"), we don't want to \
2103 recurse at all, since the instatiated template isn't written in \
2104 the source code anywhere. (Note the instatiated *type* -- \
2105 set<int> -- is written, and will still get a callback of \
2106 TemplateSpecializationType). For explicit instantiations \
2107 ("template set<int>;"), we do need a callback, since this \
2108 is the only callback that's made for this instantiation. \
2109 We use getTemplateArgsAsWritten() to distinguish. */ \
2110 if (const auto *ArgsWritten = D->getTemplateArgsAsWritten()) { \
2111 /* The args that remains unspecialized. */ \
2112 TRY_TO(TraverseTemplateArgumentLocsHelper( \
2113 ArgsWritten->getTemplateArgs(), ArgsWritten->NumTemplateArgs)); \
2114 } \
2115 \
2116 if (getDerived().shouldVisitTemplateInstantiations() || \
2117 D->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) { \
2118 /* Traverse base definition for explicit specializations */ \
2119 TRY_TO(Traverse##DECLKIND##Helper(D)); \
2120 } else { \
2121 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); \
2122 \
2123 /* Returning from here skips traversing the \
2124 declaration context of the *TemplateSpecializationDecl \
2125 (embedded in the DEF_TRAVERSE_DECL() macro) \
2126 which contains the instantiated members of the template. */ \
2127 return true; \
2128 } \
2129 })
2130
2131DEF_TRAVERSE_TMPL_SPEC_DECL(Class, CXXRecord)
2132DEF_TRAVERSE_TMPL_SPEC_DECL(Var, Var)
2133
2134#define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
2135 DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, { \
2136 /* The partial specialization. */ \
2137 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
2138 /* The args that remains unspecialized. */ \
2139 TRY_TO(TraverseTemplateArgumentLocsHelper( \
2140 D->getTemplateArgsAsWritten()->getTemplateArgs(), \
2141 D->getTemplateArgsAsWritten()->NumTemplateArgs)); \
2142 \
2143 /* Don't need the *TemplatePartialSpecializationHelper, even \
2144 though that's our parent class -- we already visit all the \
2145 template args here. */ \
2146 TRY_TO(Traverse##DECLKIND##Helper(D)); \
2147 \
2148 /* Instantiations will have been visited with the primary template. */ \
2149 })
2150
2151DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Class, CXXRecord)
2152DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Var, Var)
2153
2154DEF_TRAVERSE_DECL(EnumConstantDecl, { TRY_TO(TraverseStmt(D->getInitExpr())); })
2155
2156DEF_TRAVERSE_DECL(UnresolvedUsingValueDecl, {
2157 // Like UnresolvedUsingTypenameDecl, but without the 'typename':
2158 // template <class T> Class A : public Base<T> { using Base<T>::foo; };
2159 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2160 TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
2161})
2162
2163DEF_TRAVERSE_DECL(IndirectFieldDecl, {})
2164
2165template <typename Derived>
2166bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
2167 TRY_TO(TraverseDeclTemplateParameterLists(D));
2168 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2169 if (D->getTypeSourceInfo())
2170 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
2171 else
2172 TRY_TO(TraverseType(D->getType()));
2173 return true;
2174}
2175
2176DEF_TRAVERSE_DECL(DecompositionDecl, {
2177 TRY_TO(TraverseVarHelper(D));
2178 for (auto *Binding : D->bindings()) {
2179 TRY_TO(TraverseDecl(Binding));
2180 }
2181})
2182
2183DEF_TRAVERSE_DECL(BindingDecl, {
2184 if (getDerived().shouldVisitImplicitCode()) {
2185 TRY_TO(TraverseStmt(D->getBinding()));
2186 if (const auto HoldingVar = D->getHoldingVar())
2187 TRY_TO(TraverseDecl(HoldingVar));
2188 }
2189})
2190
2191DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
2192
2193DEF_TRAVERSE_DECL(MSGuidDecl, {})
2194DEF_TRAVERSE_DECL(UnnamedGlobalConstantDecl, {})
2195
2196DEF_TRAVERSE_DECL(TemplateParamObjectDecl, {})
2197
2198DEF_TRAVERSE_DECL(FieldDecl, {
2199 TRY_TO(TraverseDeclaratorHelper(D));
2200 if (D->isBitField())
2201 TRY_TO(TraverseStmt(D->getBitWidth()));
2202 if (D->hasInClassInitializer())
2203 TRY_TO(TraverseStmt(D->getInClassInitializer()));
2204})
2205
2206DEF_TRAVERSE_DECL(ObjCAtDefsFieldDecl, {
2207 TRY_TO(TraverseDeclaratorHelper(D));
2208 if (D->isBitField())
2209 TRY_TO(TraverseStmt(D->getBitWidth()));
2210 // FIXME: implement the rest.
2211})
2212
2213DEF_TRAVERSE_DECL(ObjCIvarDecl, {
2214 TRY_TO(TraverseDeclaratorHelper(D));
2215 if (D->isBitField())
2216 TRY_TO(TraverseStmt(D->getBitWidth()));
2217 // FIXME: implement the rest.
2218})
2219
2220template <typename Derived>
2221bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
2222 TRY_TO(TraverseDeclTemplateParameterLists(D));
2223 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2224 TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
2225
2226 // If we're an explicit template specialization, iterate over the
2227 // template args that were explicitly specified. If we were doing
2228 // this in typing order, we'd do it between the return type and
2229 // the function args, but both are handled by the FunctionTypeLoc
2230 // above, so we have to choose one side. I've decided to do before.
2231 if (const FunctionTemplateSpecializationInfo *FTSI =
2232 D->getTemplateSpecializationInfo()) {
2233 if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared &&
2234 FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
2235 // A specialization might not have explicit template arguments if it has
2236 // a templated return type and concrete arguments.
2237 if (const ASTTemplateArgumentListInfo *TALI =
2238 FTSI->TemplateArgumentsAsWritten) {
2239 TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
2240 TALI->NumTemplateArgs));
2241 }
2242 }
2243 } else if (const DependentFunctionTemplateSpecializationInfo *DFSI =
2244 D->getDependentSpecializationInfo()) {
2245 if (const ASTTemplateArgumentListInfo *TALI =
2246 DFSI->TemplateArgumentsAsWritten) {
2247 TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
2248 TALI->NumTemplateArgs));
2249 }
2250 }
2251
2252 // Visit the function type itself, which can be either
2253 // FunctionNoProtoType or FunctionProtoType, or a typedef. This
2254 // also covers the return type and the function parameters,
2255 // including exception specifications.
2256 if (TypeSourceInfo *TSI = D->getTypeSourceInfo()) {
2257 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
2258 } else if (getDerived().shouldVisitImplicitCode()) {
2259 // Visit parameter variable declarations of the implicit function
2260 // if the traverser is visiting implicit code. Parameter variable
2261 // declarations do not have valid TypeSourceInfo, so to visit them
2262 // we need to traverse the declarations explicitly.
2263 for (ParmVarDecl *Parameter : D->parameters()) {
2264 TRY_TO(TraverseDecl(Parameter));
2265 }
2266 }
2267
2268 // Visit the trailing requires clause, if any.
2269 if (const AssociatedConstraint &TrailingRequiresClause =
2270 D->getTrailingRequiresClause()) {
2271 TRY_TO(TraverseStmt(
2272 const_cast<Expr *>(TrailingRequiresClause.ConstraintExpr)));
2273 }
2274
2275 if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(Val: D)) {
2276 // Constructor initializers.
2277 for (auto *I : Ctor->inits()) {
2278 if (I->isWritten() || getDerived().shouldVisitImplicitCode())
2279 TRY_TO(TraverseConstructorInitializer(I));
2280 }
2281 }
2282
2283 bool VisitBody =
2284 D->isThisDeclarationADefinition() &&
2285 // Don't visit the function body if the function definition is generated
2286 // by clang.
2287 (!D->isDefaulted() || getDerived().shouldVisitImplicitCode());
2288
2289 if (const auto *MD = dyn_cast<CXXMethodDecl>(Val: D)) {
2290 if (const CXXRecordDecl *RD = MD->getParent()) {
2291 if (RD->isLambda() &&
2292 declaresSameEntity(D1: RD->getLambdaCallOperator(), D2: MD)) {
2293 VisitBody = VisitBody && getDerived().shouldVisitLambdaBody();
2294 }
2295 }
2296 }
2297
2298 if (VisitBody) {
2299 TRY_TO(TraverseStmt(D->getBody()));
2300 // Body may contain using declarations whose shadows are parented to the
2301 // FunctionDecl itself.
2302 for (auto *Child : D->decls()) {
2303 if (isa<UsingShadowDecl>(Val: Child))
2304 TRY_TO(TraverseDecl(Child));
2305 }
2306 }
2307 return true;
2308}
2309
2310DEF_TRAVERSE_DECL(FunctionDecl, {
2311 // We skip decls_begin/decls_end, which are already covered by
2312 // TraverseFunctionHelper().
2313 ShouldVisitChildren = false;
2314 ReturnValue = TraverseFunctionHelper(D);
2315})
2316
2317DEF_TRAVERSE_DECL(CXXDeductionGuideDecl, {
2318 // We skip decls_begin/decls_end, which are already covered by
2319 // TraverseFunctionHelper().
2320 ShouldVisitChildren = false;
2321 ReturnValue = TraverseFunctionHelper(D);
2322})
2323
2324DEF_TRAVERSE_DECL(CXXMethodDecl, {
2325 // We skip decls_begin/decls_end, which are already covered by
2326 // TraverseFunctionHelper().
2327 ShouldVisitChildren = false;
2328 ReturnValue = TraverseFunctionHelper(D);
2329})
2330
2331DEF_TRAVERSE_DECL(CXXConstructorDecl, {
2332 // We skip decls_begin/decls_end, which are already covered by
2333 // TraverseFunctionHelper().
2334 ShouldVisitChildren = false;
2335 ReturnValue = TraverseFunctionHelper(D);
2336})
2337
2338// CXXConversionDecl is the declaration of a type conversion operator.
2339// It's not a cast expression.
2340DEF_TRAVERSE_DECL(CXXConversionDecl, {
2341 // We skip decls_begin/decls_end, which are already covered by
2342 // TraverseFunctionHelper().
2343 ShouldVisitChildren = false;
2344 ReturnValue = TraverseFunctionHelper(D);
2345})
2346
2347DEF_TRAVERSE_DECL(CXXDestructorDecl, {
2348 // We skip decls_begin/decls_end, which are already covered by
2349 // TraverseFunctionHelper().
2350 ShouldVisitChildren = false;
2351 ReturnValue = TraverseFunctionHelper(D);
2352})
2353
2354template <typename Derived>
2355bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
2356 TRY_TO(TraverseDeclaratorHelper(D));
2357 // Default params are taken care of when we traverse the ParmVarDecl.
2358 if (!isa<ParmVarDecl>(Val: D) &&
2359 (!D->isCXXForRangeDecl() || getDerived().shouldVisitImplicitCode()))
2360 TRY_TO(TraverseStmt(D->getInit()));
2361 return true;
2362}
2363
2364DEF_TRAVERSE_DECL(VarDecl, { TRY_TO(TraverseVarHelper(D)); })
2365
2366DEF_TRAVERSE_DECL(ImplicitParamDecl, { TRY_TO(TraverseVarHelper(D)); })
2367
2368DEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, {
2369 // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
2370 TRY_TO(TraverseDeclaratorHelper(D));
2371 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
2372 TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
2373})
2374
2375DEF_TRAVERSE_DECL(ParmVarDecl, {
2376 TRY_TO(TraverseVarHelper(D));
2377
2378 if (D->hasDefaultArg() && D->hasUninstantiatedDefaultArg() &&
2379 !D->hasUnparsedDefaultArg())
2380 TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
2381
2382 if (D->hasDefaultArg() && !D->hasUninstantiatedDefaultArg() &&
2383 !D->hasUnparsedDefaultArg())
2384 TRY_TO(TraverseStmt(D->getDefaultArg()));
2385})
2386
2387DEF_TRAVERSE_DECL(RequiresExprBodyDecl, {})
2388
2389DEF_TRAVERSE_DECL(ImplicitConceptSpecializationDecl, {
2390 TRY_TO(TraverseTemplateArguments(D->getTemplateArguments()));
2391})
2392
2393#undef DEF_TRAVERSE_DECL
2394
2395// ----------------- Stmt traversal -----------------
2396//
2397// For stmts, we automate (in the DEF_TRAVERSE_STMT macro) iterating
2398// over the children defined in children() (every stmt defines these,
2399// though sometimes the range is empty). Each individual Traverse*
2400// method only needs to worry about children other than those. To see
2401// what children() does for a given class, see, e.g.,
2402// http://clang.llvm.org/doxygen/Stmt_8cpp_source.html
2403
2404// This macro makes available a variable S, the passed-in stmt.
2405#define DEF_TRAVERSE_STMT(STMT, CODE) \
2406 template <typename Derived> \
2407 bool RecursiveASTVisitor<Derived>::Traverse##STMT( \
2408 STMT *S, DataRecursionQueue *Queue) { \
2409 bool ShouldVisitChildren = true; \
2410 bool ReturnValue = true; \
2411 if (!getDerived().shouldTraversePostOrder()) \
2412 TRY_TO(WalkUpFrom##STMT(S)); \
2413 { CODE; } \
2414 if (ShouldVisitChildren) { \
2415 for (Stmt * SubStmt : getDerived().getStmtChildren(S)) { \
2416 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); \
2417 } \
2418 } \
2419 /* Call WalkUpFrom if TRY_TO_TRAVERSE_OR_ENQUEUE_STMT has traversed the \
2420 * children already. If TRY_TO_TRAVERSE_OR_ENQUEUE_STMT only enqueued the \
2421 * children, PostVisitStmt will call WalkUpFrom after we are done visiting \
2422 * children. */ \
2423 if (!Queue && ReturnValue && getDerived().shouldTraversePostOrder()) { \
2424 TRY_TO(WalkUpFrom##STMT(S)); \
2425 } \
2426 return ReturnValue; \
2427 }
2428
2429DEF_TRAVERSE_STMT(GCCAsmStmt, {
2430 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAsmStringExpr());
2431 for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
2432 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInputConstraintExpr(I));
2433 }
2434 for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
2435 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOutputConstraintExpr(I));
2436 }
2437 for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
2438 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getClobberExpr(I));
2439 }
2440 // children() iterates over inputExpr and outputExpr.
2441})
2442
2443DEF_TRAVERSE_STMT(
2444 MSAsmStmt,
2445 {// FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc. Once
2446 // added this needs to be implemented.
2447 })
2448
2449DEF_TRAVERSE_STMT(CXXCatchStmt, {
2450 TRY_TO(TraverseDecl(S->getExceptionDecl()));
2451 // children() iterates over the handler block.
2452})
2453
2454DEF_TRAVERSE_STMT(DeclStmt, {
2455 for (auto *I : S->decls()) {
2456 TRY_TO(TraverseDecl(I));
2457 }
2458 // Suppress the default iteration over children() by
2459 // returning. Here's why: A DeclStmt looks like 'type var [=
2460 // initializer]'. The decls above already traverse over the
2461 // initializers, so we don't have to do it again (which
2462 // children() would do).
2463 ShouldVisitChildren = false;
2464})
2465
2466// These non-expr stmts (most of them), do not need any action except
2467// iterating over the children.
2468DEF_TRAVERSE_STMT(BreakStmt, {})
2469DEF_TRAVERSE_STMT(CXXTryStmt, {})
2470DEF_TRAVERSE_STMT(CaseStmt, {})
2471DEF_TRAVERSE_STMT(CompoundStmt, {})
2472DEF_TRAVERSE_STMT(ContinueStmt, {})
2473DEF_TRAVERSE_STMT(DefaultStmt, {})
2474DEF_TRAVERSE_STMT(DoStmt, {})
2475DEF_TRAVERSE_STMT(ForStmt, {})
2476DEF_TRAVERSE_STMT(GotoStmt, {})
2477DEF_TRAVERSE_STMT(IfStmt, {})
2478DEF_TRAVERSE_STMT(IndirectGotoStmt, {})
2479DEF_TRAVERSE_STMT(LabelStmt, {})
2480DEF_TRAVERSE_STMT(AttributedStmt, {})
2481DEF_TRAVERSE_STMT(NullStmt, {})
2482DEF_TRAVERSE_STMT(ObjCAtCatchStmt, {})
2483DEF_TRAVERSE_STMT(ObjCAtFinallyStmt, {})
2484DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, {})
2485DEF_TRAVERSE_STMT(ObjCAtThrowStmt, {})
2486DEF_TRAVERSE_STMT(ObjCAtTryStmt, {})
2487DEF_TRAVERSE_STMT(ObjCForCollectionStmt, {})
2488DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, {})
2489
2490DEF_TRAVERSE_STMT(CXXForRangeStmt, {
2491 if (!getDerived().shouldVisitImplicitCode()) {
2492 if (S->getInit())
2493 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInit());
2494 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLoopVarStmt());
2495 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRangeInit());
2496 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
2497 // Visit everything else only if shouldVisitImplicitCode().
2498 ShouldVisitChildren = false;
2499 }
2500})
2501
2502DEF_TRAVERSE_STMT(MSDependentExistsStmt, {
2503 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2504 TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
2505})
2506
2507DEF_TRAVERSE_STMT(ReturnStmt, {})
2508DEF_TRAVERSE_STMT(SwitchStmt, {})
2509DEF_TRAVERSE_STMT(WhileStmt, {})
2510
2511DEF_TRAVERSE_STMT(ConstantExpr, {})
2512
2513DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
2514 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2515 TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
2516 if (S->hasExplicitTemplateArgs()) {
2517 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2518 S->getNumTemplateArgs()));
2519 }
2520})
2521
2522DEF_TRAVERSE_STMT(DeclRefExpr, {
2523 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2524 TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
2525 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2526 S->getNumTemplateArgs()));
2527})
2528
2529DEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, {
2530 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2531 TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
2532 if (S->hasExplicitTemplateArgs()) {
2533 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2534 S->getNumTemplateArgs()));
2535 }
2536})
2537
2538DEF_TRAVERSE_STMT(MemberExpr, {
2539 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2540 TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
2541 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2542 S->getNumTemplateArgs()));
2543})
2544
2545DEF_TRAVERSE_STMT(
2546 ImplicitCastExpr,
2547 {// We don't traverse the cast type, as it's not written in the
2548 // source code.
2549 })
2550
2551DEF_TRAVERSE_STMT(CStyleCastExpr, {
2552 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2553})
2554
2555DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, {
2556 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2557})
2558
2559DEF_TRAVERSE_STMT(CXXAddrspaceCastExpr, {
2560 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2561})
2562
2563DEF_TRAVERSE_STMT(CXXConstCastExpr, {
2564 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2565})
2566
2567DEF_TRAVERSE_STMT(CXXDynamicCastExpr, {
2568 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2569})
2570
2571DEF_TRAVERSE_STMT(CXXReinterpretCastExpr, {
2572 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2573})
2574
2575DEF_TRAVERSE_STMT(CXXStaticCastExpr, {
2576 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2577})
2578
2579DEF_TRAVERSE_STMT(BuiltinBitCastExpr, {
2580 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2581})
2582
2583template <typename Derived>
2584bool RecursiveASTVisitor<Derived>::TraverseSynOrSemInitListExpr(
2585 InitListExpr *S, DataRecursionQueue *Queue) {
2586 if (S) {
2587 // Skip this if we traverse postorder. We will visit it later
2588 // in PostVisitStmt.
2589 if (!getDerived().shouldTraversePostOrder())
2590 TRY_TO(WalkUpFromInitListExpr(S));
2591
2592 // All we need are the default actions. FIXME: use a helper function.
2593 for (Stmt *SubStmt : S->children()) {
2594 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt);
2595 }
2596
2597 if (!Queue && getDerived().shouldTraversePostOrder())
2598 TRY_TO(WalkUpFromInitListExpr(S));
2599 }
2600 return true;
2601}
2602
2603template <typename Derived>
2604bool RecursiveASTVisitor<Derived>::TraverseObjCProtocolLoc(
2605 ObjCProtocolLoc ProtocolLoc) {
2606 return true;
2607}
2608
2609template <typename Derived>
2610bool RecursiveASTVisitor<Derived>::TraverseConceptReference(
2611 ConceptReference *CR) {
2612 if (!getDerived().shouldTraversePostOrder())
2613 TRY_TO(VisitConceptReference(CR));
2614 TRY_TO(TraverseNestedNameSpecifierLoc(CR->getNestedNameSpecifierLoc()));
2615 TRY_TO(TraverseDeclarationNameInfo(CR->getConceptNameInfo()));
2616 if (CR->hasExplicitTemplateArgs())
2617 TRY_TO(TraverseTemplateArgumentLocsHelper(
2618 CR->getTemplateArgsAsWritten()->getTemplateArgs(),
2619 CR->getTemplateArgsAsWritten()->NumTemplateArgs));
2620 if (getDerived().shouldTraversePostOrder())
2621 TRY_TO(VisitConceptReference(CR));
2622 return true;
2623}
2624
2625// If shouldVisitImplicitCode() returns false, this method traverses only the
2626// syntactic form of InitListExpr.
2627// If shouldVisitImplicitCode() return true, this method is called once for
2628// each pair of syntactic and semantic InitListExpr, and it traverses the
2629// subtrees defined by the two forms. This may cause some of the children to be
2630// visited twice, if they appear both in the syntactic and the semantic form.
2631//
2632// There is no guarantee about which form \p S takes when this method is called.
2633template <typename Derived>
2634bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(
2635 InitListExpr *S, DataRecursionQueue *Queue) {
2636 if (S->isSemanticForm() && S->isSyntacticForm()) {
2637 // `S` does not have alternative forms, traverse only once.
2638 TRY_TO(TraverseSynOrSemInitListExpr(S, Queue));
2639 return true;
2640 }
2641 TRY_TO(TraverseSynOrSemInitListExpr(
2642 S->isSemanticForm() ? S->getSyntacticForm() : S, Queue));
2643 if (getDerived().shouldVisitImplicitCode()) {
2644 // Only visit the semantic form if the clients are interested in implicit
2645 // compiler-generated.
2646 TRY_TO(TraverseSynOrSemInitListExpr(
2647 S->isSemanticForm() ? S : S->getSemanticForm(), Queue));
2648 }
2649 return true;
2650}
2651
2652// GenericSelectionExpr is a special case because the types and expressions
2653// are interleaved. We also need to watch out for null types (default
2654// generic associations).
2655DEF_TRAVERSE_STMT(GenericSelectionExpr, {
2656 if (S->isExprPredicate())
2657 TRY_TO(TraverseStmt(S->getControllingExpr()));
2658 else
2659 TRY_TO(TraverseTypeLoc(S->getControllingType()->getTypeLoc()));
2660
2661 for (const GenericSelectionExpr::Association Assoc : S->associations()) {
2662 if (TypeSourceInfo *TSI = Assoc.getTypeSourceInfo())
2663 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
2664 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(Assoc.getAssociationExpr());
2665 }
2666 ShouldVisitChildren = false;
2667})
2668
2669// PseudoObjectExpr is a special case because of the weirdness with
2670// syntactic expressions and opaque values.
2671DEF_TRAVERSE_STMT(PseudoObjectExpr, {
2672 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getSyntacticForm());
2673 for (PseudoObjectExpr::semantics_iterator i = S->semantics_begin(),
2674 e = S->semantics_end();
2675 i != e; ++i) {
2676 Expr *sub = *i;
2677 if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub))
2678 sub = OVE->getSourceExpr();
2679 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(sub);
2680 }
2681 ShouldVisitChildren = false;
2682})
2683
2684DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, {
2685 // This is called for code like 'return T()' where T is a built-in
2686 // (i.e. non-class) type.
2687 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2688})
2689
2690DEF_TRAVERSE_STMT(CXXNewExpr, {
2691 // The child-iterator will pick up the other arguments.
2692 TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc()));
2693})
2694
2695DEF_TRAVERSE_STMT(OffsetOfExpr, {
2696 // The child-iterator will pick up the expression representing
2697 // the field.
2698 // FIMXE: for code like offsetof(Foo, a.b.c), should we get
2699 // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c?
2700 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2701})
2702
2703DEF_TRAVERSE_STMT(UnaryExprOrTypeTraitExpr, {
2704 // The child-iterator will pick up the arg if it's an expression,
2705 // but not if it's a type.
2706 if (S->isArgumentType())
2707 TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
2708})
2709
2710DEF_TRAVERSE_STMT(CXXTypeidExpr, {
2711 // The child-iterator will pick up the arg if it's an expression,
2712 // but not if it's a type.
2713 if (S->isTypeOperand())
2714 TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
2715})
2716
2717DEF_TRAVERSE_STMT(MSPropertyRefExpr, {
2718 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2719})
2720
2721DEF_TRAVERSE_STMT(MSPropertySubscriptExpr, {})
2722
2723DEF_TRAVERSE_STMT(CXXUuidofExpr, {
2724 // The child-iterator will pick up the arg if it's an expression,
2725 // but not if it's a type.
2726 if (S->isTypeOperand())
2727 TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
2728})
2729
2730DEF_TRAVERSE_STMT(TypeTraitExpr, {
2731 for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
2732 TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc()));
2733})
2734
2735DEF_TRAVERSE_STMT(ArrayTypeTraitExpr, {
2736 TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
2737})
2738
2739DEF_TRAVERSE_STMT(ExpressionTraitExpr,
2740 { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getQueriedExpression()); })
2741
2742DEF_TRAVERSE_STMT(VAArgExpr, {
2743 // The child-iterator will pick up the expression argument.
2744 TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
2745})
2746
2747DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
2748 // This is called for code like 'return T()' where T is a class type.
2749 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2750})
2751
2752// Walk only the visible parts of lambda expressions.
2753DEF_TRAVERSE_STMT(LambdaExpr, {
2754 // Visit the capture list.
2755 for (unsigned I = 0, N = S->capture_size(); I != N; ++I) {
2756 const LambdaCapture *C = S->capture_begin() + I;
2757 if (C->isExplicit() || getDerived().shouldVisitImplicitCode()) {
2758 TRY_TO(TraverseLambdaCapture(S, C, S->capture_init_begin()[I]));
2759 }
2760 }
2761
2762 if (getDerived().shouldVisitImplicitCode()) {
2763 // The implicit model is simple: everything else is in the lambda class.
2764 TRY_TO(TraverseDecl(S->getLambdaClass()));
2765 } else {
2766 // We need to poke around to find the bits that might be explicitly written.
2767 TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2768 FunctionProtoTypeLoc Proto = TL.getAsAdjusted<FunctionProtoTypeLoc>();
2769
2770 TRY_TO(TraverseTemplateParameterListHelper(S->getTemplateParameterList()));
2771 if (S->hasExplicitParameters()) {
2772 // Visit parameters.
2773 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2774 TRY_TO(TraverseDecl(Proto.getParam(I)));
2775 }
2776
2777 auto *T = Proto.getTypePtr();
2778 for (const auto &E : T->exceptions())
2779 TRY_TO(TraverseType(E));
2780
2781 if (Expr *NE = T->getNoexceptExpr())
2782 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(NE);
2783
2784 if (S->hasExplicitResultType())
2785 TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
2786 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(
2787 const_cast<Expr *>(S->getTrailingRequiresClause().ConstraintExpr));
2788
2789 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
2790 }
2791 ShouldVisitChildren = false;
2792})
2793
2794DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, {
2795 // This is called for code like 'T()', where T is a template argument.
2796 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2797})
2798
2799// These expressions all might take explicit template arguments.
2800// We traverse those if so. FIXME: implement these.
2801DEF_TRAVERSE_STMT(CXXConstructExpr, {})
2802DEF_TRAVERSE_STMT(CallExpr, {})
2803DEF_TRAVERSE_STMT(CXXMemberCallExpr, {})
2804
2805// These exprs (most of them), do not need any action except iterating
2806// over the children.
2807DEF_TRAVERSE_STMT(AddrLabelExpr, {})
2808DEF_TRAVERSE_STMT(ArraySubscriptExpr, {})
2809DEF_TRAVERSE_STMT(MatrixSubscriptExpr, {})
2810DEF_TRAVERSE_STMT(ArraySectionExpr, {})
2811DEF_TRAVERSE_STMT(OMPArrayShapingExpr, {})
2812DEF_TRAVERSE_STMT(OMPIteratorExpr, {})
2813
2814DEF_TRAVERSE_STMT(BlockExpr, {
2815 TRY_TO(TraverseDecl(S->getBlockDecl()));
2816 return true; // no child statements to loop through.
2817})
2818
2819DEF_TRAVERSE_STMT(ChooseExpr, {})
2820DEF_TRAVERSE_STMT(CompoundLiteralExpr, {
2821 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2822})
2823DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, {})
2824DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, {})
2825
2826DEF_TRAVERSE_STMT(CXXDefaultArgExpr, {
2827 if (getDerived().shouldVisitImplicitCode())
2828 TRY_TO(TraverseStmt(S->getExpr()));
2829})
2830
2831DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {
2832 if (getDerived().shouldVisitImplicitCode())
2833 TRY_TO(TraverseStmt(S->getExpr()));
2834})
2835
2836DEF_TRAVERSE_STMT(CXXDeleteExpr, {})
2837DEF_TRAVERSE_STMT(ExprWithCleanups, {})
2838DEF_TRAVERSE_STMT(CXXInheritedCtorInitExpr, {})
2839DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, {})
2840DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, {})
2841
2842DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {
2843 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2844 if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
2845 TRY_TO(TraverseTypeLoc(ScopeInfo->getTypeLoc()));
2846 if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo())
2847 TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc()));
2848})
2849
2850DEF_TRAVERSE_STMT(CXXThisExpr, {})
2851DEF_TRAVERSE_STMT(CXXThrowExpr, {})
2852DEF_TRAVERSE_STMT(UserDefinedLiteral, {})
2853DEF_TRAVERSE_STMT(DesignatedInitExpr, {})
2854DEF_TRAVERSE_STMT(DesignatedInitUpdateExpr, {})
2855DEF_TRAVERSE_STMT(ExtVectorElementExpr, {})
2856DEF_TRAVERSE_STMT(GNUNullExpr, {})
2857DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {})
2858DEF_TRAVERSE_STMT(NoInitExpr, {})
2859DEF_TRAVERSE_STMT(ArrayInitLoopExpr, {
2860 // FIXME: The source expression of the OVE should be listed as
2861 // a child of the ArrayInitLoopExpr.
2862 if (OpaqueValueExpr *OVE = S->getCommonExpr())
2863 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(OVE->getSourceExpr());
2864})
2865DEF_TRAVERSE_STMT(ArrayInitIndexExpr, {})
2866DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, {})
2867
2868DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
2869 if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
2870 TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
2871})
2872
2873DEF_TRAVERSE_STMT(ObjCIsaExpr, {})
2874DEF_TRAVERSE_STMT(ObjCIvarRefExpr, {})
2875
2876DEF_TRAVERSE_STMT(ObjCMessageExpr, {
2877 if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo())
2878 TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
2879})
2880
2881DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, {
2882 if (S->isClassReceiver()) {
2883 ObjCInterfaceDecl *IDecl = S->getClassReceiver();
2884 QualType Type = IDecl->getASTContext().getObjCInterfaceType(IDecl);
2885 ObjCInterfaceLocInfo Data;
2886 Data.NameLoc = S->getReceiverLocation();
2887 Data.NameEndLoc = Data.NameLoc;
2888 TRY_TO(TraverseTypeLoc(TypeLoc(Type, &Data)));
2889 }
2890})
2891DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, {})
2892DEF_TRAVERSE_STMT(ObjCProtocolExpr, {})
2893DEF_TRAVERSE_STMT(ObjCSelectorExpr, {})
2894DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, {})
2895
2896DEF_TRAVERSE_STMT(ObjCBridgedCastExpr, {
2897 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2898})
2899
2900DEF_TRAVERSE_STMT(ObjCAvailabilityCheckExpr, {})
2901DEF_TRAVERSE_STMT(ParenExpr, {})
2902DEF_TRAVERSE_STMT(ParenListExpr, {})
2903DEF_TRAVERSE_STMT(SYCLUniqueStableNameExpr, {
2904 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2905})
2906DEF_TRAVERSE_STMT(OpenACCAsteriskSizeExpr, {})
2907DEF_TRAVERSE_STMT(PredefinedExpr, {})
2908DEF_TRAVERSE_STMT(ShuffleVectorExpr, {})
2909DEF_TRAVERSE_STMT(ConvertVectorExpr, {})
2910DEF_TRAVERSE_STMT(StmtExpr, {})
2911DEF_TRAVERSE_STMT(SourceLocExpr, {})
2912DEF_TRAVERSE_STMT(EmbedExpr, {
2913 for (IntegerLiteral *IL : S->underlying_data_elements()) {
2914 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(IL);
2915 }
2916})
2917
2918DEF_TRAVERSE_STMT(UnresolvedLookupExpr, {
2919 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2920 if (S->hasExplicitTemplateArgs()) {
2921 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2922 S->getNumTemplateArgs()));
2923 }
2924})
2925
2926DEF_TRAVERSE_STMT(UnresolvedMemberExpr, {
2927 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2928 if (S->hasExplicitTemplateArgs()) {
2929 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2930 S->getNumTemplateArgs()));
2931 }
2932})
2933
2934DEF_TRAVERSE_STMT(SEHTryStmt, {})
2935DEF_TRAVERSE_STMT(SEHExceptStmt, {})
2936DEF_TRAVERSE_STMT(SEHFinallyStmt, {})
2937DEF_TRAVERSE_STMT(SEHLeaveStmt, {})
2938DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
2939
2940DEF_TRAVERSE_STMT(SYCLKernelCallStmt, {
2941 if (getDerived().shouldVisitImplicitCode()) {
2942 TRY_TO(TraverseStmt(S->getOriginalStmt()));
2943 TRY_TO(TraverseDecl(S->getOutlinedFunctionDecl()));
2944 ShouldVisitChildren = false;
2945 }
2946})
2947
2948DEF_TRAVERSE_STMT(CXXOperatorCallExpr, {})
2949DEF_TRAVERSE_STMT(CXXRewrittenBinaryOperator, {
2950 if (!getDerived().shouldVisitImplicitCode()) {
2951 CXXRewrittenBinaryOperator::DecomposedForm Decomposed =
2952 S->getDecomposedForm();
2953 TRY_TO(TraverseStmt(const_cast<Expr*>(Decomposed.LHS)));
2954 TRY_TO(TraverseStmt(const_cast<Expr*>(Decomposed.RHS)));
2955 ShouldVisitChildren = false;
2956 }
2957})
2958DEF_TRAVERSE_STMT(OpaqueValueExpr, {})
2959DEF_TRAVERSE_STMT(RecoveryExpr, {})
2960DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {})
2961
2962// These operators (all of them) do not need any action except
2963// iterating over the children.
2964DEF_TRAVERSE_STMT(BinaryConditionalOperator, {})
2965DEF_TRAVERSE_STMT(ConditionalOperator, {})
2966DEF_TRAVERSE_STMT(UnaryOperator, {})
2967DEF_TRAVERSE_STMT(BinaryOperator, {})
2968DEF_TRAVERSE_STMT(CompoundAssignOperator, {})
2969DEF_TRAVERSE_STMT(CXXNoexceptExpr, {})
2970DEF_TRAVERSE_STMT(PackExpansionExpr, {})
2971DEF_TRAVERSE_STMT(SizeOfPackExpr, {})
2972DEF_TRAVERSE_STMT(PackIndexingExpr, {})
2973DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, {})
2974DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {})
2975DEF_TRAVERSE_STMT(FunctionParmPackExpr, {})
2976DEF_TRAVERSE_STMT(CXXFoldExpr, {})
2977DEF_TRAVERSE_STMT(AtomicExpr, {})
2978DEF_TRAVERSE_STMT(CXXParenListInitExpr, {})
2979
2980DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {
2981 if (S->getLifetimeExtendedTemporaryDecl()) {
2982 TRY_TO(TraverseLifetimeExtendedTemporaryDecl(
2983 S->getLifetimeExtendedTemporaryDecl()));
2984 ShouldVisitChildren = false;
2985 }
2986})
2987// For coroutines expressions, traverse either the operand
2988// as written or the implied calls, depending on what the
2989// derived class requests.
2990DEF_TRAVERSE_STMT(CoroutineBodyStmt, {
2991 if (!getDerived().shouldVisitImplicitCode()) {
2992 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
2993 ShouldVisitChildren = false;
2994 }
2995})
2996DEF_TRAVERSE_STMT(CoreturnStmt, {
2997 if (!getDerived().shouldVisitImplicitCode()) {
2998 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
2999 ShouldVisitChildren = false;
3000 }
3001})
3002DEF_TRAVERSE_STMT(CoawaitExpr, {
3003 if (!getDerived().shouldVisitImplicitCode()) {
3004 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
3005 ShouldVisitChildren = false;
3006 }
3007})
3008DEF_TRAVERSE_STMT(DependentCoawaitExpr, {
3009 if (!getDerived().shouldVisitImplicitCode()) {
3010 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
3011 ShouldVisitChildren = false;
3012 }
3013})
3014DEF_TRAVERSE_STMT(CoyieldExpr, {
3015 if (!getDerived().shouldVisitImplicitCode()) {
3016 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
3017 ShouldVisitChildren = false;
3018 }
3019})
3020
3021DEF_TRAVERSE_STMT(ConceptSpecializationExpr, {
3022 TRY_TO(TraverseConceptReference(S->getConceptReference()));
3023})
3024
3025DEF_TRAVERSE_STMT(RequiresExpr, {
3026 TRY_TO(TraverseDecl(S->getBody()));
3027 for (ParmVarDecl *Parm : S->getLocalParameters())
3028 TRY_TO(TraverseDecl(Parm));
3029 for (concepts::Requirement *Req : S->getRequirements())
3030 TRY_TO(TraverseConceptRequirement(Req));
3031})
3032
3033// These literals (all of them) do not need any action.
3034DEF_TRAVERSE_STMT(IntegerLiteral, {})
3035DEF_TRAVERSE_STMT(FixedPointLiteral, {})
3036DEF_TRAVERSE_STMT(CharacterLiteral, {})
3037DEF_TRAVERSE_STMT(FloatingLiteral, {})
3038DEF_TRAVERSE_STMT(ImaginaryLiteral, {})
3039DEF_TRAVERSE_STMT(StringLiteral, {})
3040DEF_TRAVERSE_STMT(ObjCStringLiteral, {})
3041DEF_TRAVERSE_STMT(ObjCBoxedExpr, {})
3042DEF_TRAVERSE_STMT(ObjCArrayLiteral, {})
3043DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, {})
3044
3045// Traverse OpenCL: AsType, Convert.
3046DEF_TRAVERSE_STMT(AsTypeExpr, {})
3047
3048// OpenMP directives.
3049template <typename Derived>
3050bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
3051 OMPExecutableDirective *S) {
3052 for (auto *C : S->clauses()) {
3053 TRY_TO(TraverseOMPClause(C));
3054 }
3055 return true;
3056}
3057
3058DEF_TRAVERSE_STMT(OMPCanonicalLoop, {
3059 if (!getDerived().shouldVisitImplicitCode()) {
3060 // Visit only the syntactical loop.
3061 TRY_TO(TraverseStmt(S->getLoopStmt()));
3062 ShouldVisitChildren = false;
3063 }
3064})
3065
3066template <typename Derived>
3067bool
3068RecursiveASTVisitor<Derived>::TraverseOMPLoopDirective(OMPLoopDirective *S) {
3069 return TraverseOMPExecutableDirective(S);
3070}
3071
3072DEF_TRAVERSE_STMT(OMPMetaDirective,
3073 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3074
3075DEF_TRAVERSE_STMT(OMPParallelDirective,
3076 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3077
3078DEF_TRAVERSE_STMT(OMPSimdDirective,
3079 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3080
3081DEF_TRAVERSE_STMT(OMPTileDirective,
3082 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3083
3084DEF_TRAVERSE_STMT(OMPStripeDirective,
3085 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3086
3087DEF_TRAVERSE_STMT(OMPUnrollDirective,
3088 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3089
3090DEF_TRAVERSE_STMT(OMPReverseDirective,
3091 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3092
3093DEF_TRAVERSE_STMT(OMPInterchangeDirective,
3094 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3095
3096DEF_TRAVERSE_STMT(OMPForDirective,
3097 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3098
3099DEF_TRAVERSE_STMT(OMPForSimdDirective,
3100 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3101
3102DEF_TRAVERSE_STMT(OMPSectionsDirective,
3103 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3104
3105DEF_TRAVERSE_STMT(OMPSectionDirective,
3106 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3107
3108DEF_TRAVERSE_STMT(OMPScopeDirective,
3109 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3110
3111DEF_TRAVERSE_STMT(OMPSingleDirective,
3112 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3113
3114DEF_TRAVERSE_STMT(OMPMasterDirective,
3115 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3116
3117DEF_TRAVERSE_STMT(OMPCriticalDirective, {
3118 TRY_TO(TraverseDeclarationNameInfo(S->getDirectiveName()));
3119 TRY_TO(TraverseOMPExecutableDirective(S));
3120})
3121
3122DEF_TRAVERSE_STMT(OMPParallelForDirective,
3123 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3124
3125DEF_TRAVERSE_STMT(OMPParallelForSimdDirective,
3126 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3127
3128DEF_TRAVERSE_STMT(OMPParallelMasterDirective,
3129 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3130
3131DEF_TRAVERSE_STMT(OMPParallelMaskedDirective,
3132 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3133
3134DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
3135 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3136
3137DEF_TRAVERSE_STMT(OMPTaskDirective,
3138 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3139
3140DEF_TRAVERSE_STMT(OMPTaskyieldDirective,
3141 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3142
3143DEF_TRAVERSE_STMT(OMPBarrierDirective,
3144 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3145
3146DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
3147 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3148
3149DEF_TRAVERSE_STMT(OMPTaskgroupDirective,
3150 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3151
3152DEF_TRAVERSE_STMT(OMPCancellationPointDirective,
3153 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3154
3155DEF_TRAVERSE_STMT(OMPCancelDirective,
3156 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3157
3158DEF_TRAVERSE_STMT(OMPFlushDirective,
3159 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3160
3161DEF_TRAVERSE_STMT(OMPDepobjDirective,
3162 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3163
3164DEF_TRAVERSE_STMT(OMPScanDirective,
3165 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3166
3167DEF_TRAVERSE_STMT(OMPOrderedDirective,
3168 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3169
3170DEF_TRAVERSE_STMT(OMPAtomicDirective,
3171 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3172
3173DEF_TRAVERSE_STMT(OMPTargetDirective,
3174 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3175
3176DEF_TRAVERSE_STMT(OMPTargetDataDirective,
3177 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3178
3179DEF_TRAVERSE_STMT(OMPTargetEnterDataDirective,
3180 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3181
3182DEF_TRAVERSE_STMT(OMPTargetExitDataDirective,
3183 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3184
3185DEF_TRAVERSE_STMT(OMPTargetParallelDirective,
3186 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3187
3188DEF_TRAVERSE_STMT(OMPTargetParallelForDirective,
3189 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3190
3191DEF_TRAVERSE_STMT(OMPTeamsDirective,
3192 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3193
3194DEF_TRAVERSE_STMT(OMPTargetUpdateDirective,
3195 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3196
3197DEF_TRAVERSE_STMT(OMPTaskLoopDirective,
3198 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3199
3200DEF_TRAVERSE_STMT(OMPTaskLoopSimdDirective,
3201 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3202
3203DEF_TRAVERSE_STMT(OMPMasterTaskLoopDirective,
3204 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3205
3206DEF_TRAVERSE_STMT(OMPMasterTaskLoopSimdDirective,
3207 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3208
3209DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopDirective,
3210 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3211
3212DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopSimdDirective,
3213 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3214
3215DEF_TRAVERSE_STMT(OMPMaskedTaskLoopDirective,
3216 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3217
3218DEF_TRAVERSE_STMT(OMPMaskedTaskLoopSimdDirective,
3219 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3220
3221DEF_TRAVERSE_STMT(OMPParallelMaskedTaskLoopDirective,
3222 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3223
3224DEF_TRAVERSE_STMT(OMPParallelMaskedTaskLoopSimdDirective,
3225 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3226
3227DEF_TRAVERSE_STMT(OMPDistributeDirective,
3228 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3229
3230DEF_TRAVERSE_STMT(OMPDistributeParallelForDirective,
3231 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3232
3233DEF_TRAVERSE_STMT(OMPDistributeParallelForSimdDirective,
3234 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3235
3236DEF_TRAVERSE_STMT(OMPDistributeSimdDirective,
3237 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3238
3239DEF_TRAVERSE_STMT(OMPTargetParallelForSimdDirective,
3240 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3241
3242DEF_TRAVERSE_STMT(OMPTargetSimdDirective,
3243 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3244
3245DEF_TRAVERSE_STMT(OMPTeamsDistributeDirective,
3246 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3247
3248DEF_TRAVERSE_STMT(OMPTeamsDistributeSimdDirective,
3249 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3250
3251DEF_TRAVERSE_STMT(OMPTeamsDistributeParallelForSimdDirective,
3252 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3253
3254DEF_TRAVERSE_STMT(OMPTeamsDistributeParallelForDirective,
3255 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3256
3257DEF_TRAVERSE_STMT(OMPTargetTeamsDirective,
3258 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3259
3260DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeDirective,
3261 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3262
3263DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForDirective,
3264 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3265
3266DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForSimdDirective,
3267 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3268
3269DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeSimdDirective,
3270 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3271
3272DEF_TRAVERSE_STMT(OMPInteropDirective,
3273 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3274
3275DEF_TRAVERSE_STMT(OMPDispatchDirective,
3276 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3277
3278DEF_TRAVERSE_STMT(OMPMaskedDirective,
3279 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3280
3281DEF_TRAVERSE_STMT(OMPGenericLoopDirective,
3282 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3283
3284DEF_TRAVERSE_STMT(OMPTeamsGenericLoopDirective,
3285 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3286
3287DEF_TRAVERSE_STMT(OMPTargetTeamsGenericLoopDirective,
3288 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3289
3290DEF_TRAVERSE_STMT(OMPParallelGenericLoopDirective,
3291 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3292
3293DEF_TRAVERSE_STMT(OMPTargetParallelGenericLoopDirective,
3294 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3295
3296DEF_TRAVERSE_STMT(OMPAssumeDirective,
3297 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3298
3299DEF_TRAVERSE_STMT(OMPErrorDirective,
3300 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3301
3302// OpenMP clauses.
3303template <typename Derived>
3304bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
3305 if (!C)
3306 return true;
3307 switch (C->getClauseKind()) {
3308#define GEN_CLANG_CLAUSE_CLASS
3309#define CLAUSE_CLASS(Enum, Str, Class) \
3310 case llvm::omp::Clause::Enum: \
3311 TRY_TO(Visit##Class(static_cast<Class *>(C))); \
3312 break;
3313#define CLAUSE_NO_CLASS(Enum, Str) \
3314 case llvm::omp::Clause::Enum: \
3315 break;
3316#include "llvm/Frontend/OpenMP/OMP.inc"
3317 }
3318 return true;
3319}
3320
3321template <typename Derived>
3322bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPreInit(
3323 OMPClauseWithPreInit *Node) {
3324 TRY_TO(TraverseStmt(Node->getPreInitStmt()));
3325 return true;
3326}
3327
3328template <typename Derived>
3329bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPostUpdate(
3330 OMPClauseWithPostUpdate *Node) {
3331 TRY_TO(VisitOMPClauseWithPreInit(Node));
3332 TRY_TO(TraverseStmt(Node->getPostUpdateExpr()));
3333 return true;
3334}
3335
3336template <typename Derived>
3337bool RecursiveASTVisitor<Derived>::VisitOMPAllocatorClause(
3338 OMPAllocatorClause *C) {
3339 TRY_TO(TraverseStmt(C->getAllocator()));
3340 return true;
3341}
3342
3343template <typename Derived>
3344bool RecursiveASTVisitor<Derived>::VisitOMPAllocateClause(OMPAllocateClause *C) {
3345 TRY_TO(TraverseStmt(C->getAllocator()));
3346 TRY_TO(VisitOMPClauseList(C));
3347 return true;
3348}
3349
3350template <typename Derived>
3351bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
3352 TRY_TO(VisitOMPClauseWithPreInit(C));
3353 TRY_TO(TraverseStmt(C->getCondition()));
3354 return true;
3355}
3356
3357template <typename Derived>
3358bool RecursiveASTVisitor<Derived>::VisitOMPFinalClause(OMPFinalClause *C) {
3359 TRY_TO(VisitOMPClauseWithPreInit(C));
3360 TRY_TO(TraverseStmt(C->getCondition()));
3361 return true;
3362}
3363
3364template <typename Derived>
3365bool
3366RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
3367 TRY_TO(VisitOMPClauseWithPreInit(C));
3368 TRY_TO(TraverseStmt(C->getNumThreads()));
3369 return true;
3370}
3371
3372template <typename Derived>
3373bool RecursiveASTVisitor<Derived>::VisitOMPAlignClause(OMPAlignClause *C) {
3374 TRY_TO(TraverseStmt(C->getAlignment()));
3375 return true;
3376}
3377
3378template <typename Derived>
3379bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) {
3380 TRY_TO(TraverseStmt(C->getSafelen()));
3381 return true;
3382}
3383
3384template <typename Derived>
3385bool RecursiveASTVisitor<Derived>::VisitOMPSimdlenClause(OMPSimdlenClause *C) {
3386 TRY_TO(TraverseStmt(C->getSimdlen()));
3387 return true;
3388}
3389
3390template <typename Derived>
3391bool RecursiveASTVisitor<Derived>::VisitOMPSizesClause(OMPSizesClause *C) {
3392 for (Expr *E : C->getSizesRefs())
3393 TRY_TO(TraverseStmt(E));
3394 return true;
3395}
3396
3397template <typename Derived>
3398bool RecursiveASTVisitor<Derived>::VisitOMPPermutationClause(
3399 OMPPermutationClause *C) {
3400 for (Expr *E : C->getArgsRefs())
3401 TRY_TO(TraverseStmt(E));
3402 return true;
3403}
3404
3405template <typename Derived>
3406bool RecursiveASTVisitor<Derived>::VisitOMPFullClause(OMPFullClause *C) {
3407 return true;
3408}
3409
3410template <typename Derived>
3411bool RecursiveASTVisitor<Derived>::VisitOMPPartialClause(OMPPartialClause *C) {
3412 TRY_TO(TraverseStmt(C->getFactor()));
3413 return true;
3414}
3415
3416template <typename Derived>
3417bool
3418RecursiveASTVisitor<Derived>::VisitOMPCollapseClause(OMPCollapseClause *C) {
3419 TRY_TO(TraverseStmt(C->getNumForLoops()));
3420 return true;
3421}
3422
3423template <typename Derived>
3424bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *) {
3425 return true;
3426}
3427
3428template <typename Derived>
3429bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *) {
3430 return true;
3431}
3432
3433template <typename Derived>
3434bool RecursiveASTVisitor<Derived>::VisitOMPUnifiedAddressClause(
3435 OMPUnifiedAddressClause *) {
3436 return true;
3437}
3438
3439template <typename Derived>
3440bool RecursiveASTVisitor<Derived>::VisitOMPUnifiedSharedMemoryClause(
3441 OMPUnifiedSharedMemoryClause *) {
3442 return true;
3443}
3444
3445template <typename Derived>
3446bool RecursiveASTVisitor<Derived>::VisitOMPReverseOffloadClause(
3447 OMPReverseOffloadClause *) {
3448 return true;
3449}
3450
3451template <typename Derived>
3452bool RecursiveASTVisitor<Derived>::VisitOMPDynamicAllocatorsClause(
3453 OMPDynamicAllocatorsClause *) {
3454 return true;
3455}
3456
3457template <typename Derived>
3458bool RecursiveASTVisitor<Derived>::VisitOMPAtomicDefaultMemOrderClause(
3459 OMPAtomicDefaultMemOrderClause *) {
3460 return true;
3461}
3462
3463template <typename Derived>
3464bool RecursiveASTVisitor<Derived>::VisitOMPSelfMapsClause(OMPSelfMapsClause *) {
3465 return true;
3466}
3467
3468template <typename Derived>
3469bool RecursiveASTVisitor<Derived>::VisitOMPAtClause(OMPAtClause *) {
3470 return true;
3471}
3472
3473template <typename Derived>
3474bool RecursiveASTVisitor<Derived>::VisitOMPSeverityClause(OMPSeverityClause *) {
3475 return true;
3476}
3477
3478template <typename Derived>
3479bool RecursiveASTVisitor<Derived>::VisitOMPMessageClause(OMPMessageClause *C) {
3480 TRY_TO(TraverseStmt(C->getMessageString()));
3481 return true;
3482}
3483
3484template <typename Derived>
3485bool
3486RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {
3487 TRY_TO(VisitOMPClauseWithPreInit(C));
3488 TRY_TO(TraverseStmt(C->getChunkSize()));
3489 return true;
3490}
3491
3492template <typename Derived>
3493bool RecursiveASTVisitor<Derived>::VisitOMPOrderedClause(OMPOrderedClause *C) {
3494 TRY_TO(TraverseStmt(C->getNumForLoops()));
3495 return true;
3496}
3497
3498template <typename Derived>
3499bool RecursiveASTVisitor<Derived>::VisitOMPNowaitClause(OMPNowaitClause *) {
3500 return true;
3501}
3502
3503template <typename Derived>
3504bool RecursiveASTVisitor<Derived>::VisitOMPUntiedClause(OMPUntiedClause *) {
3505 return true;
3506}
3507
3508template <typename Derived>
3509bool
3510RecursiveASTVisitor<Derived>::VisitOMPMergeableClause(OMPMergeableClause *) {
3511 return true;
3512}
3513
3514template <typename Derived>
3515bool RecursiveASTVisitor<Derived>::VisitOMPReadClause(OMPReadClause *) {
3516 return true;
3517}
3518
3519template <typename Derived>
3520bool RecursiveASTVisitor<Derived>::VisitOMPWriteClause(OMPWriteClause *) {
3521 return true;
3522}
3523
3524template <typename Derived>
3525bool RecursiveASTVisitor<Derived>::VisitOMPUpdateClause(OMPUpdateClause *) {
3526 return true;
3527}
3528
3529template <typename Derived>
3530bool RecursiveASTVisitor<Derived>::VisitOMPCaptureClause(OMPCaptureClause *) {
3531 return true;
3532}
3533
3534template <typename Derived>
3535bool RecursiveASTVisitor<Derived>::VisitOMPCompareClause(OMPCompareClause *) {
3536 return true;
3537}
3538
3539template <typename Derived>
3540bool RecursiveASTVisitor<Derived>::VisitOMPFailClause(OMPFailClause *) {
3541 return true;
3542}
3543
3544template <typename Derived>
3545bool RecursiveASTVisitor<Derived>::VisitOMPSeqCstClause(OMPSeqCstClause *) {
3546 return true;
3547}
3548
3549template <typename Derived>
3550bool RecursiveASTVisitor<Derived>::VisitOMPAcqRelClause(OMPAcqRelClause *) {
3551 return true;
3552}
3553
3554template <typename Derived>
3555bool RecursiveASTVisitor<Derived>::VisitOMPAbsentClause(OMPAbsentClause *) {
3556 return true;
3557}
3558
3559template <typename Derived>
3560bool RecursiveASTVisitor<Derived>::VisitOMPHoldsClause(OMPHoldsClause *) {
3561 return true;
3562}
3563
3564template <typename Derived>
3565bool RecursiveASTVisitor<Derived>::VisitOMPContainsClause(OMPContainsClause *) {
3566 return true;
3567}
3568
3569template <typename Derived>
3570bool RecursiveASTVisitor<Derived>::VisitOMPNoOpenMPClause(OMPNoOpenMPClause *) {
3571 return true;
3572}
3573
3574template <typename Derived>
3575bool RecursiveASTVisitor<Derived>::VisitOMPNoOpenMPRoutinesClause(
3576 OMPNoOpenMPRoutinesClause *) {
3577 return true;
3578}
3579
3580template <typename Derived>
3581bool RecursiveASTVisitor<Derived>::VisitOMPNoOpenMPConstructsClause(
3582 OMPNoOpenMPConstructsClause *) {
3583 return true;
3584}
3585
3586template <typename Derived>
3587bool RecursiveASTVisitor<Derived>::VisitOMPNoParallelismClause(
3588 OMPNoParallelismClause *) {
3589 return true;
3590}
3591
3592template <typename Derived>
3593bool RecursiveASTVisitor<Derived>::VisitOMPAcquireClause(OMPAcquireClause *) {
3594 return true;
3595}
3596
3597template <typename Derived>
3598bool RecursiveASTVisitor<Derived>::VisitOMPReleaseClause(OMPReleaseClause *) {
3599 return true;
3600}
3601
3602template <typename Derived>
3603bool RecursiveASTVisitor<Derived>::VisitOMPRelaxedClause(OMPRelaxedClause *) {
3604 return true;
3605}
3606
3607template <typename Derived>
3608bool RecursiveASTVisitor<Derived>::VisitOMPWeakClause(OMPWeakClause *) {
3609 return true;
3610}
3611
3612template <typename Derived>
3613bool RecursiveASTVisitor<Derived>::VisitOMPThreadsClause(OMPThreadsClause *) {
3614 return true;
3615}
3616
3617template <typename Derived>
3618bool RecursiveASTVisitor<Derived>::VisitOMPSIMDClause(OMPSIMDClause *) {
3619 return true;
3620}
3621
3622template <typename Derived>
3623bool RecursiveASTVisitor<Derived>::VisitOMPNogroupClause(OMPNogroupClause *) {
3624 return true;
3625}
3626
3627template <typename Derived>
3628bool RecursiveASTVisitor<Derived>::VisitOMPInitClause(OMPInitClause *C) {
3629 TRY_TO(VisitOMPClauseList(C));
3630 return true;
3631}
3632
3633template <typename Derived>
3634bool RecursiveASTVisitor<Derived>::VisitOMPUseClause(OMPUseClause *C) {
3635 TRY_TO(TraverseStmt(C->getInteropVar()));
3636 return true;
3637}
3638
3639template <typename Derived>
3640bool RecursiveASTVisitor<Derived>::VisitOMPDestroyClause(OMPDestroyClause *C) {
3641 TRY_TO(TraverseStmt(C->getInteropVar()));
3642 return true;
3643}
3644
3645template <typename Derived>
3646bool RecursiveASTVisitor<Derived>::VisitOMPNovariantsClause(
3647 OMPNovariantsClause *C) {
3648 TRY_TO(VisitOMPClauseWithPreInit(C));
3649 TRY_TO(TraverseStmt(C->getCondition()));
3650 return true;
3651}
3652
3653template <typename Derived>
3654bool RecursiveASTVisitor<Derived>::VisitOMPNocontextClause(
3655 OMPNocontextClause *C) {
3656 TRY_TO(VisitOMPClauseWithPreInit(C));
3657 TRY_TO(TraverseStmt(C->getCondition()));
3658 return true;
3659}
3660
3661template <typename Derived>
3662template <typename T>
3663bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
3664 for (auto *E : Node->varlist()) {
3665 TRY_TO(TraverseStmt(E));
3666 }
3667 return true;
3668}
3669
3670template <typename Derived>
3671bool RecursiveASTVisitor<Derived>::VisitOMPInclusiveClause(
3672 OMPInclusiveClause *C) {
3673 TRY_TO(VisitOMPClauseList(C));
3674 return true;
3675}
3676
3677template <typename Derived>
3678bool RecursiveASTVisitor<Derived>::VisitOMPExclusiveClause(
3679 OMPExclusiveClause *C) {
3680 TRY_TO(VisitOMPClauseList(C));
3681 return true;
3682}
3683
3684template <typename Derived>
3685bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
3686 TRY_TO(VisitOMPClauseList(C));
3687 for (auto *E : C->private_copies()) {
3688 TRY_TO(TraverseStmt(E));
3689 }
3690 return true;
3691}
3692
3693template <typename Derived>
3694bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
3695 OMPFirstprivateClause *C) {
3696 TRY_TO(VisitOMPClauseList(C));
3697 TRY_TO(VisitOMPClauseWithPreInit(C));
3698 for (auto *E : C->private_copies()) {
3699 TRY_TO(TraverseStmt(E));
3700 }
3701 for (auto *E : C->inits()) {
3702 TRY_TO(TraverseStmt(E));
3703 }
3704 return true;
3705}
3706
3707template <typename Derived>
3708bool RecursiveASTVisitor<Derived>::VisitOMPLastprivateClause(
3709 OMPLastprivateClause *C) {
3710 TRY_TO(VisitOMPClauseList(C));
3711 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3712 for (auto *E : C->private_copies()) {
3713 TRY_TO(TraverseStmt(E));
3714 }
3715 for (auto *E : C->source_exprs()) {
3716 TRY_TO(TraverseStmt(E));
3717 }
3718 for (auto *E : C->destination_exprs()) {
3719 TRY_TO(TraverseStmt(E));
3720 }
3721 for (auto *E : C->assignment_ops()) {
3722 TRY_TO(TraverseStmt(E));
3723 }
3724 return true;
3725}
3726
3727template <typename Derived>
3728bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
3729 TRY_TO(VisitOMPClauseList(C));
3730 return true;
3731}
3732
3733template <typename Derived>
3734bool RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) {
3735 TRY_TO(TraverseStmt(C->getStep()));
3736 TRY_TO(TraverseStmt(C->getCalcStep()));
3737 TRY_TO(VisitOMPClauseList(C));
3738 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3739 for (auto *E : C->privates()) {
3740 TRY_TO(TraverseStmt(E));
3741 }
3742 for (auto *E : C->inits()) {
3743 TRY_TO(TraverseStmt(E));
3744 }
3745 for (auto *E : C->updates()) {
3746 TRY_TO(TraverseStmt(E));
3747 }
3748 for (auto *E : C->finals()) {
3749 TRY_TO(TraverseStmt(E));
3750 }
3751 return true;
3752}
3753
3754template <typename Derived>
3755bool RecursiveASTVisitor<Derived>::VisitOMPAlignedClause(OMPAlignedClause *C) {
3756 TRY_TO(TraverseStmt(C->getAlignment()));
3757 TRY_TO(VisitOMPClauseList(C));
3758 return true;
3759}
3760
3761template <typename Derived>
3762bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
3763 TRY_TO(VisitOMPClauseList(C));
3764 for (auto *E : C->source_exprs()) {
3765 TRY_TO(TraverseStmt(E));
3766 }
3767 for (auto *E : C->destination_exprs()) {
3768 TRY_TO(TraverseStmt(E));
3769 }
3770 for (auto *E : C->assignment_ops()) {
3771 TRY_TO(TraverseStmt(E));
3772 }
3773 return true;
3774}
3775
3776template <typename Derived>
3777bool RecursiveASTVisitor<Derived>::VisitOMPCopyprivateClause(
3778 OMPCopyprivateClause *C) {
3779 TRY_TO(VisitOMPClauseList(C));
3780 for (auto *E : C->source_exprs()) {
3781 TRY_TO(TraverseStmt(E));
3782 }
3783 for (auto *E : C->destination_exprs()) {
3784 TRY_TO(TraverseStmt(E));
3785 }
3786 for (auto *E : C->assignment_ops()) {
3787 TRY_TO(TraverseStmt(E));
3788 }
3789 return true;
3790}
3791
3792template <typename Derived>
3793bool
3794RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) {
3795 TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
3796 TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
3797 TRY_TO(VisitOMPClauseList(C));
3798 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3799 for (auto *E : C->privates()) {
3800 TRY_TO(TraverseStmt(E));
3801 }
3802 for (auto *E : C->lhs_exprs()) {
3803 TRY_TO(TraverseStmt(E));
3804 }
3805 for (auto *E : C->rhs_exprs()) {
3806 TRY_TO(TraverseStmt(E));
3807 }
3808 for (auto *E : C->reduction_ops()) {
3809 TRY_TO(TraverseStmt(E));
3810 }
3811 if (C->getModifier() == OMPC_REDUCTION_inscan) {
3812 for (auto *E : C->copy_ops()) {
3813 TRY_TO(TraverseStmt(E));
3814 }
3815 for (auto *E : C->copy_array_temps()) {
3816 TRY_TO(TraverseStmt(E));
3817 }
3818 for (auto *E : C->copy_array_elems()) {
3819 TRY_TO(TraverseStmt(E));
3820 }
3821 }
3822 return true;
3823}
3824
3825template <typename Derived>
3826bool RecursiveASTVisitor<Derived>::VisitOMPTaskReductionClause(
3827 OMPTaskReductionClause *C) {
3828 TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
3829 TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
3830 TRY_TO(VisitOMPClauseList(C));
3831 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3832 for (auto *E : C->privates()) {
3833 TRY_TO(TraverseStmt(E));
3834 }
3835 for (auto *E : C->lhs_exprs()) {
3836 TRY_TO(TraverseStmt(E));
3837 }
3838 for (auto *E : C->rhs_exprs()) {
3839 TRY_TO(TraverseStmt(E));
3840 }
3841 for (auto *E : C->reduction_ops()) {
3842 TRY_TO(TraverseStmt(E));
3843 }
3844 return true;
3845}
3846
3847template <typename Derived>
3848bool RecursiveASTVisitor<Derived>::VisitOMPInReductionClause(
3849 OMPInReductionClause *C) {
3850 TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
3851 TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
3852 TRY_TO(VisitOMPClauseList(C));
3853 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3854 for (auto *E : C->privates()) {
3855 TRY_TO(TraverseStmt(E));
3856 }
3857 for (auto *E : C->lhs_exprs()) {
3858 TRY_TO(TraverseStmt(E));
3859 }
3860 for (auto *E : C->rhs_exprs()) {
3861 TRY_TO(TraverseStmt(E));
3862 }
3863 for (auto *E : C->reduction_ops()) {
3864 TRY_TO(TraverseStmt(E));
3865 }
3866 for (auto *E : C->taskgroup_descriptors())
3867 TRY_TO(TraverseStmt(E));
3868 return true;
3869}
3870
3871template <typename Derived>
3872bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
3873 TRY_TO(VisitOMPClauseList(C));
3874 return true;
3875}
3876
3877template <typename Derived>
3878bool RecursiveASTVisitor<Derived>::VisitOMPDepobjClause(OMPDepobjClause *C) {
3879 TRY_TO(TraverseStmt(C->getDepobj()));
3880 return true;
3881}
3882
3883template <typename Derived>
3884bool RecursiveASTVisitor<Derived>::VisitOMPDependClause(OMPDependClause *C) {
3885 TRY_TO(VisitOMPClauseList(C));
3886 return true;
3887}
3888
3889template <typename Derived>
3890bool RecursiveASTVisitor<Derived>::VisitOMPDeviceClause(OMPDeviceClause *C) {
3891 TRY_TO(VisitOMPClauseWithPreInit(C));
3892 TRY_TO(TraverseStmt(C->getDevice()));
3893 return true;
3894}
3895
3896template <typename Derived>
3897bool RecursiveASTVisitor<Derived>::VisitOMPMapClause(OMPMapClause *C) {
3898 TRY_TO(VisitOMPClauseList(C));
3899 return true;
3900}
3901
3902template <typename Derived>
3903bool RecursiveASTVisitor<Derived>::VisitOMPNumTeamsClause(
3904 OMPNumTeamsClause *C) {
3905 TRY_TO(VisitOMPClauseList(C));
3906 TRY_TO(VisitOMPClauseWithPreInit(C));
3907 return true;
3908}
3909
3910template <typename Derived>
3911bool RecursiveASTVisitor<Derived>::VisitOMPThreadLimitClause(
3912 OMPThreadLimitClause *C) {
3913 TRY_TO(VisitOMPClauseList(C));
3914 TRY_TO(VisitOMPClauseWithPreInit(C));
3915 return true;
3916}
3917
3918template <typename Derived>
3919bool RecursiveASTVisitor<Derived>::VisitOMPPriorityClause(
3920 OMPPriorityClause *C) {
3921 TRY_TO(VisitOMPClauseWithPreInit(C));
3922 TRY_TO(TraverseStmt(C->getPriority()));
3923 return true;
3924}
3925
3926template <typename Derived>
3927bool RecursiveASTVisitor<Derived>::VisitOMPGrainsizeClause(
3928 OMPGrainsizeClause *C) {
3929 TRY_TO(VisitOMPClauseWithPreInit(C));
3930 TRY_TO(TraverseStmt(C->getGrainsize()));
3931 return true;
3932}
3933
3934template <typename Derived>
3935bool RecursiveASTVisitor<Derived>::VisitOMPNumTasksClause(
3936 OMPNumTasksClause *C) {
3937 TRY_TO(VisitOMPClauseWithPreInit(C));
3938 TRY_TO(TraverseStmt(C->getNumTasks()));
3939 return true;
3940}
3941
3942template <typename Derived>
3943bool RecursiveASTVisitor<Derived>::VisitOMPHintClause(OMPHintClause *C) {
3944 TRY_TO(TraverseStmt(C->getHint()));
3945 return true;
3946}
3947
3948template <typename Derived>
3949bool RecursiveASTVisitor<Derived>::VisitOMPDistScheduleClause(
3950 OMPDistScheduleClause *C) {
3951 TRY_TO(VisitOMPClauseWithPreInit(C));
3952 TRY_TO(TraverseStmt(C->getChunkSize()));
3953 return true;
3954}
3955
3956template <typename Derived>
3957bool
3958RecursiveASTVisitor<Derived>::VisitOMPDefaultmapClause(OMPDefaultmapClause *C) {
3959 return true;
3960}
3961
3962template <typename Derived>
3963bool RecursiveASTVisitor<Derived>::VisitOMPToClause(OMPToClause *C) {
3964 TRY_TO(VisitOMPClauseList(C));
3965 return true;
3966}
3967
3968template <typename Derived>
3969bool RecursiveASTVisitor<Derived>::VisitOMPFromClause(OMPFromClause *C) {
3970 TRY_TO(VisitOMPClauseList(C));
3971 return true;
3972}
3973
3974template <typename Derived>
3975bool RecursiveASTVisitor<Derived>::VisitOMPUseDevicePtrClause(
3976 OMPUseDevicePtrClause *C) {
3977 TRY_TO(VisitOMPClauseList(C));
3978 return true;
3979}
3980
3981template <typename Derived>
3982bool RecursiveASTVisitor<Derived>::VisitOMPUseDeviceAddrClause(
3983 OMPUseDeviceAddrClause *C) {
3984 TRY_TO(VisitOMPClauseList(C));
3985 return true;
3986}
3987
3988template <typename Derived>
3989bool RecursiveASTVisitor<Derived>::VisitOMPIsDevicePtrClause(
3990 OMPIsDevicePtrClause *C) {
3991 TRY_TO(VisitOMPClauseList(C));
3992 return true;
3993}
3994
3995template <typename Derived>
3996bool RecursiveASTVisitor<Derived>::VisitOMPHasDeviceAddrClause(
3997 OMPHasDeviceAddrClause *C) {
3998 TRY_TO(VisitOMPClauseList(C));
3999 return true;
4000}
4001
4002template <typename Derived>
4003bool RecursiveASTVisitor<Derived>::VisitOMPNontemporalClause(
4004 OMPNontemporalClause *C) {
4005 TRY_TO(VisitOMPClauseList(C));
4006 for (auto *E : C->private_refs()) {
4007 TRY_TO(TraverseStmt(E));
4008 }
4009 return true;
4010}
4011
4012template <typename Derived>
4013bool RecursiveASTVisitor<Derived>::VisitOMPOrderClause(OMPOrderClause *) {
4014 return true;
4015}
4016
4017template <typename Derived>
4018bool RecursiveASTVisitor<Derived>::VisitOMPDetachClause(OMPDetachClause *C) {
4019 TRY_TO(TraverseStmt(C->getEventHandler()));
4020 return true;
4021}
4022
4023template <typename Derived>
4024bool RecursiveASTVisitor<Derived>::VisitOMPUsesAllocatorsClause(
4025 OMPUsesAllocatorsClause *C) {
4026 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
4027 const OMPUsesAllocatorsClause::Data Data = C->getAllocatorData(I);
4028 TRY_TO(TraverseStmt(Data.Allocator));
4029 TRY_TO(TraverseStmt(Data.AllocatorTraits));
4030 }
4031 return true;
4032}
4033
4034template <typename Derived>
4035bool RecursiveASTVisitor<Derived>::VisitOMPAffinityClause(
4036 OMPAffinityClause *C) {
4037 TRY_TO(TraverseStmt(C->getModifier()));
4038 for (Expr *E : C->varlist())
4039 TRY_TO(TraverseStmt(E));
4040 return true;
4041}
4042
4043template <typename Derived>
4044bool RecursiveASTVisitor<Derived>::VisitOMPFilterClause(OMPFilterClause *C) {
4045 TRY_TO(VisitOMPClauseWithPreInit(C));
4046 TRY_TO(TraverseStmt(C->getThreadID()));
4047 return true;
4048}
4049
4050template <typename Derived>
4051bool RecursiveASTVisitor<Derived>::VisitOMPBindClause(OMPBindClause *C) {
4052 return true;
4053}
4054
4055template <typename Derived>
4056bool RecursiveASTVisitor<Derived>::VisitOMPXDynCGroupMemClause(
4057 OMPXDynCGroupMemClause *C) {
4058 TRY_TO(VisitOMPClauseWithPreInit(C));
4059 TRY_TO(TraverseStmt(C->getSize()));
4060 return true;
4061}
4062
4063template <typename Derived>
4064bool RecursiveASTVisitor<Derived>::VisitOMPDoacrossClause(
4065 OMPDoacrossClause *C) {
4066 TRY_TO(VisitOMPClauseList(C));
4067 return true;
4068}
4069
4070template <typename Derived>
4071bool RecursiveASTVisitor<Derived>::VisitOMPXAttributeClause(
4072 OMPXAttributeClause *C) {
4073 return true;
4074}
4075
4076template <typename Derived>
4077bool RecursiveASTVisitor<Derived>::VisitOMPXBareClause(OMPXBareClause *C) {
4078 return true;
4079}
4080
4081template <typename Derived>
4082bool RecursiveASTVisitor<Derived>::TraverseOpenACCConstructStmt(
4083 OpenACCConstructStmt *C) {
4084 TRY_TO(VisitOpenACCClauseList(C->clauses()));
4085 return true;
4086}
4087
4088template <typename Derived>
4089bool RecursiveASTVisitor<Derived>::TraverseOpenACCAssociatedStmtConstruct(
4090 OpenACCAssociatedStmtConstruct *S) {
4091 TRY_TO(TraverseOpenACCConstructStmt(S));
4092 TRY_TO(TraverseStmt(S->getAssociatedStmt()));
4093 return true;
4094}
4095
4096template <typename Derived>
4097bool RecursiveASTVisitor<Derived>::VisitOpenACCClause(const OpenACCClause *C) {
4098 for (const Stmt *Child : C->children())
4099 TRY_TO(TraverseStmt(const_cast<Stmt *>(Child)));
4100 return true;
4101}
4102
4103template <typename Derived>
4104bool RecursiveASTVisitor<Derived>::VisitOpenACCClauseList(
4105 ArrayRef<const OpenACCClause *> Clauses) {
4106
4107 for (const auto *C : Clauses)
4108 TRY_TO(VisitOpenACCClause(C));
4109 return true;
4110}
4111
4112DEF_TRAVERSE_STMT(OpenACCComputeConstruct,
4113 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4114DEF_TRAVERSE_STMT(OpenACCLoopConstruct,
4115 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4116DEF_TRAVERSE_STMT(OpenACCCombinedConstruct,
4117 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4118DEF_TRAVERSE_STMT(OpenACCDataConstruct,
4119 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4120DEF_TRAVERSE_STMT(OpenACCEnterDataConstruct,
4121 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4122DEF_TRAVERSE_STMT(OpenACCExitDataConstruct,
4123 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4124DEF_TRAVERSE_STMT(OpenACCHostDataConstruct,
4125 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4126DEF_TRAVERSE_STMT(OpenACCWaitConstruct, {
4127 if (S->hasDevNumExpr())
4128 TRY_TO(TraverseStmt(S->getDevNumExpr()));
4129 for (auto *E : S->getQueueIdExprs())
4130 TRY_TO(TraverseStmt(E));
4131 TRY_TO(VisitOpenACCClauseList(S->clauses()));
4132})
4133DEF_TRAVERSE_STMT(OpenACCInitConstruct,
4134 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4135DEF_TRAVERSE_STMT(OpenACCShutdownConstruct,
4136 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4137DEF_TRAVERSE_STMT(OpenACCSetConstruct,
4138 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4139DEF_TRAVERSE_STMT(OpenACCUpdateConstruct,
4140 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4141DEF_TRAVERSE_STMT(OpenACCAtomicConstruct,
4142 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4143DEF_TRAVERSE_STMT(OpenACCCacheConstruct, {
4144 for (auto *E : S->getVarList())
4145 TRY_TO(TraverseStmt(E));
4146})
4147
4148// Traverse HLSL: Out argument expression
4149DEF_TRAVERSE_STMT(HLSLOutArgExpr, {})
4150
4151// FIXME: look at the following tricky-seeming exprs to see if we
4152// need to recurse on anything. These are ones that have methods
4153// returning decls or qualtypes or nestednamespecifier -- though I'm
4154// not sure if they own them -- or just seemed very complicated, or
4155// had lots of sub-types to explore.
4156//
4157// VisitOverloadExpr and its children: recurse on template args? etc?
4158
4159// FIXME: go through all the stmts and exprs again, and see which of them
4160// create new types, and recurse on the types (TypeLocs?) of those.
4161// Candidates:
4162//
4163// http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html
4164// http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html
4165// http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html
4166// Every class that has getQualifier.
4167
4168#undef DEF_TRAVERSE_STMT
4169#undef TRAVERSE_STMT
4170#undef TRAVERSE_STMT_BASE
4171
4172#undef TRY_TO
4173
4174} // end namespace clang
4175
4176#endif // LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
4177

source code of clang/include/clang/AST/RecursiveASTVisitor.h