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