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