clang 22.0.0git
RecursiveASTVisitor.h
Go to the documentation of this file.
1//===--- RecursiveASTVisitor.h - Recursive AST Visitor ----------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the RecursiveASTVisitor interface, which recursively
10// traverses the entire AST.
11//
12//===----------------------------------------------------------------------===//
13#ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
14#define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
15
17#include "clang/AST/Attr.h"
18#include "clang/AST/Decl.h"
19#include "clang/AST/DeclBase.h"
20#include "clang/AST/DeclCXX.h"
22#include "clang/AST/DeclObjC.h"
27#include "clang/AST/Expr.h"
28#include "clang/AST/ExprCXX.h"
30#include "clang/AST/ExprObjC.h"
36#include "clang/AST/Stmt.h"
37#include "clang/AST/StmtCXX.h"
38#include "clang/AST/StmtObjC.h"
41#include "clang/AST/StmtSYCL.h"
44#include "clang/AST/Type.h"
45#include "clang/AST/TypeLoc.h"
46#include "clang/Basic/LLVM.h"
49#include "llvm/ADT/PointerIntPair.h"
50#include "llvm/ADT/SmallVector.h"
51#include "llvm/Support/Casting.h"
52#include <algorithm>
53#include <cstddef>
54#include <type_traits>
55
56namespace clang {
57
58// A helper macro to implement short-circuiting when recursing. It
59// invokes CALL_EXPR, which must be a method call, on the derived
60// object (s.t. a user of RecursiveASTVisitor can override the method
61// in CALL_EXPR).
62#define TRY_TO(CALL_EXPR) \
63 do { \
64 if (!getDerived().CALL_EXPR) \
65 return false; \
66 } while (false)
67
68namespace detail {
69
70template <typename T, typename U>
71struct has_same_member_pointer_type : std::false_type {};
72template <typename T, typename U, typename R, typename... P>
73struct has_same_member_pointer_type<R (T::*)(P...), R (U::*)(P...)>
74 : std::true_type {};
75
76/// Returns true if and only if \p FirstMethodPtr and \p SecondMethodPtr
77/// are pointers to the same non-static member function.
78template <typename FirstMethodPtrTy, typename SecondMethodPtrTy>
79LLVM_ATTRIBUTE_ALWAYS_INLINE LLVM_ATTRIBUTE_NODEBUG auto
80isSameMethod([[maybe_unused]] FirstMethodPtrTy FirstMethodPtr,
81 [[maybe_unused]] SecondMethodPtrTy SecondMethodPtr)
82 -> bool {
83 if constexpr (has_same_member_pointer_type<FirstMethodPtrTy,
84 SecondMethodPtrTy>::value)
85 return FirstMethodPtr == SecondMethodPtr;
86 return false;
87}
88
89} // end namespace detail
90
91/// A class that does preorder or postorder
92/// depth-first traversal on the entire Clang AST and visits each node.
93///
94/// This class performs three distinct tasks:
95/// 1. traverse the AST (i.e. go to each node);
96/// 2. at a given node, walk up the class hierarchy, starting from
97/// the node's dynamic type, until the top-most class (e.g. Stmt,
98/// Decl, or Type) is reached.
99/// 3. given a (node, class) combination, where 'class' is some base
100/// class of the dynamic type of 'node', call a user-overridable
101/// function to actually visit the node.
102///
103/// These tasks are done by three groups of methods, respectively:
104/// 1. TraverseDecl(Decl *x) does task #1. It is the entry point
105/// for traversing an AST rooted at x. This method simply
106/// dispatches (i.e. forwards) to TraverseFoo(Foo *x) where Foo
107/// is the dynamic type of *x, which calls WalkUpFromFoo(x) and
108/// then recursively visits the child nodes of x.
109/// TraverseStmt(Stmt *x) and TraverseType(QualType x) work
110/// similarly.
111/// 2. WalkUpFromFoo(Foo *x) does task #2. It does not try to visit
112/// any child node of x. Instead, it first calls WalkUpFromBar(x)
113/// where Bar is the direct parent class of Foo (unless Foo has
114/// no parent), and then calls VisitFoo(x) (see the next list item).
115/// 3. VisitFoo(Foo *x) does task #3.
116///
117/// These three method groups are tiered (Traverse* > WalkUpFrom* >
118/// Visit*). A method (e.g. Traverse*) may call methods from the same
119/// tier (e.g. other Traverse*) or one tier lower (e.g. WalkUpFrom*).
120/// It may not call methods from a higher tier.
121///
122/// Note that since WalkUpFromFoo() calls WalkUpFromBar() (where Bar
123/// is Foo's super class) before calling VisitFoo(), the result is
124/// that the Visit*() methods for a given node are called in the
125/// top-down order (e.g. for a node of type NamespaceDecl, the order will
126/// be VisitDecl(), VisitNamedDecl(), and then VisitNamespaceDecl()).
127///
128/// This scheme guarantees that all Visit*() calls for the same AST
129/// node are grouped together. In other words, Visit*() methods for
130/// different nodes are never interleaved.
131///
132/// Clients of this visitor should subclass the visitor (providing
133/// themselves as the template argument, using the curiously recurring
134/// template pattern) and override any of the Traverse*, WalkUpFrom*,
135/// and Visit* methods for declarations, types, statements,
136/// expressions, or other AST nodes where the visitor should customize
137/// behavior. Most users only need to override Visit*. Advanced
138/// users may override Traverse* and WalkUpFrom* to implement custom
139/// traversal strategies. Returning false from one of these overridden
140/// functions will abort the entire traversal.
141///
142/// By default, this visitor tries to visit every part of the explicit
143/// source code exactly once. The default policy towards templates
144/// is to descend into the 'pattern' class or function body, not any
145/// explicit or implicit instantiations. Explicit specializations
146/// are still visited, and the patterns of partial specializations
147/// are visited separately. This behavior can be changed by
148/// overriding shouldVisitTemplateInstantiations() in the derived class
149/// to return true, in which case all known implicit and explicit
150/// instantiations will be visited at the same time as the pattern
151/// from which they were produced.
152///
153/// By default, this visitor preorder traverses the AST. If postorder traversal
154/// is needed, the \c shouldTraversePostOrder method needs to be overridden
155/// to return \c true.
156template <typename Derived> class RecursiveASTVisitor {
157public:
158 /// A queue used for performing data recursion over statements.
159 /// Parameters involving this type are used to implement data
160 /// recursion over Stmts and Exprs within this class, and should
161 /// typically not be explicitly specified by derived classes.
162 /// The bool bit indicates whether the statement has been traversed or not.
165
166 /// Return a reference to the derived class.
167 Derived &getDerived() { return *static_cast<Derived *>(this); }
168
169 /// Return whether this visitor should recurse into
170 /// template instantiations.
171 bool shouldVisitTemplateInstantiations() const { return false; }
172
173 /// Return whether this visitor should recurse into the types of
174 /// TypeLocs.
175 bool shouldWalkTypesOfTypeLocs() const { return true; }
176
177 /// Return whether this visitor should recurse into implicit
178 /// code, e.g., implicit constructors and destructors.
179 bool shouldVisitImplicitCode() const { return false; }
180
181 /// Return whether this visitor should recurse into lambda body
182 bool shouldVisitLambdaBody() const { return true; }
183
184 /// Return whether this visitor should traverse post-order.
185 bool shouldTraversePostOrder() const { return false; }
186
187 /// Recursively visits an entire AST, starting from the TranslationUnitDecl.
188 /// \returns false if visitation was terminated early.
190 // Currently just an alias for TraverseDecl(TUDecl), but kept in case
191 // we change the implementation again.
192 return getDerived().TraverseDecl(AST.getTranslationUnitDecl());
193 }
194
195 /// Recursively visit a statement or expression, by
196 /// dispatching to Traverse*() based on the argument's dynamic type.
197 ///
198 /// \returns false if the visitation was terminated early, true
199 /// otherwise (including when the argument is nullptr).
200 bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue = nullptr);
201
202 /// Invoked before visiting a statement or expression via data recursion.
203 ///
204 /// \returns false to skip visiting the node, true otherwise.
205 bool dataTraverseStmtPre(Stmt *S) { return true; }
206
207 /// Invoked after visiting a statement or expression via data recursion.
208 /// This is not invoked if the previously invoked \c dataTraverseStmtPre
209 /// returned false.
210 ///
211 /// \returns false if the visitation was terminated early, true otherwise.
212 bool dataTraverseStmtPost(Stmt *S) { return true; }
213
214 /// Recursively visit a type, by dispatching to
215 /// Traverse*Type() based on the argument's getTypeClass() property.
216 ///
217 /// \returns false if the visitation was terminated early, true
218 /// otherwise (including when the argument is a Null type).
219 bool TraverseType(QualType T, bool TraverseQualifier = true);
220
221 /// Recursively visit a type with location, by dispatching to
222 /// Traverse*TypeLoc() based on the argument type's getTypeClass() property.
223 ///
224 /// \returns false if the visitation was terminated early, true
225 /// otherwise (including when the argument is a Null type location).
226 bool TraverseTypeLoc(TypeLoc TL, bool TraverseQualifier = true);
227
228 /// Recursively visit an attribute, by dispatching to
229 /// Traverse*Attr() based on the argument's dynamic type.
230 ///
231 /// \returns false if the visitation was terminated early, true
232 /// otherwise (including when the argument is a Null type location).
234
235 /// Recursively visit a declaration, by dispatching to
236 /// Traverse*Decl() based on the argument's dynamic type.
237 ///
238 /// \returns false if the visitation was terminated early, true
239 /// otherwise (including when the argument is NULL).
241
242 /// Recursively visit a C++ nested-name-specifier.
243 ///
244 /// \returns false if the visitation was terminated early, true otherwise.
246
247 /// Recursively visit a C++ nested-name-specifier with location
248 /// information.
249 ///
250 /// \returns false if the visitation was terminated early, true otherwise.
252
253 /// Recursively visit a name with its location information.
254 ///
255 /// \returns false if the visitation was terminated early, true otherwise.
257
258 /// Recursively visit a template name and dispatch to the
259 /// appropriate method.
260 ///
261 /// \returns false if the visitation was terminated early, true otherwise.
263
264 /// Recursively visit a template argument and dispatch to the
265 /// appropriate method for the argument type.
266 ///
267 /// \returns false if the visitation was terminated early, true otherwise.
268 // FIXME: migrate callers to TemplateArgumentLoc instead.
270
271 /// Recursively visit a template argument location and dispatch to the
272 /// appropriate method for the argument type.
273 ///
274 /// \returns false if the visitation was terminated early, true otherwise.
276
277 /// Recursively visit a set of template arguments.
278 /// This can be overridden by a subclass, but it's not expected that
279 /// will be needed -- this visitor always dispatches to another.
280 ///
281 /// \returns false if the visitation was terminated early, true otherwise.
282 // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead.
284
285 /// Recursively visit a base specifier. This can be overridden by a
286 /// subclass.
287 ///
288 /// \returns false if the visitation was terminated early, true otherwise.
290
291 /// Recursively visit a constructor initializer. This
292 /// automatically dispatches to another visitor for the initializer
293 /// expression, but not for the name of the initializer, so may
294 /// be overridden for clients that need access to the name.
295 ///
296 /// \returns false if the visitation was terminated early, true otherwise.
298
299 /// Recursively visit a lambda capture. \c Init is the expression that
300 /// will be used to initialize the capture.
301 ///
302 /// \returns false if the visitation was terminated early, true otherwise.
304 Expr *Init);
305
306 /// Recursively visit the syntactic or semantic form of an
307 /// initialization list.
308 ///
309 /// \returns false if the visitation was terminated early, true otherwise.
311 DataRecursionQueue *Queue = nullptr);
312
313 /// Recursively visit an Objective-C protocol reference with location
314 /// information.
315 ///
316 /// \returns false if the visitation was terminated early, true otherwise.
318
319 /// Recursively visit concept reference with location information.
320 ///
321 /// \returns false if the visitation was terminated early, true otherwise.
323
324 // Visit concept reference.
325 bool VisitConceptReference(ConceptReference *CR) { return true; }
326 // ---- Methods on Attrs ----
327
328 // Visit an attribute.
329 bool VisitAttr(Attr *A) { return true; }
330
331// Declare Traverse* and empty Visit* for all Attr classes.
332#define ATTR_VISITOR_DECLS_ONLY
333#include "clang/AST/AttrVisitor.inc"
334#undef ATTR_VISITOR_DECLS_ONLY
335
336// ---- Methods on Stmts ----
337
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>
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>
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(HLSLAttributedResourceType,
1161 { TRY_TO(TraverseType(T->getWrappedType())); })
1162
1163DEF_TRAVERSE_TYPE(HLSLInlineSpirvType, {
1164 for (auto &Operand : T->getOperands()) {
1165 if (Operand.isConstant() || Operand.isType()) {
1166 TRY_TO(TraverseType(Operand.getResultType()));
1167 }
1168 }
1169})
1170
1171DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
1172
1174 { TRY_TO(TraverseType(T->getUnderlyingType())); })
1175
1176template <typename Derived>
1177bool RecursiveASTVisitor<Derived>::TraverseTagType(TagType *T,
1178 bool TraverseQualifier) {
1179 if (TraverseQualifier)
1180 TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
1181 return true;
1182}
1183
1184DEF_TRAVERSE_TYPE(EnumType, { TRY_TO(TraverseTagType(T, TraverseQualifier)); })
1185DEF_TRAVERSE_TYPE(RecordType,
1186 { TRY_TO(TraverseTagType(T, TraverseQualifier)); })
1187DEF_TRAVERSE_TYPE(InjectedClassNameType,
1188 { TRY_TO(TraverseTagType(T, TraverseQualifier)); })
1189
1190DEF_TRAVERSE_TYPE(DependentNameType, {
1191 if (TraverseQualifier)
1192 TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
1193})
1194
1195DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
1196 if (TraverseQualifier) {
1197 TRY_TO(TraverseTemplateName(T->getTemplateName()));
1198 } else {
1199 // FIXME: Try to preserve the rest of the template name.
1200 TRY_TO(TraverseTemplateName(TemplateName(
1201 T->getTemplateName().getAsTemplateDecl(/*IgnoreDeduced=*/true))));
1202 }
1203 TRY_TO(TraverseTemplateArguments(T->template_arguments()));
1204})
1205
1206DEF_TRAVERSE_TYPE(DeducedTemplateSpecializationType, {
1207 if (TraverseQualifier) {
1208 TRY_TO(TraverseTemplateName(T->getTemplateName()));
1209 } else {
1210 // FIXME: Try to preserve the rest of the template name.
1211 TRY_TO(TraverseTemplateName(TemplateName(
1212 T->getTemplateName().getAsTemplateDecl(/*IgnoreDeduced=*/true))));
1213 }
1214 TRY_TO(TraverseType(T->getDeducedType()));
1215})
1216
1217DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); })
1218
1219DEF_TRAVERSE_TYPE(ObjCTypeParamType, {})
1220
1222
1223DEF_TRAVERSE_TYPE(ObjCObjectType, {
1224 // We have to watch out here because an ObjCInterfaceType's base
1225 // type is itself.
1226 if (T->getBaseType().getTypePtr() != T)
1227 TRY_TO(TraverseType(T->getBaseType()));
1228 for (auto typeArg : T->getTypeArgsAsWritten()) {
1229 TRY_TO(TraverseType(typeArg));
1230 }
1231})
1232
1234 { TRY_TO(TraverseType(T->getPointeeType())); })
1235
1236DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); })
1237
1238DEF_TRAVERSE_TYPE(PipeType, { TRY_TO(TraverseType(T->getElementType())); })
1239
1240DEF_TRAVERSE_TYPE(BitIntType, {})
1242 { TRY_TO(TraverseStmt(T->getNumBitsExpr())); })
1243
1245
1246#undef DEF_TRAVERSE_TYPE
1247
1248// ----------------- TypeLoc traversal -----------------
1249
1250// This macro makes available a variable TL, the passed-in TypeLoc.
1251// If requested, it calls WalkUpFrom* for the Type in the given TypeLoc,
1252// in addition to WalkUpFrom* for the TypeLoc itself, such that existing
1253// clients that override the WalkUpFrom*Type() and/or Visit*Type() methods
1254// continue to work.
1256 template <typename Derived> \
1257 bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc( \
1258 TYPE##Loc TL, bool TraverseQualifier) { \
1259 if (!getDerived().shouldTraversePostOrder()) { \
1260 TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
1261 if (getDerived().shouldWalkTypesOfTypeLocs()) \
1262 TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \
1263 } \
1264 { \
1265 CODE; \
1266 } \
1267 if (getDerived().shouldTraversePostOrder()) { \
1268 TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
1269 if (getDerived().shouldWalkTypesOfTypeLocs()) \
1270 TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \
1271 } \
1272 return true; \
1273 }
1274
1275template <typename Derived>
1277 QualifiedTypeLoc TL, bool TraverseQualifier) {
1278 assert(TraverseQualifier &&
1279 "Qualifiers should never occur within NestedNameSpecifiers");
1280 // Move this over to the 'main' typeloc tree. Note that this is a
1281 // move -- we pretend that we were really looking at the unqualified
1282 // typeloc all along -- rather than a recursion, so we don't follow
1283 // the normal CRTP plan of going through
1284 // getDerived().TraverseTypeLoc. If we did, we'd be traversing
1285 // twice for the same type (once as a QualifiedTypeLoc version of
1286 // the type, once as an UnqualifiedTypeLoc version of the type),
1287 // which in effect means we'd call VisitTypeLoc twice with the
1288 // 'same' type. This solves that problem, at the cost of never
1289 // seeing the qualified version of the type (unless the client
1290 // subclasses TraverseQualifiedTypeLoc themselves). It's not a
1291 // perfect solution. A perfect solution probably requires making
1292 // QualifiedTypeLoc a wrapper around TypeLoc -- like QualType is a
1293 // wrapper around Type* -- rather than being its own class in the
1294 // type hierarchy.
1295 return TraverseTypeLoc(TL.getUnqualifiedLoc());
1296}
1297
1299
1300// FIXME: ComplexTypeLoc is unfinished
1302 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1303})
1304
1305DEF_TRAVERSE_TYPELOC(PointerType,
1306 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1307
1309 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1310
1311DEF_TRAVERSE_TYPELOC(LValueReferenceType,
1312 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1313
1315 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1316
1317// We traverse this in the type case as well, but how is it not reached through
1318// the pointee type?
1319DEF_TRAVERSE_TYPELOC(MemberPointerType, {
1320 if (NestedNameSpecifierLoc QL = TL.getQualifierLoc())
1322 else
1323 TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
1324 TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
1325})
1326
1328 { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
1329
1330DEF_TRAVERSE_TYPELOC(DecayedType,
1331 { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
1332
1333template <typename Derived>
1334bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
1335 // This isn't available for ArrayType, but is for the ArrayTypeLoc.
1336 TRY_TO(TraverseStmt(TL.getSizeExpr()));
1337 return true;
1338}
1339
1341 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1342 TRY_TO(TraverseArrayTypeLocHelper(TL));
1343})
1344
1345DEF_TRAVERSE_TYPELOC(ArrayParameterType, {
1346 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1347 TRY_TO(TraverseArrayTypeLocHelper(TL));
1348})
1349
1351 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1352 TRY_TO(TraverseArrayTypeLocHelper(TL));
1353})
1354
1355DEF_TRAVERSE_TYPELOC(VariableArrayType, {
1356 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1357 TRY_TO(TraverseArrayTypeLocHelper(TL));
1358})
1359
1361 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1362 TRY_TO(TraverseArrayTypeLocHelper(TL));
1363})
1364
1365DEF_TRAVERSE_TYPELOC(DependentAddressSpaceType, {
1366 TRY_TO(TraverseStmt(TL.getTypePtr()->getAddrSpaceExpr()));
1367 TRY_TO(TraverseType(TL.getTypePtr()->getPointeeType()));
1368})
1369
1370// FIXME: order? why not size expr first?
1371// FIXME: base VectorTypeLoc is unfinished
1373 if (TL.getTypePtr()->getSizeExpr())
1374 TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
1375 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1376})
1377
1378// FIXME: VectorTypeLoc is unfinished
1379DEF_TRAVERSE_TYPELOC(VectorType, {
1380 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1381})
1382
1384 if (TL.getTypePtr()->getSizeExpr())
1385 TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
1386 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1387})
1388
1389// FIXME: size and attributes
1390// FIXME: base VectorTypeLoc is unfinished
1391DEF_TRAVERSE_TYPELOC(ExtVectorType, {
1392 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1393})
1394
1396 TRY_TO(TraverseStmt(TL.getAttrRowOperand()));
1397 TRY_TO(TraverseStmt(TL.getAttrColumnOperand()));
1398 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1399})
1400
1401DEF_TRAVERSE_TYPELOC(DependentSizedMatrixType, {
1402 TRY_TO(TraverseStmt(TL.getAttrRowOperand()));
1403 TRY_TO(TraverseStmt(TL.getAttrColumnOperand()));
1404 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1405})
1406
1408 { TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); })
1409
1410// FIXME: location of exception specifications (attributes?)
1411DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
1412 TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
1413
1414 const FunctionProtoType *T = TL.getTypePtr();
1415
1416 for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) {
1417 if (TL.getParam(I)) {
1418 TRY_TO(TraverseDecl(TL.getParam(I)));
1419 } else if (I < T->getNumParams()) {
1420 TRY_TO(TraverseType(T->getParamType(I)));
1421 }
1422 }
1423
1424 for (const auto &E : T->exceptions()) {
1425 TRY_TO(TraverseType(E));
1426 }
1427
1428 if (Expr *NE = T->getNoexceptExpr())
1429 TRY_TO(TraverseStmt(NE));
1430})
1431
1433 if (NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
1434 TraverseQualifier && QualifierLoc)
1436})
1437DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {
1438 if (NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
1439 TraverseQualifier && QualifierLoc)
1441})
1443 if (NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
1444 TraverseQualifier && QualifierLoc)
1446})
1447
1448DEF_TRAVERSE_TYPELOC(TypeOfExprType,
1449 { TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); })
1450
1452 TRY_TO(TraverseTypeLoc(TL.getUnmodifiedTInfo()->getTypeLoc()));
1453})
1454
1455// FIXME: location of underlying expr
1456DEF_TRAVERSE_TYPELOC(DecltypeType, {
1457 TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
1458})
1459
1460DEF_TRAVERSE_TYPELOC(PackIndexingType, {
1461 TRY_TO(TraverseType(TL.getPattern()));
1462 TRY_TO(TraverseStmt(TL.getTypePtr()->getIndexExpr()));
1463})
1464
1465DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
1466 TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
1467})
1468
1470 TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
1471 if (TL.isConstrained()) {
1472 TRY_TO(TraverseConceptReference(TL.getConceptReference()));
1473 }
1474})
1475
1476DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {})
1477DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, {
1478 TRY_TO(TraverseType(TL.getTypePtr()->getReplacementType()));
1479})
1480
1481template <typename Derived>
1482bool RecursiveASTVisitor<Derived>::TraverseSubstPackTypeLocHelper(
1483 SubstPackTypeLoc TL) {
1484 TRY_TO(TraverseTemplateArgument(TL.getTypePtr()->getArgumentPack()));
1485 return true;
1486}
1487
1488template <typename Derived>
1489bool RecursiveASTVisitor<Derived>::TraverseSubstPackTypeHelper(
1490 SubstPackType *T) {
1491 TRY_TO(TraverseTemplateArgument(T->getArgumentPack()));
1492 return true;
1493}
1494
1495DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType,
1496 { TRY_TO(TraverseSubstPackTypeLocHelper(TL)); })
1497
1498DEF_TRAVERSE_TYPELOC(SubstBuiltinTemplatePackType,
1499 { TRY_TO(TraverseSubstPackTypeLocHelper(TL)); })
1500
1501DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
1502
1503DEF_TRAVERSE_TYPELOC(MacroQualifiedType,
1504 { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
1505
1507 { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
1508
1509DEF_TRAVERSE_TYPELOC(CountAttributedType,
1510 { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
1511
1512DEF_TRAVERSE_TYPELOC(BTFTagAttributedType,
1513 { TRY_TO(TraverseTypeLoc(TL.getWrappedLoc())); })
1514
1515DEF_TRAVERSE_TYPELOC(HLSLAttributedResourceType,
1516 { TRY_TO(TraverseTypeLoc(TL.getWrappedLoc())); })
1517
1518DEF_TRAVERSE_TYPELOC(HLSLInlineSpirvType,
1519 { TRY_TO(TraverseType(TL.getType())); })
1520
1521template <typename Derived>
1522bool RecursiveASTVisitor<Derived>::TraverseTagTypeLoc(TagTypeLoc TL,
1523 bool TraverseQualifier) {
1524 if (NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
1525 TraverseQualifier && QualifierLoc)
1527 return true;
1528}
1529
1531 { TRY_TO(TraverseTagTypeLoc(TL, TraverseQualifier)); })
1532DEF_TRAVERSE_TYPELOC(RecordType,
1533 { TRY_TO(TraverseTagTypeLoc(TL, TraverseQualifier)); })
1534DEF_TRAVERSE_TYPELOC(InjectedClassNameType,
1535 { TRY_TO(TraverseTagTypeLoc(TL, TraverseQualifier)); })
1536
1537DEF_TRAVERSE_TYPELOC(DependentNameType, {
1538 if (TraverseQualifier)
1539 TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
1540})
1541
1542DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
1543 if (TraverseQualifier)
1544 TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
1545
1546 // FIXME: Try to preserve the rest of the template name.
1547 TRY_TO(TraverseTemplateName(
1548 TemplateName(TL.getTypePtr()->getTemplateName().getAsTemplateDecl(
1549 /*IgnoreDeduced=*/true))));
1550
1551 for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
1552 TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
1553 }
1554})
1555
1556DEF_TRAVERSE_TYPELOC(DeducedTemplateSpecializationType, {
1557 if (TraverseQualifier)
1558 TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
1559
1560 const auto *T = TL.getTypePtr();
1561 // FIXME: Try to preserve the rest of the template name.
1563 TraverseTemplateName(TemplateName(T->getTemplateName().getAsTemplateDecl(
1564 /*IgnoreDeduced=*/true))));
1565
1566 TRY_TO(TraverseType(T->getDeducedType()));
1567})
1568
1569DEF_TRAVERSE_TYPELOC(PackExpansionType,
1570 { TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); })
1571
1572DEF_TRAVERSE_TYPELOC(ObjCTypeParamType, {
1573 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1574 ObjCProtocolLoc ProtocolLoc(TL.getProtocol(I), TL.getProtocolLoc(I));
1575 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1576 }
1577})
1578
1580
1581DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
1582 // We have to watch out here because an ObjCInterfaceType's base
1583 // type is itself.
1584 if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
1585 TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
1586 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
1587 TRY_TO(TraverseTypeLoc(TL.getTypeArgTInfo(i)->getTypeLoc()));
1588 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1589 ObjCProtocolLoc ProtocolLoc(TL.getProtocol(I), TL.getProtocolLoc(I));
1590 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1591 }
1592})
1593
1595 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1596
1597DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
1598
1599DEF_TRAVERSE_TYPELOC(PipeType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
1600
1603 TRY_TO(TraverseStmt(TL.getTypePtr()->getNumBitsExpr()));
1604})
1605
1607
1609
1610// ----------------- Decl traversal -----------------
1611//
1612// For a Decl, we automate (in the DEF_TRAVERSE_DECL macro) traversing
1613// the children that come from the DeclContext associated with it.
1614// Therefore each Traverse* only needs to worry about children other
1615// than those.
1616
1617template <typename Derived>
1619 const Decl *Child) {
1620 // BlockDecls are traversed through BlockExprs,
1621 // CapturedDecls are traversed through CapturedStmts.
1622 if (isa<BlockDecl>(Child) || isa<CapturedDecl>(Child))
1623 return true;
1624 // Lambda classes are traversed through LambdaExprs.
1625 if (const CXXRecordDecl* Cls = dyn_cast<CXXRecordDecl>(Child))
1626 return Cls->isLambda();
1627 return false;
1628}
1629
1630template <typename Derived>
1631bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
1632 if (!DC)
1633 return true;
1634
1635 for (auto *Child : DC->decls()) {
1636 if (!canIgnoreChildDeclWhileTraversingDeclContext(Child))
1637 TRY_TO(TraverseDecl(Child));
1638 }
1639
1640 return true;
1641}
1642
1643// This macro makes available a variable D, the passed-in decl.
1644#define DEF_TRAVERSE_DECL(DECL, CODE) \
1645 template <typename Derived> \
1646 bool RecursiveASTVisitor<Derived>::Traverse##DECL(DECL *D) { \
1647 bool ShouldVisitChildren = true; \
1648 bool ReturnValue = true; \
1649 if (!getDerived().shouldTraversePostOrder()) \
1650 TRY_TO(WalkUpFrom##DECL(D)); \
1651 { CODE; } \
1652 if (ReturnValue && ShouldVisitChildren) \
1653 TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D))); \
1654 if (ReturnValue) { \
1655 /* Visit any attributes attached to this declaration. */ \
1656 for (auto *I : D->attrs()) \
1657 TRY_TO(getDerived().TraverseAttr(I)); \
1658 } \
1659 if (ReturnValue && getDerived().shouldTraversePostOrder()) \
1660 TRY_TO(WalkUpFrom##DECL(D)); \
1661 return ReturnValue; \
1662 }
1663
1665
1667 if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
1668 TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
1669 TRY_TO(TraverseStmt(D->getBody()));
1670 for (const auto &I : D->captures()) {
1671 if (I.hasCopyExpr()) {
1672 TRY_TO(TraverseStmt(I.getCopyExpr()));
1673 }
1674 }
1675 ShouldVisitChildren = false;
1676})
1677
1679 TRY_TO(TraverseStmt(D->getBody()));
1680 ShouldVisitChildren = false;
1681})
1682
1684 TRY_TO(TraverseStmt(D->getBody()));
1685 ShouldVisitChildren = false;
1686})
1687
1689
1691
1693
1695 TRY_TO(TraverseStmt(D->getTemporaryExpr()));
1696})
1697
1699 { TRY_TO(TraverseStmt(D->getAsmStringExpr())); })
1700
1701DEF_TRAVERSE_DECL(TopLevelStmtDecl, { TRY_TO(TraverseStmt(D->getStmt())); })
1702
1704
1706 // Friend is either decl or a type.
1707 if (D->getFriendType()) {
1708 TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
1709 // Traverse any CXXRecordDecl owned by this type, since
1710 // it will not be in the parent context:
1711 if (auto *TT = D->getFriendType()->getType()->getAs<TagType>();
1712 TT && TT->isTagOwned())
1713 TRY_TO(TraverseDecl(TT->getDecl()));
1714 } else {
1715 TRY_TO(TraverseDecl(D->getFriendDecl()));
1716 }
1717})
1718
1720 if (D->getFriendType())
1721 TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
1722 else
1723 TRY_TO(TraverseDecl(D->getFriendDecl()));
1724 for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
1725 TemplateParameterList *TPL = D->getTemplateParameterList(I);
1726 for (TemplateParameterList::iterator ITPL = TPL->begin(), ETPL = TPL->end();
1727 ITPL != ETPL; ++ITPL) {
1728 TRY_TO(TraverseDecl(*ITPL));
1729 }
1730 }
1731})
1732
1734
1736
1737DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {// FIXME: implement this
1738 })
1739
1741 TRY_TO(TraverseStmt(D->getAssertExpr()));
1742 TRY_TO(TraverseStmt(D->getMessage()));
1743})
1744
1746 // Code in an unnamed namespace shows up automatically in
1747 // decls_begin()/decls_end(). Thus we don't need to recurse on
1748 // D->getAnonymousNamespace().
1749
1750 // If the traversal scope is set, then consider them to be the children of
1751 // the TUDecl, rather than traversing (and loading?) all top-level decls.
1752 auto Scope = D->getASTContext().getTraversalScope();
1753 bool HasLimitedScope =
1754 Scope.size() != 1 || !isa<TranslationUnitDecl>(Scope.front());
1755 if (HasLimitedScope) {
1756 ShouldVisitChildren = false; // we'll do that here instead
1757 for (auto *Child : Scope) {
1758 if (!canIgnoreChildDeclWhileTraversingDeclContext(Child))
1759 TRY_TO(TraverseDecl(Child));
1760 }
1761 }
1762})
1763
1765
1767
1769
1771 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1772
1773 // We shouldn't traverse an aliased namespace, since it will be
1774 // defined (and, therefore, traversed) somewhere else.
1775 ShouldVisitChildren = false;
1776})
1777
1778DEF_TRAVERSE_DECL(LabelDecl, {// There is no code in a LabelDecl.
1779 })
1780
1783 {// Code in an unnamed namespace shows up automatically in
1784 // decls_begin()/decls_end(). Thus we don't need to recurse on
1785 // D->getAnonymousNamespace().
1786 })
1787
1788DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement
1789 })
1790
1792 if (ObjCTypeParamList *typeParamList = D->getTypeParamList()) {
1793 for (auto typeParam : *typeParamList) {
1794 TRY_TO(TraverseObjCTypeParamDecl(typeParam));
1795 }
1796 }
1797 for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
1798 ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
1799 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1800 }
1801})
1802
1803DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement
1804 })
1805
1806DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement
1807 })
1808
1810 if (ObjCTypeParamList *typeParamList = D->getTypeParamListAsWritten()) {
1811 for (auto typeParam : *typeParamList) {
1812 TRY_TO(TraverseObjCTypeParamDecl(typeParam));
1813 }
1814 }
1815
1816 if (TypeSourceInfo *superTInfo = D->getSuperClassTInfo()) {
1817 TRY_TO(TraverseTypeLoc(superTInfo->getTypeLoc()));
1818 }
1819 if (D->isThisDeclarationADefinition()) {
1820 for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
1821 ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
1822 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1823 }
1824 }
1825})
1826
1828 if (D->isThisDeclarationADefinition()) {
1829 for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
1830 ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
1831 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1832 }
1833 }
1834})
1835
1837 if (D->getReturnTypeSourceInfo()) {
1838 TRY_TO(TraverseTypeLoc(D->getReturnTypeSourceInfo()->getTypeLoc()));
1839 }
1840 for (ParmVarDecl *Parameter : D->parameters()) {
1841 TRY_TO(TraverseDecl(Parameter));
1842 }
1843 if (D->isThisDeclarationADefinition()) {
1844 TRY_TO(TraverseStmt(D->getBody()));
1845 }
1846 ShouldVisitChildren = false;
1847})
1848
1850 if (D->hasExplicitBound()) {
1851 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
1852 // We shouldn't traverse D->getTypeForDecl(); it's a result of
1853 // declaring the type alias, not something that was written in the
1854 // source.
1855 }
1856})
1857
1859 if (D->getTypeSourceInfo())
1860 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
1861 else
1862 TRY_TO(TraverseType(D->getType()));
1863 ShouldVisitChildren = false;
1864})
1865
1867 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1868 TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
1869})
1870
1872 { TRY_TO(TraverseTypeLoc(D->getEnumTypeLoc())); })
1873
1875
1877 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1878})
1879
1881
1883
1885 for (auto *I : D->varlist()) {
1886 TRY_TO(TraverseStmt(I));
1887 }
1888})
1889
1891 for (auto *I : D->varlist()) {
1892 TRY_TO(TraverseStmt(I));
1893 }
1894})
1895
1897 for (auto *C : D->clauselists()) {
1898 TRY_TO(TraverseOMPClause(C));
1899 }
1900})
1901
1903 TRY_TO(TraverseStmt(D->getCombiner()));
1904 if (auto *Initializer = D->getInitializer())
1905 TRY_TO(TraverseStmt(Initializer));
1906 TRY_TO(TraverseType(D->getType()));
1907 return true;
1908})
1909
1911 for (auto *C : D->clauselists())
1912 TRY_TO(TraverseOMPClause(C));
1913 TRY_TO(TraverseType(D->getType()));
1914 return true;
1915})
1916
1917DEF_TRAVERSE_DECL(OMPCapturedExprDecl, { TRY_TO(TraverseVarHelper(D)); })
1918
1920 for (auto *I : D->varlist())
1921 TRY_TO(TraverseStmt(I));
1922 for (auto *C : D->clauselists())
1923 TRY_TO(TraverseOMPClause(C));
1924})
1925
1927 { TRY_TO(VisitOpenACCClauseList(D->clauses())); })
1928
1930 TRY_TO(TraverseStmt(D->getFunctionReference()));
1931 TRY_TO(VisitOpenACCClauseList(D->clauses()));
1932})
1933
1934// A helper method for TemplateDecl's children.
1935template <typename Derived>
1936bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
1937 TemplateParameterList *TPL) {
1938 if (TPL) {
1939 for (NamedDecl *D : *TPL) {
1940 TRY_TO(TraverseDecl(D));
1941 }
1942 if (Expr *RequiresClause = TPL->getRequiresClause()) {
1943 TRY_TO(TraverseStmt(RequiresClause));
1944 }
1945 }
1946 return true;
1947}
1948
1949template <typename Derived>
1950template <typename T>
1951bool RecursiveASTVisitor<Derived>::TraverseDeclTemplateParameterLists(T *D) {
1952 for (unsigned i = 0; i < D->getNumTemplateParameterLists(); i++) {
1953 TemplateParameterList *TPL = D->getTemplateParameterList(i);
1954 TraverseTemplateParameterListHelper(TPL);
1955 }
1956 return true;
1957}
1958
1959template <typename Derived>
1961 ClassTemplateDecl *D) {
1962 for (auto *SD : D->specializations()) {
1963 for (auto *RD : SD->redecls()) {
1964 assert(!cast<CXXRecordDecl>(RD)->isInjectedClassName());
1965 switch (
1966 cast<ClassTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
1967 // Visit the implicit instantiations with the requested pattern.
1968 case TSK_Undeclared:
1970 TRY_TO(TraverseDecl(RD));
1971 break;
1972
1973 // We don't need to do anything on an explicit instantiation
1974 // or explicit specialization because there will be an explicit
1975 // node for it elsewhere.
1979 break;
1980 }
1981 }
1982 }
1983
1984 return true;
1985}
1986
1987template <typename Derived>
1989 VarTemplateDecl *D) {
1990 for (auto *SD : D->specializations()) {
1991 for (auto *RD : SD->redecls()) {
1992 switch (
1993 cast<VarTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
1994 case TSK_Undeclared:
1996 TRY_TO(TraverseDecl(RD));
1997 break;
1998
2002 break;
2003 }
2004 }
2005 }
2006
2007 return true;
2008}
2009
2010// A helper method for traversing the instantiations of a
2011// function while skipping its specializations.
2012template <typename Derived>
2015 for (auto *FD : D->specializations()) {
2016 for (auto *RD : FD->redecls()) {
2017 switch (RD->getTemplateSpecializationKind()) {
2018 case TSK_Undeclared:
2020 // We don't know what kind of FunctionDecl this is.
2021 TRY_TO(TraverseDecl(RD));
2022 break;
2023
2024 // FIXME: For now traverse explicit instantiations here. Change that
2025 // once they are represented as dedicated nodes in the AST.
2028 TRY_TO(TraverseDecl(RD));
2029 break;
2030
2032 break;
2033 }
2034 }
2035 }
2036
2037 return true;
2038}
2039
2040// This macro unifies the traversal of class, variable and function
2041// template declarations.
2042#define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND) \
2043 DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, { \
2044 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
2045 TRY_TO(TraverseDecl(D->getTemplatedDecl())); \
2046 \
2047 /* By default, we do not traverse the instantiations of \
2048 class templates since they do not appear in the user code. The \
2049 following code optionally traverses them. \
2050 \
2051 We only traverse the class instantiations when we see the canonical \
2052 declaration of the template, to ensure we only visit them once. */ \
2053 if (getDerived().shouldVisitTemplateInstantiations() && \
2054 D == D->getCanonicalDecl()) \
2055 TRY_TO(TraverseTemplateInstantiations(D)); \
2056 \
2057 /* Note that getInstantiatedFromMemberTemplate() is just a link \
2058 from a template instantiation back to the template from which \
2059 it was instantiated, and thus should not be traversed. */ \
2060 })
2061
2065
2067 // D is the "T" in something like
2068 // template <template <typename> class T> class container { };
2069 TRY_TO(TraverseDecl(D->getTemplatedDecl()));
2070 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
2071 TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
2072 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
2073})
2074
2076 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
2077})
2078
2079template <typename Derived>
2080bool RecursiveASTVisitor<Derived>::TraverseTemplateTypeParamDeclConstraints(
2081 const TemplateTypeParmDecl *D) {
2082 if (const auto *TC = D->getTypeConstraint())
2083 TRY_TO(TraverseTypeConstraint(TC));
2084 return true;
2085}
2086
2088 // D is the "T" in something like "template<typename T> class vector;"
2089 if (D->getTypeForDecl())
2090 TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
2091 TRY_TO(TraverseTemplateTypeParamDeclConstraints(D));
2092 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
2093 TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
2094})
2095
2097 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
2098 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2099 // declaring the typedef, not something that was written in the
2100 // source.
2101})
2102
2104 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
2105 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2106 // declaring the type alias, not something that was written in the
2107 // source.
2108})
2109
2111 TRY_TO(TraverseDecl(D->getTemplatedDecl()));
2112 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
2113})
2114
2116 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
2117 TRY_TO(TraverseStmt(D->getConstraintExpr()));
2118})
2119
2121 // A dependent using declaration which was marked with 'typename'.
2122 // template<class T> class A : public B<T> { using typename B<T>::foo; };
2123 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2124 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2125 // declaring the type, not something that was written in the
2126 // source.
2127})
2128
2130
2132 TRY_TO(TraverseDeclTemplateParameterLists(D));
2133
2134 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2135 if (auto *TSI = D->getIntegerTypeSourceInfo())
2136 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
2137 // The enumerators are already traversed by
2138 // decls_begin()/decls_end().
2139})
2140
2141// Helper methods for RecordDecl and its children.
2142template <typename Derived>
2143bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) {
2144 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2145 // declaring the type, not something that was written in the source.
2146
2147 TRY_TO(TraverseDeclTemplateParameterLists(D));
2148 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2149 return true;
2150}
2151
2152template <typename Derived>
2154 const CXXBaseSpecifier &Base) {
2155 TRY_TO(TraverseTypeLoc(Base.getTypeSourceInfo()->getTypeLoc()));
2156 return true;
2157}
2158
2159template <typename Derived>
2160bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(CXXRecordDecl *D) {
2161 if (!TraverseRecordHelper(D))
2162 return false;
2163 if (D->isCompleteDefinition()) {
2164 for (const auto &I : D->bases()) {
2165 TRY_TO(TraverseCXXBaseSpecifier(I));
2166 }
2167 // We don't traverse the friends or the conversions, as they are
2168 // already in decls_begin()/decls_end().
2169 }
2170 return true;
2171}
2172
2173DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); })
2174
2175DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
2176
2177template <typename Derived>
2178bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
2179 const TemplateArgumentLoc *TAL, unsigned Count) {
2180 for (unsigned I = 0; I < Count; ++I) {
2181 TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
2182 }
2183 return true;
2184}
2185
2186#define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
2187 DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, { \
2188 /* For implicit instantiations ("set<int> x;"), we don't want to \
2189 recurse at all, since the instatiated template isn't written in \
2190 the source code anywhere. (Note the instatiated *type* -- \
2191 set<int> -- is written, and will still get a callback of \
2192 TemplateSpecializationType). For explicit instantiations \
2193 ("template set<int>;"), we do need a callback, since this \
2194 is the only callback that's made for this instantiation. \
2195 We use getTemplateArgsAsWritten() to distinguish. */ \
2196 if (const auto *ArgsWritten = D->getTemplateArgsAsWritten()) { \
2197 assert(D->getTemplateSpecializationKind() != TSK_ImplicitInstantiation); \
2198 /* The args that remains unspecialized. */ \
2199 TRY_TO(TraverseTemplateArgumentLocsHelper( \
2200 ArgsWritten->getTemplateArgs(), ArgsWritten->NumTemplateArgs)); \
2201 } \
2202 \
2203 if (getDerived().shouldVisitTemplateInstantiations() || \
2204 D->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) { \
2205 /* Traverse base definition for explicit specializations */ \
2206 TRY_TO(Traverse##DECLKIND##Helper(D)); \
2207 } else { \
2208 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); \
2209 \
2210 /* Returning from here skips traversing the \
2211 declaration context of the *TemplateSpecializationDecl \
2212 (embedded in the DEF_TRAVERSE_DECL() macro) \
2213 which contains the instantiated members of the template. */ \
2214 return true; \
2215 } \
2216 })
2217
2220
2221#define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
2222 DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, { \
2223 /* The partial specialization. */ \
2224 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
2225 /* The args that remains unspecialized. */ \
2226 TRY_TO(TraverseTemplateArgumentLocsHelper( \
2227 D->getTemplateArgsAsWritten()->getTemplateArgs(), \
2228 D->getTemplateArgsAsWritten()->NumTemplateArgs)); \
2229 \
2230 /* Don't need the *TemplatePartialSpecializationHelper, even \
2231 though that's our parent class -- we already visit all the \
2232 template args here. */ \
2233 TRY_TO(Traverse##DECLKIND##Helper(D)); \
2234 \
2235 /* Instantiations will have been visited with the primary template. */ \
2236 })
2237
2240
2241DEF_TRAVERSE_DECL(EnumConstantDecl, { TRY_TO(TraverseStmt(D->getInitExpr())); })
2242
2244 // Like UnresolvedUsingTypenameDecl, but without the 'typename':
2245 // template <class T> Class A : public Base<T> { using Base<T>::foo; };
2246 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2247 TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
2248})
2249
2251
2252template <typename Derived>
2253bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
2254 TRY_TO(TraverseDeclTemplateParameterLists(D));
2255 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2256 if (D->getTypeSourceInfo())
2257 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
2258 else
2259 TRY_TO(TraverseType(D->getType()));
2260 return true;
2261}
2262
2264 TRY_TO(TraverseVarHelper(D));
2265 for (auto *Binding : D->bindings()) {
2266 TRY_TO(TraverseDecl(Binding));
2267 }
2268})
2269
2271 if (getDerived().shouldVisitImplicitCode()) {
2272 TRY_TO(TraverseStmt(D->getBinding()));
2273 if (const auto HoldingVar = D->getHoldingVar())
2274 TRY_TO(TraverseDecl(HoldingVar));
2275 }
2276})
2277
2278DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
2279
2282
2284
2286 TRY_TO(TraverseDeclaratorHelper(D));
2287 if (D->isBitField())
2288 TRY_TO(TraverseStmt(D->getBitWidth()));
2289 if (D->hasInClassInitializer())
2290 TRY_TO(TraverseStmt(D->getInClassInitializer()));
2291})
2292
2294 TRY_TO(TraverseDeclaratorHelper(D));
2295 if (D->isBitField())
2296 TRY_TO(TraverseStmt(D->getBitWidth()));
2297 // FIXME: implement the rest.
2298})
2299
2301 TRY_TO(TraverseDeclaratorHelper(D));
2302 if (D->isBitField())
2303 TRY_TO(TraverseStmt(D->getBitWidth()));
2304 // FIXME: implement the rest.
2305})
2306
2307template <typename Derived>
2308bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
2309 TRY_TO(TraverseDeclTemplateParameterLists(D));
2310 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2311 TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
2312
2313 // If we're an explicit template specialization, iterate over the
2314 // template args that were explicitly specified. If we were doing
2315 // this in typing order, we'd do it between the return type and
2316 // the function args, but both are handled by the FunctionTypeLoc
2317 // above, so we have to choose one side. I've decided to do before.
2318 if (const FunctionTemplateSpecializationInfo *FTSI =
2319 D->getTemplateSpecializationInfo()) {
2320 if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared &&
2321 FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
2322 // A specialization might not have explicit template arguments if it has
2323 // a templated return type and concrete arguments.
2324 if (const ASTTemplateArgumentListInfo *TALI =
2325 FTSI->TemplateArgumentsAsWritten) {
2326 TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
2327 TALI->NumTemplateArgs));
2328 }
2329 }
2330 } else if (const DependentFunctionTemplateSpecializationInfo *DFSI =
2331 D->getDependentSpecializationInfo()) {
2332 if (const ASTTemplateArgumentListInfo *TALI =
2333 DFSI->TemplateArgumentsAsWritten) {
2334 TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
2335 TALI->NumTemplateArgs));
2336 }
2337 }
2338
2339 // Visit the function type itself, which can be either
2340 // FunctionNoProtoType or FunctionProtoType, or a typedef. This
2341 // also covers the return type and the function parameters,
2342 // including exception specifications.
2343 if (TypeSourceInfo *TSI = D->getTypeSourceInfo()) {
2344 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
2345 } else if (getDerived().shouldVisitImplicitCode()) {
2346 // Visit parameter variable declarations of the implicit function
2347 // if the traverser is visiting implicit code. Parameter variable
2348 // declarations do not have valid TypeSourceInfo, so to visit them
2349 // we need to traverse the declarations explicitly.
2350 for (ParmVarDecl *Parameter : D->parameters()) {
2351 TRY_TO(TraverseDecl(Parameter));
2352 }
2353 }
2354
2355 // Visit the trailing requires clause, if any.
2356 if (const AssociatedConstraint &TrailingRequiresClause =
2357 D->getTrailingRequiresClause()) {
2358 TRY_TO(TraverseStmt(
2359 const_cast<Expr *>(TrailingRequiresClause.ConstraintExpr)));
2360 }
2361
2362 if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
2363 // Constructor initializers.
2364 for (auto *I : Ctor->inits()) {
2365 if (I->isWritten() || getDerived().shouldVisitImplicitCode())
2366 TRY_TO(TraverseConstructorInitializer(I));
2367 }
2368 }
2369
2370 bool VisitBody =
2371 D->isThisDeclarationADefinition() &&
2372 // Don't visit the function body if the function definition is generated
2373 // by clang.
2374 (!D->isDefaulted() || getDerived().shouldVisitImplicitCode());
2375
2376 if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
2377 if (const CXXRecordDecl *RD = MD->getParent()) {
2378 if (RD->isLambda() &&
2379 declaresSameEntity(RD->getLambdaCallOperator(), MD)) {
2380 VisitBody = VisitBody && getDerived().shouldVisitLambdaBody();
2381 }
2382 }
2383 }
2384
2385 if (VisitBody) {
2386 TRY_TO(TraverseStmt(D->getBody()));
2387 // Body may contain using declarations whose shadows are parented to the
2388 // FunctionDecl itself.
2389 for (auto *Child : D->decls()) {
2390 if (isa<UsingShadowDecl>(Child))
2391 TRY_TO(TraverseDecl(Child));
2392 }
2393 }
2394 return true;
2395}
2396
2398 // We skip decls_begin/decls_end, which are already covered by
2399 // TraverseFunctionHelper().
2400 ShouldVisitChildren = false;
2401 ReturnValue = TraverseFunctionHelper(D);
2402})
2403
2405 // We skip decls_begin/decls_end, which are already covered by
2406 // TraverseFunctionHelper().
2407 ShouldVisitChildren = false;
2408 ReturnValue = TraverseFunctionHelper(D);
2409})
2410
2412 // We skip decls_begin/decls_end, which are already covered by
2413 // TraverseFunctionHelper().
2414 ShouldVisitChildren = false;
2415 ReturnValue = TraverseFunctionHelper(D);
2416})
2417
2419 // We skip decls_begin/decls_end, which are already covered by
2420 // TraverseFunctionHelper().
2421 ShouldVisitChildren = false;
2422 ReturnValue = TraverseFunctionHelper(D);
2423})
2424
2425// CXXConversionDecl is the declaration of a type conversion operator.
2426// It's not a cast expression.
2428 // We skip decls_begin/decls_end, which are already covered by
2429 // TraverseFunctionHelper().
2430 ShouldVisitChildren = false;
2431 ReturnValue = TraverseFunctionHelper(D);
2432})
2433
2435 // We skip decls_begin/decls_end, which are already covered by
2436 // TraverseFunctionHelper().
2437 ShouldVisitChildren = false;
2438 ReturnValue = TraverseFunctionHelper(D);
2439})
2440
2441template <typename Derived>
2442bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
2443 TRY_TO(TraverseDeclaratorHelper(D));
2444 // Default params are taken care of when we traverse the ParmVarDecl.
2445 if (!isa<ParmVarDecl>(D) &&
2446 (!D->isCXXForRangeDecl() || getDerived().shouldVisitImplicitCode()))
2447 TRY_TO(TraverseStmt(D->getInit()));
2448 return true;
2449}
2450
2451DEF_TRAVERSE_DECL(VarDecl, { TRY_TO(TraverseVarHelper(D)); })
2452
2453DEF_TRAVERSE_DECL(ImplicitParamDecl, { TRY_TO(TraverseVarHelper(D)); })
2454
2456 // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
2457 TRY_TO(TraverseDeclaratorHelper(D));
2458 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
2459 TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
2460})
2461
2463 TRY_TO(TraverseVarHelper(D));
2464
2465 if (D->hasDefaultArg() && D->hasUninstantiatedDefaultArg() &&
2466 !D->hasUnparsedDefaultArg())
2467 TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
2468
2469 if (D->hasDefaultArg() && !D->hasUninstantiatedDefaultArg() &&
2470 !D->hasUnparsedDefaultArg())
2471 TRY_TO(TraverseStmt(D->getDefaultArg()));
2472})
2473
2475
2477 TRY_TO(TraverseTemplateArguments(D->getTemplateArguments()));
2478})
2479
2480#undef DEF_TRAVERSE_DECL
2481
2482// ----------------- Stmt traversal -----------------
2483//
2484// For stmts, we automate (in the DEF_TRAVERSE_STMT macro) iterating
2485// over the children defined in children() (every stmt defines these,
2486// though sometimes the range is empty). Each individual Traverse*
2487// method only needs to worry about children other than those. To see
2488// what children() does for a given class, see, e.g.,
2489// http://clang.llvm.org/doxygen/Stmt_8cpp_source.html
2490
2491// This macro makes available a variable S, the passed-in stmt.
2492#define DEF_TRAVERSE_STMT(STMT, CODE) \
2493 template <typename Derived> \
2495 STMT *S, DataRecursionQueue *Queue) { \
2496 bool ShouldVisitChildren = true; \
2497 bool ReturnValue = true; \
2498 if (!getDerived().shouldTraversePostOrder()) \
2499 TRY_TO(WalkUpFrom##STMT(S)); \
2500 { CODE; } \
2501 if (ShouldVisitChildren) { \
2502 for (Stmt * SubStmt : getDerived().getStmtChildren(S)) { \
2503 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); \
2504 } \
2505 } \
2506 /* Call WalkUpFrom if TRY_TO_TRAVERSE_OR_ENQUEUE_STMT has traversed the \
2507 * children already. If TRY_TO_TRAVERSE_OR_ENQUEUE_STMT only enqueued the \
2508 * children, PostVisitStmt will call WalkUpFrom after we are done visiting \
2509 * children. */ \
2510 if (!Queue && ReturnValue && getDerived().shouldTraversePostOrder()) { \
2511 TRY_TO(WalkUpFrom##STMT(S)); \
2512 } \
2513 return ReturnValue; \
2514 }
2515
2517 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAsmStringExpr());
2518 for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
2519 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInputConstraintExpr(I));
2520 }
2521 for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
2522 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOutputConstraintExpr(I));
2523 }
2524 for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
2525 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getClobberExpr(I));
2526 }
2527 // children() iterates over inputExpr and outputExpr.
2528})
2529
2531 MSAsmStmt,
2532 {// FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc. Once
2533 // added this needs to be implemented.
2534 })
2535
2537 TRY_TO(TraverseDecl(S->getExceptionDecl()));
2538 // children() iterates over the handler block.
2539})
2540
2542 for (auto *I : S->decls()) {
2543 TRY_TO(TraverseDecl(I));
2544 }
2545 // Suppress the default iteration over children() by
2546 // returning. Here's why: A DeclStmt looks like 'type var [=
2547 // initializer]'. The decls above already traverse over the
2548 // initializers, so we don't have to do it again (which
2549 // children() would do).
2550 ShouldVisitChildren = false;
2551})
2552
2553// These non-expr stmts (most of them), do not need any action except
2554// iterating over the children.
2577
2579 if (!getDerived().shouldVisitImplicitCode()) {
2580 if (S->getInit())
2581 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInit());
2582 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLoopVarStmt());
2583 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRangeInit());
2584 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
2585 // Visit everything else only if shouldVisitImplicitCode().
2586 ShouldVisitChildren = false;
2587 }
2588})
2589
2591 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2592 TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
2593})
2594
2598
2600
2602 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2603 TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
2604 if (S->hasExplicitTemplateArgs()) {
2605 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2606 S->getNumTemplateArgs()));
2607 }
2608})
2609
2611 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2612 TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
2613 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2614 S->getNumTemplateArgs()));
2615})
2616
2618 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2619 TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
2620 if (S->hasExplicitTemplateArgs()) {
2621 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2622 S->getNumTemplateArgs()));
2623 }
2624})
2625
2627 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2628 TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
2629 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2630 S->getNumTemplateArgs()));
2631})
2632
2635 {// We don't traverse the cast type, as it's not written in the
2636 // source code.
2637 })
2638
2640 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2641})
2642
2644 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2645})
2646
2648 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2649})
2650
2652 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2653})
2654
2656 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2657})
2658
2660 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2661})
2662
2664 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2665})
2666
2668 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2669})
2670
2671template <typename Derived>
2673 InitListExpr *S, DataRecursionQueue *Queue) {
2674 if (S) {
2675 // Skip this if we traverse postorder. We will visit it later
2676 // in PostVisitStmt.
2677 if (!getDerived().shouldTraversePostOrder())
2678 TRY_TO(WalkUpFromInitListExpr(S));
2679
2680 // All we need are the default actions. FIXME: use a helper function.
2681 for (Stmt *SubStmt : S->children()) {
2683 }
2684
2685 if (!Queue && getDerived().shouldTraversePostOrder())
2686 TRY_TO(WalkUpFromInitListExpr(S));
2687 }
2688 return true;
2689}
2690
2691template <typename Derived>
2693 ObjCProtocolLoc ProtocolLoc) {
2694 return true;
2695}
2696
2697template <typename Derived>
2699 ConceptReference *CR) {
2700 if (!getDerived().shouldTraversePostOrder())
2701 TRY_TO(VisitConceptReference(CR));
2702 TRY_TO(TraverseNestedNameSpecifierLoc(CR->getNestedNameSpecifierLoc()));
2703 TRY_TO(TraverseDeclarationNameInfo(CR->getConceptNameInfo()));
2704 if (CR->hasExplicitTemplateArgs())
2705 TRY_TO(TraverseTemplateArgumentLocsHelper(
2706 CR->getTemplateArgsAsWritten()->getTemplateArgs(),
2707 CR->getTemplateArgsAsWritten()->NumTemplateArgs));
2708 if (getDerived().shouldTraversePostOrder())
2709 TRY_TO(VisitConceptReference(CR));
2710 return true;
2711}
2712
2713// If shouldVisitImplicitCode() returns false, this method traverses only the
2714// syntactic form of InitListExpr.
2715// If shouldVisitImplicitCode() return true, this method is called once for
2716// each pair of syntactic and semantic InitListExpr, and it traverses the
2717// subtrees defined by the two forms. This may cause some of the children to be
2718// visited twice, if they appear both in the syntactic and the semantic form.
2719//
2720// There is no guarantee about which form \p S takes when this method is called.
2721template <typename Derived>
2723 InitListExpr *S, DataRecursionQueue *Queue) {
2724 if (S->isSemanticForm() && S->isSyntacticForm()) {
2725 // `S` does not have alternative forms, traverse only once.
2726 TRY_TO(TraverseSynOrSemInitListExpr(S, Queue));
2727 return true;
2728 }
2729 TRY_TO(TraverseSynOrSemInitListExpr(
2730 S->isSemanticForm() ? S->getSyntacticForm() : S, Queue));
2731 if (getDerived().shouldVisitImplicitCode()) {
2732 // Only visit the semantic form if the clients are interested in implicit
2733 // compiler-generated.
2734 TRY_TO(TraverseSynOrSemInitListExpr(
2735 S->isSemanticForm() ? S : S->getSemanticForm(), Queue));
2736 }
2737 return true;
2738}
2739
2740// GenericSelectionExpr is a special case because the types and expressions
2741// are interleaved. We also need to watch out for null types (default
2742// generic associations).
2744 if (S->isExprPredicate())
2745 TRY_TO(TraverseStmt(S->getControllingExpr()));
2746 else
2747 TRY_TO(TraverseTypeLoc(S->getControllingType()->getTypeLoc()));
2748
2749 for (const GenericSelectionExpr::Association Assoc : S->associations()) {
2750 if (TypeSourceInfo *TSI = Assoc.getTypeSourceInfo())
2751 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
2752 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(Assoc.getAssociationExpr());
2753 }
2754 ShouldVisitChildren = false;
2755})
2756
2757// PseudoObjectExpr is a special case because of the weirdness with
2758// syntactic expressions and opaque values.
2760 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getSyntacticForm());
2761 for (PseudoObjectExpr::semantics_iterator i = S->semantics_begin(),
2762 e = S->semantics_end();
2763 i != e; ++i) {
2764 Expr *sub = *i;
2765 if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub))
2766 sub = OVE->getSourceExpr();
2768 }
2769 ShouldVisitChildren = false;
2770})
2771
2773 // This is called for code like 'return T()' where T is a built-in
2774 // (i.e. non-class) type.
2775 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2776})
2777
2779 // The child-iterator will pick up the other arguments.
2780 TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc()));
2781})
2782
2784 // The child-iterator will pick up the expression representing
2785 // the field.
2786 // FIMXE: for code like offsetof(Foo, a.b.c), should we get
2787 // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c?
2788 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2789})
2790
2792 // The child-iterator will pick up the arg if it's an expression,
2793 // but not if it's a type.
2794 if (S->isArgumentType())
2795 TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
2796})
2797
2799 // The child-iterator will pick up the arg if it's an expression,
2800 // but not if it's a type.
2801 if (S->isTypeOperand())
2802 TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
2803})
2804
2806 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2807})
2808
2810
2812 // The child-iterator will pick up the arg if it's an expression,
2813 // but not if it's a type.
2814 if (S->isTypeOperand())
2815 TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
2816})
2817
2819 for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
2820 TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc()));
2821})
2822
2824 TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
2825})
2826
2828 { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getQueriedExpression()); })
2829
2831 // The child-iterator will pick up the expression argument.
2832 TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
2833})
2834
2836 // This is called for code like 'return T()' where T is a class type.
2837 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2838})
2839
2840// Walk only the visible parts of lambda expressions.
2842 // Visit the capture list.
2843 for (unsigned I = 0, N = S->capture_size(); I != N; ++I) {
2844 const LambdaCapture *C = S->capture_begin() + I;
2845 if (C->isExplicit() || getDerived().shouldVisitImplicitCode()) {
2846 TRY_TO(TraverseLambdaCapture(S, C, S->capture_init_begin()[I]));
2847 }
2848 }
2849
2850 if (getDerived().shouldVisitImplicitCode()) {
2851 // The implicit model is simple: everything else is in the lambda class.
2852 TRY_TO(TraverseDecl(S->getLambdaClass()));
2853 } else {
2854 // We need to poke around to find the bits that might be explicitly written.
2855 TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2857
2858 TRY_TO(TraverseTemplateParameterListHelper(S->getTemplateParameterList()));
2859 if (S->hasExplicitParameters()) {
2860 // Visit parameters.
2861 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2862 TRY_TO(TraverseDecl(Proto.getParam(I)));
2863 }
2864
2865 auto *T = Proto.getTypePtr();
2866 for (const auto &E : T->exceptions())
2867 TRY_TO(TraverseType(E));
2868
2869 if (Expr *NE = T->getNoexceptExpr())
2871
2872 if (S->hasExplicitResultType())
2873 TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
2875 const_cast<Expr *>(S->getTrailingRequiresClause().ConstraintExpr));
2876
2877 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
2878 }
2879 ShouldVisitChildren = false;
2880})
2881
2883 // This is called for code like 'T()', where T is a template argument.
2884 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2885})
2886
2887// These expressions all might take explicit template arguments.
2888// We traverse those if so. FIXME: implement these.
2892
2893// These exprs (most of them), do not need any action except iterating
2894// over the children.
2902
2904 TRY_TO(TraverseDecl(S->getBlockDecl()));
2905 return true; // no child statements to loop through.
2906})
2907
2910 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2911})
2914
2916 if (getDerived().shouldVisitImplicitCode())
2917 TRY_TO(TraverseStmt(S->getExpr()));
2918})
2919
2921 if (getDerived().shouldVisitImplicitCode())
2922 TRY_TO(TraverseStmt(S->getExpr()));
2923})
2924
2930
2932 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2933 if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
2934 TRY_TO(TraverseTypeLoc(ScopeInfo->getTypeLoc()));
2935 if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo())
2936 TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc()));
2937})
2938
2949 // FIXME: The source expression of the OVE should be listed as
2950 // a child of the ArrayInitLoopExpr.
2951 if (OpaqueValueExpr *OVE = S->getCommonExpr())
2952 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(OVE->getSourceExpr());
2953})
2956
2958 if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
2959 TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
2960})
2961
2964
2966 if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo())
2967 TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
2968})
2969
2971 if (S->isClassReceiver()) {
2972 ObjCInterfaceDecl *IDecl = S->getClassReceiver();
2973 QualType Type = IDecl->getASTContext().getObjCInterfaceType(IDecl);
2975 Data.NameLoc = S->getReceiverLocation();
2976 Data.NameEndLoc = Data.NameLoc;
2977 TRY_TO(TraverseTypeLoc(TypeLoc(Type, &Data)));
2978 }
2979})
2984
2986 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2987})
2988
2993 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2994})
3002 for (IntegerLiteral *IL : S->underlying_data_elements()) {
3004 }
3005})
3006
3008 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
3009 if (S->hasExplicitTemplateArgs()) {
3010 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
3011 S->getNumTemplateArgs()));
3012 }
3013})
3014
3016 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
3017 if (S->hasExplicitTemplateArgs()) {
3018 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
3019 S->getNumTemplateArgs()));
3020 }
3021})
3022
3027DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
3028
3030 if (getDerived().shouldVisitImplicitCode()) {
3031 TRY_TO(TraverseStmt(S->getOriginalStmt()));
3032 TRY_TO(TraverseDecl(S->getOutlinedFunctionDecl()));
3033 ShouldVisitChildren = false;
3034 }
3035})
3036
3039 if (!getDerived().shouldVisitImplicitCode()) {
3041 S->getDecomposedForm();
3042 TRY_TO(TraverseStmt(const_cast<Expr*>(Decomposed.LHS)));
3043 TRY_TO(TraverseStmt(const_cast<Expr*>(Decomposed.RHS)));
3044 ShouldVisitChildren = false;
3045 }
3046})
3050
3051// These operators (all of them) do not need any action except
3052// iterating over the children.
3068
3070 if (S->getLifetimeExtendedTemporaryDecl()) {
3071 TRY_TO(TraverseLifetimeExtendedTemporaryDecl(
3072 S->getLifetimeExtendedTemporaryDecl()));
3073 ShouldVisitChildren = false;
3074 }
3075})
3076// For coroutines expressions, traverse either the operand
3077// as written or the implied calls, depending on what the
3078// derived class requests.
3080 if (!getDerived().shouldVisitImplicitCode()) {
3081 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
3082 ShouldVisitChildren = false;
3083 }
3084})
3086 if (!getDerived().shouldVisitImplicitCode()) {
3087 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
3088 ShouldVisitChildren = false;
3089 }
3090})
3092 if (!getDerived().shouldVisitImplicitCode()) {
3093 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
3094 ShouldVisitChildren = false;
3095 }
3096})
3098 if (!getDerived().shouldVisitImplicitCode()) {
3099 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
3100 ShouldVisitChildren = false;
3101 }
3102})
3104 if (!getDerived().shouldVisitImplicitCode()) {
3105 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
3106 ShouldVisitChildren = false;
3107 }
3108})
3109
3111 TRY_TO(TraverseConceptReference(S->getConceptReference()));
3112})
3113
3115 TRY_TO(TraverseDecl(S->getBody()));
3116 for (ParmVarDecl *Parm : S->getLocalParameters())
3117 TRY_TO(TraverseDecl(Parm));
3118 for (concepts::Requirement *Req : S->getRequirements())
3119 TRY_TO(TraverseConceptRequirement(Req));
3120})
3121
3122// These literals (all of them) do not need any action.
3133
3134// Traverse OpenCL: AsType, Convert.
3136
3137// OpenMP directives.
3138template <typename Derived>
3139bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
3140 OMPExecutableDirective *S) {
3141 for (auto *C : S->clauses()) {
3142 TRY_TO(TraverseOMPClause(C));
3143 }
3144 return true;
3145}
3146
3147DEF_TRAVERSE_STMT(OMPCanonicalLoop, {
3148 if (!getDerived().shouldVisitImplicitCode()) {
3149 // Visit only the syntactical loop.
3150 TRY_TO(TraverseStmt(S->getLoopStmt()));
3151 ShouldVisitChildren = false;
3152 }
3153})
3154
3155template <typename Derived>
3156bool
3157RecursiveASTVisitor<Derived>::TraverseOMPLoopDirective(OMPLoopDirective *S) {
3158 return TraverseOMPExecutableDirective(S);
3159}
3160
3161DEF_TRAVERSE_STMT(OMPMetaDirective,
3162 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3163
3164DEF_TRAVERSE_STMT(OMPParallelDirective,
3165 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3166
3167DEF_TRAVERSE_STMT(OMPSimdDirective,
3168 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3169
3170DEF_TRAVERSE_STMT(OMPTileDirective,
3171 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3172
3173DEF_TRAVERSE_STMT(OMPStripeDirective,
3174 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3175
3176DEF_TRAVERSE_STMT(OMPUnrollDirective,
3177 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3178
3179DEF_TRAVERSE_STMT(OMPReverseDirective,
3180 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3181
3182DEF_TRAVERSE_STMT(OMPFuseDirective,
3183 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3184
3185DEF_TRAVERSE_STMT(OMPInterchangeDirective,
3186 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3187
3188DEF_TRAVERSE_STMT(OMPForDirective,
3189 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3190
3191DEF_TRAVERSE_STMT(OMPForSimdDirective,
3192 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3193
3194DEF_TRAVERSE_STMT(OMPSectionsDirective,
3195 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3196
3197DEF_TRAVERSE_STMT(OMPSectionDirective,
3198 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3199
3200DEF_TRAVERSE_STMT(OMPScopeDirective,
3201 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3202
3203DEF_TRAVERSE_STMT(OMPSingleDirective,
3204 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3205
3206DEF_TRAVERSE_STMT(OMPMasterDirective,
3207 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3208
3209DEF_TRAVERSE_STMT(OMPCriticalDirective, {
3210 TRY_TO(TraverseDeclarationNameInfo(S->getDirectiveName()));
3211 TRY_TO(TraverseOMPExecutableDirective(S));
3212})
3213
3214DEF_TRAVERSE_STMT(OMPParallelForDirective,
3215 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3216
3217DEF_TRAVERSE_STMT(OMPParallelForSimdDirective,
3218 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3219
3220DEF_TRAVERSE_STMT(OMPParallelMasterDirective,
3221 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3222
3223DEF_TRAVERSE_STMT(OMPParallelMaskedDirective,
3224 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3225
3226DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
3227 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3228
3229DEF_TRAVERSE_STMT(OMPTaskDirective,
3230 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3231
3232DEF_TRAVERSE_STMT(OMPTaskyieldDirective,
3233 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3234
3235DEF_TRAVERSE_STMT(OMPBarrierDirective,
3236 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3237
3238DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
3239 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3240
3241DEF_TRAVERSE_STMT(OMPTaskgroupDirective,
3242 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3243
3244DEF_TRAVERSE_STMT(OMPCancellationPointDirective,
3245 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3246
3247DEF_TRAVERSE_STMT(OMPCancelDirective,
3248 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3249
3250DEF_TRAVERSE_STMT(OMPFlushDirective,
3251 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3252
3253DEF_TRAVERSE_STMT(OMPDepobjDirective,
3254 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3255
3256DEF_TRAVERSE_STMT(OMPScanDirective,
3257 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3258
3259DEF_TRAVERSE_STMT(OMPOrderedDirective,
3260 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3261
3262DEF_TRAVERSE_STMT(OMPAtomicDirective,
3263 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3264
3265DEF_TRAVERSE_STMT(OMPTargetDirective,
3266 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3267
3268DEF_TRAVERSE_STMT(OMPTargetDataDirective,
3269 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3270
3271DEF_TRAVERSE_STMT(OMPTargetEnterDataDirective,
3272 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3273
3274DEF_TRAVERSE_STMT(OMPTargetExitDataDirective,
3275 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3276
3277DEF_TRAVERSE_STMT(OMPTargetParallelDirective,
3278 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3279
3280DEF_TRAVERSE_STMT(OMPTargetParallelForDirective,
3281 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3282
3283DEF_TRAVERSE_STMT(OMPTeamsDirective,
3284 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3285
3286DEF_TRAVERSE_STMT(OMPTargetUpdateDirective,
3287 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3288
3289DEF_TRAVERSE_STMT(OMPTaskLoopDirective,
3290 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3291
3292DEF_TRAVERSE_STMT(OMPTaskLoopSimdDirective,
3293 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3294
3295DEF_TRAVERSE_STMT(OMPMasterTaskLoopDirective,
3296 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3297
3298DEF_TRAVERSE_STMT(OMPMasterTaskLoopSimdDirective,
3299 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3300
3301DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopDirective,
3302 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3303
3304DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopSimdDirective,
3305 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3306
3307DEF_TRAVERSE_STMT(OMPMaskedTaskLoopDirective,
3308 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3309
3310DEF_TRAVERSE_STMT(OMPMaskedTaskLoopSimdDirective,
3311 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3312
3313DEF_TRAVERSE_STMT(OMPParallelMaskedTaskLoopDirective,
3314 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3315
3316DEF_TRAVERSE_STMT(OMPParallelMaskedTaskLoopSimdDirective,
3317 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3318
3319DEF_TRAVERSE_STMT(OMPDistributeDirective,
3320 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3321
3322DEF_TRAVERSE_STMT(OMPDistributeParallelForDirective,
3323 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3324
3325DEF_TRAVERSE_STMT(OMPDistributeParallelForSimdDirective,
3326 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3327
3328DEF_TRAVERSE_STMT(OMPDistributeSimdDirective,
3329 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3330
3331DEF_TRAVERSE_STMT(OMPTargetParallelForSimdDirective,
3332 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3333
3334DEF_TRAVERSE_STMT(OMPTargetSimdDirective,
3335 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3336
3337DEF_TRAVERSE_STMT(OMPTeamsDistributeDirective,
3338 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3339
3340DEF_TRAVERSE_STMT(OMPTeamsDistributeSimdDirective,
3341 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3342
3343DEF_TRAVERSE_STMT(OMPTeamsDistributeParallelForSimdDirective,
3344 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3345
3346DEF_TRAVERSE_STMT(OMPTeamsDistributeParallelForDirective,
3347 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3348
3349DEF_TRAVERSE_STMT(OMPTargetTeamsDirective,
3350 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3351
3352DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeDirective,
3353 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3354
3355DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForDirective,
3356 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3357
3358DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForSimdDirective,
3359 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3360
3361DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeSimdDirective,
3362 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3363
3364DEF_TRAVERSE_STMT(OMPInteropDirective,
3365 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3366
3367DEF_TRAVERSE_STMT(OMPDispatchDirective,
3368 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3369
3370DEF_TRAVERSE_STMT(OMPMaskedDirective,
3371 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3372
3373DEF_TRAVERSE_STMT(OMPGenericLoopDirective,
3374 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3375
3376DEF_TRAVERSE_STMT(OMPTeamsGenericLoopDirective,
3377 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3378
3379DEF_TRAVERSE_STMT(OMPTargetTeamsGenericLoopDirective,
3380 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3381
3382DEF_TRAVERSE_STMT(OMPParallelGenericLoopDirective,
3383 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3384
3385DEF_TRAVERSE_STMT(OMPTargetParallelGenericLoopDirective,
3386 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3387
3388DEF_TRAVERSE_STMT(OMPAssumeDirective,
3389 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3390
3391DEF_TRAVERSE_STMT(OMPErrorDirective,
3392 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3393
3394// OpenMP clauses.
3395template <typename Derived>
3396bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
3397 if (!C)
3398 return true;
3399 switch (C->getClauseKind()) {
3400#define GEN_CLANG_CLAUSE_CLASS
3401#define CLAUSE_CLASS(Enum, Str, Class) \
3402 case llvm::omp::Clause::Enum: \
3403 TRY_TO(Visit##Class(static_cast<Class *>(C))); \
3404 break;
3405#define CLAUSE_NO_CLASS(Enum, Str) \
3406 case llvm::omp::Clause::Enum: \
3407 break;
3408#include "llvm/Frontend/OpenMP/OMP.inc"
3409 }
3410 return true;
3411}
3412
3413template <typename Derived>
3414bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPreInit(
3415 OMPClauseWithPreInit *Node) {
3416 TRY_TO(TraverseStmt(Node->getPreInitStmt()));
3417 return true;
3418}
3419
3420template <typename Derived>
3421bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPostUpdate(
3423 TRY_TO(VisitOMPClauseWithPreInit(Node));
3424 TRY_TO(TraverseStmt(Node->getPostUpdateExpr()));
3425 return true;
3426}
3427
3428template <typename Derived>
3431 TRY_TO(TraverseStmt(C->getAllocator()));
3432 return true;
3433}
3434
3435template <typename Derived>
3437 TRY_TO(TraverseStmt(C->getAllocator()));
3438 TRY_TO(VisitOMPClauseList(C));
3439 return true;
3440}
3441
3442template <typename Derived>
3444 TRY_TO(VisitOMPClauseWithPreInit(C));
3445 TRY_TO(TraverseStmt(C->getCondition()));
3446 return true;
3447}
3448
3449template <typename Derived>
3451 TRY_TO(VisitOMPClauseWithPreInit(C));
3452 TRY_TO(TraverseStmt(C->getCondition()));
3453 return true;
3454}
3455
3456template <typename Derived>
3457bool
3459 TRY_TO(VisitOMPClauseWithPreInit(C));
3460 TRY_TO(TraverseStmt(C->getNumThreads()));
3461 return true;
3462}
3463
3464template <typename Derived>
3466 TRY_TO(TraverseStmt(C->getAlignment()));
3467 return true;
3468}
3469
3470template <typename Derived>
3472 TRY_TO(TraverseStmt(C->getSafelen()));
3473 return true;
3474}
3475
3476template <typename Derived>
3478 TRY_TO(TraverseStmt(C->getSimdlen()));
3479 return true;
3480}
3481
3482template <typename Derived>
3484 for (Expr *E : C->getSizesRefs())
3485 TRY_TO(TraverseStmt(E));
3486 return true;
3487}
3488
3489template <typename Derived>
3492 for (Expr *E : C->getArgsRefs())
3493 TRY_TO(TraverseStmt(E));
3494 return true;
3495}
3496
3497template <typename Derived>
3499 return true;
3500}
3501
3502template <typename Derived>
3505 TRY_TO(TraverseStmt(C->getFirst()));
3506 TRY_TO(TraverseStmt(C->getCount()));
3507 return true;
3508}
3509
3510template <typename Derived>
3512 TRY_TO(TraverseStmt(C->getFactor()));
3513 return true;
3514}
3515
3516template <typename Derived>
3517bool
3519 TRY_TO(TraverseStmt(C->getNumForLoops()));
3520 return true;
3521}
3522
3523template <typename Derived>
3525 return true;
3526}
3527
3528template <typename Derived>
3531 return true;
3532}
3533
3534template <typename Derived>
3536 return true;
3537}
3538
3539template <typename Derived>
3542 return true;
3543}
3544
3545template <typename Derived>
3548 return true;
3549}
3550
3551template <typename Derived>
3554 return true;
3555}
3556
3557template <typename Derived>
3560 return true;
3561}
3562
3563template <typename Derived>
3566 return true;
3567}
3568
3569template <typename Derived>
3571 return true;
3572}
3573
3574template <typename Derived>
3576 return true;
3577}
3578
3579template <typename Derived>
3581 return true;
3582}
3583
3584template <typename Derived>
3586 TRY_TO(TraverseStmt(C->getMessageString()));
3587 return true;
3588}
3589
3590template <typename Derived>
3591bool
3593 TRY_TO(VisitOMPClauseWithPreInit(C));
3594 TRY_TO(TraverseStmt(C->getChunkSize()));
3595 return true;
3596}
3597
3598template <typename Derived>
3600 TRY_TO(TraverseStmt(C->getNumForLoops()));
3601 return true;
3602}
3603
3604template <typename Derived>
3606 TRY_TO(TraverseStmt(C->getCondition()));
3607 return true;
3608}
3609
3610template <typename Derived>
3612 return true;
3613}
3614
3615template <typename Derived>
3616bool
3618 return true;
3619}
3620
3621template <typename Derived>
3623 return true;
3624}
3625
3626template <typename Derived>
3628 return true;
3629}
3630
3631template <typename Derived>
3633 return true;
3634}
3635
3636template <typename Derived>
3638 return true;
3639}
3640
3641template <typename Derived>
3643 return true;
3644}
3645
3646template <typename Derived>
3648 return true;
3649}
3650
3651template <typename Derived>
3653 return true;
3654}
3655
3656template <typename Derived>
3658 return true;
3659}
3660
3661template <typename Derived>
3663 return true;
3664}
3665
3666template <typename Derived>
3668 return true;
3669}
3670
3671template <typename Derived>
3673 return true;
3674}
3675
3676template <typename Derived>
3678 return true;
3679}
3680
3681template <typename Derived>
3684 return true;
3685}
3686
3687template <typename Derived>
3690 return true;
3691}
3692
3693template <typename Derived>
3696 return true;
3697}
3698
3699template <typename Derived>
3701 return true;
3702}
3703
3704template <typename Derived>
3706 return true;
3707}
3708
3709template <typename Derived>
3711 return true;
3712}
3713
3714template <typename Derived>
3716 return true;
3717}
3718
3719template <typename Derived>
3721 return true;
3722}
3723
3724template <typename Derived>
3726 return true;
3727}
3728
3729template <typename Derived>
3731 return true;
3732}
3733
3734template <typename Derived>
3736 TRY_TO(VisitOMPClauseList(C));
3737 return true;
3738}
3739
3740template <typename Derived>
3742 TRY_TO(TraverseStmt(C->getInteropVar()));
3743 return true;
3744}
3745
3746template <typename Derived>
3748 TRY_TO(TraverseStmt(C->getInteropVar()));
3749 return true;
3750}
3751
3752template <typename Derived>
3755 TRY_TO(VisitOMPClauseWithPreInit(C));
3756 TRY_TO(TraverseStmt(C->getCondition()));
3757 return true;
3758}
3759
3760template <typename Derived>
3763 TRY_TO(VisitOMPClauseWithPreInit(C));
3764 TRY_TO(TraverseStmt(C->getCondition()));
3765 return true;
3766}
3767
3768template <typename Derived>
3769template <typename T>
3770bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
3771 for (auto *E : Node->varlist()) {
3772 TRY_TO(TraverseStmt(E));
3773 }
3774 return true;
3775}
3776
3777template <typename Derived>
3780 TRY_TO(VisitOMPClauseList(C));
3781 return true;
3782}
3783
3784template <typename Derived>
3787 TRY_TO(VisitOMPClauseList(C));
3788 return true;
3789}
3790
3791template <typename Derived>
3793 TRY_TO(VisitOMPClauseList(C));
3794 for (auto *E : C->private_copies()) {
3795 TRY_TO(TraverseStmt(E));
3796 }
3797 return true;
3798}
3799
3800template <typename Derived>
3803 TRY_TO(VisitOMPClauseList(C));
3804 TRY_TO(VisitOMPClauseWithPreInit(C));
3805 for (auto *E : C->private_copies()) {
3806 TRY_TO(TraverseStmt(E));
3807 }
3808 for (auto *E : C->inits()) {
3809 TRY_TO(TraverseStmt(E));
3810 }
3811 return true;
3812}
3813
3814template <typename Derived>
3817 TRY_TO(VisitOMPClauseList(C));
3818 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3819 for (auto *E : C->private_copies()) {
3820 TRY_TO(TraverseStmt(E));
3821 }
3822 for (auto *E : C->source_exprs()) {
3823 TRY_TO(TraverseStmt(E));
3824 }
3825 for (auto *E : C->destination_exprs()) {
3826 TRY_TO(TraverseStmt(E));
3827 }
3828 for (auto *E : C->assignment_ops()) {
3829 TRY_TO(TraverseStmt(E));
3830 }
3831 return true;
3832}
3833
3834template <typename Derived>
3836 TRY_TO(VisitOMPClauseList(C));
3837 return true;
3838}
3839
3840template <typename Derived>
3842 TRY_TO(TraverseStmt(C->getStep()));
3843 TRY_TO(TraverseStmt(C->getCalcStep()));
3844 TRY_TO(VisitOMPClauseList(C));
3845 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3846 for (auto *E : C->privates()) {
3847 TRY_TO(TraverseStmt(E));
3848 }
3849 for (auto *E : C->inits()) {
3850 TRY_TO(TraverseStmt(E));
3851 }
3852 for (auto *E : C->updates()) {
3853 TRY_TO(TraverseStmt(E));
3854 }
3855 for (auto *E : C->finals()) {
3856 TRY_TO(TraverseStmt(E));
3857 }
3858 return true;
3859}
3860
3861template <typename Derived>
3863 TRY_TO(TraverseStmt(C->getAlignment()));
3864 TRY_TO(VisitOMPClauseList(C));
3865 return true;
3866}
3867
3868template <typename Derived>
3870 TRY_TO(VisitOMPClauseList(C));
3871 for (auto *E : C->source_exprs()) {
3872 TRY_TO(TraverseStmt(E));
3873 }
3874 for (auto *E : C->destination_exprs()) {
3875 TRY_TO(TraverseStmt(E));
3876 }
3877 for (auto *E : C->assignment_ops()) {
3878 TRY_TO(TraverseStmt(E));
3879 }
3880 return true;
3881}
3882
3883template <typename Derived>
3886 TRY_TO(VisitOMPClauseList(C));
3887 for (auto *E : C->source_exprs()) {
3888 TRY_TO(TraverseStmt(E));
3889 }
3890 for (auto *E : C->destination_exprs()) {
3891 TRY_TO(TraverseStmt(E));
3892 }
3893 for (auto *E : C->assignment_ops()) {
3894 TRY_TO(TraverseStmt(E));
3895 }
3896 return true;
3897}
3898
3899template <typename Derived>
3900bool
3902 TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
3903 TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
3904 TRY_TO(VisitOMPClauseList(C));
3905 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3906 for (auto *E : C->privates()) {
3907 TRY_TO(TraverseStmt(E));
3908 }
3909 for (auto *E : C->lhs_exprs()) {
3910 TRY_TO(TraverseStmt(E));
3911 }
3912 for (auto *E : C->rhs_exprs()) {
3913 TRY_TO(TraverseStmt(E));
3914 }
3915 for (auto *E : C->reduction_ops()) {
3916 TRY_TO(TraverseStmt(E));
3917 }
3918 if (C->getModifier() == OMPC_REDUCTION_inscan) {
3919 for (auto *E : C->copy_ops()) {
3920 TRY_TO(TraverseStmt(E));
3921 }
3922 for (auto *E : C->copy_array_temps()) {
3923 TRY_TO(TraverseStmt(E));
3924 }
3925 for (auto *E : C->copy_array_elems()) {
3926 TRY_TO(TraverseStmt(E));
3927 }
3928 }
3929 return true;
3930}
3931
3932template <typename Derived>
3935 TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
3936 TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
3937 TRY_TO(VisitOMPClauseList(C));
3938 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3939 for (auto *E : C->privates()) {
3940 TRY_TO(TraverseStmt(E));
3941 }
3942 for (auto *E : C->lhs_exprs()) {
3943 TRY_TO(TraverseStmt(E));
3944 }
3945 for (auto *E : C->rhs_exprs()) {
3946 TRY_TO(TraverseStmt(E));
3947 }
3948 for (auto *E : C->reduction_ops()) {
3949 TRY_TO(TraverseStmt(E));
3950 }
3951 return true;
3952}
3953
3954template <typename Derived>
3957 TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
3958 TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
3959 TRY_TO(VisitOMPClauseList(C));
3960 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3961 for (auto *E : C->privates()) {
3962 TRY_TO(TraverseStmt(E));
3963 }
3964 for (auto *E : C->lhs_exprs()) {
3965 TRY_TO(TraverseStmt(E));
3966 }
3967 for (auto *E : C->rhs_exprs()) {
3968 TRY_TO(TraverseStmt(E));
3969 }
3970 for (auto *E : C->reduction_ops()) {
3971 TRY_TO(TraverseStmt(E));
3972 }
3973 for (auto *E : C->taskgroup_descriptors())
3974 TRY_TO(TraverseStmt(E));
3975 return true;
3976}
3977
3978template <typename Derived>
3980 TRY_TO(VisitOMPClauseList(C));
3981 return true;
3982}
3983
3984template <typename Derived>
3986 TRY_TO(TraverseStmt(C->getDepobj()));
3987 return true;
3988}
3989
3990template <typename Derived>
3992 TRY_TO(VisitOMPClauseList(C));
3993 return true;
3994}
3995
3996template <typename Derived>
3998 TRY_TO(VisitOMPClauseWithPreInit(C));
3999 TRY_TO(TraverseStmt(C->getDevice()));
4000 return true;
4001}
4002
4003template <typename Derived>
4005 TRY_TO(VisitOMPClauseList(C));
4006 return true;
4007}
4008
4009template <typename Derived>
4012 TRY_TO(VisitOMPClauseList(C));
4013 TRY_TO(VisitOMPClauseWithPreInit(C));
4014 return true;
4015}
4016
4017template <typename Derived>
4020 TRY_TO(VisitOMPClauseList(C));
4021 TRY_TO(VisitOMPClauseWithPreInit(C));
4022 return true;
4023}
4024
4025template <typename Derived>
4028 TRY_TO(VisitOMPClauseWithPreInit(C));
4029 TRY_TO(TraverseStmt(C->getPriority()));
4030 return true;
4031}
4032
4033template <typename Derived>
4036 TRY_TO(VisitOMPClauseWithPreInit(C));
4037 TRY_TO(TraverseStmt(C->getGrainsize()));
4038 return true;
4039}
4040
4041template <typename Derived>
4044 TRY_TO(VisitOMPClauseWithPreInit(C));
4045 TRY_TO(TraverseStmt(C->getNumTasks()));
4046 return true;
4047}
4048
4049template <typename Derived>
4051 TRY_TO(TraverseStmt(C->getHint()));
4052 return true;
4053}
4054
4055template <typename Derived>
4058 TRY_TO(VisitOMPClauseWithPreInit(C));
4059 TRY_TO(TraverseStmt(C->getChunkSize()));
4060 return true;
4061}
4062
4063template <typename Derived>
4064bool
4066 return true;
4067}
4068
4069template <typename Derived>
4071 TRY_TO(VisitOMPClauseList(C));
4072 return true;
4073}
4074
4075template <typename Derived>
4077 TRY_TO(VisitOMPClauseList(C));
4078 return true;
4079}
4080
4081template <typename Derived>
4084 TRY_TO(VisitOMPClauseList(C));
4085 return true;
4086}
4087
4088template <typename Derived>
4091 TRY_TO(VisitOMPClauseList(C));
4092 return true;
4093}
4094
4095template <typename Derived>
4098 TRY_TO(VisitOMPClauseList(C));
4099 return true;
4100}
4101
4102template <typename Derived>
4105 TRY_TO(VisitOMPClauseList(C));
4106 return true;
4107}
4108
4109template <typename Derived>
4112 TRY_TO(VisitOMPClauseList(C));
4113 for (auto *E : C->private_refs()) {
4114 TRY_TO(TraverseStmt(E));
4115 }
4116 return true;
4117}
4118
4119template <typename Derived>
4121 return true;
4122}
4123
4124template <typename Derived>
4126 TRY_TO(TraverseStmt(C->getEventHandler()));
4127 return true;
4128}
4129
4130template <typename Derived>
4133 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
4134 const OMPUsesAllocatorsClause::Data Data = C->getAllocatorData(I);
4135 TRY_TO(TraverseStmt(Data.Allocator));
4136 TRY_TO(TraverseStmt(Data.AllocatorTraits));
4137 }
4138 return true;
4139}
4140
4141template <typename Derived>
4144 TRY_TO(TraverseStmt(C->getModifier()));
4145 for (Expr *E : C->varlist())
4146 TRY_TO(TraverseStmt(E));
4147 return true;
4148}
4149
4150template <typename Derived>
4152 TRY_TO(VisitOMPClauseWithPreInit(C));
4153 TRY_TO(TraverseStmt(C->getThreadID()));
4154 return true;
4155}
4156
4157template <typename Derived>
4159 return true;
4160}
4161
4162template <typename Derived>
4165 TRY_TO(VisitOMPClauseWithPreInit(C));
4166 TRY_TO(TraverseStmt(C->getSize()));
4167 return true;
4168}
4169
4170template <typename Derived>
4173 TRY_TO(VisitOMPClauseWithPreInit(C));
4174 TRY_TO(TraverseStmt(C->getSize()));
4175 return true;
4176}
4177
4178template <typename Derived>
4181 TRY_TO(VisitOMPClauseList(C));
4182 return true;
4183}
4184
4185template <typename Derived>
4188 return true;
4189}
4190
4191template <typename Derived>
4193 return true;
4194}
4195
4196template <typename Derived>
4197bool RecursiveASTVisitor<Derived>::TraverseOpenACCConstructStmt(
4199 TRY_TO(VisitOpenACCClauseList(C->clauses()));
4200 return true;
4201}
4202
4203template <typename Derived>
4204bool RecursiveASTVisitor<Derived>::TraverseOpenACCAssociatedStmtConstruct(
4206 TRY_TO(TraverseOpenACCConstructStmt(S));
4207 TRY_TO(TraverseStmt(S->getAssociatedStmt()));
4208 return true;
4209}
4210
4211template <typename Derived>
4212bool RecursiveASTVisitor<Derived>::VisitOpenACCClause(const OpenACCClause *C) {
4213 for (const Stmt *Child : C->children())
4214 TRY_TO(TraverseStmt(const_cast<Stmt *>(Child)));
4215 return true;
4216}
4217
4218template <typename Derived>
4219bool RecursiveASTVisitor<Derived>::VisitOpenACCClauseList(
4221
4222 for (const auto *C : Clauses)
4223 TRY_TO(VisitOpenACCClause(C));
4224 return true;
4225}
4226
4228 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4229DEF_TRAVERSE_STMT(OpenACCLoopConstruct,
4230 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4231DEF_TRAVERSE_STMT(OpenACCCombinedConstruct,
4232 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4233DEF_TRAVERSE_STMT(OpenACCDataConstruct,
4234 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4235DEF_TRAVERSE_STMT(OpenACCEnterDataConstruct,
4236 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4237DEF_TRAVERSE_STMT(OpenACCExitDataConstruct,
4238 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4239DEF_TRAVERSE_STMT(OpenACCHostDataConstruct,
4240 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4241DEF_TRAVERSE_STMT(OpenACCWaitConstruct, {
4242 if (S->hasDevNumExpr())
4243 TRY_TO(TraverseStmt(S->getDevNumExpr()));
4244 for (auto *E : S->getQueueIdExprs())
4245 TRY_TO(TraverseStmt(E));
4246 TRY_TO(VisitOpenACCClauseList(S->clauses()));
4247})
4248DEF_TRAVERSE_STMT(OpenACCInitConstruct,
4249 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4250DEF_TRAVERSE_STMT(OpenACCShutdownConstruct,
4251 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4252DEF_TRAVERSE_STMT(OpenACCSetConstruct,
4253 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4254DEF_TRAVERSE_STMT(OpenACCUpdateConstruct,
4255 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4256DEF_TRAVERSE_STMT(OpenACCAtomicConstruct,
4257 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4258DEF_TRAVERSE_STMT(OpenACCCacheConstruct, {
4259 for (auto *E : S->getVarList())
4260 TRY_TO(TraverseStmt(E));
4261})
4262
4263// Traverse HLSL: Out argument expression
4265
4266// FIXME: look at the following tricky-seeming exprs to see if we
4267// need to recurse on anything. These are ones that have methods
4268// returning decls or qualtypes or nestednamespecifier -- though I'm
4269// not sure if they own them -- or just seemed very complicated, or
4270// had lots of sub-types to explore.
4271//
4272// VisitOverloadExpr and its children: recurse on template args? etc?
4273
4274// FIXME: go through all the stmts and exprs again, and see which of them
4275// create new types, and recurse on the types (TypeLocs?) of those.
4276// Candidates:
4277//
4278// http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html
4279// http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html
4280// http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html
4281// Every class that has getQualifier.
4282
4283#undef DEF_TRAVERSE_STMT
4284#undef TRAVERSE_STMT
4285#undef TRAVERSE_STMT_BASE
4286
4287#undef TRY_TO
4288
4289} // end namespace clang
4290
4291#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:220
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:4550
Represents a type which was implicitly adjusted by the semantic engine for arbitrary reasons.
Definition TypeBase.h:3490
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Definition Expr.h:6021
Represents a loop initializing the elements of an array.
Definition Expr.h:5968
This class represents BOTH the OpenMP Array Section and OpenACC 'subarray', with a boolean differenti...
Definition Expr.h:7171
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition Expr.h:2721
Wrapper for source info for arrays.
Definition TypeLoc.h:1748
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
Definition ExprCXX.h:2996
AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2] This AST node provides support ...
Definition Expr.h:6685
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
Definition Expr.h:6880
Attr - This represents one attribute.
Definition Attr.h:45
Represents an attribute applied to a statement.
Definition Stmt.h:2194
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
Definition Expr.h:4453
A builtin binary operation expression such as "x + y" or "x <= y".
Definition Expr.h:4038
A binding in a decomposition declaration.
Definition DeclCXX.h:4181
A fixed int type of a specified bitwidth.
Definition TypeBase.h:8145
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition Decl.h:4668
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition Expr.h:6624
Pointer to a block type.
Definition TypeBase.h:3543
BreakStmt - This represents a break.
Definition Stmt.h:3126
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:3165
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Definition Expr.h:3969
Represents a call to a CUDA kernel function.
Definition ExprCXX.h:234
A C++ addrspace_cast expression (currently only enabled for OpenCL).
Definition ExprCXX.h:604
Represents a base class of a C++ class.
Definition DeclCXX.h:146
Represents binding an expression to a temporary.
Definition ExprCXX.h:1493
A boolean literal, per ([C++ lex.bool] Boolean literals).
Definition ExprCXX.h:723
CXXCatchStmt - This represents a C++ catch block.
Definition StmtCXX.h:28
A C++ const_cast expression (C++ [expr.const.cast]).
Definition ExprCXX.h:566
Represents a call to a C++ constructor.
Definition ExprCXX.h:1548
Represents a C++ constructor within a class.
Definition DeclCXX.h:2604
Represents a C++ conversion function within a class.
Definition DeclCXX.h:2939
Represents a C++ base or member initializer.
Definition DeclCXX.h:2369
Represents a C++ deduction guide declaration.
Definition DeclCXX.h:1979
A default argument (C++ [dcl.fct.default]).
Definition ExprCXX.h:1270
A use of a default initializer in a constructor or in aggregate initialization.
Definition ExprCXX.h:1377
Represents a delete expression for memory deallocation and destructor calls, e.g.
Definition ExprCXX.h:2626
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:2869
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
Definition ExprCXX.h:481
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:1831
Represents a call to an inherited base class constructor from an inheriting constructor.
Definition ExprCXX.h:1751
Represents a call to a member function that may be written either with member call syntax (e....
Definition ExprCXX.h:179
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2129
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition ExprCXX.h:2355
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:768
A call to an overloaded operator written using operator syntax.
Definition ExprCXX.h:84
Represents a list-initialization with parenthesis.
Definition ExprCXX.h:5141
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
Definition ExprCXX.h:2745
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
Definition ExprCXX.h:526
A rewritten comparison expression that was originally written using operator syntax.
Definition ExprCXX.h:286
An expression "T()" which creates an rvalue of a non-class type T.
Definition ExprCXX.h:2196
A C++ static_cast expression (C++ [expr.static.cast]).
Definition ExprCXX.h:436
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
Definition ExprCXX.h:800
Represents a C++ functional cast expression that builds a temporary object.
Definition ExprCXX.h:1899
Represents the this expression in C++.
Definition ExprCXX.h:1154
A C++ throw-expression (C++ [except.throw]).
Definition ExprCXX.h:1208
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:848
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:1068
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:2943
Represents the body of a CapturedStmt, and serves as its DeclContext.
Definition Decl.h:4940
This captures a statement into a function.
Definition Stmt.h:3918
CaseStmt - Represent a case statement.
Definition Stmt.h:1911
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Definition Expr.h:4848
Declaration of a class template.
Represents a 'co_await' expression.
Definition ExprCXX.h:5369
Complex values, per C99 6.2.5p11.
Definition TypeBase.h:3276
CompoundAssignOperator - For compound assignments (e.g.
Definition Expr.h:4300
CompoundLiteralExpr - [C99 6.5.2.5].
Definition Expr.h:3605
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition Stmt.h:1731
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:4391
Represents the canonical version of C arrays with a specified constant size.
Definition TypeBase.h:3761
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Definition Expr.h:1082
Represents a concrete matrix type with constant number of rows and columns.
Definition TypeBase.h:4388
Represents a shadow constructor declaration introduced into a class by a C++11 using-declaration that...
Definition DeclCXX.h:3673
ContinueStmt - This represents a continue.
Definition Stmt.h:3110
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Definition Expr.h:4719
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 'co_yield' expression.
Definition ExprCXX.h:5450
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1449
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2109
A reference to a declared variable, function, enum, etc.
Definition Expr.h:1270
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition Stmt.h:1622
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition DeclBase.h:593
Kind getKind() const
Definition DeclBase.h:442
TemplateDecl * getCXXDeductionGuideTemplate() const
If this name is the name of a C++ deduction guide, return the template associated with that name.
NameKind getNameKind() const
Determine what kind of name this is.
Represents a ValueDecl that came out of a declarator.
Definition Decl.h:780
A decomposition declaration.
Definition DeclCXX.h:4245
DeferStmt - This represents a deferred statement.
Definition Stmt.h:3227
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:4012
Represents an extended vector type where either the type or size is dependent.
Definition TypeBase.h:4102
Represents a vector type where either the type or size is dependent.
Definition TypeBase.h:4228
Represents a C99 designated initializer expression.
Definition Expr.h:5551
DoStmt - This represents a 'do/while' stmt.
Definition Stmt.h:2823
Represents a reference to emded data.
Definition Expr.h:5126
Represents an empty-declaration.
Definition Decl.h:5175
An instance of this object exists for each enum constant that is defined.
Definition Decl.h:3423
Represents an enum.
Definition Decl.h:4007
Represents a standard C++ module export declaration.
Definition Decl.h:5128
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:3069
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
Definition Expr.h:6564
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:3160
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Definition Stmt.h:2879
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:2000
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Definition TypeBase.h:4847
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:5269
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:3427
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Definition Expr.h:4923
Represents a C11 generic selection.
Definition Expr.h:6178
AssociationTy< false > Association
Definition Expr.h:6409
GotoStmt - This represents a direct goto.
Definition Stmt.h:2960
HLSLBufferDecl - Represent a cbuffer or tbuffer declaration.
Definition Decl.h:5190
This class represents temporary values used to represent inout and out arguments in HLSL.
Definition Expr.h:7349
IfStmt - This represents an if/then/else.
Definition Stmt.h:2250
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
Definition Expr.h:1731
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Definition Expr.h:3853
Represents an implicitly-generated value initialization of an object of a given type.
Definition Expr.h:6057
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Definition Decl.h:5049
Represents a C array with an unspecified size.
Definition TypeBase.h:3910
Represents a field injected from an anonymous union/struct into the parent scope.
Definition Decl.h:3467
IndirectGotoStmt - This represents an indirect goto.
Definition Stmt.h:2999
Describes an C or C++ initializer list.
Definition Expr.h:5299
Represents the declaration of a label.
Definition Decl.h:524
LabelStmt - Represents a label, which has a substatement.
Definition Stmt.h:2137
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:1968
Implicit declaration of a temporary that was materialized by a MaterializeTemporaryExpr and lifetime-...
Definition DeclCXX.h:3304
Represents a linkage specification.
Definition DeclCXX.h:3011
This represents a Microsoft inline-assembly statement extension.
Definition Stmt.h:3646
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:4394
An instance of this class represents the declaration of a property member.
Definition DeclCXX.h:4340
A member reference to an MSPropertyDecl.
Definition ExprCXX.h:936
MS property subscript expression.
Definition ExprCXX.h:1006
Sugar type that represents a type that was qualified by a qualifier written as a macro invocation.
Definition TypeBase.h:6148
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:2795
MatrixSubscriptExpr - Matrix subscript expression for the MatrixType extension.
Definition Expr.h:2865
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition Expr.h:3364
This represents a decl that may have a name.
Definition Decl.h:274
Represents a C++ namespace alias.
Definition DeclCXX.h:3197
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:5877
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
NullStmt - This is the null statement ";": C99 6.8.3p3.
Definition Stmt.h:1694
This represents the 'absent' clause in the 'pragma omp assume' directive.
This represents 'acq_rel' clause in the 'pragma omp atomic|flush' directives.
This represents 'acquire' clause in the 'pragma omp atomic|flush' directives.
This represents clause 'affinity' in the 'pragma omp task'-based directives.
This represents the 'align' clause in the 'pragma omp allocate' directive.
This represents clause 'aligned' in the 'pragma omp ...' directives.
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
This represents 'at' clause in the 'pragma omp error' directive.
This represents 'atomic_default_mem_order' clause in the 'pragma omp requires' directive.
This represents 'bind' clause in the 'pragma omp ...' directives.
This represents 'capture' clause in the 'pragma omp atomic' directive.
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 'compare' clause in the 'pragma omp atomic' directive.
This represents the 'contains' clause in the 'pragma omp assume' directive.
This represents clause 'copyin' in the 'pragma omp ...' directives.
This represents clause 'copyprivate' in the 'pragma omp ...' directives.
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 'defaultmap' clause in the 'pragma omp ...' directive.
This represents implicit clause 'depend' for the 'pragma omp task' directive.
This represents implicit clause 'depobj' for the 'pragma omp depobj' directive.
This represents 'destroy' clause in the 'pragma omp depobj' directive or the 'pragma omp interop' dir...
This represents 'detach' clause in the 'pragma omp task' directive.
This represents 'device' clause in the 'pragma omp ...' directive.
This represents 'dist_schedule' clause in the 'pragma omp ...' directive.
This represents the 'doacross' clause for the 'pragma omp ordered' directive.
This represents 'dyn_groupprivate' clause in 'pragma omp target ...' and 'pragma omp teams ....
This represents 'dynamic_allocators' clause in the 'pragma omp requires' directive.
This represents clause 'exclusive' in the 'pragma omp scan' directive.
This represents 'fail' clause in the 'pragma omp atomic' directive.
This represents 'filter' clause in the 'pragma omp ...' directive.
This represents 'final' clause in the 'pragma omp ...' directive.
This represents clause 'firstprivate' in the 'pragma omp ...' directives.
This represents implicit clause 'flush' for the 'pragma omp flush' directive.
This represents clause 'from' in the 'pragma omp ...' directives.
Representation of the 'full' clause of the 'pragma omp unroll' directive.
This represents 'grainsize' clause in the 'pragma omp ...' directive.
This represents 'pragma omp groupprivate ...' directive.
Definition DeclOpenMP.h:173
This represents clause 'has_device_ptr' in the 'pragma omp ...' directives.
This represents 'hint' clause in the 'pragma omp ...' directive.
This represents the 'holds' clause in the 'pragma omp assume' directive.
This represents 'if' clause in the 'pragma omp ...' directive.
This represents clause 'in_reduction' in the 'pragma omp task' directives.
This represents clause 'inclusive' in the 'pragma omp scan' directive.
This represents the 'init' clause in 'pragma omp ...' directives.
This represents clause 'is_device_ptr' in the 'pragma omp ...' directives.
OpenMP 5.0 [2.1.6 Iterators] Iterators are identifiers that expand to multiple values in the clause o...
Definition ExprOpenMP.h:151
This represents clause 'lastprivate' in the 'pragma omp ...' directives.
This represents clause 'linear' in the 'pragma omp ...' directives.
This class represents the 'looprange' clause in the 'pragma omp fuse' directive.
This represents clause 'map' in the 'pragma omp ...' directives.
This represents 'mergeable' clause in the 'pragma omp ...' directive.
This represents the 'message' clause in the 'pragma omp error' and the 'pragma omp parallel' directiv...
This represents the 'no_openmp' clause in the 'pragma omp assume' directive.
This represents the 'no_openmp_constructs' clause in the.
This represents the 'no_openmp_routines' clause in the 'pragma omp assume' directive.
This represents the 'no_parallelism' clause in the 'pragma omp assume' directive.
This represents 'nocontext' clause in the 'pragma omp ...' directive.
This represents 'nogroup' clause in the 'pragma omp ...' directive.
This represents clause 'nontemporal' in the 'pragma omp ...' directives.
This represents 'novariants' clause in the 'pragma omp ...' directive.
This represents 'nowait' clause in the 'pragma omp ...' directive.
This represents 'num_tasks' clause in the 'pragma omp ...' directive.
This represents 'num_teams' clause in the 'pragma omp ...' directive.
This represents 'num_threads' clause in the 'pragma omp ...' directive.
This represents 'order' clause in the 'pragma omp ...' directive.
This represents 'ordered' 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 'priority' clause in the 'pragma omp ...' directive.
This represents clause 'private' in the 'pragma omp ...' directives.
This represents 'proc_bind' clause in the 'pragma omp ...' directive.
This represents 'read' clause in the 'pragma omp atomic' directive.
This represents clause 'reduction' in the 'pragma omp ...' directives.
This represents 'relaxed' clause in the 'pragma omp atomic' directives.
This represents 'release' clause in the 'pragma omp atomic|flush' directives.
This represents 'pragma omp requires...' directive.
Definition DeclOpenMP.h:479
This represents 'reverse_offload' clause in the 'pragma omp requires' directive.
This represents 'simd' clause in the 'pragma omp ...' directive.
This represents 'safelen' clause in the 'pragma omp ...' directive.
This represents 'schedule' clause in the 'pragma omp ...' directive.
This represents 'self_maps' clause in the 'pragma omp requires' directive.
This represents 'seq_cst' clause in the 'pragma omp atomic|flush' directives.
This represents the 'severity' clause in the 'pragma omp error' and the 'pragma omp parallel' directi...
This represents clause 'shared' in the 'pragma omp ...' directives.
This represents 'simdlen' clause in the 'pragma omp ...' directive.
This represents the 'sizes' clause in the 'pragma omp tile' directive.
This represents clause 'task_reduction' in the 'pragma omp taskgroup' directives.
This represents 'thread_limit' clause in the 'pragma omp ...' directive.
This represents 'pragma omp threadprivate ...' directive.
Definition DeclOpenMP.h:110
This represents 'threads' clause in the 'pragma omp ...' directive.
This represents 'threadset' clause in the 'pragma omp task ...' directive.
This represents clause 'to' in the 'pragma omp ...' directives.
This represents 'unified_address' clause in the 'pragma omp requires' directive.
This represents 'unified_shared_memory' clause in the 'pragma omp requires' directive.
This represents 'untied' clause in the 'pragma omp ...' directive.
This represents 'update' clause in the 'pragma omp atomic' directive.
This represents the 'use' clause in 'pragma omp ...' directives.
This represents clause 'use_device_addr' in the 'pragma omp ...' directives.
This represents clause 'use_device_ptr' in the 'pragma omp ...' directives.
This represents clause 'uses_allocators' in the 'pragma omp target'-based directives.
This represents 'weak' clause in the 'pragma omp atomic' directives.
This represents 'write' clause in the 'pragma omp atomic' directive.
This represents 'ompx_attribute' clause in a directive that might generate an outlined function.
This represents 'ompx_bare' clause in the 'pragma omp target teams ...' directive.
This represents 'ompx_dyn_cgroup_mem' clause in the 'pragma omp target ...' directive.
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
Definition ExprObjC.h:192
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:1700
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
Definition ExprObjC.h:88
ObjCBoxedExpr - used for generalized expression boxing.
Definition ExprObjC.h:128
An Objective-C "bridged" cast expression, which casts between Objective-C pointers and C pointers,...
Definition ExprObjC.h:1640
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:307
ObjCEncodeExpr, used for @encode in Objective-C.
Definition ExprObjC.h:407
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:1579
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:7855
ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
Definition ExprObjC.h:1495
ObjCIvarDecl - Represents an ObjC instance variable.
Definition DeclObjC.h:1952
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Definition ExprObjC.h:546
An expression that sends a message to the given Objective-C object or class.
Definition ExprObjC.h:937
ObjCMethodDecl - Represents an instance or class method declaration.
Definition DeclObjC.h:140
Represents a pointer to an Objective C object.
Definition TypeBase.h:7911
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:614
Represents an Objective-C protocol declaration.
Definition DeclObjC.h:2084
ObjCProtocolExpr used for protocol expression in Objective-C.
Definition ExprObjC.h:502
ObjCSelectorExpr used for @selector in Objective-C.
Definition ExprObjC.h:452
ObjCStringLiteral, used for Objective-C string literals i.e.
Definition ExprObjC.h:52
ObjCSubscriptRefExpr - used for array and dictionary subscripting.
Definition ExprObjC.h:836
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:2527
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition Expr.h:1178
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:2090
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:4875
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:2182
Sugar for parentheses used when specifying types.
Definition TypeBase.h:3303
Represents a parameter to a function.
Definition Decl.h:1790
PipeType - OpenCL20.
Definition TypeBase.h:8111
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:2005
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition Expr.h:6756
Expr *const * semantics_iterator
Definition Expr.h:6815
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:3636
Represents a struct/union/class.
Definition Decl.h:4321
Frontend produces RecoveryExprs on semantic errors that prevent creating other well-formed expression...
Definition Expr.h:7455
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:2098
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:3151
Represents a __leave statement.
Definition Stmt.h:3879
SYCLKernelCallStmt represents the transformation that is applied to the body of a function declared w...
Definition StmtSYCL.h:37
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:4643
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:5017
Represents a C++11 static_assert declaration.
Definition DeclCXX.h:4132
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
Definition Expr.h:4595
Stmt - This represents one statement.
Definition Stmt.h:85
@ NoStmtClass
Definition Stmt.h:88
child_range children()
Definition Stmt.cpp:299
StmtClass getStmtClass() const
Definition Stmt.h:1484
llvm::iterator_range< child_iterator > child_range
Definition Stmt.h:1573
StringLiteral - This represents a string literal expression, e.g.
Definition Expr.h:1799
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:2500
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:4631
The top declaration context.
Definition Decl.h:105
Represents the declaration of a typedef-name via a C++11 alias-declaration.
Definition Decl.h:3688
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:2706
A container of type source information.
Definition TypeBase.h:8264
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition TypeLoc.h:267
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
Definition ExprCXX.h:2896
The base class of the type hierarchy.
Definition TypeBase.h:1833
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Definition Decl.h:3667
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition Expr.h:2625
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition Expr.h:2244
An artificial decl, representing a global anonymous constant value which is uniquified by value withi...
Definition DeclCXX.h:4451
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:4114
Represents a dependent using declaration which was marked with typename.
Definition DeclCXX.h:4033
Represents a dependent using declaration which was not marked with typename.
Definition DeclCXX.h:3936
A call to a literal operator (C++11 [over.literal]) written as a user-defined literal (C++11 [lit....
Definition ExprCXX.h:640
Represents a C++ using-declaration.
Definition DeclCXX.h:3587
Represents C++ using-directive.
Definition DeclCXX.h:3092
Represents a C++ using-enum-declaration.
Definition DeclCXX.h:3788
Represents a pack of using declarations that a single using-declarator pack-expanded into.
Definition DeclCXX.h:3869
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Definition DeclCXX.h:3395
Represents a call to the builtin function __builtin_va_arg.
Definition Expr.h:4957
Represents a variable declaration or definition.
Definition Decl.h:926
Declaration of a variable template.
Represents a GCC generic vector type.
Definition TypeBase.h:4176
WhileStmt - This represents a 'while' stmt.
Definition Stmt.h:2688
A requires-expression requirement which queries the validity and properties of an expression ('simple...
const ReturnTypeRequirement & getReturnTypeRequirement() const
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...
RequirementKind getKind() const
A requires-expression requirement which queries the existence of a type name or type template special...
TypeSourceInfo * getType() const
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))
DEF_TRAVERSE_TYPELOC(ComplexType, { TRY_TO(TraverseType(TL.getTypePtr() ->getElementType()));}) DEF_TRAVERSE_TYPELOC(PointerType
@ 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
const FunctionProtoType * T
@ 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:1288
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
Definition Specifiers.h:206
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
Definition Specifiers.h:202
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition Specifiers.h:198
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
Definition Specifiers.h:194
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition Specifiers.h:191
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Class
The "class" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:5879
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.
Data for list of allocators.