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