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