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