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