clang 23.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
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);
470 DEF_TRAVERSE_TMPL_INST(Function)
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) {
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(
553 return getDerived().TraverseConceptExprRequirement(
556 return getDerived().TraverseConceptNestedRequirement(
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>
592 if (!R->isExprSubstitutionFailure())
593 TRY_TO(TraverseStmt(R->getExpr()));
594 auto &RetReq = R->getReturnTypeRequirement();
595 if (RetReq.isTypeConstraint()) {
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>
616bool RecursiveASTVisitor<Derived>::PostVisitStmt(Stmt *S) {
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();
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).
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;
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>
833
834template <typename Derived>
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())
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)
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
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
1122DEF_TRAVERSE_TYPE(PackIndexingType, {
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})
1143DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType,
1144 { TRY_TO(TraverseSubstPackTypeHelper(T)); })
1145DEF_TRAVERSE_TYPE(SubstBuiltinTemplatePackType,
1146 { TRY_TO(TraverseSubstPackTypeHelper(T)); })
1147
1148DEF_TRAVERSE_TYPE(AttributedType,
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
1157DEF_TRAVERSE_TYPE(BTFTagAttributedType,
1158 { TRY_TO(TraverseType(T->getWrappedType())); })
1159
1160DEF_TRAVERSE_TYPE(OverflowBehaviorType,
1161 { TRY_TO(TraverseType(T->getUnderlyingType())); })
1162
1163DEF_TRAVERSE_TYPE(HLSLAttributedResourceType,
1164 { TRY_TO(TraverseType(T->getWrappedType())); })
1165
1166DEF_TRAVERSE_TYPE(HLSLInlineSpirvType, {
1167 for (auto &Operand : T->getOperands()) {
1168 if (Operand.isConstant() || Operand.isType()) {
1169 TRY_TO(TraverseType(Operand.getResultType()));
1170 }
1171 }
1172})
1173
1174DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
1175
1177 { TRY_TO(TraverseType(T->getUnderlyingType())); })
1178
1179template <typename Derived>
1180bool RecursiveASTVisitor<Derived>::TraverseTagType(TagType *T,
1181 bool TraverseQualifier) {
1182 if (TraverseQualifier)
1183 TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
1184 return true;
1185}
1186
1187DEF_TRAVERSE_TYPE(EnumType, { TRY_TO(TraverseTagType(T, TraverseQualifier)); })
1188DEF_TRAVERSE_TYPE(RecordType,
1189 { TRY_TO(TraverseTagType(T, TraverseQualifier)); })
1190DEF_TRAVERSE_TYPE(InjectedClassNameType,
1191 { TRY_TO(TraverseTagType(T, TraverseQualifier)); })
1192
1193DEF_TRAVERSE_TYPE(DependentNameType, {
1194 if (TraverseQualifier)
1195 TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
1196})
1197
1198DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
1199 if (TraverseQualifier) {
1200 TRY_TO(TraverseTemplateName(T->getTemplateName()));
1201 } else {
1202 // FIXME: Try to preserve the rest of the template name.
1203 TRY_TO(TraverseTemplateName(TemplateName(
1204 T->getTemplateName().getAsTemplateDecl(/*IgnoreDeduced=*/true))));
1205 }
1206 TRY_TO(TraverseTemplateArguments(T->template_arguments()));
1207})
1208
1209DEF_TRAVERSE_TYPE(DeducedTemplateSpecializationType, {
1210 if (TraverseQualifier) {
1211 TRY_TO(TraverseTemplateName(T->getTemplateName()));
1212 } else {
1213 // FIXME: Try to preserve the rest of the template name.
1214 TRY_TO(TraverseTemplateName(TemplateName(
1215 T->getTemplateName().getAsTemplateDecl(/*IgnoreDeduced=*/true))));
1216 }
1217 TRY_TO(TraverseType(T->getDeducedType()));
1218})
1219
1220DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); })
1221
1222DEF_TRAVERSE_TYPE(ObjCTypeParamType, {})
1223
1225
1226DEF_TRAVERSE_TYPE(ObjCObjectType, {
1227 // We have to watch out here because an ObjCInterfaceType's base
1228 // type is itself.
1229 if (T->getBaseType().getTypePtr() != T)
1230 TRY_TO(TraverseType(T->getBaseType()));
1231 for (auto typeArg : T->getTypeArgsAsWritten()) {
1232 TRY_TO(TraverseType(typeArg));
1233 }
1234})
1235
1237 { TRY_TO(TraverseType(T->getPointeeType())); })
1238
1239DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); })
1240
1241DEF_TRAVERSE_TYPE(PipeType, { TRY_TO(TraverseType(T->getElementType())); })
1242
1245 { TRY_TO(TraverseStmt(T->getNumBitsExpr())); })
1246
1248
1249#undef DEF_TRAVERSE_TYPE
1250
1251// ----------------- TypeLoc traversal -----------------
1252
1253// This macro makes available a variable TL, the passed-in TypeLoc.
1254// If requested, it calls WalkUpFrom* for the Type in the given TypeLoc,
1255// in addition to WalkUpFrom* for the TypeLoc itself, such that existing
1256// clients that override the WalkUpFrom*Type() and/or Visit*Type() methods
1257// continue to work.
1258#define DEF_TRAVERSE_TYPELOC(TYPE, CODE) \
1259 template <typename Derived> \
1261 TYPE##Loc TL, bool TraverseQualifier) { \
1262 if (!getDerived().shouldTraversePostOrder()) { \
1263 TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
1264 if (getDerived().shouldWalkTypesOfTypeLocs()) \
1265 TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \
1266 } \
1267 { \
1268 CODE; \
1269 } \
1270 if (getDerived().shouldTraversePostOrder()) { \
1271 TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
1272 if (getDerived().shouldWalkTypesOfTypeLocs()) \
1273 TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \
1274 } \
1275 return true; \
1276 }
1277
1278template <typename Derived>
1280 QualifiedTypeLoc TL, bool TraverseQualifier) {
1281 assert(TraverseQualifier &&
1282 "Qualifiers should never occur within NestedNameSpecifiers");
1283 // Move this over to the 'main' typeloc tree. Note that this is a
1284 // move -- we pretend that we were really looking at the unqualified
1285 // typeloc all along -- rather than a recursion, so we don't follow
1286 // the normal CRTP plan of going through
1287 // getDerived().TraverseTypeLoc. If we did, we'd be traversing
1288 // twice for the same type (once as a QualifiedTypeLoc version of
1289 // the type, once as an UnqualifiedTypeLoc version of the type),
1290 // which in effect means we'd call VisitTypeLoc twice with the
1291 // 'same' type. This solves that problem, at the cost of never
1292 // seeing the qualified version of the type (unless the client
1293 // subclasses TraverseQualifiedTypeLoc themselves). It's not a
1294 // perfect solution. A perfect solution probably requires making
1295 // QualifiedTypeLoc a wrapper around TypeLoc -- like QualType is a
1296 // wrapper around Type* -- rather than being its own class in the
1297 // type hierarchy.
1298 return TraverseTypeLoc(TL.getUnqualifiedLoc());
1299}
1300
1302
1303// FIXME: ComplexTypeLoc is unfinished
1305 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1306})
1307
1309 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1310
1312 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1313
1315 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1316
1318 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1319
1320// We traverse this in the type case as well, but how is it not reached through
1321// the pointee type?
1323 if (NestedNameSpecifierLoc QL = TL.getQualifierLoc())
1325 else
1326 TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
1327 TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
1328})
1329
1331 { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
1332
1334 { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
1335
1336template <typename Derived>
1337bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
1338 // This isn't available for ArrayType, but is for the ArrayTypeLoc.
1339 TRY_TO(TraverseStmt(TL.getSizeExpr()));
1340 return true;
1341}
1342
1344 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1345 TRY_TO(TraverseArrayTypeLocHelper(TL));
1346})
1347
1349 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1350 TRY_TO(TraverseArrayTypeLocHelper(TL));
1351})
1352
1354 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1355 TRY_TO(TraverseArrayTypeLocHelper(TL));
1356})
1357
1359 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1360 TRY_TO(TraverseArrayTypeLocHelper(TL));
1361})
1362
1364 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1365 TRY_TO(TraverseArrayTypeLocHelper(TL));
1366})
1367
1369 TRY_TO(TraverseStmt(TL.getTypePtr()->getAddrSpaceExpr()));
1370 TRY_TO(TraverseType(TL.getTypePtr()->getPointeeType()));
1371})
1372
1373// FIXME: order? why not size expr first?
1374// FIXME: base VectorTypeLoc is unfinished
1376 if (TL.getTypePtr()->getSizeExpr())
1377 TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
1378 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1379})
1380
1381// FIXME: VectorTypeLoc is unfinished
1383 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1384})
1385
1387 if (TL.getTypePtr()->getSizeExpr())
1388 TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
1389 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1390})
1391
1392// FIXME: size and attributes
1393// FIXME: base VectorTypeLoc is unfinished
1395 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1396})
1397
1399 TRY_TO(TraverseStmt(TL.getAttrRowOperand()));
1400 TRY_TO(TraverseStmt(TL.getAttrColumnOperand()));
1401 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1402})
1403
1405 TRY_TO(TraverseStmt(TL.getAttrRowOperand()));
1406 TRY_TO(TraverseStmt(TL.getAttrColumnOperand()));
1407 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1408})
1409
1411 { TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); })
1412
1413// FIXME: location of exception specifications (attributes?)
1415 TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
1416
1417 const FunctionProtoType *T = TL.getTypePtr();
1418
1419 for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) {
1420 if (TL.getParam(I)) {
1421 TRY_TO(TraverseDecl(TL.getParam(I)));
1422 } else if (I < T->getNumParams()) {
1423 TRY_TO(TraverseType(T->getParamType(I)));
1424 }
1425 }
1426
1427 for (const auto &E : T->exceptions()) {
1428 TRY_TO(TraverseType(E));
1429 }
1430
1431 if (Expr *NE = T->getNoexceptExpr())
1432 TRY_TO(TraverseStmt(NE));
1433})
1434
1436 if (NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
1437 TraverseQualifier && QualifierLoc)
1439})
1441 if (NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
1442 TraverseQualifier && QualifierLoc)
1444})
1446 if (NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
1447 TraverseQualifier && QualifierLoc)
1449})
1450
1452 { TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); })
1453
1454DEF_TRAVERSE_TYPELOC(TypeOfType, {
1455 TRY_TO(TraverseTypeLoc(TL.getUnmodifiedTInfo()->getTypeLoc()));
1456})
1457
1458// FIXME: location of underlying expr
1459DEF_TRAVERSE_TYPELOC(DecltypeType, {
1460 TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
1461})
1462
1463DEF_TRAVERSE_TYPELOC(PackIndexingType, {
1464 TRY_TO(TraverseType(TL.getPattern()));
1465 TRY_TO(TraverseStmt(TL.getTypePtr()->getIndexExpr()));
1466})
1467
1468DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
1469 TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
1470})
1471
1472DEF_TRAVERSE_TYPELOC(AutoType, {
1473 TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
1474 if (TL.isConstrained()) {
1475 TRY_TO(TraverseConceptReference(TL.getConceptReference()));
1476 }
1477})
1478
1479DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {})
1480DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, {
1481 TRY_TO(TraverseType(TL.getTypePtr()->getReplacementType()));
1482})
1483
1484template <typename Derived>
1485bool RecursiveASTVisitor<Derived>::TraverseSubstPackTypeLocHelper(
1486 SubstPackTypeLoc TL) {
1487 TRY_TO(TraverseTemplateArgument(TL.getTypePtr()->getArgumentPack()));
1488 return true;
1489}
1490
1491template <typename Derived>
1492bool RecursiveASTVisitor<Derived>::TraverseSubstPackTypeHelper(
1493 SubstPackType *T) {
1494 TRY_TO(TraverseTemplateArgument(T->getArgumentPack()));
1495 return true;
1496}
1497
1498DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType,
1499 { TRY_TO(TraverseSubstPackTypeLocHelper(TL)); })
1500
1501DEF_TRAVERSE_TYPELOC(SubstBuiltinTemplatePackType,
1502 { TRY_TO(TraverseSubstPackTypeLocHelper(TL)); })
1503
1504DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
1505
1507 { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
1508
1509DEF_TRAVERSE_TYPELOC(AttributedType,
1510 { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
1511
1513 { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
1514
1515DEF_TRAVERSE_TYPELOC(BTFTagAttributedType,
1516 { TRY_TO(TraverseTypeLoc(TL.getWrappedLoc())); })
1517
1518DEF_TRAVERSE_TYPELOC(OverflowBehaviorType,
1519 { TRY_TO(TraverseTypeLoc(TL.getWrappedLoc())); })
1520
1521DEF_TRAVERSE_TYPELOC(HLSLAttributedResourceType,
1522 { TRY_TO(TraverseTypeLoc(TL.getWrappedLoc())); })
1523
1524DEF_TRAVERSE_TYPELOC(HLSLInlineSpirvType,
1525 { TRY_TO(TraverseType(TL.getType())); })
1526
1527template <typename Derived>
1528bool RecursiveASTVisitor<Derived>::TraverseTagTypeLoc(TagTypeLoc TL,
1529 bool TraverseQualifier) {
1530 if (NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
1531 TraverseQualifier && QualifierLoc)
1533 return true;
1534}
1535
1536DEF_TRAVERSE_TYPELOC(EnumType,
1537 { TRY_TO(TraverseTagTypeLoc(TL, TraverseQualifier)); })
1538DEF_TRAVERSE_TYPELOC(RecordType,
1539 { TRY_TO(TraverseTagTypeLoc(TL, TraverseQualifier)); })
1540DEF_TRAVERSE_TYPELOC(InjectedClassNameType,
1541 { TRY_TO(TraverseTagTypeLoc(TL, TraverseQualifier)); })
1542
1543DEF_TRAVERSE_TYPELOC(DependentNameType, {
1544 if (TraverseQualifier)
1545 TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
1546})
1547
1548DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
1549 if (TraverseQualifier)
1550 TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
1551
1552 // FIXME: Try to preserve the rest of the template name.
1553 TRY_TO(TraverseTemplateName(
1554 TemplateName(TL.getTypePtr()->getTemplateName().getAsTemplateDecl(
1555 /*IgnoreDeduced=*/true))));
1556
1557 for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
1558 TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
1559 }
1560})
1561
1562DEF_TRAVERSE_TYPELOC(DeducedTemplateSpecializationType, {
1563 if (TraverseQualifier)
1564 TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
1565
1566 const auto *T = TL.getTypePtr();
1567 // FIXME: Try to preserve the rest of the template name.
1568 TRY_TO(
1569 TraverseTemplateName(TemplateName(T->getTemplateName().getAsTemplateDecl(
1570 /*IgnoreDeduced=*/true))));
1571
1572 TRY_TO(TraverseType(T->getDeducedType()));
1573})
1574
1575DEF_TRAVERSE_TYPELOC(PackExpansionType,
1576 { TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); })
1577
1578DEF_TRAVERSE_TYPELOC(ObjCTypeParamType, {
1579 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1580 ObjCProtocolLoc ProtocolLoc(TL.getProtocol(I), TL.getProtocolLoc(I));
1581 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1582 }
1583})
1584
1586
1587DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
1588 // We have to watch out here because an ObjCInterfaceType's base
1589 // type is itself.
1590 if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
1591 TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
1592 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
1593 TRY_TO(TraverseTypeLoc(TL.getTypeArgTInfo(i)->getTypeLoc()));
1594 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1595 ObjCProtocolLoc ProtocolLoc(TL.getProtocol(I), TL.getProtocolLoc(I));
1596 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1597 }
1598})
1599
1601 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1602
1603DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
1604
1605DEF_TRAVERSE_TYPELOC(PipeType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
1606
1609 TRY_TO(TraverseStmt(TL.getTypePtr()->getNumBitsExpr()));
1610})
1611
1613
1615
1616// ----------------- Decl traversal -----------------
1617//
1618// For a Decl, we automate (in the DEF_TRAVERSE_DECL macro) traversing
1619// the children that come from the DeclContext associated with it.
1620// Therefore each Traverse* only needs to worry about children other
1621// than those.
1622
1623template <typename Derived>
1625 const Decl *Child) {
1626 // BlockDecls are traversed through BlockExprs,
1627 // CapturedDecls are traversed through CapturedStmts.
1628 if (isa<BlockDecl>(Child) || isa<CapturedDecl>(Child))
1629 return true;
1630 // Lambda classes are traversed through LambdaExprs.
1631 if (const CXXRecordDecl* Cls = dyn_cast<CXXRecordDecl>(Child))
1632 return Cls->isLambda();
1633 return false;
1634}
1635
1636template <typename Derived>
1637bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
1638 if (!DC)
1639 return true;
1640
1641 for (auto *Child : DC->decls()) {
1642 if (!canIgnoreChildDeclWhileTraversingDeclContext(Child))
1643 TRY_TO(TraverseDecl(Child));
1644 }
1645
1646 return true;
1647}
1648
1649// This macro makes available a variable D, the passed-in decl.
1650#define DEF_TRAVERSE_DECL(DECL, CODE) \
1651 template <typename Derived> \
1652 bool RecursiveASTVisitor<Derived>::Traverse##DECL(DECL *D) { \
1653 bool ShouldVisitChildren = true; \
1654 bool ReturnValue = true; \
1655 if (!getDerived().shouldTraversePostOrder()) \
1656 TRY_TO(WalkUpFrom##DECL(D)); \
1657 { CODE; } \
1658 if (ReturnValue && ShouldVisitChildren) \
1659 TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D))); \
1660 if (ReturnValue) { \
1661 /* Visit any attributes attached to this declaration. */ \
1662 for (auto *I : D->attrs()) \
1663 TRY_TO(getDerived().TraverseAttr(I)); \
1664 } \
1665 if (ReturnValue && getDerived().shouldTraversePostOrder()) \
1666 TRY_TO(WalkUpFrom##DECL(D)); \
1667 return ReturnValue; \
1668 }
1669
1671
1673 if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
1674 TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
1675 TRY_TO(TraverseStmt(D->getBody()));
1676 for (const auto &I : D->captures()) {
1677 if (I.hasCopyExpr()) {
1678 TRY_TO(TraverseStmt(I.getCopyExpr()));
1679 }
1680 }
1681 ShouldVisitChildren = false;
1682})
1683
1685 TRY_TO(TraverseStmt(D->getBody()));
1686 ShouldVisitChildren = false;
1687})
1688
1690 TRY_TO(TraverseStmt(D->getBody()));
1691 ShouldVisitChildren = false;
1692})
1693
1695
1697
1699
1701 TRY_TO(TraverseStmt(D->getTemporaryExpr()));
1702})
1703
1705 { TRY_TO(TraverseStmt(D->getAsmStringExpr())); })
1706
1707DEF_TRAVERSE_DECL(TopLevelStmtDecl, { TRY_TO(TraverseStmt(D->getStmt())); })
1708
1710
1712 // Friend is either decl or a type.
1713 if (D->getFriendType()) {
1714 TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
1715 // Traverse any CXXRecordDecl owned by this type, since
1716 // it will not be in the parent context:
1717 if (auto *TT = D->getFriendType()->getType()->getAs<TagType>();
1718 TT && TT->isTagOwned())
1719 TRY_TO(TraverseDecl(TT->getDecl()));
1720 } else {
1721 TRY_TO(TraverseDecl(D->getFriendDecl()));
1722 }
1723})
1724
1726 if (D->getFriendType())
1727 TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
1728 else
1729 TRY_TO(TraverseDecl(D->getFriendDecl()));
1730 for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
1731 TemplateParameterList *TPL = D->getTemplateParameterList(I);
1732 for (TemplateParameterList::iterator ITPL = TPL->begin(), ETPL = TPL->end();
1733 ITPL != ETPL; ++ITPL) {
1734 TRY_TO(TraverseDecl(*ITPL));
1735 }
1736 }
1737})
1738
1740
1742
1743DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {// FIXME: implement this
1744 })
1745
1747 TRY_TO(TraverseStmt(D->getAssertExpr()));
1748 TRY_TO(TraverseStmt(D->getMessage()));
1749})
1750
1752 // Code in an unnamed namespace shows up automatically in
1753 // decls_begin()/decls_end(). Thus we don't need to recurse on
1754 // D->getAnonymousNamespace().
1755
1756 // If the traversal scope is set, then consider them to be the children of
1757 // the TUDecl, rather than traversing (and loading?) all top-level decls.
1758 auto Scope = D->getASTContext().getTraversalScope();
1759 bool HasLimitedScope =
1760 Scope.size() != 1 || !isa<TranslationUnitDecl>(Scope.front());
1761 if (HasLimitedScope) {
1762 ShouldVisitChildren = false; // we'll do that here instead
1763 for (auto *Child : Scope) {
1764 if (!canIgnoreChildDeclWhileTraversingDeclContext(Child))
1765 TRY_TO(TraverseDecl(Child));
1766 }
1767 }
1768})
1769
1771
1773
1775
1777 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1778
1779 // We shouldn't traverse an aliased namespace, since it will be
1780 // defined (and, therefore, traversed) somewhere else.
1781 ShouldVisitChildren = false;
1782})
1783
1784DEF_TRAVERSE_DECL(LabelDecl, {// There is no code in a LabelDecl.
1785 })
1786
1789 {// Code in an unnamed namespace shows up automatically in
1790 // decls_begin()/decls_end(). Thus we don't need to recurse on
1791 // D->getAnonymousNamespace().
1792 })
1793
1794DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement
1795 })
1796
1798 if (ObjCTypeParamList *typeParamList = D->getTypeParamList()) {
1799 for (auto typeParam : *typeParamList) {
1800 TRY_TO(TraverseObjCTypeParamDecl(typeParam));
1801 }
1802 }
1803 for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
1804 ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
1805 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1806 }
1807})
1808
1809DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement
1810 })
1811
1812DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement
1813 })
1814
1816 if (ObjCTypeParamList *typeParamList = D->getTypeParamListAsWritten()) {
1817 for (auto typeParam : *typeParamList) {
1818 TRY_TO(TraverseObjCTypeParamDecl(typeParam));
1819 }
1820 }
1821
1822 if (TypeSourceInfo *superTInfo = D->getSuperClassTInfo()) {
1823 TRY_TO(TraverseTypeLoc(superTInfo->getTypeLoc()));
1824 }
1825 if (D->isThisDeclarationADefinition()) {
1826 for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
1827 ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
1828 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1829 }
1830 }
1831})
1832
1834 if (D->isThisDeclarationADefinition()) {
1835 for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
1836 ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
1837 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1838 }
1839 }
1840})
1841
1843 if (D->getReturnTypeSourceInfo()) {
1844 TRY_TO(TraverseTypeLoc(D->getReturnTypeSourceInfo()->getTypeLoc()));
1845 }
1846 for (ParmVarDecl *Parameter : D->parameters()) {
1847 TRY_TO(TraverseDecl(Parameter));
1848 }
1849 if (D->isThisDeclarationADefinition()) {
1850 TRY_TO(TraverseStmt(D->getBody()));
1851 }
1852 ShouldVisitChildren = false;
1853})
1854
1856 if (D->hasExplicitBound()) {
1857 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
1858 // We shouldn't traverse D->getTypeForDecl(); it's a result of
1859 // declaring the type alias, not something that was written in the
1860 // source.
1861 }
1862})
1863
1865 if (D->getTypeSourceInfo())
1866 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
1867 else
1868 TRY_TO(TraverseType(D->getType()));
1869 ShouldVisitChildren = false;
1870})
1871
1873 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1874 TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
1875})
1876
1878 { TRY_TO(TraverseTypeLoc(D->getEnumTypeLoc())); })
1879
1881
1883 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1884})
1885
1887
1889
1891 for (auto *I : D->varlist()) {
1892 TRY_TO(TraverseStmt(I));
1893 }
1894})
1895
1897 for (auto *I : D->varlist()) {
1898 TRY_TO(TraverseStmt(I));
1899 }
1900})
1901
1903 for (auto *C : D->clauselists()) {
1904 TRY_TO(TraverseOMPClause(C));
1905 }
1906})
1907
1909 TRY_TO(TraverseStmt(D->getCombiner()));
1910 if (auto *Initializer = D->getInitializer())
1911 TRY_TO(TraverseStmt(Initializer));
1912 TRY_TO(TraverseType(D->getType()));
1913 return true;
1914})
1915
1917 for (auto *C : D->clauselists())
1918 TRY_TO(TraverseOMPClause(C));
1919 TRY_TO(TraverseType(D->getType()));
1920 return true;
1921})
1922
1923DEF_TRAVERSE_DECL(OMPCapturedExprDecl, { TRY_TO(TraverseVarHelper(D)); })
1924
1926 for (auto *I : D->varlist())
1927 TRY_TO(TraverseStmt(I));
1928 for (auto *C : D->clauselists())
1929 TRY_TO(TraverseOMPClause(C));
1930})
1931
1933 { TRY_TO(VisitOpenACCClauseList(D->clauses())); })
1934
1936 TRY_TO(TraverseStmt(D->getFunctionReference()));
1937 TRY_TO(VisitOpenACCClauseList(D->clauses()));
1938})
1939
1940// A helper method for TemplateDecl's children.
1941template <typename Derived>
1942bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
1943 TemplateParameterList *TPL) {
1944 if (TPL) {
1945 for (NamedDecl *D : *TPL) {
1946 TRY_TO(TraverseDecl(D));
1947 }
1948 if (Expr *RequiresClause = TPL->getRequiresClause()) {
1949 TRY_TO(TraverseStmt(RequiresClause));
1950 }
1951 }
1952 return true;
1953}
1954
1955template <typename Derived>
1956template <typename T>
1957bool RecursiveASTVisitor<Derived>::TraverseDeclTemplateParameterLists(T *D) {
1958 for (unsigned i = 0; i < D->getNumTemplateParameterLists(); i++) {
1959 TemplateParameterList *TPL = D->getTemplateParameterList(i);
1960 TraverseTemplateParameterListHelper(TPL);
1961 }
1962 return true;
1963}
1964
1965template <typename Derived>
1967 ClassTemplateDecl *D) {
1968 for (auto *SD : D->specializations()) {
1969 for (auto *RD : SD->redecls()) {
1970 assert(!cast<CXXRecordDecl>(RD)->isInjectedClassName());
1971 switch (
1972 cast<ClassTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
1973 // Visit the implicit instantiations with the requested pattern.
1974 case TSK_Undeclared:
1976 TRY_TO(TraverseDecl(RD));
1977 break;
1978
1979 // We don't need to do anything on an explicit instantiation
1980 // or explicit specialization because there will be an explicit
1981 // node for it elsewhere.
1985 break;
1986 }
1987 }
1988 }
1989
1990 return true;
1991}
1992
1993template <typename Derived>
1995 VarTemplateDecl *D) {
1996 for (auto *SD : D->specializations()) {
1997 for (auto *RD : SD->redecls()) {
1998 switch (
1999 cast<VarTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
2000 case TSK_Undeclared:
2002 TRY_TO(TraverseDecl(RD));
2003 break;
2004
2008 break;
2009 }
2010 }
2011 }
2012
2013 return true;
2014}
2015
2016// A helper method for traversing the instantiations of a
2017// function while skipping its specializations.
2018template <typename Derived>
2021 for (auto *FD : D->specializations()) {
2022 for (auto *RD : FD->redecls()) {
2023 switch (RD->getTemplateSpecializationKind()) {
2024 case TSK_Undeclared:
2026 // We don't know what kind of FunctionDecl this is.
2027 TRY_TO(TraverseDecl(RD));
2028 break;
2029
2030 // FIXME: For now traverse explicit instantiations here. Change that
2031 // once they are represented as dedicated nodes in the AST.
2034 TRY_TO(TraverseDecl(RD));
2035 break;
2036
2038 break;
2039 }
2040 }
2041 }
2042
2043 return true;
2044}
2045
2046// This macro unifies the traversal of class, variable and function
2047// template declarations.
2048#define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND) \
2049 DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, { \
2050 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
2051 TRY_TO(TraverseDecl(D->getTemplatedDecl())); \
2052 \
2053 /* By default, we do not traverse the instantiations of \
2054 class templates since they do not appear in the user code. The \
2055 following code optionally traverses them. \
2056 \
2057 We only traverse the class instantiations when we see the canonical \
2058 declaration of the template, to ensure we only visit them once. */ \
2059 if (getDerived().shouldVisitTemplateInstantiations() && \
2060 D == D->getCanonicalDecl()) \
2061 TRY_TO(TraverseTemplateInstantiations(D)); \
2062 \
2063 /* Note that getInstantiatedFromMemberTemplate() is just a link \
2064 from a template instantiation back to the template from which \
2065 it was instantiated, and thus should not be traversed. */ \
2066 })
2067
2071
2073 // D is the "T" in something like
2074 // template <template <typename> class T> class container { };
2075 TRY_TO(TraverseDecl(D->getTemplatedDecl()));
2076 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
2077 TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
2078 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
2079})
2080
2082 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
2083})
2084
2085template <typename Derived>
2086bool RecursiveASTVisitor<Derived>::TraverseTemplateTypeParamDeclConstraints(
2087 const TemplateTypeParmDecl *D) {
2088 if (const auto *TC = D->getTypeConstraint())
2089 TRY_TO(TraverseTypeConstraint(TC));
2090 return true;
2091}
2092
2094 // D is the "T" in something like "template<typename T> class vector;"
2095 if (D->getTypeForDecl())
2096 TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
2097 TRY_TO(TraverseTemplateTypeParamDeclConstraints(D));
2098 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
2099 TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
2100})
2101
2103 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
2104 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2105 // declaring the typedef, not something that was written in the
2106 // source.
2107})
2108
2110 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
2111 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2112 // declaring the type alias, not something that was written in the
2113 // source.
2114})
2115
2117 TRY_TO(TraverseDecl(D->getTemplatedDecl()));
2118 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
2119})
2120
2122 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
2123 TRY_TO(TraverseStmt(D->getConstraintExpr()));
2124})
2125
2127 // A dependent using declaration which was marked with 'typename'.
2128 // template<class T> class A : public B<T> { using typename B<T>::foo; };
2129 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2130 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2131 // declaring the type, not something that was written in the
2132 // source.
2133})
2134
2136
2138 TRY_TO(TraverseDeclTemplateParameterLists(D));
2139
2140 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2141 if (auto *TSI = D->getIntegerTypeSourceInfo())
2142 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
2143 // The enumerators are already traversed by
2144 // decls_begin()/decls_end().
2145})
2146
2147// Helper methods for RecordDecl and its children.
2148template <typename Derived>
2149bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) {
2150 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2151 // declaring the type, not something that was written in the source.
2152
2153 TRY_TO(TraverseDeclTemplateParameterLists(D));
2154 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2155 return true;
2156}
2157
2158template <typename Derived>
2160 const CXXBaseSpecifier &Base) {
2161 TRY_TO(TraverseTypeLoc(Base.getTypeSourceInfo()->getTypeLoc()));
2162 return true;
2163}
2164
2165template <typename Derived>
2166bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(CXXRecordDecl *D) {
2167 if (!TraverseRecordHelper(D))
2168 return false;
2169 if (D->isCompleteDefinition()) {
2170 for (const auto &I : D->bases()) {
2171 TRY_TO(TraverseCXXBaseSpecifier(I));
2172 }
2173 // We don't traverse the friends or the conversions, as they are
2174 // already in decls_begin()/decls_end().
2175 }
2176 return true;
2177}
2178
2179DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); })
2180
2181DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
2182
2183template <typename Derived>
2184bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
2185 const TemplateArgumentLoc *TAL, unsigned Count) {
2186 for (unsigned I = 0; I < Count; ++I) {
2187 TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
2188 }
2189 return true;
2190}
2191
2192#define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
2193 DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, { \
2194 /* For implicit instantiations ("set<int> x;"), we don't want to \
2195 recurse at all, since the instatiated template isn't written in \
2196 the source code anywhere. (Note the instatiated *type* -- \
2197 set<int> -- is written, and will still get a callback of \
2198 TemplateSpecializationType). For explicit instantiations \
2199 ("template set<int>;"), we do need a callback, since this \
2200 is the only callback that's made for this instantiation. \
2201 We use getTemplateArgsAsWritten() to distinguish. */ \
2202 if (const auto *ArgsWritten = D->getTemplateArgsAsWritten()) { \
2203 assert(D->getTemplateSpecializationKind() != TSK_ImplicitInstantiation); \
2204 /* The args that remains unspecialized. */ \
2205 TRY_TO(TraverseTemplateArgumentLocsHelper( \
2206 ArgsWritten->getTemplateArgs(), ArgsWritten->NumTemplateArgs)); \
2207 } \
2208 \
2209 if (getDerived().shouldVisitTemplateInstantiations() || \
2210 D->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) { \
2211 /* Traverse base definition for explicit specializations */ \
2212 TRY_TO(Traverse##DECLKIND##Helper(D)); \
2213 } else { \
2214 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); \
2215 \
2216 /* Returning from here skips traversing the \
2217 declaration context of the *TemplateSpecializationDecl \
2218 (embedded in the DEF_TRAVERSE_DECL() macro) \
2219 which contains the instantiated members of the template. */ \
2220 return true; \
2221 } \
2222 })
2223
2226
2227#define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
2228 DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, { \
2229 /* The partial specialization. */ \
2230 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
2231 /* The args that remains unspecialized. */ \
2232 TRY_TO(TraverseTemplateArgumentLocsHelper( \
2233 D->getTemplateArgsAsWritten()->getTemplateArgs(), \
2234 D->getTemplateArgsAsWritten()->NumTemplateArgs)); \
2235 \
2236 /* Don't need the *TemplatePartialSpecializationHelper, even \
2237 though that's our parent class -- we already visit all the \
2238 template args here. */ \
2239 TRY_TO(Traverse##DECLKIND##Helper(D)); \
2240 \
2241 /* Instantiations will have been visited with the primary template. */ \
2242 })
2243
2246
2247DEF_TRAVERSE_DECL(EnumConstantDecl, { TRY_TO(TraverseStmt(D->getInitExpr())); })
2248
2250 // Like UnresolvedUsingTypenameDecl, but without the 'typename':
2251 // template <class T> Class A : public Base<T> { using Base<T>::foo; };
2252 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2253 TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
2254})
2255
2257
2258template <typename Derived>
2259bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
2260 TRY_TO(TraverseDeclTemplateParameterLists(D));
2261 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2262 if (D->getTypeSourceInfo())
2263 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
2264 else
2265 TRY_TO(TraverseType(D->getType()));
2266 return true;
2267}
2268
2270 TRY_TO(TraverseVarHelper(D));
2271 for (auto *Binding : D->bindings()) {
2272 TRY_TO(TraverseDecl(Binding));
2273 }
2274})
2275
2277 if (getDerived().shouldVisitImplicitCode()) {
2278 TRY_TO(TraverseStmt(D->getBinding()));
2279 if (const auto HoldingVar = D->getHoldingVar())
2280 TRY_TO(TraverseDecl(HoldingVar));
2281 }
2282})
2283
2284DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
2285
2288
2290
2292 TRY_TO(TraverseDeclaratorHelper(D));
2293 if (D->isBitField())
2294 TRY_TO(TraverseStmt(D->getBitWidth()));
2295 if (D->hasInClassInitializer())
2296 TRY_TO(TraverseStmt(D->getInClassInitializer()));
2297})
2298
2300 TRY_TO(TraverseDeclaratorHelper(D));
2301 if (D->isBitField())
2302 TRY_TO(TraverseStmt(D->getBitWidth()));
2303 // FIXME: implement the rest.
2304})
2305
2307 TRY_TO(TraverseDeclaratorHelper(D));
2308 if (D->isBitField())
2309 TRY_TO(TraverseStmt(D->getBitWidth()));
2310 // FIXME: implement the rest.
2311})
2312
2313template <typename Derived>
2314bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
2315 TRY_TO(TraverseDeclTemplateParameterLists(D));
2316 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2317 TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
2318
2319 // If we're an explicit template specialization, iterate over the
2320 // template args that were explicitly specified. If we were doing
2321 // this in typing order, we'd do it between the return type and
2322 // the function args, but both are handled by the FunctionTypeLoc
2323 // above, so we have to choose one side. I've decided to do before.
2324 if (const FunctionTemplateSpecializationInfo *FTSI =
2325 D->getTemplateSpecializationInfo()) {
2326 if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared &&
2327 FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
2328 // A specialization might not have explicit template arguments if it has
2329 // a templated return type and concrete arguments.
2330 if (const ASTTemplateArgumentListInfo *TALI =
2331 FTSI->TemplateArgumentsAsWritten) {
2332 TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
2333 TALI->NumTemplateArgs));
2334 }
2335 }
2336 } else if (const DependentFunctionTemplateSpecializationInfo *DFSI =
2337 D->getDependentSpecializationInfo()) {
2338 if (const ASTTemplateArgumentListInfo *TALI =
2339 DFSI->TemplateArgumentsAsWritten) {
2340 TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
2341 TALI->NumTemplateArgs));
2342 }
2343 }
2344
2345 // Visit the function type itself, which can be either
2346 // FunctionNoProtoType or FunctionProtoType, or a typedef. This
2347 // also covers the return type and the function parameters,
2348 // including exception specifications.
2349 if (TypeSourceInfo *TSI = D->getTypeSourceInfo()) {
2350 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
2351 } else if (getDerived().shouldVisitImplicitCode()) {
2352 // Visit parameter variable declarations of the implicit function
2353 // if the traverser is visiting implicit code. Parameter variable
2354 // declarations do not have valid TypeSourceInfo, so to visit them
2355 // we need to traverse the declarations explicitly.
2356 for (ParmVarDecl *Parameter : D->parameters()) {
2357 TRY_TO(TraverseDecl(Parameter));
2358 }
2359 }
2360
2361 // Visit the trailing requires clause, if any.
2362 if (const AssociatedConstraint &TrailingRequiresClause =
2363 D->getTrailingRequiresClause()) {
2364 TRY_TO(TraverseStmt(
2365 const_cast<Expr *>(TrailingRequiresClause.ConstraintExpr)));
2366 }
2367
2368 if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
2369 // Constructor initializers.
2370 for (auto *I : Ctor->inits()) {
2371 if (I->isWritten() || getDerived().shouldVisitImplicitCode())
2372 TRY_TO(TraverseConstructorInitializer(I));
2373 }
2374 }
2375
2376 bool VisitBody =
2377 D->isThisDeclarationADefinition() &&
2378 // Don't visit the function body if the function definition is generated
2379 // by clang.
2380 (!D->isDefaulted() || getDerived().shouldVisitImplicitCode());
2381
2382 if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
2383 if (const CXXRecordDecl *RD = MD->getParent()) {
2384 if (RD->isLambda() &&
2385 declaresSameEntity(RD->getLambdaCallOperator(), MD)) {
2386 VisitBody = VisitBody && getDerived().shouldVisitLambdaBody();
2387 }
2388 }
2389 }
2390
2391 if (VisitBody) {
2392 TRY_TO(TraverseStmt(D->getBody()));
2393 // Body may contain using declarations whose shadows are parented to the
2394 // FunctionDecl itself.
2395 for (auto *Child : D->decls()) {
2396 if (isa<UsingShadowDecl>(Child))
2397 TRY_TO(TraverseDecl(Child));
2398 }
2399 }
2400 return true;
2401}
2402
2404 // We skip decls_begin/decls_end, which are already covered by
2405 // TraverseFunctionHelper().
2406 ShouldVisitChildren = false;
2407 ReturnValue = TraverseFunctionHelper(D);
2408})
2409
2411 // We skip decls_begin/decls_end, which are already covered by
2412 // TraverseFunctionHelper().
2413 ShouldVisitChildren = false;
2414 ReturnValue = TraverseFunctionHelper(D);
2415})
2416
2418 // We skip decls_begin/decls_end, which are already covered by
2419 // TraverseFunctionHelper().
2420 ShouldVisitChildren = false;
2421 ReturnValue = TraverseFunctionHelper(D);
2422})
2423
2425 // We skip decls_begin/decls_end, which are already covered by
2426 // TraverseFunctionHelper().
2427 ShouldVisitChildren = false;
2428 ReturnValue = TraverseFunctionHelper(D);
2429})
2430
2431// CXXConversionDecl is the declaration of a type conversion operator.
2432// It's not a cast expression.
2434 // We skip decls_begin/decls_end, which are already covered by
2435 // TraverseFunctionHelper().
2436 ShouldVisitChildren = false;
2437 ReturnValue = TraverseFunctionHelper(D);
2438})
2439
2441 // We skip decls_begin/decls_end, which are already covered by
2442 // TraverseFunctionHelper().
2443 ShouldVisitChildren = false;
2444 ReturnValue = TraverseFunctionHelper(D);
2445})
2446
2447template <typename Derived>
2448bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
2449 TRY_TO(TraverseDeclaratorHelper(D));
2450 // Default params are taken care of when we traverse the ParmVarDecl.
2451 if (!isa<ParmVarDecl>(D) &&
2452 (!D->isCXXForRangeDecl() || getDerived().shouldVisitImplicitCode()))
2453 TRY_TO(TraverseStmt(D->getInit()));
2454 return true;
2455}
2456
2457DEF_TRAVERSE_DECL(VarDecl, { TRY_TO(TraverseVarHelper(D)); })
2458
2459DEF_TRAVERSE_DECL(ImplicitParamDecl, { TRY_TO(TraverseVarHelper(D)); })
2460
2462 // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
2463 TRY_TO(TraverseDeclaratorHelper(D));
2464 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
2465 TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
2466})
2467
2469 TRY_TO(TraverseVarHelper(D));
2470
2471 if (D->hasDefaultArg() && D->hasUninstantiatedDefaultArg() &&
2472 !D->hasUnparsedDefaultArg())
2473 TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
2474
2475 if (D->hasDefaultArg() && !D->hasUninstantiatedDefaultArg() &&
2476 !D->hasUnparsedDefaultArg())
2477 TRY_TO(TraverseStmt(D->getDefaultArg()));
2478})
2479
2481
2483 TRY_TO(TraverseTemplateArguments(D->getTemplateArguments()));
2484})
2485
2486#undef DEF_TRAVERSE_DECL
2487
2488// ----------------- Stmt traversal -----------------
2489//
2490// For stmts, we automate (in the DEF_TRAVERSE_STMT macro) iterating
2491// over the children defined in children() (every stmt defines these,
2492// though sometimes the range is empty). Each individual Traverse*
2493// method only needs to worry about children other than those. To see
2494// what children() does for a given class, see, e.g.,
2495// http://clang.llvm.org/doxygen/Stmt_8cpp_source.html
2496
2497// This macro makes available a variable S, the passed-in stmt.
2498#define DEF_TRAVERSE_STMT(STMT, CODE) \
2499 template <typename Derived> \
2501 STMT *S, DataRecursionQueue *Queue) { \
2502 bool ShouldVisitChildren = true; \
2503 bool ReturnValue = true; \
2504 if (!getDerived().shouldTraversePostOrder()) \
2505 TRY_TO(WalkUpFrom##STMT(S)); \
2506 { CODE; } \
2507 if (ShouldVisitChildren) { \
2508 for (Stmt * SubStmt : getDerived().getStmtChildren(S)) { \
2509 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); \
2510 } \
2511 } \
2512 /* Call WalkUpFrom if TRY_TO_TRAVERSE_OR_ENQUEUE_STMT has traversed the \
2513 * children already. If TRY_TO_TRAVERSE_OR_ENQUEUE_STMT only enqueued the \
2514 * children, PostVisitStmt will call WalkUpFrom after we are done visiting \
2515 * children. */ \
2516 if (!Queue && ReturnValue && getDerived().shouldTraversePostOrder()) { \
2517 TRY_TO(WalkUpFrom##STMT(S)); \
2518 } \
2519 return ReturnValue; \
2520 }
2521
2523 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAsmStringExpr());
2524 for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
2525 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInputConstraintExpr(I));
2526 }
2527 for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
2528 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOutputConstraintExpr(I));
2529 }
2530 for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
2531 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getClobberExpr(I));
2532 }
2533 // children() iterates over inputExpr and outputExpr.
2534})
2535
2537 MSAsmStmt,
2538 {// FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc. Once
2539 // added this needs to be implemented.
2540 })
2541
2543 TRY_TO(TraverseDecl(S->getExceptionDecl()));
2544 // children() iterates over the handler block.
2545})
2546
2548 for (auto *I : S->decls()) {
2549 TRY_TO(TraverseDecl(I));
2550 }
2551 // Suppress the default iteration over children() by
2552 // returning. Here's why: A DeclStmt looks like 'type var [=
2553 // initializer]'. The decls above already traverse over the
2554 // initializers, so we don't have to do it again (which
2555 // children() would do).
2556 ShouldVisitChildren = false;
2557})
2558
2559// These non-expr stmts (most of them), do not need any action except
2560// iterating over the children.
2583
2585 if (!getDerived().shouldVisitImplicitCode()) {
2586 if (S->getInit())
2587 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInit());
2588 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLoopVarStmt());
2589 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRangeInit());
2590 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
2591 // Visit everything else only if shouldVisitImplicitCode().
2592 ShouldVisitChildren = false;
2593 }
2594})
2595
2597 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2598 TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
2599})
2600
2604
2606
2608 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2609 TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
2610 if (S->hasExplicitTemplateArgs()) {
2611 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2612 S->getNumTemplateArgs()));
2613 }
2614})
2615
2617 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2618 TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
2619 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2620 S->getNumTemplateArgs()));
2621})
2622
2624 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2625 TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
2626 if (S->hasExplicitTemplateArgs()) {
2627 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2628 S->getNumTemplateArgs()));
2629 }
2630})
2631
2633 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2634 TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
2635 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2636 S->getNumTemplateArgs()));
2637})
2638
2641 {// We don't traverse the cast type, as it's not written in the
2642 // source code.
2643 })
2644
2646 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2647})
2648
2650 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2651})
2652
2654 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2655})
2656
2658 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2659})
2660
2662 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2663})
2664
2666 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2667})
2668
2670 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2671})
2672
2674 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2675})
2676
2677template <typename Derived>
2679 InitListExpr *S, DataRecursionQueue *Queue) {
2680 if (S) {
2681 // Skip this if we traverse postorder. We will visit it later
2682 // in PostVisitStmt.
2683 if (!getDerived().shouldTraversePostOrder())
2684 TRY_TO(WalkUpFromInitListExpr(S));
2685
2686 // All we need are the default actions. FIXME: use a helper function.
2687 for (Stmt *SubStmt : S->children()) {
2689 }
2690
2691 if (!Queue && getDerived().shouldTraversePostOrder())
2692 TRY_TO(WalkUpFromInitListExpr(S));
2693 }
2694 return true;
2695}
2696
2697template <typename Derived>
2699 ObjCProtocolLoc ProtocolLoc) {
2700 return true;
2701}
2702
2703template <typename Derived>
2705 ConceptReference *CR) {
2706 if (!getDerived().shouldTraversePostOrder())
2707 TRY_TO(VisitConceptReference(CR));
2708 TRY_TO(TraverseNestedNameSpecifierLoc(CR->getNestedNameSpecifierLoc()));
2709 TRY_TO(TraverseDeclarationNameInfo(CR->getConceptNameInfo()));
2710 if (CR->hasExplicitTemplateArgs())
2711 TRY_TO(TraverseTemplateArgumentLocsHelper(
2712 CR->getTemplateArgsAsWritten()->getTemplateArgs(),
2713 CR->getTemplateArgsAsWritten()->NumTemplateArgs));
2714 if (getDerived().shouldTraversePostOrder())
2715 TRY_TO(VisitConceptReference(CR));
2716 return true;
2717}
2718
2719// If shouldVisitImplicitCode() returns false, this method traverses only the
2720// syntactic form of InitListExpr.
2721// If shouldVisitImplicitCode() return true, this method is called once for
2722// each pair of syntactic and semantic InitListExpr, and it traverses the
2723// subtrees defined by the two forms. This may cause some of the children to be
2724// visited twice, if they appear both in the syntactic and the semantic form.
2725//
2726// There is no guarantee about which form \p S takes when this method is called.
2727template <typename Derived>
2729 InitListExpr *S, DataRecursionQueue *Queue) {
2730 if (S->isSemanticForm() && S->isSyntacticForm()) {
2731 // `S` does not have alternative forms, traverse only once.
2732 TRY_TO(TraverseSynOrSemInitListExpr(S, Queue));
2733 return true;
2734 }
2735 TRY_TO(TraverseSynOrSemInitListExpr(
2736 S->isSemanticForm() ? S->getSyntacticForm() : S, Queue));
2737 if (getDerived().shouldVisitImplicitCode()) {
2738 // Only visit the semantic form if the clients are interested in implicit
2739 // compiler-generated.
2740 TRY_TO(TraverseSynOrSemInitListExpr(
2741 S->isSemanticForm() ? S : S->getSemanticForm(), Queue));
2742 }
2743 return true;
2744}
2745
2746// GenericSelectionExpr is a special case because the types and expressions
2747// are interleaved. We also need to watch out for null types (default
2748// generic associations).
2750 if (S->isExprPredicate())
2751 TRY_TO(TraverseStmt(S->getControllingExpr()));
2752 else
2753 TRY_TO(TraverseTypeLoc(S->getControllingType()->getTypeLoc()));
2754
2755 for (const GenericSelectionExpr::Association Assoc : S->associations()) {
2756 if (TypeSourceInfo *TSI = Assoc.getTypeSourceInfo())
2757 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
2758 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(Assoc.getAssociationExpr());
2759 }
2760 ShouldVisitChildren = false;
2761})
2762
2763// PseudoObjectExpr is a special case because of the weirdness with
2764// syntactic expressions and opaque values.
2766 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getSyntacticForm());
2767 for (PseudoObjectExpr::semantics_iterator i = S->semantics_begin(),
2768 e = S->semantics_end();
2769 i != e; ++i) {
2770 Expr *sub = *i;
2771 if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub))
2772 sub = OVE->getSourceExpr();
2774 }
2775 ShouldVisitChildren = false;
2776})
2777
2779 // This is called for code like 'return T()' where T is a built-in
2780 // (i.e. non-class) type.
2781 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2782})
2783
2785 // The child-iterator will pick up the other arguments.
2786 TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc()));
2787})
2788
2790 // The child-iterator will pick up the expression representing
2791 // the field.
2792 // FIXME: for code like offsetof(Foo, a.b.c), should we get
2793 // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c?
2794 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2795})
2796
2798 // The child-iterator will pick up the arg if it's an expression,
2799 // but not if it's a type.
2800 if (S->isArgumentType())
2801 TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
2802})
2803
2805 // The child-iterator will pick up the arg if it's an expression,
2806 // but not if it's a type.
2807 if (S->isTypeOperand())
2808 TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
2809})
2810
2812 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2813})
2814
2816
2818 // The child-iterator will pick up the arg if it's an expression,
2819 // but not if it's a type.
2820 if (S->isTypeOperand())
2821 TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
2822})
2823
2825 for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
2826 TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc()));
2827})
2828
2830 TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
2831})
2832
2834 { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getQueriedExpression()); })
2835
2837 // The child-iterator will pick up the expression argument.
2838 TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
2839})
2840
2842 // This is called for code like 'return T()' where T is a class type.
2843 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2844})
2845
2846// Walk only the visible parts of lambda expressions.
2848 // Visit the capture list.
2849 for (unsigned I = 0, N = S->capture_size(); I != N; ++I) {
2850 const LambdaCapture *C = S->capture_begin() + I;
2851 if (C->isExplicit() || getDerived().shouldVisitImplicitCode()) {
2852 TRY_TO(TraverseLambdaCapture(S, C, S->capture_init_begin()[I]));
2853 }
2854 }
2855
2856 if (getDerived().shouldVisitImplicitCode()) {
2857 // The implicit model is simple: everything else is in the lambda class.
2858 TRY_TO(TraverseDecl(S->getLambdaClass()));
2859 } else {
2860 // We need to poke around to find the bits that might be explicitly written.
2861 TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2863
2864 TRY_TO(TraverseTemplateParameterListHelper(S->getTemplateParameterList()));
2865 if (S->hasExplicitParameters()) {
2866 // Visit parameters.
2867 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2868 TRY_TO(TraverseDecl(Proto.getParam(I)));
2869 }
2870
2871 auto *T = Proto.getTypePtr();
2872 for (const auto &E : T->exceptions())
2873 TRY_TO(TraverseType(E));
2874
2875 if (Expr *NE = T->getNoexceptExpr())
2877
2878 if (S->hasExplicitResultType())
2879 TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
2881 const_cast<Expr *>(S->getTrailingRequiresClause().ConstraintExpr));
2882
2883 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
2884 }
2885 ShouldVisitChildren = false;
2886})
2887
2889 // This is called for code like 'T()', where T is a template argument.
2890 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2891})
2892
2894
2895// These expressions all might take explicit template arguments.
2896// We traverse those if so. FIXME: implement these.
2900
2901// These exprs (most of them), do not need any action except iterating
2902// over the children.
2910
2912 TRY_TO(TraverseDecl(S->getBlockDecl()));
2913 return true; // no child statements to loop through.
2914})
2915
2918 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2919})
2922
2924 if (getDerived().shouldVisitImplicitCode())
2925 TRY_TO(TraverseStmt(S->getExpr()));
2926})
2927
2929 if (getDerived().shouldVisitImplicitCode())
2930 TRY_TO(TraverseStmt(S->getExpr()));
2931})
2932
2938
2940 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2941 if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
2942 TRY_TO(TraverseTypeLoc(ScopeInfo->getTypeLoc()));
2943 if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo())
2944 TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc()));
2945})
2946
2958 // FIXME: The source expression of the OVE should be listed as
2959 // a child of the ArrayInitLoopExpr.
2960 if (OpaqueValueExpr *OVE = S->getCommonExpr())
2961 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(OVE->getSourceExpr());
2962})
2965
2967 if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
2968 TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
2969})
2970
2973
2975 if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo())
2976 TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
2977})
2978
2980 if (S->isClassReceiver()) {
2981 ObjCInterfaceDecl *IDecl = S->getClassReceiver();
2982 QualType Type = IDecl->getASTContext().getObjCInterfaceType(IDecl);
2984 Data.NameLoc = S->getReceiverLocation();
2985 Data.NameEndLoc = Data.NameLoc;
2986 TRY_TO(TraverseTypeLoc(TypeLoc(Type, &Data)));
2987 }
2988})
2993
2995 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2996})
2997
3002 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
3003})
3005 if (getDerived().shouldVisitImplicitCode()) {
3006 TRY_TO(TraverseStmt(S->getOriginalStmt()));
3007 TRY_TO(TraverseStmt(S->getKernelLaunchIdExpr()));
3008 ShouldVisitChildren = false;
3009 }
3010})
3018 for (IntegerLiteral *IL : S->underlying_data_elements()) {
3020 }
3021})
3022
3024 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
3025 if (S->hasExplicitTemplateArgs()) {
3026 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
3027 S->getNumTemplateArgs()));
3028 }
3029})
3030
3032 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
3033 if (S->hasExplicitTemplateArgs()) {
3034 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
3035 S->getNumTemplateArgs()));
3036 }
3037})
3038
3043DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
3044
3046 if (getDerived().shouldVisitImplicitCode()) {
3047 TRY_TO(TraverseStmt(S->getOriginalStmt()));
3048 TRY_TO(TraverseStmt(S->getKernelLaunchStmt()));
3049 TRY_TO(TraverseDecl(S->getOutlinedFunctionDecl()));
3050 ShouldVisitChildren = false;
3051 }
3052})
3053
3056 if (!getDerived().shouldVisitImplicitCode()) {
3058 S->getDecomposedForm();
3059 TRY_TO(TraverseStmt(const_cast<Expr*>(Decomposed.LHS)));
3060 TRY_TO(TraverseStmt(const_cast<Expr*>(Decomposed.RHS)));
3061 ShouldVisitChildren = false;
3062 }
3063})
3067
3068// These operators (all of them) do not need any action except
3069// iterating over the children.
3085
3087 if (S->getLifetimeExtendedTemporaryDecl()) {
3088 TRY_TO(TraverseLifetimeExtendedTemporaryDecl(
3089 S->getLifetimeExtendedTemporaryDecl()));
3090 ShouldVisitChildren = false;
3091 }
3092})
3093// For coroutines expressions, traverse either the operand
3094// as written or the implied calls, depending on what the
3095// derived class requests.
3097 if (!getDerived().shouldVisitImplicitCode()) {
3098 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
3099 ShouldVisitChildren = false;
3100 }
3101})
3103 if (!getDerived().shouldVisitImplicitCode()) {
3104 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
3105 ShouldVisitChildren = false;
3106 }
3107})
3109 if (!getDerived().shouldVisitImplicitCode()) {
3110 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
3111 ShouldVisitChildren = false;
3112 }
3113})
3115 if (!getDerived().shouldVisitImplicitCode()) {
3116 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
3117 ShouldVisitChildren = false;
3118 }
3119})
3121 if (!getDerived().shouldVisitImplicitCode()) {
3122 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
3123 ShouldVisitChildren = false;
3124 }
3125})
3126
3128 TRY_TO(TraverseConceptReference(S->getConceptReference()));
3129})
3130
3132 TRY_TO(TraverseDecl(S->getBody()));
3133 for (ParmVarDecl *Parm : S->getLocalParameters())
3134 TRY_TO(TraverseDecl(Parm));
3135 for (concepts::Requirement *Req : S->getRequirements())
3136 TRY_TO(TraverseConceptRequirement(Req));
3137})
3138
3139// These literals (all of them) do not need any action.
3150
3151// Traverse OpenCL: AsType, Convert.
3153
3154// OpenMP directives.
3155template <typename Derived>
3156bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
3157 OMPExecutableDirective *S) {
3158 for (auto *C : S->clauses()) {
3159 TRY_TO(TraverseOMPClause(C));
3160 }
3161 return true;
3162}
3163
3164DEF_TRAVERSE_STMT(OMPCanonicalLoop, {
3165 if (!getDerived().shouldVisitImplicitCode()) {
3166 // Visit only the syntactical loop.
3167 TRY_TO(TraverseStmt(S->getLoopStmt()));
3168 ShouldVisitChildren = false;
3169 }
3170})
3171
3172template <typename Derived>
3173bool
3174RecursiveASTVisitor<Derived>::TraverseOMPLoopDirective(OMPLoopDirective *S) {
3175 return TraverseOMPExecutableDirective(S);
3176}
3177
3178DEF_TRAVERSE_STMT(OMPMetaDirective,
3179 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3180
3181DEF_TRAVERSE_STMT(OMPParallelDirective,
3182 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3183
3184DEF_TRAVERSE_STMT(OMPSimdDirective,
3185 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3186
3187DEF_TRAVERSE_STMT(OMPTileDirective,
3188 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3189
3190DEF_TRAVERSE_STMT(OMPStripeDirective,
3191 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3192
3193DEF_TRAVERSE_STMT(OMPUnrollDirective,
3194 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3195
3196DEF_TRAVERSE_STMT(OMPReverseDirective,
3197 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3198
3199DEF_TRAVERSE_STMT(OMPFuseDirective,
3200 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3201
3202DEF_TRAVERSE_STMT(OMPInterchangeDirective,
3203 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3204
3205DEF_TRAVERSE_STMT(OMPSplitDirective,
3206 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3207
3208DEF_TRAVERSE_STMT(OMPForDirective,
3209 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3210
3211DEF_TRAVERSE_STMT(OMPForSimdDirective,
3212 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3213
3214DEF_TRAVERSE_STMT(OMPSectionsDirective,
3215 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3216
3217DEF_TRAVERSE_STMT(OMPSectionDirective,
3218 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3219
3220DEF_TRAVERSE_STMT(OMPScopeDirective,
3221 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3222
3223DEF_TRAVERSE_STMT(OMPSingleDirective,
3224 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3225
3226DEF_TRAVERSE_STMT(OMPMasterDirective,
3227 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3228
3229DEF_TRAVERSE_STMT(OMPCriticalDirective, {
3230 TRY_TO(TraverseDeclarationNameInfo(S->getDirectiveName()));
3231 TRY_TO(TraverseOMPExecutableDirective(S));
3232})
3233
3234DEF_TRAVERSE_STMT(OMPParallelForDirective,
3235 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3236
3237DEF_TRAVERSE_STMT(OMPParallelForSimdDirective,
3238 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3239
3240DEF_TRAVERSE_STMT(OMPParallelMasterDirective,
3241 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3242
3243DEF_TRAVERSE_STMT(OMPParallelMaskedDirective,
3244 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3245
3246DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
3247 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3248
3249DEF_TRAVERSE_STMT(OMPTaskDirective,
3250 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3251
3252DEF_TRAVERSE_STMT(OMPTaskyieldDirective,
3253 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3254
3255DEF_TRAVERSE_STMT(OMPBarrierDirective,
3256 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3257
3258DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
3259 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3260
3261DEF_TRAVERSE_STMT(OMPTaskgroupDirective,
3262 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3263
3264DEF_TRAVERSE_STMT(OMPCancellationPointDirective,
3265 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3266
3267DEF_TRAVERSE_STMT(OMPCancelDirective,
3268 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3269
3270DEF_TRAVERSE_STMT(OMPFlushDirective,
3271 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3272
3273DEF_TRAVERSE_STMT(OMPDepobjDirective,
3274 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3275
3276DEF_TRAVERSE_STMT(OMPScanDirective,
3277 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3278
3279DEF_TRAVERSE_STMT(OMPOrderedDirective,
3280 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3281
3282DEF_TRAVERSE_STMT(OMPAtomicDirective,
3283 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3284
3285DEF_TRAVERSE_STMT(OMPTargetDirective,
3286 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3287
3288DEF_TRAVERSE_STMT(OMPTargetDataDirective,
3289 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3290
3291DEF_TRAVERSE_STMT(OMPTargetEnterDataDirective,
3292 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3293
3294DEF_TRAVERSE_STMT(OMPTargetExitDataDirective,
3295 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3296
3297DEF_TRAVERSE_STMT(OMPTargetParallelDirective,
3298 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3299
3300DEF_TRAVERSE_STMT(OMPTargetParallelForDirective,
3301 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3302
3303DEF_TRAVERSE_STMT(OMPTeamsDirective,
3304 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3305
3306DEF_TRAVERSE_STMT(OMPTargetUpdateDirective,
3307 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3308
3309DEF_TRAVERSE_STMT(OMPTaskLoopDirective,
3310 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3311
3312DEF_TRAVERSE_STMT(OMPTaskLoopSimdDirective,
3313 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3314
3315DEF_TRAVERSE_STMT(OMPMasterTaskLoopDirective,
3316 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3317
3318DEF_TRAVERSE_STMT(OMPMasterTaskLoopSimdDirective,
3319 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3320
3321DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopDirective,
3322 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3323
3324DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopSimdDirective,
3325 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3326
3327DEF_TRAVERSE_STMT(OMPMaskedTaskLoopDirective,
3328 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3329
3330DEF_TRAVERSE_STMT(OMPMaskedTaskLoopSimdDirective,
3331 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3332
3333DEF_TRAVERSE_STMT(OMPParallelMaskedTaskLoopDirective,
3334 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3335
3336DEF_TRAVERSE_STMT(OMPParallelMaskedTaskLoopSimdDirective,
3337 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3338
3339DEF_TRAVERSE_STMT(OMPDistributeDirective,
3340 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3341
3342DEF_TRAVERSE_STMT(OMPDistributeParallelForDirective,
3343 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3344
3345DEF_TRAVERSE_STMT(OMPDistributeParallelForSimdDirective,
3346 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3347
3348DEF_TRAVERSE_STMT(OMPDistributeSimdDirective,
3349 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3350
3351DEF_TRAVERSE_STMT(OMPTargetParallelForSimdDirective,
3352 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3353
3354DEF_TRAVERSE_STMT(OMPTargetSimdDirective,
3355 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3356
3357DEF_TRAVERSE_STMT(OMPTeamsDistributeDirective,
3358 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3359
3360DEF_TRAVERSE_STMT(OMPTeamsDistributeSimdDirective,
3361 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3362
3363DEF_TRAVERSE_STMT(OMPTeamsDistributeParallelForSimdDirective,
3364 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3365
3366DEF_TRAVERSE_STMT(OMPTeamsDistributeParallelForDirective,
3367 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3368
3369DEF_TRAVERSE_STMT(OMPTargetTeamsDirective,
3370 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3371
3372DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeDirective,
3373 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3374
3375DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForDirective,
3376 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3377
3378DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForSimdDirective,
3379 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3380
3381DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeSimdDirective,
3382 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3383
3384DEF_TRAVERSE_STMT(OMPInteropDirective,
3385 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3386
3387DEF_TRAVERSE_STMT(OMPDispatchDirective,
3388 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3389
3390DEF_TRAVERSE_STMT(OMPMaskedDirective,
3391 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3392
3393DEF_TRAVERSE_STMT(OMPGenericLoopDirective,
3394 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3395
3396DEF_TRAVERSE_STMT(OMPTeamsGenericLoopDirective,
3397 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3398
3399DEF_TRAVERSE_STMT(OMPTargetTeamsGenericLoopDirective,
3400 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3401
3402DEF_TRAVERSE_STMT(OMPParallelGenericLoopDirective,
3403 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3404
3405DEF_TRAVERSE_STMT(OMPTargetParallelGenericLoopDirective,
3406 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3407
3408DEF_TRAVERSE_STMT(OMPAssumeDirective,
3409 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3410
3411DEF_TRAVERSE_STMT(OMPErrorDirective,
3412 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3413
3414// OpenMP clauses.
3415template <typename Derived>
3416bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
3417 if (!C)
3418 return true;
3419 switch (C->getClauseKind()) {
3420#define GEN_CLANG_CLAUSE_CLASS
3421#define CLAUSE_CLASS(Enum, Str, Class) \
3422 case llvm::omp::Clause::Enum: \
3423 TRY_TO(Visit##Class(static_cast<Class *>(C))); \
3424 break;
3425#define CLAUSE_NO_CLASS(Enum, Str) \
3426 case llvm::omp::Clause::Enum: \
3427 break;
3428#include "llvm/Frontend/OpenMP/OMP.inc"
3429 }
3430 return true;
3431}
3432
3433template <typename Derived>
3434bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPreInit(
3435 OMPClauseWithPreInit *Node) {
3436 TRY_TO(TraverseStmt(Node->getPreInitStmt()));
3437 return true;
3438}
3439
3440template <typename Derived>
3441bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPostUpdate(
3443 TRY_TO(VisitOMPClauseWithPreInit(Node));
3444 TRY_TO(TraverseStmt(Node->getPostUpdateExpr()));
3445 return true;
3446}
3447
3448template <typename Derived>
3451 TRY_TO(TraverseStmt(C->getAllocator()));
3452 return true;
3453}
3454
3455template <typename Derived>
3457 TRY_TO(TraverseStmt(C->getAllocator()));
3458 TRY_TO(VisitOMPClauseList(C));
3459 return true;
3460}
3461
3462template <typename Derived>
3464 TRY_TO(VisitOMPClauseWithPreInit(C));
3465 TRY_TO(TraverseStmt(C->getCondition()));
3466 return true;
3467}
3468
3469template <typename Derived>
3471 TRY_TO(VisitOMPClauseWithPreInit(C));
3472 TRY_TO(TraverseStmt(C->getCondition()));
3473 return true;
3474}
3475
3476template <typename Derived>
3477bool
3479 TRY_TO(VisitOMPClauseWithPreInit(C));
3480 TRY_TO(TraverseStmt(C->getNumThreads()));
3481 return true;
3482}
3483
3484template <typename Derived>
3486 TRY_TO(TraverseStmt(C->getAlignment()));
3487 return true;
3488}
3489
3490template <typename Derived>
3492 TRY_TO(TraverseStmt(C->getSafelen()));
3493 return true;
3494}
3495
3496template <typename Derived>
3498 TRY_TO(TraverseStmt(C->getSimdlen()));
3499 return true;
3500}
3501
3502template <typename Derived>
3504 for (Expr *E : C->getSizesRefs())
3505 TRY_TO(TraverseStmt(E));
3506 return true;
3507}
3508
3509template <typename Derived>
3511 for (Expr *E : C->getCountsRefs())
3512 TRY_TO(TraverseStmt(E));
3513 return true;
3514}
3515
3516template <typename Derived>
3519 for (Expr *E : C->getArgsRefs())
3520 TRY_TO(TraverseStmt(E));
3521 return true;
3522}
3523
3524template <typename Derived>
3526 return true;
3527}
3528
3529template <typename Derived>
3532 TRY_TO(TraverseStmt(C->getFirst()));
3533 TRY_TO(TraverseStmt(C->getCount()));
3534 return true;
3535}
3536
3537template <typename Derived>
3539 TRY_TO(TraverseStmt(C->getFactor()));
3540 return true;
3541}
3542
3543template <typename Derived>
3544bool
3546 TRY_TO(TraverseStmt(C->getNumForLoops()));
3547 return true;
3548}
3549
3550template <typename Derived>
3552 return true;
3553}
3554
3555template <typename Derived>
3558 return true;
3559}
3560
3561template <typename Derived>
3563 OMPTransparentClause *C) {
3564 TRY_TO(TraverseStmt(C->getImpexType()));
3565 return true;
3566}
3567
3568template <typename Derived>
3570 return true;
3571}
3572
3573template <typename Derived>
3575 OMPUnifiedAddressClause *) {
3576 return true;
3577}
3578
3579template <typename Derived>
3581 OMPUnifiedSharedMemoryClause *) {
3582 return true;
3583}
3584
3585template <typename Derived>
3587 OMPReverseOffloadClause *) {
3588 return true;
3589}
3590
3591template <typename Derived>
3593 OMPDynamicAllocatorsClause *) {
3594 return true;
3595}
3596
3597template <typename Derived>
3599 OMPAtomicDefaultMemOrderClause *) {
3600 return true;
3601}
3602
3603template <typename Derived>
3605 return true;
3606}
3607
3608template <typename Derived>
3610 return true;
3611}
3612
3613template <typename Derived>
3615 return true;
3616}
3617
3618template <typename Derived>
3620 TRY_TO(TraverseStmt(C->getMessageString()));
3621 return true;
3622}
3623
3624template <typename Derived>
3625bool
3627 TRY_TO(VisitOMPClauseWithPreInit(C));
3628 TRY_TO(TraverseStmt(C->getChunkSize()));
3629 return true;
3630}
3631
3632template <typename Derived>
3634 TRY_TO(TraverseStmt(C->getNumForLoops()));
3635 return true;
3636}
3637
3638template <typename Derived>
3640 TRY_TO(TraverseStmt(C->getCondition()));
3641 return true;
3642}
3643
3644template <typename Derived>
3646 return true;
3647}
3648
3649template <typename Derived>
3650bool
3652 return true;
3653}
3654
3655template <typename Derived>
3657 return true;
3658}
3659
3660template <typename Derived>
3662 return true;
3663}
3664
3665template <typename Derived>
3667 return true;
3668}
3669
3670template <typename Derived>
3672 return true;
3673}
3674
3675template <typename Derived>
3677 return true;
3678}
3679
3680template <typename Derived>
3682 return true;
3683}
3684
3685template <typename Derived>
3687 return true;
3688}
3689
3690template <typename Derived>
3692 return true;
3693}
3694
3695template <typename Derived>
3697 return true;
3698}
3699
3700template <typename Derived>
3702 return true;
3703}
3704
3705template <typename Derived>
3707 return true;
3708}
3709
3710template <typename Derived>
3712 return true;
3713}
3714
3715template <typename Derived>
3717 OMPNoOpenMPRoutinesClause *) {
3718 return true;
3719}
3720
3721template <typename Derived>
3723 OMPNoOpenMPConstructsClause *) {
3724 return true;
3725}
3726
3727template <typename Derived>
3729 OMPNoParallelismClause *) {
3730 return true;
3731}
3732
3733template <typename Derived>
3735 return true;
3736}
3737
3738template <typename Derived>
3740 return true;
3741}
3742
3743template <typename Derived>
3745 return true;
3746}
3747
3748template <typename Derived>
3750 return true;
3751}
3752
3753template <typename Derived>
3755 return true;
3756}
3757
3758template <typename Derived>
3760 return true;
3761}
3762
3763template <typename Derived>
3765 return true;
3766}
3767
3768template <typename Derived>
3770 TRY_TO(VisitOMPClauseList(C));
3771 return true;
3772}
3773
3774template <typename Derived>
3776 TRY_TO(TraverseStmt(C->getInteropVar()));
3777 return true;
3778}
3779
3780template <typename Derived>
3782 TRY_TO(TraverseStmt(C->getInteropVar()));
3783 return true;
3784}
3785
3786template <typename Derived>
3788 OMPNovariantsClause *C) {
3789 TRY_TO(VisitOMPClauseWithPreInit(C));
3790 TRY_TO(TraverseStmt(C->getCondition()));
3791 return true;
3792}
3793
3794template <typename Derived>
3796 OMPNocontextClause *C) {
3797 TRY_TO(VisitOMPClauseWithPreInit(C));
3798 TRY_TO(TraverseStmt(C->getCondition()));
3799 return true;
3800}
3801
3802template <typename Derived>
3803template <typename T>
3804bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
3805 for (auto *E : Node->varlist()) {
3806 TRY_TO(TraverseStmt(E));
3807 }
3808 return true;
3809}
3810
3811template <typename Derived>
3813 OMPInclusiveClause *C) {
3814 TRY_TO(VisitOMPClauseList(C));
3815 return true;
3816}
3817
3818template <typename Derived>
3820 OMPExclusiveClause *C) {
3821 TRY_TO(VisitOMPClauseList(C));
3822 return true;
3823}
3824
3825template <typename Derived>
3827 TRY_TO(VisitOMPClauseList(C));
3828 for (auto *E : C->private_copies()) {
3829 TRY_TO(TraverseStmt(E));
3830 }
3831 return true;
3832}
3833
3834template <typename Derived>
3836 OMPFirstprivateClause *C) {
3837 TRY_TO(VisitOMPClauseList(C));
3838 TRY_TO(VisitOMPClauseWithPreInit(C));
3839 for (auto *E : C->private_copies()) {
3840 TRY_TO(TraverseStmt(E));
3841 }
3842 for (auto *E : C->inits()) {
3843 TRY_TO(TraverseStmt(E));
3844 }
3845 return true;
3846}
3847
3848template <typename Derived>
3850 OMPLastprivateClause *C) {
3851 TRY_TO(VisitOMPClauseList(C));
3852 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3853 for (auto *E : C->private_copies()) {
3854 TRY_TO(TraverseStmt(E));
3855 }
3856 for (auto *E : C->source_exprs()) {
3857 TRY_TO(TraverseStmt(E));
3858 }
3859 for (auto *E : C->destination_exprs()) {
3860 TRY_TO(TraverseStmt(E));
3861 }
3862 for (auto *E : C->assignment_ops()) {
3863 TRY_TO(TraverseStmt(E));
3864 }
3865 return true;
3866}
3867
3868template <typename Derived>
3870 TRY_TO(VisitOMPClauseList(C));
3871 return true;
3872}
3873
3874template <typename Derived>
3876 TRY_TO(TraverseStmt(C->getStep()));
3877 TRY_TO(TraverseStmt(C->getCalcStep()));
3878 TRY_TO(VisitOMPClauseList(C));
3879 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3880 for (auto *E : C->privates()) {
3881 TRY_TO(TraverseStmt(E));
3882 }
3883 for (auto *E : C->inits()) {
3884 TRY_TO(TraverseStmt(E));
3885 }
3886 for (auto *E : C->updates()) {
3887 TRY_TO(TraverseStmt(E));
3888 }
3889 for (auto *E : C->finals()) {
3890 TRY_TO(TraverseStmt(E));
3891 }
3892 return true;
3893}
3894
3895template <typename Derived>
3897 TRY_TO(TraverseStmt(C->getAlignment()));
3898 TRY_TO(VisitOMPClauseList(C));
3899 return true;
3900}
3901
3902template <typename Derived>
3904 TRY_TO(VisitOMPClauseList(C));
3905 for (auto *E : C->source_exprs()) {
3906 TRY_TO(TraverseStmt(E));
3907 }
3908 for (auto *E : C->destination_exprs()) {
3909 TRY_TO(TraverseStmt(E));
3910 }
3911 for (auto *E : C->assignment_ops()) {
3912 TRY_TO(TraverseStmt(E));
3913 }
3914 return true;
3915}
3916
3917template <typename Derived>
3919 OMPCopyprivateClause *C) {
3920 TRY_TO(VisitOMPClauseList(C));
3921 for (auto *E : C->source_exprs()) {
3922 TRY_TO(TraverseStmt(E));
3923 }
3924 for (auto *E : C->destination_exprs()) {
3925 TRY_TO(TraverseStmt(E));
3926 }
3927 for (auto *E : C->assignment_ops()) {
3928 TRY_TO(TraverseStmt(E));
3929 }
3930 return true;
3931}
3932
3933template <typename Derived>
3934bool
3936 TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
3937 TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
3938 TRY_TO(VisitOMPClauseList(C));
3939 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3940 for (auto *E : C->privates()) {
3941 TRY_TO(TraverseStmt(E));
3942 }
3943 for (auto *E : C->lhs_exprs()) {
3944 TRY_TO(TraverseStmt(E));
3945 }
3946 for (auto *E : C->rhs_exprs()) {
3947 TRY_TO(TraverseStmt(E));
3948 }
3949 for (auto *E : C->reduction_ops()) {
3950 TRY_TO(TraverseStmt(E));
3951 }
3952 if (C->getModifier() == OMPC_REDUCTION_inscan) {
3953 for (auto *E : C->copy_ops()) {
3954 TRY_TO(TraverseStmt(E));
3955 }
3956 for (auto *E : C->copy_array_temps()) {
3957 TRY_TO(TraverseStmt(E));
3958 }
3959 for (auto *E : C->copy_array_elems()) {
3960 TRY_TO(TraverseStmt(E));
3961 }
3962 }
3963 return true;
3964}
3965
3966template <typename Derived>
3968 OMPTaskReductionClause *C) {
3969 TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
3970 TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
3971 TRY_TO(VisitOMPClauseList(C));
3972 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3973 for (auto *E : C->privates()) {
3974 TRY_TO(TraverseStmt(E));
3975 }
3976 for (auto *E : C->lhs_exprs()) {
3977 TRY_TO(TraverseStmt(E));
3978 }
3979 for (auto *E : C->rhs_exprs()) {
3980 TRY_TO(TraverseStmt(E));
3981 }
3982 for (auto *E : C->reduction_ops()) {
3983 TRY_TO(TraverseStmt(E));
3984 }
3985 return true;
3986}
3987
3988template <typename Derived>
3990 OMPInReductionClause *C) {
3991 TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
3992 TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
3993 TRY_TO(VisitOMPClauseList(C));
3994 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3995 for (auto *E : C->privates()) {
3996 TRY_TO(TraverseStmt(E));
3997 }
3998 for (auto *E : C->lhs_exprs()) {
3999 TRY_TO(TraverseStmt(E));
4000 }
4001 for (auto *E : C->rhs_exprs()) {
4002 TRY_TO(TraverseStmt(E));
4003 }
4004 for (auto *E : C->reduction_ops()) {
4005 TRY_TO(TraverseStmt(E));
4006 }
4007 for (auto *E : C->taskgroup_descriptors())
4008 TRY_TO(TraverseStmt(E));
4009 return true;
4010}
4011
4012template <typename Derived>
4014 TRY_TO(VisitOMPClauseList(C));
4015 return true;
4016}
4017
4018template <typename Derived>
4020 TRY_TO(TraverseStmt(C->getDepobj()));
4021 return true;
4022}
4023
4024template <typename Derived>
4026 TRY_TO(VisitOMPClauseList(C));
4027 return true;
4028}
4029
4030template <typename Derived>
4032 TRY_TO(VisitOMPClauseWithPreInit(C));
4033 TRY_TO(TraverseStmt(C->getDevice()));
4034 return true;
4035}
4036
4037template <typename Derived>
4039 TRY_TO(VisitOMPClauseList(C));
4040 return true;
4041}
4042
4043template <typename Derived>
4045 OMPNumTeamsClause *C) {
4046 TRY_TO(VisitOMPClauseList(C));
4047 TRY_TO(VisitOMPClauseWithPreInit(C));
4048 return true;
4049}
4050
4051template <typename Derived>
4053 OMPThreadLimitClause *C) {
4054 TRY_TO(VisitOMPClauseList(C));
4055 TRY_TO(VisitOMPClauseWithPreInit(C));
4056 return true;
4057}
4058
4059template <typename Derived>
4061 OMPPriorityClause *C) {
4062 TRY_TO(VisitOMPClauseWithPreInit(C));
4063 TRY_TO(TraverseStmt(C->getPriority()));
4064 return true;
4065}
4066
4067template <typename Derived>
4069 OMPGrainsizeClause *C) {
4070 TRY_TO(VisitOMPClauseWithPreInit(C));
4071 TRY_TO(TraverseStmt(C->getGrainsize()));
4072 return true;
4073}
4074
4075template <typename Derived>
4077 OMPNumTasksClause *C) {
4078 TRY_TO(VisitOMPClauseWithPreInit(C));
4079 TRY_TO(TraverseStmt(C->getNumTasks()));
4080 return true;
4081}
4082
4083template <typename Derived>
4085 TRY_TO(TraverseStmt(C->getHint()));
4086 return true;
4087}
4088
4089template <typename Derived>
4091 OMPDistScheduleClause *C) {
4092 TRY_TO(VisitOMPClauseWithPreInit(C));
4093 TRY_TO(TraverseStmt(C->getChunkSize()));
4094 return true;
4095}
4096
4097template <typename Derived>
4098bool
4100 return true;
4101}
4102
4103template <typename Derived>
4105 TRY_TO(VisitOMPClauseList(C));
4106 return true;
4107}
4108
4109template <typename Derived>
4111 TRY_TO(VisitOMPClauseList(C));
4112 return true;
4113}
4114
4115template <typename Derived>
4117 OMPUseDevicePtrClause *C) {
4118 TRY_TO(VisitOMPClauseList(C));
4119 return true;
4120}
4121
4122template <typename Derived>
4124 OMPUseDeviceAddrClause *C) {
4125 TRY_TO(VisitOMPClauseList(C));
4126 return true;
4127}
4128
4129template <typename Derived>
4131 OMPIsDevicePtrClause *C) {
4132 TRY_TO(VisitOMPClauseList(C));
4133 return true;
4134}
4135
4136template <typename Derived>
4138 OMPHasDeviceAddrClause *C) {
4139 TRY_TO(VisitOMPClauseList(C));
4140 return true;
4141}
4142
4143template <typename Derived>
4145 OMPNontemporalClause *C) {
4146 TRY_TO(VisitOMPClauseList(C));
4147 for (auto *E : C->private_refs()) {
4148 TRY_TO(TraverseStmt(E));
4149 }
4150 return true;
4151}
4152
4153template <typename Derived>
4155 return true;
4156}
4157
4158template <typename Derived>
4160 TRY_TO(TraverseStmt(C->getEventHandler()));
4161 return true;
4162}
4163
4164template <typename Derived>
4166 OMPUsesAllocatorsClause *C) {
4167 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
4168 const OMPUsesAllocatorsClause::Data Data = C->getAllocatorData(I);
4169 TRY_TO(TraverseStmt(Data.Allocator));
4170 TRY_TO(TraverseStmt(Data.AllocatorTraits));
4171 }
4172 return true;
4173}
4174
4175template <typename Derived>
4177 OMPAffinityClause *C) {
4178 TRY_TO(TraverseStmt(C->getModifier()));
4179 for (Expr *E : C->varlist())
4180 TRY_TO(TraverseStmt(E));
4181 return true;
4182}
4183
4184template <typename Derived>
4186 TRY_TO(VisitOMPClauseWithPreInit(C));
4187 TRY_TO(TraverseStmt(C->getThreadID()));
4188 return true;
4189}
4190
4191template <typename Derived>
4193 return true;
4194}
4195
4196template <typename Derived>
4198 OMPXDynCGroupMemClause *C) {
4199 TRY_TO(VisitOMPClauseWithPreInit(C));
4200 TRY_TO(TraverseStmt(C->getSize()));
4201 return true;
4202}
4203
4204template <typename Derived>
4206 OMPDynGroupprivateClause *C) {
4207 TRY_TO(VisitOMPClauseWithPreInit(C));
4208 TRY_TO(TraverseStmt(C->getSize()));
4209 return true;
4210}
4211
4212template <typename Derived>
4214 OMPDoacrossClause *C) {
4215 TRY_TO(VisitOMPClauseList(C));
4216 return true;
4217}
4218
4219template <typename Derived>
4221 OMPXAttributeClause *C) {
4222 return true;
4223}
4224
4225template <typename Derived>
4227 return true;
4228}
4229
4230template <typename Derived>
4231bool RecursiveASTVisitor<Derived>::TraverseOpenACCConstructStmt(
4233 TRY_TO(VisitOpenACCClauseList(C->clauses()));
4234 return true;
4235}
4236
4237template <typename Derived>
4238bool RecursiveASTVisitor<Derived>::TraverseOpenACCAssociatedStmtConstruct(
4240 TRY_TO(TraverseOpenACCConstructStmt(S));
4241 TRY_TO(TraverseStmt(S->getAssociatedStmt()));
4242 return true;
4243}
4244
4245template <typename Derived>
4246bool RecursiveASTVisitor<Derived>::VisitOpenACCClause(const OpenACCClause *C) {
4247 for (const Stmt *Child : C->children())
4248 TRY_TO(TraverseStmt(const_cast<Stmt *>(Child)));
4249 return true;
4250}
4251
4252template <typename Derived>
4253bool RecursiveASTVisitor<Derived>::VisitOpenACCClauseList(
4255
4256 for (const auto *C : Clauses)
4257 TRY_TO(VisitOpenACCClause(C));
4258 return true;
4259}
4260
4262 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4263DEF_TRAVERSE_STMT(OpenACCLoopConstruct,
4264 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4265DEF_TRAVERSE_STMT(OpenACCCombinedConstruct,
4266 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4267DEF_TRAVERSE_STMT(OpenACCDataConstruct,
4268 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4269DEF_TRAVERSE_STMT(OpenACCEnterDataConstruct,
4270 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4271DEF_TRAVERSE_STMT(OpenACCExitDataConstruct,
4272 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4273DEF_TRAVERSE_STMT(OpenACCHostDataConstruct,
4274 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4275DEF_TRAVERSE_STMT(OpenACCWaitConstruct, {
4276 if (S->hasDevNumExpr())
4277 TRY_TO(TraverseStmt(S->getDevNumExpr()));
4278 for (auto *E : S->getQueueIdExprs())
4279 TRY_TO(TraverseStmt(E));
4280 TRY_TO(VisitOpenACCClauseList(S->clauses()));
4281})
4282DEF_TRAVERSE_STMT(OpenACCInitConstruct,
4283 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4284DEF_TRAVERSE_STMT(OpenACCShutdownConstruct,
4285 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4286DEF_TRAVERSE_STMT(OpenACCSetConstruct,
4287 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4288DEF_TRAVERSE_STMT(OpenACCUpdateConstruct,
4289 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4290DEF_TRAVERSE_STMT(OpenACCAtomicConstruct,
4291 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4292DEF_TRAVERSE_STMT(OpenACCCacheConstruct, {
4293 for (auto *E : S->getVarList())
4294 TRY_TO(TraverseStmt(E));
4295})
4296
4297// Traverse HLSL: Out argument expression
4299
4300// FIXME: look at the following tricky-seeming exprs to see if we
4301// need to recurse on anything. These are ones that have methods
4302// returning decls or qualtypes or nestednamespecifier -- though I'm
4303// not sure if they own them -- or just seemed very complicated, or
4304// had lots of sub-types to explore.
4305//
4306// VisitOverloadExpr and its children: recurse on template args? etc?
4307
4308// FIXME: go through all the stmts and exprs again, and see which of them
4309// create new types, and recurse on the types (TypeLocs?) of those.
4310// Candidates:
4311//
4312// http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html
4313// http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html
4314// http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html
4315// Every class that has getQualifier.
4316
4317#undef DEF_TRAVERSE_STMT
4318#undef TRAVERSE_STMT
4319#undef TRAVERSE_STMT_BASE
4320
4321#undef TRY_TO
4322
4323} // end namespace clang
4324
4325#endif // LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
This file provides AST data structures related to concepts.
#define STMT(DERIVED, BASE)
Definition ASTFwd.h:23
#define TYPE(DERIVED, BASE)
Definition ASTFwd.h:26
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc QualifierLoc)
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.
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 DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND, DECLKIND)
#define DEF_TRAVERSE_DECL(DECL, CODE)
#define DEF_TRAVERSE_STMT(STMT, CODE)
#define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND)
#define TRY_TO(CALL_EXPR)
Defines various enumerations that describe declaration and type specifiers.
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:226
TranslationUnitDecl * getTranslationUnitDecl() const
Represents an access specifier followed by colon ':'.
Definition DeclCXX.h:86
AddrLabelExpr - The GNU address of label extension, representing &&label.
Definition Expr.h:4553
Represents a type which was implicitly adjusted by the semantic engine for arbitrary reasons.
Definition TypeBase.h:3539
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Definition Expr.h:6024
Represents a loop initializing the elements of an array.
Definition Expr.h:5971
Represents a constant array type that does not decay to a pointer when used as a function parameter.
Definition TypeBase.h:3942
This class represents BOTH the OpenMP Array Section and OpenACC 'subarray', with a boolean differenti...
Definition Expr.h:7218
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition Expr.h:2724
Wrapper for source info for arrays.
Definition TypeLoc.h:1777
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
Definition ExprCXX.h:3000
AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2] This AST node provides support ...
Definition Expr.h:6732
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
Definition Expr.h:6927
Attr - This represents one attribute.
Definition Attr.h:46
Represents an attribute applied to a statement.
Definition Stmt.h:2209
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
Definition Expr.h:4456
A builtin binary operation expression such as "x + y" or "x <= y".
Definition Expr.h:4041
A binding in a decomposition declaration.
Definition DeclCXX.h:4201
A fixed int type of a specified bitwidth.
Definition TypeBase.h:8283
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition Decl.h:4689
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition Expr.h:6671
Pointer to a block type.
Definition TypeBase.h:3592
BreakStmt - This represents a break.
Definition Stmt.h:3141
Represents a C++2a __builtin_bit_cast(T, v) expression.
Definition ExprCXX.h:5476
Represents the builtin template declaration which is used to implement __make_integer_seq and other b...
This class is used for builtin types like 'int'.
Definition TypeBase.h:3214
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Definition Expr.h:3972
Represents a call to a CUDA kernel function.
Definition ExprCXX.h:238
A C++ addrspace_cast expression (currently only enabled for OpenCL).
Definition ExprCXX.h:608
Represents a base class of a C++ class.
Definition DeclCXX.h:146
Represents binding an expression to a temporary.
Definition ExprCXX.h:1497
A boolean literal, per ([C++ lex.bool] Boolean literals).
Definition ExprCXX.h:727
CXXCatchStmt - This represents a C++ catch block.
Definition StmtCXX.h:28
A C++ const_cast expression (C++ [expr.const.cast]).
Definition ExprCXX.h:570
Represents a call to a C++ constructor.
Definition ExprCXX.h:1552
Represents a C++ constructor within a class.
Definition DeclCXX.h:2624
Represents a C++ conversion function within a class.
Definition DeclCXX.h:2959
Represents a C++ base or member initializer.
Definition DeclCXX.h:2389
Represents a C++ deduction guide declaration.
Definition DeclCXX.h:1986
A default argument (C++ [dcl.fct.default]).
Definition ExprCXX.h:1274
A use of a default initializer in a constructor or in aggregate initialization.
Definition ExprCXX.h:1381
Represents a delete expression for memory deallocation and destructor calls, e.g.
Definition ExprCXX.h:2630
Represents a C++ member access expression where the actual member referenced could not be resolved be...
Definition ExprCXX.h:3870
Represents a C++ destructor within a class.
Definition DeclCXX.h:2889
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
Definition ExprCXX.h:485
Represents a folding of a pack over an operator.
Definition ExprCXX.h:5032
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
Definition StmtCXX.h:135
Represents an explicit C++ type conversion that uses "functional" notation (C++ [expr....
Definition ExprCXX.h:1835
Represents a call to an inherited base class constructor from an inheriting constructor.
Definition ExprCXX.h:1755
Represents a call to a member function that may be written either with member call syntax (e....
Definition ExprCXX.h:183
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2136
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition ExprCXX.h:2359
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
Definition ExprCXX.h:4309
The null pointer literal (C++11 [lex.nullptr])
Definition ExprCXX.h:772
A call to an overloaded operator written using operator syntax.
Definition ExprCXX.h:85
Represents a list-initialization with parenthesis.
Definition ExprCXX.h:5141
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
Definition ExprCXX.h:2749
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
Represents a C++26 reflect expression [expr.reflect].
Definition ExprCXX.h:5508
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
Definition ExprCXX.h:530
A rewritten comparison expression that was originally written using operator syntax.
Definition ExprCXX.h:290
An expression "T()" which creates an rvalue of a non-class type T.
Definition ExprCXX.h:2200
A C++ static_cast expression (C++ [expr.static.cast]).
Definition ExprCXX.h:440
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
Definition ExprCXX.h:804
Represents a C++ functional cast expression that builds a temporary object.
Definition ExprCXX.h:1903
Represents the this expression in C++.
Definition ExprCXX.h:1158
A C++ throw-expression (C++ [except.throw]).
Definition ExprCXX.h:1212
CXXTryStmt - A C++ try block, including all handlers.
Definition StmtCXX.h:69
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
Definition ExprCXX.h:852
Describes an explicit type conversion that uses functional notion but could not be resolved because o...
Definition ExprCXX.h:3744
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
Definition ExprCXX.h:1072
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:2946
Represents the body of a CapturedStmt, and serves as its DeclContext.
Definition Decl.h:4961
This captures a statement into a function.
Definition Stmt.h:3943
CaseStmt - Represent a case statement.
Definition Stmt.h:1926
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Definition Expr.h:4851
Declaration of a class template.
Represents a 'co_await' expression.
Definition ExprCXX.h:5369
Complex values, per C99 6.2.5p11.
Definition TypeBase.h:3325
CompoundAssignOperator - For compound assignments (e.g.
Definition Expr.h:4303
CompoundLiteralExpr - [C99 6.5.2.5].
Definition Expr.h:3608
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition Stmt.h:1746
Declaration of a C++20 concept.
A reference to a concept and its template args, as it appears in the code.
Definition ASTConcept.h:130
Represents the specialization of a concept - evaluates to a prvalue of type bool.
ConditionalOperator - The ?
Definition Expr.h:4394
Represents the canonical version of C arrays with a specified constant size.
Definition TypeBase.h:3810
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Definition Expr.h:1085
Represents a concrete matrix type with constant number of rows and columns.
Definition TypeBase.h:4437
Represents a shadow constructor declaration introduced into a class by a C++11 using-declaration that...
Definition DeclCXX.h:3693
ContinueStmt - This represents a continue.
Definition Stmt.h:3125
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Definition Expr.h:4722
Represents a 'co_return' statement in the C++ Coroutines TS.
Definition StmtCXX.h:473
Represents the body of a coroutine.
Definition StmtCXX.h:320
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
Definition TypeBase.h:3486
Represents a 'co_yield' expression.
Definition ExprCXX.h:5450
Represents a pointer type decayed from an array or function type.
Definition TypeBase.h:3575
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1462
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2122
A reference to a declared variable, function, enum, etc.
Definition Expr.h:1273
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition Stmt.h:1637
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:601
Kind getKind() const
Definition DeclBase.h:450
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:780
A decomposition declaration.
Definition DeclCXX.h:4265
DeferStmt - This represents a deferred statement.
Definition Stmt.h:3242
Represents an extended address space qualifier where the input address space value is dependent.
Definition TypeBase.h:4111
Represents a 'co_await' expression while the type of the promise is dependent.
Definition ExprCXX.h:5401
Provides information about a dependent function-template specialization declaration.
A qualified reference to a name whose declaration cannot yet be resolved.
Definition ExprCXX.h:3510
Represents an array type in C++ whose size is a value-dependent expression.
Definition TypeBase.h:4061
Represents an extended vector type where either the type or size is dependent.
Definition TypeBase.h:4151
Represents a matrix type where the type and the number of rows and columns is dependent on a template...
Definition TypeBase.h:4523
Represents a vector type where either the type or size is dependent.
Definition TypeBase.h:4277
Represents a C99 designated initializer expression.
Definition Expr.h:5554
DoStmt - This represents a 'do/while' stmt.
Definition Stmt.h:2838
Represents a reference to emded data.
Definition Expr.h:5129
Represents an empty-declaration.
Definition Decl.h:5196
An instance of this object exists for each enum constant that is defined.
Definition Decl.h:3438
Represents an enum.
Definition Decl.h:4028
Represents a standard C++ module export declaration.
Definition Decl.h:5149
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
Definition ExprCXX.h:3661
This represents one expression.
Definition Expr.h:112
An expression trait intrinsic.
Definition ExprCXX.h:3073
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
Definition Expr.h:6609
ExtVectorType - Extended vector type.
Definition TypeBase.h:4317
Declaration context for names declared as extern "C" in C++.
Definition Decl.h:247
Represents a member of a struct/union/class.
Definition Decl.h:3175
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Definition Stmt.h:2894
FriendDecl - Represents the declaration of a friend entity, which can be a function,...
Definition DeclFriend.h:54
Declaration of a friend template.
Represents a function declaration or definition.
Definition Decl.h:2015
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Definition TypeBase.h:4935
Represents a reference to a function parameter pack, init-capture pack, or binding pack that has been...
Definition ExprCXX.h:4841
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5357
Declaration of a template function.
Provides information about a function template specialization, which is a FunctionDecl that has been ...
This represents a GCC inline-assembly statement extension.
Definition Stmt.h:3452
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Definition Expr.h:4926
Represents a C11 generic selection.
Definition Expr.h:6181
AssociationTy< false > Association
Definition Expr.h:6414
GotoStmt - This represents a direct goto.
Definition Stmt.h:2975
HLSLBufferDecl - Represent a cbuffer or tbuffer declaration.
Definition Decl.h:5211
This class represents temporary values used to represent inout and out arguments in HLSL.
Definition Expr.h:7396
IfStmt - This represents an if/then/else.
Definition Stmt.h:2265
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
Definition Expr.h:1734
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Definition Expr.h:3856
Represents an implicitly-generated value initialization of an object of a given type.
Definition Expr.h:6060
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Definition Decl.h:5070
Represents a C array with an unspecified size.
Definition TypeBase.h:3959
Represents a field injected from an anonymous union/struct into the parent scope.
Definition Decl.h:3482
IndirectGotoStmt - This represents an indirect goto.
Definition Stmt.h:3014
Describes an C or C++ initializer list.
Definition Expr.h:5302
An lvalue reference type, per C++11 [dcl.ref].
Definition TypeBase.h:3667
Represents the declaration of a label.
Definition Decl.h:524
LabelStmt - Represents a label, which has a substatement.
Definition Stmt.h:2152
Describes the capture of a variable or of this, or of a C++1y init-capture.
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition ExprCXX.h:1972
Implicit declaration of a temporary that was materialized by a MaterializeTemporaryExpr and lifetime-...
Definition DeclCXX.h:3324
Represents a linkage specification.
Definition DeclCXX.h:3031
This represents a Microsoft inline-assembly statement extension.
Definition Stmt.h:3671
Representation of a Microsoft __if_exists or __if_not_exists statement with a dependent name.
Definition StmtCXX.h:253
A global _GUID constant.
Definition DeclCXX.h:4414
An instance of this class represents the declaration of a property member.
Definition DeclCXX.h:4360
A member reference to an MSPropertyDecl.
Definition ExprCXX.h:940
MS property subscript expression.
Definition ExprCXX.h:1010
Sugar type that represents a type that was qualified by a qualifier written as a macro invocation.
Definition TypeBase.h:6236
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition ExprCXX.h:4920
MatrixSingleSubscriptExpr - Matrix single subscript expression for the MatrixType extension when you ...
Definition Expr.h:2798
MatrixSubscriptExpr - Matrix subscript expression for the MatrixType extension.
Definition Expr.h:2868
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition Expr.h:3367
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition TypeBase.h:3703
This represents a decl that may have a name.
Definition Decl.h:274
Represents a C++ namespace alias.
Definition DeclCXX.h:3217
Represent a C++ namespace.
Definition Decl.h:592
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.
@ Namespace
A namespace-like entity, stored as a NamespaceBaseDecl*.
Represents a place-holder for an object not to be initialized by anything.
Definition Expr.h:5880
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
NullStmt - This is the null statement ";": C99 6.8.3p3.
Definition Stmt.h:1709
This represents the 'align' clause in the 'pragma omp allocate' directive.
This represents clause 'allocate' in the 'pragma omp ...' directives.
This represents 'pragma omp allocate ...' directive.
Definition DeclOpenMP.h:536
This represents 'allocator' clause in the 'pragma omp ...' directive.
An explicit cast in C or a C-style cast in C++, which uses the syntax ([s1][s2]......
Definition ExprOpenMP.h:24
Pseudo declaration for capturing expressions.
Definition DeclOpenMP.h:445
Class that handles post-update expression for some clauses, like 'lastprivate', 'reduction' etc.
Class that handles pre-initialization statement for some clauses, like 'schedule',...
This is a basic class for representing single OpenMP clause.
This represents 'collapse' clause in the 'pragma omp ...' directive.
This represents the 'counts' clause in the 'pragma omp split' directive.
This represents 'pragma omp declare mapper ...' directive.
Definition DeclOpenMP.h:349
This represents 'pragma omp declare reduction ...' directive.
Definition DeclOpenMP.h:239
This represents 'default' clause in the 'pragma omp ...' directive.
This represents 'final' clause in the 'pragma omp ...' directive.
Representation of the 'full' clause of the 'pragma omp unroll' directive.
This represents 'pragma omp groupprivate ...' directive.
Definition DeclOpenMP.h:173
This represents 'if' clause in the 'pragma omp ...' directive.
OpenMP 5.0 [2.1.6 Iterators] Iterators are identifiers that expand to multiple values in the clause o...
Definition ExprOpenMP.h:151
This class represents the 'looprange' clause in the 'pragma omp fuse' directive.
This represents 'num_threads' clause in the 'pragma omp ...' directive.
Representation of the 'partial' clause of the 'pragma omp unroll' directive.
This class represents the 'permutation' clause in the 'pragma omp interchange' directive.
This represents 'pragma omp requires...' directive.
Definition DeclOpenMP.h:479
This represents 'safelen' clause in the 'pragma omp ...' directive.
This represents 'simdlen' clause in the 'pragma omp ...' directive.
This represents the 'sizes' clause in the 'pragma omp tile' directive.
This represents 'pragma omp threadprivate ...' directive.
Definition DeclOpenMP.h:110
This represents 'threadset' clause in the 'pragma omp task ...' directive.
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
Definition ExprObjC.h:220
Represents Objective-C's @catch statement.
Definition StmtObjC.h:77
Represents a field declaration created by an @defs(...).
Definition DeclObjC.h:2030
Represents Objective-C's @finally statement.
Definition StmtObjC.h:127
Represents Objective-C's @synchronized statement.
Definition StmtObjC.h:303
Represents Objective-C's @throw statement.
Definition StmtObjC.h:358
Represents Objective-C's @try ... @catch ... @finally statement.
Definition StmtObjC.h:167
Represents Objective-C's @autoreleasepool Statement.
Definition StmtObjC.h:394
A runtime availability query.
Definition ExprObjC.h:1734
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
Definition ExprObjC.h:119
ObjCBoxedExpr - used for generalized expression boxing.
Definition ExprObjC.h:159
An Objective-C "bridged" cast expression, which casts between Objective-C pointers and C pointers,...
Definition ExprObjC.h:1674
ObjCCategoryDecl - Represents a category declaration.
Definition DeclObjC.h:2329
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
Definition DeclObjC.h:2545
ObjCCompatibleAliasDecl - Represents alias of a class.
Definition DeclObjC.h:2775
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
Definition ExprObjC.h:342
ObjCEncodeExpr, used for @encode in Objective-C.
Definition ExprObjC.h:441
Represents Objective-C's collection statement.
Definition StmtObjC.h:23
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Definition DeclObjC.h:2597
ObjCIndirectCopyRestoreExpr - Represents the passing of a function argument by indirect copy-restore ...
Definition ExprObjC.h:1613
Represents an ObjC class declaration.
Definition DeclObjC.h:1154
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
Definition TypeBase.h:7993
ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
Definition ExprObjC.h:1529
ObjCIvarDecl - Represents an ObjC instance variable.
Definition DeclObjC.h:1952
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Definition ExprObjC.h:580
An expression that sends a message to the given Objective-C object or class.
Definition ExprObjC.h:971
ObjCMethodDecl - Represents an instance or class method declaration.
Definition DeclObjC.h:140
Represents a pointer to an Objective C object.
Definition TypeBase.h:8049
Represents one property declaration in an Objective-C interface.
Definition DeclObjC.h:731
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
Definition DeclObjC.h:2805
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
Definition ExprObjC.h:648
Represents an Objective-C protocol declaration.
Definition DeclObjC.h:2084
ObjCProtocolExpr used for protocol expression in Objective-C.
Definition ExprObjC.h:536
ObjCSelectorExpr used for @selector in Objective-C.
Definition ExprObjC.h:486
ObjCStringLiteral, used for Objective-C string literals i.e.
Definition ExprObjC.h:84
ObjCSubscriptRefExpr - used for array and dictionary subscripting.
Definition ExprObjC.h:870
Represents the declaration of an Objective-C type parameter.
Definition DeclObjC.h:578
Stores a list of Objective-C type parameters for a parameterized class or a category/extension thereo...
Definition DeclObjC.h:662
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition Expr.h:2530
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition Expr.h:1181
This is a base class for any OpenACC statement-level constructs that have an associated statement.
Definition StmtOpenACC.h:81
This expression type represents an asterisk in an OpenACC Size-Expr, used in the 'tile' and 'gang' cl...
Definition Expr.h:2093
This is the base type for all OpenACC Clauses.
This is the base class for an OpenACC statement-level construct, other construct types are expected t...
Definition StmtOpenACC.h:26
Represents a partial function definition.
Definition Decl.h:4896
Represents a C++11 pack expansion that produces a sequence of expressions.
Definition ExprCXX.h:4363
ParenExpr - This represents a parenthesized expression, e.g.
Definition Expr.h:2185
Sugar for parentheses used when specifying types.
Definition TypeBase.h:3352
Represents a parameter to a function.
Definition Decl.h:1805
PipeType - OpenCL20.
Definition TypeBase.h:8249
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition TypeBase.h:3378
Represents a #pragma comment line.
Definition Decl.h:167
Represents a #pragma detect_mismatch line.
Definition Decl.h:201
[C99 6.4.2.2] - A predefined identifier such as func.
Definition Expr.h:2008
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition Expr.h:6803
Expr *const * semantics_iterator
Definition Expr.h:6862
A (possibly-)qualified type.
Definition TypeBase.h:937
Represents a template name as written in source code.
Wrapper of type source information for a type with non-trivial direct qualifiers.
Definition TypeLoc.h:300
UnqualTypeLoc getUnqualifiedLoc() const
Definition TypeLoc.h:304
An rvalue reference type, per C++11 [dcl.ref].
Definition TypeBase.h:3685
Represents a struct/union/class.
Definition Decl.h:4342
Frontend produces RecoveryExprs on semantic errors that prevent creating other well-formed expression...
Definition Expr.h:7502
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.
Represents the body of a requires-expression.
Definition DeclCXX.h:2105
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Definition Stmt.h:3166
Represents a __leave statement.
Definition Stmt.h:3904
SYCLKernelCallStmt represents the transformation that is applied to the body of a function declared w...
Definition StmtSYCL.h:36
Scope - A scope is a transient data structure that is used while parsing the program.
Definition Scope.h:41
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Definition Expr.h:4646
Represents an expression that computes the length of a parameter pack.
Definition ExprCXX.h:4441
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
Definition Expr.h:5020
Represents a C++11 static_assert declaration.
Definition DeclCXX.h:4152
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
Definition Expr.h:4598
Stmt - This represents one statement.
Definition Stmt.h:86
@ NoStmtClass
Definition Stmt.h:89
child_range children()
Definition Stmt.cpp:304
StmtClass getStmtClass() const
Definition Stmt.h:1499
llvm::iterator_range< child_iterator > child_range
Definition Stmt.h:1588
StringLiteral - This represents a string literal expression, e.g.
Definition Expr.h:1802
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Definition ExprCXX.h:4664
Represents a reference to a non-type template parameter pack that has been substituted with a non-tem...
Definition ExprCXX.h:4754
Abstract type representing delayed type pack expansions.
Definition TypeLoc.h:986
SwitchStmt - This represents a 'switch' stmt.
Definition Stmt.h:2515
Location wrapper for a TemplateArgument.
const TemplateArgument & getArgument() const
TypeSourceInfo * getTypeSourceInfo() const
Expr * getSourceExpression() const
NestedNameSpecifierLoc getTemplateQualifierLoc() const
Represents a template argument.
Expr * getAsExpr() const
Retrieve the template argument as an expression.
QualType getAsType() const
Retrieve the type for a type template argument.
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Template
The template argument is a template name that was provided for a template template parameter.
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
@ Pack
The template argument is actually a parameter pack.
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
@ Type
The template argument is a type.
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion,...
Represents a C++ template name within the type system.
A template parameter object.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl ** iterator
Iterates through the template parameters in this list.
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
Declaration of a template type parameter.
A declaration that models statements at global scope.
Definition Decl.h:4652
The top declaration context.
Definition Decl.h:105
Represents the declaration of a typedef-name via a C++11 alias-declaration.
Definition Decl.h:3703
Declaration of an alias template.
Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...
Definition ASTConcept.h:227
Base wrapper for a particular "section" of type source info.
Definition TypeLoc.h:59
UnqualTypeLoc getUnqualifiedLoc() const
Skips past any qualifiers, if this is qualified.
Definition TypeLoc.h:349
NestedNameSpecifierLoc getPrefix() const
If this type represents a qualified-id, this returns it's nested name specifier.
Definition TypeLoc.cpp:473
TypeLocClass getTypeLocClass() const
Definition TypeLoc.h:116
bool isNull() const
Definition TypeLoc.h:121
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
Definition TypeLoc.h:2735
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
Definition TypeBase.h:6268
A container of type source information.
Definition TypeBase.h:8402
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
Definition ExprCXX.h:2900
The base class of the type hierarchy.
Definition TypeBase.h:1866
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Definition Decl.h:3682
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition Expr.h:2628
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition Expr.h:2247
An artificial decl, representing a global anonymous constant value which is uniquified by value withi...
Definition DeclCXX.h:4471
Wrapper of type source information for a type with no direct qualifiers.
Definition TypeLoc.h:274
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
Definition ExprCXX.h:3390
Represents a C++ member access expression for which lookup produced a set of overloaded functions.
Definition ExprCXX.h:4126
This node is generated when a using-declaration that was annotated with attribute((using_if_exists)) ...
Definition DeclCXX.h:4134
Represents the dependent type named by a dependently-scoped typename using declaration,...
Definition TypeBase.h:6073
Represents a dependent using declaration which was marked with typename.
Definition DeclCXX.h:4053
Represents a dependent using declaration which was not marked with typename.
Definition DeclCXX.h:3956
A call to a literal operator (C++11 [over.literal]) written as a user-defined literal (C++11 [lit....
Definition ExprCXX.h:644
Represents a C++ using-declaration.
Definition DeclCXX.h:3607
Represents C++ using-directive.
Definition DeclCXX.h:3112
Represents a C++ using-enum-declaration.
Definition DeclCXX.h:3808
Represents a pack of using declarations that a single using-declarator pack-expanded into.
Definition DeclCXX.h:3889
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Definition DeclCXX.h:3415
Represents a call to the builtin function __builtin_va_arg.
Definition Expr.h:4960
Represents a variable declaration or definition.
Definition Decl.h:926
Declaration of a variable template.
Represents a C array with a specified size that is not an integer-constant-expression.
Definition TypeBase.h:4016
Represents a GCC generic vector type.
Definition TypeBase.h:4225
WhileStmt - This represents a 'while' stmt.
Definition Stmt.h:2703
A requires-expression requirement which queries the validity and properties of an expression ('simple...
A requires-expression requirement which is satisfied when a general constraint expression is satisfie...
A static requirement that can be used in a requires-expression to check properties of types and expre...
A requires-expression requirement which queries the existence of a type name or type template special...
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.
bool isa(CodeGen::Address addr)
Definition Address.h:330
TRY_TO(TraverseNestedNameSpecifier(Qualifier))
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
Definition Parser.h:61
OpenACCComputeConstruct(OpenACCDirectiveKind K, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses, Stmt *StructuredBlock)
@ Parameter
The parameter type of a method or function.
Definition TypeBase.h:908
@ Template
We are parsing a template declaration.
Definition Parser.h:81
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
Definition DeclBase.h:1301
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
Definition Specifiers.h:207
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
Definition Specifiers.h:203
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition Specifiers.h:199
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
Definition Specifiers.h:195
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition Specifiers.h:192
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Class
The "class" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:5967
DEF_TRAVERSE_TYPE(ComplexType, { TRY_TO(TraverseType(T->getElementType()));}) DEF_TRAVERSE_TYPE(PointerType
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
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.