clang 24.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
327 /// Recursively visit a single component of an __builtin_offsetof
328 /// designator (a field, identifier, base-class, or array-index node).
329 ///
330 /// \returns false if the visitation was terminated early, true otherwise.
332
333 /// Visit a single component of an __builtin_offsetof designator.
334 bool VisitOffsetOfNode(const OffsetOfNode *Node) { return true; }
335
336 // ---- Methods on Attrs ----
337
338 // Visit an attribute.
339 bool VisitAttr(Attr *A) { return true; }
340
341// Declare Traverse* and empty Visit* for all Attr classes.
342#define ATTR_VISITOR_DECLS_ONLY
343#include "clang/AST/AttrVisitor.inc"
344#undef ATTR_VISITOR_DECLS_ONLY
345
346// ---- Methods on Stmts ----
347
349
350private:
351 // Traverse the given statement. If the most-derived traverse function takes a
352 // data recursion queue, pass it on; otherwise, discard it. Note that the
353 // first branch of this conditional must compile whether or not the derived
354 // class can take a queue, so if we're taking the second arm, make the first
355 // arm call our function rather than the derived class version.
356#define TRAVERSE_STMT_BASE(NAME, CLASS, VAR, QUEUE) \
357 (::clang::detail::has_same_member_pointer_type< \
358 decltype(&RecursiveASTVisitor::Traverse##NAME), \
359 decltype(&Derived::Traverse##NAME)>::value \
360 ? static_cast<std::conditional_t< \
361 ::clang::detail::has_same_member_pointer_type< \
362 decltype(&RecursiveASTVisitor::Traverse##NAME), \
363 decltype(&Derived::Traverse##NAME)>::value, \
364 Derived &, RecursiveASTVisitor &>>(*this) \
365 .Traverse##NAME(static_cast<CLASS *>(VAR), QUEUE) \
366 : getDerived().Traverse##NAME(static_cast<CLASS *>(VAR)))
367
368// Try to traverse the given statement, or enqueue it if we're performing data
369// recursion in the middle of traversing another statement. Can only be called
370// from within a DEF_TRAVERSE_STMT body or similar context.
371#define TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S) \
372 do { \
373 if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S, Queue)) \
374 return false; \
375 } while (false)
376
377public:
378// Declare Traverse*() for all concrete Stmt classes.
379#define ABSTRACT_STMT(STMT)
380#define STMT(CLASS, PARENT) \
381 bool Traverse##CLASS(CLASS *S, DataRecursionQueue *Queue = nullptr);
382#include "clang/AST/StmtNodes.inc"
383 // The above header #undefs ABSTRACT_STMT and STMT upon exit.
384
385 // Define WalkUpFrom*() and empty Visit*() for all Stmt classes.
386 bool WalkUpFromStmt(Stmt *S) { return getDerived().VisitStmt(S); }
387 bool VisitStmt(Stmt *S) { return true; }
388#define STMT(CLASS, PARENT) \
389 bool WalkUpFrom##CLASS(CLASS *S) { \
390 TRY_TO(WalkUpFrom##PARENT(S)); \
391 TRY_TO(Visit##CLASS(S)); \
392 return true; \
393 } \
394 bool Visit##CLASS(CLASS *S) { return true; }
395#include "clang/AST/StmtNodes.inc"
396
397// ---- Methods on Types ----
398// FIXME: revamp to take TypeLoc's rather than Types.
399
400// Declare Traverse*() for all concrete Type classes.
401#define ABSTRACT_TYPE(CLASS, BASE)
402#define TYPE(CLASS, BASE) \
403 bool Traverse##CLASS##Type(CLASS##Type *T, bool TraverseQualifier);
404#include "clang/AST/TypeNodes.inc"
405 // The above header #undefs ABSTRACT_TYPE and TYPE upon exit.
406
407 // Define WalkUpFrom*() and empty Visit*() for all Type classes.
408 bool WalkUpFromType(Type *T) { return getDerived().VisitType(T); }
409 bool VisitType(Type *T) { return true; }
410#define TYPE(CLASS, BASE) \
411 bool WalkUpFrom##CLASS##Type(CLASS##Type *T) { \
412 TRY_TO(WalkUpFrom##BASE(T)); \
413 TRY_TO(Visit##CLASS##Type(T)); \
414 return true; \
415 } \
416 bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
417#include "clang/AST/TypeNodes.inc"
418
419// ---- Methods on TypeLocs ----
420// FIXME: this currently just calls the matching Type methods
421
422// Declare Traverse*() for all concrete TypeLoc classes.
423#define ABSTRACT_TYPELOC(CLASS, BASE)
424#define TYPELOC(CLASS, BASE) \
425 bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL, bool TraverseQualifier);
426#include "clang/AST/TypeLocNodes.def"
427 // The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit.
428
429 // Define WalkUpFrom*() and empty Visit*() for all TypeLoc classes.
430 bool WalkUpFromTypeLoc(TypeLoc TL) { return getDerived().VisitTypeLoc(TL); }
431 bool VisitTypeLoc(TypeLoc TL) { return true; }
432
433 // QualifiedTypeLoc and UnqualTypeLoc are not declared in
434 // TypeNodes.inc and thus need to be handled specially.
436 return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
437 }
438 bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { return true; }
440 return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
441 }
442 bool VisitUnqualTypeLoc(UnqualTypeLoc TL) { return true; }
443
444// Note that BASE includes trailing 'Type' which CLASS doesn't.
445#define TYPE(CLASS, BASE) \
446 bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
447 TRY_TO(WalkUpFrom##BASE##Loc(TL)); \
448 TRY_TO(Visit##CLASS##TypeLoc(TL)); \
449 return true; \
450 } \
451 bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
452#include "clang/AST/TypeNodes.inc"
453
454// ---- Methods on Decls ----
455
456// Declare Traverse*() for all concrete Decl classes.
457#define ABSTRACT_DECL(DECL)
458#define DECL(CLASS, BASE) bool Traverse##CLASS##Decl(CLASS##Decl *D);
459#include "clang/AST/DeclNodes.inc"
460 // The above header #undefs ABSTRACT_DECL and DECL upon exit.
461
462 // Define WalkUpFrom*() and empty Visit*() for all Decl classes.
463 bool WalkUpFromDecl(Decl *D) { return getDerived().VisitDecl(D); }
464 bool VisitDecl(Decl *D) { return true; }
465#define DECL(CLASS, BASE) \
466 bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) { \
467 TRY_TO(WalkUpFrom##BASE(D)); \
468 TRY_TO(Visit##CLASS##Decl(D)); \
469 return true; \
470 } \
471 bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
472#include "clang/AST/DeclNodes.inc"
473
475
476#define DEF_TRAVERSE_TMPL_INST(TMPLDECLKIND) \
477 bool TraverseTemplateInstantiations(TMPLDECLKIND##TemplateDecl *D);
480 DEF_TRAVERSE_TMPL_INST(Function)
481#undef DEF_TRAVERSE_TMPL_INST
482
484
489
491
492private:
493 // These are helper methods used by more than one Traverse* method.
494 bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
495
496 // Traverses template parameter lists of either a DeclaratorDecl or TagDecl.
497 template <typename T>
498 bool TraverseDeclTemplateParameterLists(T *D);
499
500 bool TraverseTemplateTypeParamDeclConstraints(const TemplateTypeParmDecl *D);
501
502 bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL,
503 unsigned Count);
504 bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL);
505 bool TraverseSubstPackTypeHelper(SubstPackType *T);
506 bool TraverseSubstPackTypeLocHelper(SubstPackTypeLoc TL);
507 bool TraverseRecordHelper(RecordDecl *D);
508 bool TraverseCXXRecordHelper(CXXRecordDecl *D);
509 bool TraverseDeclaratorHelper(DeclaratorDecl *D);
510 bool TraverseDeclContextHelper(DeclContext *DC);
511 bool TraverseFunctionHelper(FunctionDecl *D);
512 bool TraverseVarHelper(VarDecl *D);
513 bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
514 bool TraverseOMPLoopDirective(OMPLoopDirective *S);
515 bool TraverseOMPClause(OMPClause *C);
516 bool TraverseTagType(TagType *T, bool TraverseQualifier);
517 bool TraverseTagTypeLoc(TagTypeLoc TL, bool TraverseQualifier);
518#define GEN_CLANG_CLAUSE_CLASS
519#define CLAUSE_CLASS(Enum, Str, Class) bool Visit##Class(Class *C);
520#include "llvm/Frontend/OpenMP/OMP.inc"
521 /// Process clauses with list of variables.
522 template <typename T> bool VisitOMPClauseList(T *Node);
523 /// Process clauses with pre-initis.
524 bool VisitOMPClauseWithPreInit(OMPClauseWithPreInit *Node);
525 bool VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *Node);
526
527 bool PostVisitStmt(Stmt *S);
528 bool TraverseOpenACCConstructStmt(OpenACCConstructStmt *S);
529 bool
530 TraverseOpenACCAssociatedStmtConstruct(OpenACCAssociatedStmtConstruct *S);
531 bool VisitOpenACCClauseList(ArrayRef<const OpenACCClause *>);
532 bool VisitOpenACCClause(const OpenACCClause *);
533};
534
535template <typename Derived>
537 const TypeConstraint *C) {
539 TRY_TO(TraverseConceptReference(C->getConceptReference()));
540 return true;
541 }
542 if (Expr *IDC = C->getImmediatelyDeclaredConstraint()) {
543 TRY_TO(TraverseStmt(IDC));
544 } else {
545 // Avoid traversing the ConceptReference in the TypeConstraint
546 // if we have an immediately-declared-constraint, otherwise
547 // we'll end up visiting the concept and the arguments in
548 // the TC twice.
549 TRY_TO(TraverseConceptReference(C->getConceptReference()));
550 }
551 return true;
552}
553
554template <typename Derived>
557 switch (R->getKind()) {
559 return getDerived().TraverseConceptTypeRequirement(
563 return getDerived().TraverseConceptExprRequirement(
566 return getDerived().TraverseConceptNestedRequirement(
568 }
569 llvm_unreachable("unexpected case");
570}
571
572template <typename Derived>
574 DataRecursionQueue *Queue) {
575 // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
576 switch (S->getStmtClass()) {
578 break;
579#define ABSTRACT_STMT(STMT)
580#define STMT(CLASS, PARENT) \
581 case Stmt::CLASS##Class: \
582 return TRAVERSE_STMT_BASE(CLASS, CLASS, S, Queue);
583#include "clang/AST/StmtNodes.inc"
584 }
585
586 return true;
587}
588
589#undef DISPATCH_STMT
590
591template <typename Derived>
594 if (R->isSubstitutionFailure())
595 return true;
596 return getDerived().TraverseTypeLoc(R->getType()->getTypeLoc());
597}
598
599template <typename Derived>
602 if (!R->isExprSubstitutionFailure())
603 TRY_TO(TraverseStmt(R->getExpr()));
604 auto &RetReq = R->getReturnTypeRequirement();
605 if (RetReq.isTypeConstraint()) {
607 TRY_TO(TraverseTemplateParameterListHelper(
608 RetReq.getTypeConstraintTemplateParameterList()));
609 } else {
610 // Template parameter list is implicit, visit constraint directly.
611 TRY_TO(TraverseTypeConstraint(RetReq.getTypeConstraint()));
612 }
613 }
614 return true;
615}
616
617template <typename Derived>
620 if (!R->hasInvalidConstraint())
621 return getDerived().TraverseStmt(R->getConstraintExpr());
622 return true;
623}
624
625template <typename Derived>
626bool RecursiveASTVisitor<Derived>::PostVisitStmt(Stmt *S) {
627 // In pre-order traversal mode, each Traverse##STMT method is responsible for
628 // calling WalkUpFrom. Therefore, if the user overrides Traverse##STMT and
629 // does not call the default implementation, the WalkUpFrom callback is not
630 // called. Post-order traversal mode should provide the same behavior
631 // regarding method overrides.
632 //
633 // In post-order traversal mode the Traverse##STMT method, when it receives a
634 // DataRecursionQueue, can't call WalkUpFrom after traversing children because
635 // it only enqueues the children and does not traverse them. TraverseStmt
636 // traverses the enqueued children, and we call WalkUpFrom here.
637 //
638 // However, to make pre-order and post-order modes identical with regards to
639 // whether they call WalkUpFrom at all, we call WalkUpFrom if and only if the
640 // user did not override the Traverse##STMT method. We implement the override
641 // check with isSameMethod calls below.
642
643 switch (S->getStmtClass()) {
645 break;
646#define ABSTRACT_STMT(STMT)
647#define STMT(CLASS, PARENT) \
648 case Stmt::CLASS##Class: \
649 if (::clang::detail::isSameMethod(&RecursiveASTVisitor::Traverse##CLASS, \
650 &Derived::Traverse##CLASS)) { \
651 TRY_TO(WalkUpFrom##CLASS(static_cast<CLASS *>(S))); \
652 } \
653 break;
654#define INITLISTEXPR(CLASS, PARENT) \
655 case Stmt::CLASS##Class: \
656 if (::clang::detail::isSameMethod(&RecursiveASTVisitor::Traverse##CLASS, \
657 &Derived::Traverse##CLASS)) { \
658 auto ILE = static_cast<CLASS *>(S); \
659 if (auto Syn = ILE->isSemanticForm() ? ILE->getSyntacticForm() : ILE) \
660 TRY_TO(WalkUpFrom##CLASS(Syn)); \
661 if (auto Sem = ILE->isSemanticForm() ? ILE : ILE->getSemanticForm()) \
662 TRY_TO(WalkUpFrom##CLASS(Sem)); \
663 } \
664 break;
665#include "clang/AST/StmtNodes.inc"
666 }
667
668 return true;
669}
670
671#undef DISPATCH_STMT
672
673// Inlining this method can lead to large code size and compile-time increases
674// without any benefit to runtime performance.
675template <typename Derived>
676LLVM_ATTRIBUTE_NOINLINE bool
678 if (!S)
679 return true;
680
681 if (Queue) {
682 Queue->push_back({S, false});
683 return true;
684 }
685
687 LocalQueue.push_back({S, false});
688
689 while (!LocalQueue.empty()) {
690 auto &CurrSAndVisited = LocalQueue.back();
691 Stmt *CurrS = CurrSAndVisited.getPointer();
692 bool Visited = CurrSAndVisited.getInt();
693 if (Visited) {
694 LocalQueue.pop_back();
697 TRY_TO(PostVisitStmt(CurrS));
698 }
699 continue;
700 }
701
702 if (getDerived().dataTraverseStmtPre(CurrS)) {
703 CurrSAndVisited.setInt(true);
704 size_t N = LocalQueue.size();
705 TRY_TO(dataTraverseNode(CurrS, &LocalQueue));
706 // Process new children in the order they were added.
707 std::reverse(LocalQueue.begin() + N, LocalQueue.end());
708 } else {
709 LocalQueue.pop_back();
710 }
711 }
712
713 return true;
714}
715
716template <typename Derived>
718 bool TraverseQualifier) {
719 if (T.isNull())
720 return true;
721
722 switch (T->getTypeClass()) {
723#define ABSTRACT_TYPE(CLASS, BASE)
724#define TYPE(CLASS, BASE) \
725 case Type::CLASS: \
726 return getDerived().Traverse##CLASS##Type( \
727 static_cast<CLASS##Type *>(const_cast<Type *>(T.getTypePtr())), \
728 TraverseQualifier);
729#include "clang/AST/TypeNodes.inc"
730 }
731
732 return true;
733}
734
735template <typename Derived>
737 bool TraverseQualifier) {
738 if (TL.isNull())
739 return true;
740
741 switch (TL.getTypeLocClass()) {
742#define ABSTRACT_TYPELOC(CLASS, BASE)
743#define TYPELOC(CLASS, BASE) \
744 case TypeLoc::CLASS: \
745 return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>(), \
746 TraverseQualifier);
747#include "clang/AST/TypeLocNodes.def"
748 }
749
750 return true;
751}
752
753// Define the Traverse*Attr(Attr* A) methods
754#define VISITORCLASS RecursiveASTVisitor
755#include "clang/AST/AttrVisitor.inc"
756#undef VISITORCLASS
757
758template <typename Derived>
760 if (!D)
761 return true;
762
763 // As a syntax visitor, by default we want to ignore declarations for
764 // implicit declarations (ones not typed explicitly by the user).
766 if (D->isImplicit()) {
767 // For an implicit template type parameter, its type constraints are not
768 // implicit and are not represented anywhere else. We still need to visit
769 // them.
770 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(D))
771 return TraverseTemplateTypeParamDeclConstraints(TTPD);
772 return true;
773 }
774
775 // Deduction guides for alias templates are always synthesized, so they
776 // should not be traversed unless shouldVisitImplicitCode() returns true.
777 //
778 // It's important to note that checking the implicit bit is not efficient
779 // for the alias case. For deduction guides synthesized from explicit
780 // user-defined deduction guides, we must maintain the explicit bit to
781 // ensure correct overload resolution.
782 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
783 if (llvm::isa_and_present<TypeAliasTemplateDecl>(
784 FTD->getDeclName().getCXXDeductionGuideTemplate()))
785 return true;
786 }
787
788 switch (D->getKind()) {
789#define ABSTRACT_DECL(DECL)
790#define DECL(CLASS, BASE) \
791 case Decl::CLASS: \
792 if (!getDerived().Traverse##CLASS##Decl(static_cast<CLASS##Decl *>(D))) \
793 return false; \
794 break;
795#include "clang/AST/DeclNodes.inc"
796 }
797 return true;
798}
799
800template <typename Derived>
803 switch (NNS.getKind()) {
807 return true;
810 return true;
812 auto *T = const_cast<Type *>(NNS.getAsType());
813 TRY_TO(TraverseNestedNameSpecifier(T->getPrefix()));
814 TRY_TO(TraverseType(QualType(T, 0), /*TraverseQualifier=*/false));
815 return true;
816 }
817 }
818 llvm_unreachable("unhandled kind");
819}
820
821template <typename Derived>
843
844template <typename Derived>
872
873template <typename Derived>
875 if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
876 TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier()));
877 } else if (QualifiedTemplateName *QTN =
878 Template.getAsQualifiedTemplateName()) {
879 if (QTN->getQualifier()) {
880 TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier()));
881 }
882 }
883
884 return true;
885}
886
887template <typename Derived>
889 const TemplateArgument &Arg) {
890 switch (Arg.getKind()) {
896 return true;
897
899 return getDerived().TraverseType(Arg.getAsType());
900
903 return getDerived().TraverseTemplateName(
905
907 return getDerived().TraverseStmt(Arg.getAsExpr());
908
910 return getDerived().TraverseTemplateArguments(Arg.pack_elements());
911 }
912
913 return true;
914}
915
916// FIXME: no template name location?
917// FIXME: no source locations for a template argument pack?
918template <typename Derived>
920 const TemplateArgumentLoc &ArgLoc) {
921 const TemplateArgument &Arg = ArgLoc.getArgument();
922
923 switch (Arg.getKind()) {
929 return true;
930
932 // FIXME: how can TSI ever be NULL?
933 if (TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo())
934 return getDerived().TraverseTypeLoc(TSI->getTypeLoc());
935 else
936 return getDerived().TraverseType(Arg.getAsType());
937 }
938
941 if (ArgLoc.getTemplateQualifierLoc())
943 ArgLoc.getTemplateQualifierLoc()));
944 return getDerived().TraverseTemplateName(
946
948 return getDerived().TraverseStmt(ArgLoc.getSourceExpression());
949
951 return getDerived().TraverseTemplateArguments(Arg.pack_elements());
952 }
953
954 return true;
955}
956
957template <typename Derived>
960 for (const TemplateArgument &Arg : Args)
962
963 return true;
964}
965
966template <typename Derived>
969 if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo())
970 TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
971
972 if (Init->isWritten() || getDerived().shouldVisitImplicitCode())
973 TRY_TO(TraverseStmt(Init->getInit()));
974
975 return true;
976}
977
978template <typename Derived>
979bool
981 const LambdaCapture *C,
982 Expr *Init) {
983 if (LE->isInitCapture(C))
984 TRY_TO(TraverseDecl(C->getCapturedVar()));
985 else
987 return true;
988}
989
990// ----------------- Type traversal -----------------
991
992// This macro makes available a variable T, the passed-in type.
993#define DEF_TRAVERSE_TYPE(TYPE, CODE) \
994 template <typename Derived> \
995 bool RecursiveASTVisitor<Derived>::Traverse##TYPE(TYPE *T, \
996 bool TraverseQualifier) { \
997 if (!getDerived().shouldTraversePostOrder()) \
998 TRY_TO(WalkUpFrom##TYPE(T)); \
999 { \
1000 CODE; \
1001 } \
1002 if (getDerived().shouldTraversePostOrder()) \
1003 TRY_TO(WalkUpFrom##TYPE(T)); \
1004 return true; \
1005 }
1006
1007DEF_TRAVERSE_TYPE(BuiltinType, {})
1008
1009DEF_TRAVERSE_TYPE(ComplexType, { TRY_TO(TraverseType(T->getElementType())); })
1010
1011DEF_TRAVERSE_TYPE(PointerType, { TRY_TO(TraverseType(T->getPointeeType())); })
1012
1014 { TRY_TO(TraverseType(T->getPointeeType())); })
1015
1016DEF_TRAVERSE_TYPE(LValueReferenceType,
1017 { TRY_TO(TraverseType(T->getPointeeType())); })
1018
1020 { TRY_TO(TraverseType(T->getPointeeType())); })
1021
1022DEF_TRAVERSE_TYPE(MemberPointerType, {
1023 NestedNameSpecifier Qualifier =
1024 T->isSugared() ? cast<MemberPointerType>(T->getCanonicalTypeUnqualified())
1025 ->getQualifier()
1026 : T->getQualifier();
1027 TRY_TO(TraverseNestedNameSpecifier(Qualifier));
1028 TRY_TO(TraverseType(T->getPointeeType()));
1029})
1030
1031DEF_TRAVERSE_TYPE(AdjustedType, { TRY_TO(TraverseType(T->getOriginalType())); })
1032
1033DEF_TRAVERSE_TYPE(DecayedType, { TRY_TO(TraverseType(T->getOriginalType())); })
1034
1036 TRY_TO(TraverseType(T->getElementType()));
1037 if (T->getSizeExpr())
1038 TRY_TO(TraverseStmt(const_cast<Expr*>(T->getSizeExpr())));
1039})
1040
1041DEF_TRAVERSE_TYPE(ArrayParameterType, {
1042 TRY_TO(TraverseType(T->getElementType()));
1043 if (T->getSizeExpr())
1044 TRY_TO(TraverseStmt(const_cast<Expr *>(T->getSizeExpr())));
1045})
1046
1048 { TRY_TO(TraverseType(T->getElementType())); })
1049
1050DEF_TRAVERSE_TYPE(VariableArrayType, {
1051 TRY_TO(TraverseType(T->getElementType()));
1052 TRY_TO(TraverseStmt(T->getSizeExpr()));
1053})
1054
1056 TRY_TO(TraverseType(T->getElementType()));
1057 if (T->getSizeExpr())
1058 TRY_TO(TraverseStmt(T->getSizeExpr()));
1059})
1060
1061DEF_TRAVERSE_TYPE(DependentAddressSpaceType, {
1062 TRY_TO(TraverseStmt(T->getAddrSpaceExpr()));
1063 TRY_TO(TraverseType(T->getPointeeType()));
1064})
1065
1067 if (T->getSizeExpr())
1068 TRY_TO(TraverseStmt(T->getSizeExpr()));
1069 TRY_TO(TraverseType(T->getElementType()));
1070})
1071
1072DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
1073 if (T->getSizeExpr())
1074 TRY_TO(TraverseStmt(T->getSizeExpr()));
1075 TRY_TO(TraverseType(T->getElementType()));
1076})
1077
1078DEF_TRAVERSE_TYPE(VectorType, { TRY_TO(TraverseType(T->getElementType())); })
1079
1080DEF_TRAVERSE_TYPE(ExtVectorType, { TRY_TO(TraverseType(T->getElementType())); })
1081
1083 { TRY_TO(TraverseType(T->getElementType())); })
1084
1085DEF_TRAVERSE_TYPE(DependentSizedMatrixType, {
1086 if (T->getRowExpr())
1087 TRY_TO(TraverseStmt(T->getRowExpr()));
1088 if (T->getColumnExpr())
1089 TRY_TO(TraverseStmt(T->getColumnExpr()));
1090 TRY_TO(TraverseType(T->getElementType()));
1091})
1092
1094 { TRY_TO(TraverseType(T->getReturnType())); })
1095
1096DEF_TRAVERSE_TYPE(FunctionProtoType, {
1097 TRY_TO(TraverseType(T->getReturnType()));
1098
1099 for (const auto &A : T->param_types()) {
1100 TRY_TO(TraverseType(A));
1101 }
1102
1103 for (const auto &E : T->exceptions()) {
1104 TRY_TO(TraverseType(E));
1105 }
1106
1107 if (Expr *NE = T->getNoexceptExpr())
1108 TRY_TO(TraverseStmt(NE));
1109})
1110
1112 if (TraverseQualifier)
1113 TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
1114})
1115DEF_TRAVERSE_TYPE(UnresolvedUsingType, {
1116 if (TraverseQualifier)
1117 TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
1118})
1120 if (TraverseQualifier)
1121 TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
1122})
1123
1124DEF_TRAVERSE_TYPE(TypeOfExprType,
1125 { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
1126
1127DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnmodifiedType())); })
1128
1129DEF_TRAVERSE_TYPE(DecltypeType,
1130 { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
1131
1132DEF_TRAVERSE_TYPE(PackIndexingType, {
1133 TRY_TO(TraverseType(T->getPattern()));
1134 TRY_TO(TraverseStmt(T->getIndexExpr()));
1135})
1136
1137DEF_TRAVERSE_TYPE(UnaryTransformType, {
1138 TRY_TO(TraverseType(T->getBaseType()));
1139 TRY_TO(TraverseType(T->getUnderlyingType()));
1140})
1141
1143 TRY_TO(TraverseType(T->getDeducedType()));
1144 if (T->isConstrained()) {
1145 TRY_TO(TraverseTemplateArguments(T->getTypeConstraintArguments()));
1146 }
1147})
1148
1149DEF_TRAVERSE_TYPE(TemplateTypeParmType, {})
1150DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, {
1151 TRY_TO(TraverseType(T->getReplacementType()));
1152})
1153DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType,
1154 { TRY_TO(TraverseSubstPackTypeHelper(T)); })
1155DEF_TRAVERSE_TYPE(SubstBuiltinTemplatePackType,
1156 { TRY_TO(TraverseSubstPackTypeHelper(T)); })
1157
1158DEF_TRAVERSE_TYPE(AttributedType,
1159 { TRY_TO(TraverseType(T->getModifiedType())); })
1160
1161DEF_TRAVERSE_TYPE(CountAttributedType, {
1162 if (T->getCountExpr())
1163 TRY_TO(TraverseStmt(T->getCountExpr()));
1164 TRY_TO(TraverseType(T->desugar()));
1165})
1166
1168 { TRY_TO(TraverseType(T->getWrappedType())); })
1169
1170DEF_TRAVERSE_TYPE(BTFTagAttributedType,
1171 { TRY_TO(TraverseType(T->getWrappedType())); })
1172
1173DEF_TRAVERSE_TYPE(OverflowBehaviorType,
1174 { TRY_TO(TraverseType(T->getUnderlyingType())); })
1175
1176DEF_TRAVERSE_TYPE(HLSLAttributedResourceType,
1177 { TRY_TO(TraverseType(T->getWrappedType())); })
1178
1179DEF_TRAVERSE_TYPE(HLSLInlineSpirvType, {
1180 for (auto &Operand : T->getOperands()) {
1181 if (Operand.isConstant() || Operand.isType()) {
1182 TRY_TO(TraverseType(Operand.getResultType()));
1183 }
1184 }
1185})
1186
1187DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
1188
1190 { TRY_TO(TraverseType(T->getUnderlyingType())); })
1191
1192template <typename Derived>
1193bool RecursiveASTVisitor<Derived>::TraverseTagType(TagType *T,
1194 bool TraverseQualifier) {
1195 if (TraverseQualifier)
1196 TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
1197 return true;
1198}
1199
1200DEF_TRAVERSE_TYPE(EnumType, { TRY_TO(TraverseTagType(T, TraverseQualifier)); })
1201DEF_TRAVERSE_TYPE(RecordType,
1202 { TRY_TO(TraverseTagType(T, TraverseQualifier)); })
1203DEF_TRAVERSE_TYPE(InjectedClassNameType,
1204 { TRY_TO(TraverseTagType(T, TraverseQualifier)); })
1205
1206DEF_TRAVERSE_TYPE(DependentNameType, {
1207 if (TraverseQualifier)
1208 TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
1209})
1210
1211DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
1212 if (TraverseQualifier) {
1213 TRY_TO(TraverseTemplateName(T->getTemplateName()));
1214 } else {
1215 // FIXME: Try to preserve the rest of the template name.
1216 TRY_TO(TraverseTemplateName(TemplateName(
1217 T->getTemplateName().getAsTemplateDecl(/*IgnoreDeduced=*/true))));
1218 }
1219 TRY_TO(TraverseTemplateArguments(T->template_arguments()));
1220})
1221
1222DEF_TRAVERSE_TYPE(DeducedTemplateSpecializationType, {
1223 if (TraverseQualifier) {
1224 TRY_TO(TraverseTemplateName(T->getTemplateName()));
1225 } else {
1226 // FIXME: Try to preserve the rest of the template name.
1227 TRY_TO(TraverseTemplateName(TemplateName(
1228 T->getTemplateName().getAsTemplateDecl(/*IgnoreDeduced=*/true))));
1229 }
1230 TRY_TO(TraverseType(T->getDeducedType()));
1231})
1232
1233DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); })
1234
1235DEF_TRAVERSE_TYPE(ObjCTypeParamType, {})
1236
1238
1239DEF_TRAVERSE_TYPE(ObjCObjectType, {
1240 // We have to watch out here because an ObjCInterfaceType's base
1241 // type is itself.
1242 if (T->getBaseType().getTypePtr() != T)
1243 TRY_TO(TraverseType(T->getBaseType()));
1244 for (auto typeArg : T->getTypeArgsAsWritten()) {
1245 TRY_TO(TraverseType(typeArg));
1246 }
1247})
1248
1250 { TRY_TO(TraverseType(T->getPointeeType())); })
1251
1252DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); })
1253
1254DEF_TRAVERSE_TYPE(PipeType, { TRY_TO(TraverseType(T->getElementType())); })
1255
1256DEF_TRAVERSE_TYPE(BitIntType, {})
1258 { TRY_TO(TraverseStmt(T->getNumBitsExpr())); })
1259
1261
1262#undef DEF_TRAVERSE_TYPE
1263
1264// ----------------- TypeLoc traversal -----------------
1265
1266// This macro makes available a variable TL, the passed-in TypeLoc.
1267// If requested, it calls WalkUpFrom* for the Type in the given TypeLoc,
1268// in addition to WalkUpFrom* for the TypeLoc itself, such that existing
1269// clients that override the WalkUpFrom*Type() and/or Visit*Type() methods
1270// continue to work.
1272 template <typename Derived> \
1273 bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc( \
1274 TYPE##Loc TL, bool TraverseQualifier) { \
1275 if (!getDerived().shouldTraversePostOrder()) { \
1276 TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
1277 if (getDerived().shouldWalkTypesOfTypeLocs()) \
1278 TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \
1279 } \
1280 { \
1281 CODE; \
1282 } \
1283 if (getDerived().shouldTraversePostOrder()) { \
1284 TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
1285 if (getDerived().shouldWalkTypesOfTypeLocs()) \
1286 TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \
1287 } \
1288 return true; \
1289 }
1290
1291template <typename Derived>
1293 QualifiedTypeLoc TL, bool TraverseQualifier) {
1294 assert(TraverseQualifier &&
1295 "Qualifiers should never occur within NestedNameSpecifiers");
1296 // Move this over to the 'main' typeloc tree. Note that this is a
1297 // move -- we pretend that we were really looking at the unqualified
1298 // typeloc all along -- rather than a recursion, so we don't follow
1299 // the normal CRTP plan of going through
1300 // getDerived().TraverseTypeLoc. If we did, we'd be traversing
1301 // twice for the same type (once as a QualifiedTypeLoc version of
1302 // the type, once as an UnqualifiedTypeLoc version of the type),
1303 // which in effect means we'd call VisitTypeLoc twice with the
1304 // 'same' type. This solves that problem, at the cost of never
1305 // seeing the qualified version of the type (unless the client
1306 // subclasses TraverseQualifiedTypeLoc themselves). It's not a
1307 // perfect solution. A perfect solution probably requires making
1308 // QualifiedTypeLoc a wrapper around TypeLoc -- like QualType is a
1309 // wrapper around Type* -- rather than being its own class in the
1310 // type hierarchy.
1311 return TraverseTypeLoc(TL.getUnqualifiedLoc());
1312}
1313
1315
1316// FIXME: ComplexTypeLoc is unfinished
1318 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1319})
1320
1321DEF_TRAVERSE_TYPELOC(PointerType,
1322 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1323
1325 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1326
1327DEF_TRAVERSE_TYPELOC(LValueReferenceType,
1328 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1329
1331 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1332
1333// We traverse this in the type case as well, but how is it not reached through
1334// the pointee type?
1335DEF_TRAVERSE_TYPELOC(MemberPointerType, {
1336 if (NestedNameSpecifierLoc QL = TL.getQualifierLoc())
1338 else
1339 TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
1340 TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
1341})
1342
1344 { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
1345
1346DEF_TRAVERSE_TYPELOC(DecayedType,
1347 { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
1348
1349template <typename Derived>
1350bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
1351 // This isn't available for ArrayType, but is for the ArrayTypeLoc.
1352 TRY_TO(TraverseStmt(TL.getSizeExpr()));
1353 return true;
1354}
1355
1357 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1358 TRY_TO(TraverseArrayTypeLocHelper(TL));
1359})
1360
1361DEF_TRAVERSE_TYPELOC(ArrayParameterType, {
1362 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1363 TRY_TO(TraverseArrayTypeLocHelper(TL));
1364})
1365
1367 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1368 TRY_TO(TraverseArrayTypeLocHelper(TL));
1369})
1370
1371DEF_TRAVERSE_TYPELOC(VariableArrayType, {
1372 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1373 TRY_TO(TraverseArrayTypeLocHelper(TL));
1374})
1375
1377 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1378 TRY_TO(TraverseArrayTypeLocHelper(TL));
1379})
1380
1381DEF_TRAVERSE_TYPELOC(DependentAddressSpaceType, {
1382 TRY_TO(TraverseStmt(TL.getTypePtr()->getAddrSpaceExpr()));
1383 TRY_TO(TraverseType(TL.getTypePtr()->getPointeeType()));
1384})
1385
1386// FIXME: order? why not size expr first?
1387// FIXME: base VectorTypeLoc is unfinished
1389 if (TL.getTypePtr()->getSizeExpr())
1390 TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
1391 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1392})
1393
1394// FIXME: VectorTypeLoc is unfinished
1395DEF_TRAVERSE_TYPELOC(VectorType, {
1396 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1397})
1398
1400 if (TL.getTypePtr()->getSizeExpr())
1401 TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
1402 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1403})
1404
1405// FIXME: size and attributes
1406// FIXME: base VectorTypeLoc is unfinished
1407DEF_TRAVERSE_TYPELOC(ExtVectorType, {
1408 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1409})
1410
1412 TRY_TO(TraverseStmt(TL.getAttrRowOperand()));
1413 TRY_TO(TraverseStmt(TL.getAttrColumnOperand()));
1414 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1415})
1416
1417DEF_TRAVERSE_TYPELOC(DependentSizedMatrixType, {
1418 TRY_TO(TraverseStmt(TL.getAttrRowOperand()));
1419 TRY_TO(TraverseStmt(TL.getAttrColumnOperand()));
1420 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1421})
1422
1424 { TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); })
1425
1426// FIXME: location of exception specifications (attributes?)
1427DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
1428 TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
1429
1430 const FunctionProtoType *T = TL.getTypePtr();
1431
1432 for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) {
1433 if (TL.getParam(I)) {
1434 TRY_TO(TraverseDecl(TL.getParam(I)));
1435 } else if (I < T->getNumParams()) {
1436 TRY_TO(TraverseType(T->getParamType(I)));
1437 }
1438 }
1439
1440 for (const auto &E : T->exceptions()) {
1441 TRY_TO(TraverseType(E));
1442 }
1443
1444 if (Expr *NE = T->getNoexceptExpr())
1445 TRY_TO(TraverseStmt(NE));
1446})
1447
1449 if (NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
1450 TraverseQualifier && QualifierLoc)
1452})
1453DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {
1454 if (NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
1455 TraverseQualifier && QualifierLoc)
1457})
1459 if (NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
1460 TraverseQualifier && QualifierLoc)
1462})
1463
1464DEF_TRAVERSE_TYPELOC(TypeOfExprType,
1465 { TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); })
1466
1468 TRY_TO(TraverseTypeLoc(TL.getUnmodifiedTInfo()->getTypeLoc()));
1469})
1470
1471// FIXME: location of underlying expr
1472DEF_TRAVERSE_TYPELOC(DecltypeType, {
1473 TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
1474})
1475
1476DEF_TRAVERSE_TYPELOC(PackIndexingType, {
1477 TRY_TO(TraverseType(TL.getPattern()));
1478 TRY_TO(TraverseStmt(TL.getTypePtr()->getIndexExpr()));
1479})
1480
1481DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
1482 TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
1483})
1484
1486 TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
1487 if (TL.isConstrained()) {
1488 TRY_TO(TraverseConceptReference(TL.getConceptReference()));
1489 }
1490})
1491
1492DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {})
1493DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, {
1494 TRY_TO(TraverseType(TL.getTypePtr()->getReplacementType()));
1495})
1496
1497template <typename Derived>
1498bool RecursiveASTVisitor<Derived>::TraverseSubstPackTypeLocHelper(
1499 SubstPackTypeLoc TL) {
1500 TRY_TO(TraverseTemplateArgument(TL.getTypePtr()->getArgumentPack()));
1501 return true;
1502}
1503
1504template <typename Derived>
1505bool RecursiveASTVisitor<Derived>::TraverseSubstPackTypeHelper(
1506 SubstPackType *T) {
1507 TRY_TO(TraverseTemplateArgument(T->getArgumentPack()));
1508 return true;
1509}
1510
1511DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType,
1512 { TRY_TO(TraverseSubstPackTypeLocHelper(TL)); })
1513
1514DEF_TRAVERSE_TYPELOC(SubstBuiltinTemplatePackType,
1515 { TRY_TO(TraverseSubstPackTypeLocHelper(TL)); })
1516
1517DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
1518
1519DEF_TRAVERSE_TYPELOC(MacroQualifiedType,
1520 { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
1521
1523 { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
1524
1525DEF_TRAVERSE_TYPELOC(CountAttributedType,
1526 { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
1527
1529 { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
1530
1531DEF_TRAVERSE_TYPELOC(BTFTagAttributedType,
1532 { TRY_TO(TraverseTypeLoc(TL.getWrappedLoc())); })
1533
1534DEF_TRAVERSE_TYPELOC(OverflowBehaviorType,
1535 { TRY_TO(TraverseTypeLoc(TL.getWrappedLoc())); })
1536
1537DEF_TRAVERSE_TYPELOC(HLSLAttributedResourceType,
1538 { TRY_TO(TraverseTypeLoc(TL.getWrappedLoc())); })
1539
1540DEF_TRAVERSE_TYPELOC(HLSLInlineSpirvType,
1541 { TRY_TO(TraverseType(TL.getType())); })
1542
1543template <typename Derived>
1544bool RecursiveASTVisitor<Derived>::TraverseTagTypeLoc(TagTypeLoc TL,
1545 bool TraverseQualifier) {
1546 if (NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
1547 TraverseQualifier && QualifierLoc)
1549 return true;
1550}
1551
1553 { TRY_TO(TraverseTagTypeLoc(TL, TraverseQualifier)); })
1554DEF_TRAVERSE_TYPELOC(RecordType,
1555 { TRY_TO(TraverseTagTypeLoc(TL, TraverseQualifier)); })
1556DEF_TRAVERSE_TYPELOC(InjectedClassNameType,
1557 { TRY_TO(TraverseTagTypeLoc(TL, TraverseQualifier)); })
1558
1559DEF_TRAVERSE_TYPELOC(DependentNameType, {
1560 if (TraverseQualifier)
1561 TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
1562})
1563
1564DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
1565 if (TraverseQualifier)
1566 TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
1567
1568 // FIXME: Try to preserve the rest of the template name.
1569 TRY_TO(TraverseTemplateName(
1570 TemplateName(TL.getTypePtr()->getTemplateName().getAsTemplateDecl(
1571 /*IgnoreDeduced=*/true))));
1572
1573 for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
1574 TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
1575 }
1576})
1577
1578DEF_TRAVERSE_TYPELOC(DeducedTemplateSpecializationType, {
1579 if (TraverseQualifier)
1580 TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
1581
1582 const auto *T = TL.getTypePtr();
1583 // FIXME: Try to preserve the rest of the template name.
1585 TraverseTemplateName(TemplateName(T->getTemplateName().getAsTemplateDecl(
1586 /*IgnoreDeduced=*/true))));
1587
1588 TRY_TO(TraverseType(T->getDeducedType()));
1589})
1590
1591DEF_TRAVERSE_TYPELOC(PackExpansionType,
1592 { TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); })
1593
1594DEF_TRAVERSE_TYPELOC(ObjCTypeParamType, {
1595 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1596 ObjCProtocolLoc ProtocolLoc(TL.getProtocol(I), TL.getProtocolLoc(I));
1597 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1598 }
1599})
1600
1602
1603DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
1604 // We have to watch out here because an ObjCInterfaceType's base
1605 // type is itself.
1606 if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
1607 TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
1608 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
1609 TRY_TO(TraverseTypeLoc(TL.getTypeArgTInfo(i)->getTypeLoc()));
1610 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1611 ObjCProtocolLoc ProtocolLoc(TL.getProtocol(I), TL.getProtocolLoc(I));
1612 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1613 }
1614})
1615
1617 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1618
1619DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
1620
1621DEF_TRAVERSE_TYPELOC(PipeType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
1622
1625 TRY_TO(TraverseStmt(TL.getTypePtr()->getNumBitsExpr()));
1626})
1627
1629
1631
1632// ----------------- Decl traversal -----------------
1633//
1634// For a Decl, we automate (in the DEF_TRAVERSE_DECL macro) traversing
1635// the children that come from the DeclContext associated with it.
1636// Therefore each Traverse* only needs to worry about children other
1637// than those.
1638
1639template <typename Derived>
1641 const Decl *Child) {
1642 // BlockDecls are traversed through BlockExprs,
1643 // CapturedDecls are traversed through CapturedStmts.
1644 if (isa<BlockDecl>(Child) || isa<CapturedDecl>(Child))
1645 return true;
1646 // Lambda classes are traversed through LambdaExprs.
1647 if (const CXXRecordDecl* Cls = dyn_cast<CXXRecordDecl>(Child))
1648 return Cls->isLambda();
1649 return false;
1650}
1651
1652template <typename Derived>
1653bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
1654 if (!DC)
1655 return true;
1656
1657 for (auto *Child : DC->decls()) {
1658 if (!canIgnoreChildDeclWhileTraversingDeclContext(Child))
1659 TRY_TO(TraverseDecl(Child));
1660 }
1661
1662 return true;
1663}
1664
1665// This macro makes available a variable D, the passed-in decl.
1666#define DEF_TRAVERSE_DECL(DECL, CODE) \
1667 template <typename Derived> \
1668 bool RecursiveASTVisitor<Derived>::Traverse##DECL(DECL *D) { \
1669 bool ShouldVisitChildren = true; \
1670 bool ReturnValue = true; \
1671 if (!getDerived().shouldTraversePostOrder()) \
1672 TRY_TO(WalkUpFrom##DECL(D)); \
1673 { CODE; } \
1674 if (ReturnValue && ShouldVisitChildren) \
1675 TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D))); \
1676 if (ReturnValue) { \
1677 /* Visit any attributes attached to this declaration. */ \
1678 for (auto *I : D->attrs()) \
1679 TRY_TO(getDerived().TraverseAttr(I)); \
1680 } \
1681 if (ReturnValue && getDerived().shouldTraversePostOrder()) \
1682 TRY_TO(WalkUpFrom##DECL(D)); \
1683 return ReturnValue; \
1684 }
1685
1687
1689 if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
1690 TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
1691 TRY_TO(TraverseStmt(D->getBody()));
1692 for (const auto &I : D->captures()) {
1693 if (I.hasCopyExpr()) {
1694 TRY_TO(TraverseStmt(I.getCopyExpr()));
1695 }
1696 }
1697 ShouldVisitChildren = false;
1698})
1699
1701 TRY_TO(TraverseStmt(D->getBody()));
1702 ShouldVisitChildren = false;
1703})
1704
1706 TRY_TO(TraverseStmt(D->getBody()));
1707 ShouldVisitChildren = false;
1708})
1709
1711
1713
1715
1717 TRY_TO(TraverseStmt(D->getTemporaryExpr()));
1718})
1719
1721 { TRY_TO(TraverseStmt(D->getAsmStringExpr())); })
1722
1723DEF_TRAVERSE_DECL(TopLevelStmtDecl, { TRY_TO(TraverseStmt(D->getStmt())); })
1724
1726
1728 // Friend is either decl or a type.
1729 if (D->getFriendType()) {
1730 TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
1731 // Traverse any CXXRecordDecl owned by this type, since
1732 // it will not be in the parent context:
1733 if (auto *TT = D->getFriendType()->getType()->getAs<TagType>();
1734 TT && TT->isTagOwned())
1735 TRY_TO(TraverseDecl(TT->getDecl()));
1736 } else {
1737 TRY_TO(TraverseDecl(D->getFriendDecl()));
1738 }
1739})
1740
1742 const TemplateName Template = D->getFriendTemplateName();
1743 if (D->getFriendType())
1744 TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
1745 else if (!Template.isNull())
1746 TRY_TO(TraverseTemplateName(Template));
1747 else
1748 TRY_TO(TraverseDecl(D->getFriendDecl()));
1749 for (TemplateParameterList *TPL : D->getTemplateParameterLists())
1750 TRY_TO(TraverseTemplateParameterListHelper(TPL));
1751})
1752
1754
1756
1757DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {// FIXME: implement this
1758 })
1759
1761 TRY_TO(TraverseStmt(D->getAssertExpr()));
1762 TRY_TO(TraverseStmt(D->getMessage()));
1763})
1764
1766 // No double visiting: getTypeAsWritten() returns null for class
1767 // templates/nested classes where the qualifier lives inside the TSI.
1768 if (D->getQualifierLoc())
1769 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1770 if (TypeSourceInfo *TSI = D->getTypeAsWritten())
1771 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
1772 if (auto NumArgs = D->getNumTemplateArgs())
1773 for (unsigned I = 0; I != *NumArgs; ++I)
1774 TRY_TO(TraverseTemplateArgumentLoc(D->getTemplateArg(I)));
1775})
1776
1778 // Code in an unnamed namespace shows up automatically in
1779 // decls_begin()/decls_end(). Thus we don't need to recurse on
1780 // D->getAnonymousNamespace().
1781
1782 // If the traversal scope is set, then consider them to be the children of
1783 // the TUDecl, rather than traversing (and loading?) all top-level decls.
1784 auto Scope = D->getASTContext().getTraversalScope();
1785 bool HasLimitedScope =
1786 Scope.size() != 1 || !isa<TranslationUnitDecl>(Scope.front());
1787 if (HasLimitedScope) {
1788 ShouldVisitChildren = false; // we'll do that here instead
1789 for (auto *Child : Scope) {
1790 if (!canIgnoreChildDeclWhileTraversingDeclContext(Child))
1791 TRY_TO(TraverseDecl(Child));
1792 }
1793 }
1794})
1795
1797
1799
1801
1803 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1804
1805 // We shouldn't traverse an aliased namespace, since it will be
1806 // defined (and, therefore, traversed) somewhere else.
1807 ShouldVisitChildren = false;
1808})
1809
1810DEF_TRAVERSE_DECL(LabelDecl, {// There is no code in a LabelDecl.
1811 })
1812
1815 {// Code in an unnamed namespace shows up automatically in
1816 // decls_begin()/decls_end(). Thus we don't need to recurse on
1817 // D->getAnonymousNamespace().
1818 })
1819
1820DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement
1821 })
1822
1824 if (ObjCTypeParamList *typeParamList = D->getTypeParamList()) {
1825 for (auto typeParam : *typeParamList) {
1826 TRY_TO(TraverseObjCTypeParamDecl(typeParam));
1827 }
1828 }
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
1835DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement
1836 })
1837
1838DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement
1839 })
1840
1842 if (ObjCTypeParamList *typeParamList = D->getTypeParamListAsWritten()) {
1843 for (auto typeParam : *typeParamList) {
1844 TRY_TO(TraverseObjCTypeParamDecl(typeParam));
1845 }
1846 }
1847
1848 if (TypeSourceInfo *superTInfo = D->getSuperClassTInfo()) {
1849 TRY_TO(TraverseTypeLoc(superTInfo->getTypeLoc()));
1850 }
1851 if (D->isThisDeclarationADefinition()) {
1852 for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
1853 ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
1854 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1855 }
1856 }
1857})
1858
1860 if (D->isThisDeclarationADefinition()) {
1861 for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
1862 ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
1863 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1864 }
1865 }
1866})
1867
1869 if (D->getReturnTypeSourceInfo()) {
1870 TRY_TO(TraverseTypeLoc(D->getReturnTypeSourceInfo()->getTypeLoc()));
1871 }
1872 for (ParmVarDecl *Parameter : D->parameters()) {
1873 TRY_TO(TraverseDecl(Parameter));
1874 }
1875 if (D->isThisDeclarationADefinition()) {
1876 TRY_TO(TraverseStmt(D->getBody()));
1877 }
1878 ShouldVisitChildren = false;
1879})
1880
1882 if (D->hasExplicitBound()) {
1883 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
1884 // We shouldn't traverse D->getTypeForDecl(); it's a result of
1885 // declaring the type alias, not something that was written in the
1886 // source.
1887 }
1888})
1889
1891 if (D->getTypeSourceInfo())
1892 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
1893 else
1894 TRY_TO(TraverseType(D->getType()));
1895 ShouldVisitChildren = false;
1896})
1897
1899 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1900 TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
1901})
1902
1904 { TRY_TO(TraverseTypeLoc(D->getEnumTypeLoc())); })
1905
1907
1909 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1910})
1911
1913
1915
1917 if (D->getInstantiations() &&
1918 getDerived().shouldVisitTemplateInstantiations())
1919 TRY_TO(TraverseStmt(D->getInstantiations()));
1920
1921 TRY_TO(TraverseStmt(D->getExpansionPattern()));
1922})
1923
1925 for (auto *I : D->varlist()) {
1926 TRY_TO(TraverseStmt(I));
1927 }
1928})
1929
1931 for (auto *I : D->varlist()) {
1932 TRY_TO(TraverseStmt(I));
1933 }
1934})
1935
1937 for (auto *C : D->clauselists()) {
1938 TRY_TO(TraverseOMPClause(C));
1939 }
1940})
1941
1943 TRY_TO(TraverseStmt(D->getCombiner()));
1944 if (auto *Initializer = D->getInitializer())
1945 TRY_TO(TraverseStmt(Initializer));
1946 TRY_TO(TraverseType(D->getType()));
1947 return true;
1948})
1949
1951 for (auto *C : D->clauselists())
1952 TRY_TO(TraverseOMPClause(C));
1953 TRY_TO(TraverseType(D->getType()));
1954 return true;
1955})
1956
1957DEF_TRAVERSE_DECL(OMPCapturedExprDecl, { TRY_TO(TraverseVarHelper(D)); })
1958
1960 for (auto *I : D->varlist())
1961 TRY_TO(TraverseStmt(I));
1962 for (auto *C : D->clauselists())
1963 TRY_TO(TraverseOMPClause(C));
1964})
1965
1967 { TRY_TO(VisitOpenACCClauseList(D->clauses())); })
1968
1970 TRY_TO(TraverseStmt(D->getFunctionReference()));
1971 TRY_TO(VisitOpenACCClauseList(D->clauses()));
1972})
1973
1974// A helper method for TemplateDecl's children.
1975template <typename Derived>
1976bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
1977 TemplateParameterList *TPL) {
1978 if (TPL) {
1979 for (NamedDecl *D : *TPL) {
1980 TRY_TO(TraverseDecl(D));
1981 }
1982 if (Expr *RequiresClause = TPL->getRequiresClause()) {
1983 TRY_TO(TraverseStmt(RequiresClause));
1984 }
1985 }
1986 return true;
1987}
1988
1989template <typename Derived>
1990template <typename T>
1991bool RecursiveASTVisitor<Derived>::TraverseDeclTemplateParameterLists(T *D) {
1992 for (TemplateParameterList *TPL : D->getTemplateParameterLists())
1993 TraverseTemplateParameterListHelper(TPL);
1994 return true;
1995}
1996
1997template <typename Derived>
1999 ClassTemplateDecl *D) {
2000 for (auto *SD : D->specializations()) {
2001 for (auto *RD : SD->redecls()) {
2002 assert(!cast<CXXRecordDecl>(RD)->isInjectedClassName());
2003 switch (
2004 cast<ClassTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
2005 // Visit the implicit instantiations with the requested pattern.
2006 case TSK_Undeclared:
2008 TRY_TO(TraverseDecl(RD));
2009 break;
2010
2011 // We don't need to do anything on an explicit instantiation
2012 // or explicit specialization because there will be an explicit
2013 // node for it elsewhere.
2017 break;
2018 }
2019 }
2020 }
2021
2022 return true;
2023}
2024
2025template <typename Derived>
2027 VarTemplateDecl *D) {
2028 for (auto *SD : D->specializations()) {
2029 for (auto *RD : SD->redecls()) {
2030 switch (
2031 cast<VarTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
2032 case TSK_Undeclared:
2034 TRY_TO(TraverseDecl(RD));
2035 break;
2036
2040 break;
2041 }
2042 }
2043 }
2044
2045 return true;
2046}
2047
2048// A helper method for traversing the instantiations of a
2049// function while skipping its specializations.
2050template <typename Derived>
2053 for (auto *FD : D->specializations()) {
2054 for (auto *RD : FD->redecls()) {
2055 switch (RD->getTemplateSpecializationKind()) {
2056 case TSK_Undeclared:
2058 // We don't know what kind of FunctionDecl this is.
2059 TRY_TO(TraverseDecl(RD));
2060 break;
2061
2062 // Unlike class/variable template specializations, function template
2063 // specializations are not independent children of the DeclContext —
2064 // they are only reachable via FunctionTemplateDecl::specializations().
2065 // We must traverse them here so visitors can see the instantiated body.
2068 TRY_TO(TraverseDecl(RD));
2069 break;
2070
2072 break;
2073 }
2074 }
2075 }
2076
2077 return true;
2078}
2079
2080// This macro unifies the traversal of class, variable and function
2081// template declarations.
2082#define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND) \
2083 DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, { \
2084 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
2085 TRY_TO(TraverseDecl(D->getTemplatedDecl())); \
2086 \
2087 /* By default, we do not traverse the instantiations of \
2088 class templates since they do not appear in the user code. The \
2089 following code optionally traverses them. \
2090 \
2091 We only traverse the class instantiations when we see the canonical \
2092 declaration of the template, to ensure we only visit them once. */ \
2093 if (getDerived().shouldVisitTemplateInstantiations() && \
2094 D == D->getCanonicalDecl()) \
2095 TRY_TO(TraverseTemplateInstantiations(D)); \
2096 \
2097 /* Note that getInstantiatedFromMemberTemplate() is just a link \
2098 from a template instantiation back to the template from which \
2099 it was instantiated, and thus should not be traversed. */ \
2100 })
2101
2105
2107 // D is the "T" in something like
2108 // template <template <typename> class T> class container { };
2109 TRY_TO(TraverseDecl(D->getTemplatedDecl()));
2110 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
2111 TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
2112 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
2113})
2114
2116 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
2117})
2118
2119template <typename Derived>
2120bool RecursiveASTVisitor<Derived>::TraverseTemplateTypeParamDeclConstraints(
2121 const TemplateTypeParmDecl *D) {
2122 if (const auto *TC = D->getTypeConstraint())
2123 TRY_TO(TraverseTypeConstraint(TC));
2124 return true;
2125}
2126
2128 // D is the "T" in something like "template<typename T> class vector;"
2129 if (D->getTypeForDecl())
2130 TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
2131 TRY_TO(TraverseTemplateTypeParamDeclConstraints(D));
2132 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
2133 TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
2134})
2135
2137 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
2138 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2139 // declaring the typedef, not something that was written in the
2140 // source.
2141})
2142
2144 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
2145 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2146 // declaring the type alias, not something that was written in the
2147 // source.
2148})
2149
2151 TRY_TO(TraverseDecl(D->getTemplatedDecl()));
2152 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
2153})
2154
2156 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
2157 TRY_TO(TraverseStmt(D->getConstraintExpr()));
2158})
2159
2161 // A dependent using declaration which was marked with 'typename'.
2162 // template<class T> class A : public B<T> { using typename B<T>::foo; };
2163 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2164 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2165 // declaring the type, not something that was written in the
2166 // source.
2167})
2168
2170
2172 TRY_TO(TraverseDeclTemplateParameterLists(D));
2173
2174 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2175 if (auto *TSI = D->getIntegerTypeSourceInfo())
2176 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
2177 // The enumerators are already traversed by
2178 // decls_begin()/decls_end().
2179})
2180
2181// Helper methods for RecordDecl and its children.
2182template <typename Derived>
2183bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) {
2184 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2185 // declaring the type, not something that was written in the source.
2186
2187 TRY_TO(TraverseDeclTemplateParameterLists(D));
2188 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2189 return true;
2190}
2191
2192template <typename Derived>
2194 const CXXBaseSpecifier &Base) {
2195 TRY_TO(TraverseTypeLoc(Base.getTypeSourceInfo()->getTypeLoc()));
2196 return true;
2197}
2198
2199template <typename Derived>
2200bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(CXXRecordDecl *D) {
2201 if (!TraverseRecordHelper(D))
2202 return false;
2203 if (D->isCompleteDefinition()) {
2204 for (const auto &I : D->bases()) {
2205 TRY_TO(TraverseCXXBaseSpecifier(I));
2206 }
2207 // We don't traverse the friends or the conversions, as they are
2208 // already in decls_begin()/decls_end().
2209 }
2210 return true;
2211}
2212
2213DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); })
2214
2215DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
2216
2217template <typename Derived>
2218bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
2219 const TemplateArgumentLoc *TAL, unsigned Count) {
2220 for (unsigned I = 0; I < Count; ++I) {
2221 TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
2222 }
2223 return true;
2224}
2225
2226#define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
2227 DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, { \
2228 /* For implicit instantiations ("set<int> x;"), we don't want to \
2229 recurse at all, since the instatiated template isn't written in \
2230 the source code anywhere. (Note the instatiated *type* -- \
2231 set<int> -- is written, and will still get a callback of \
2232 TemplateSpecializationType). For explicit instantiations \
2233 ("template set<int>;"), the ExplicitInstantiationDecl node \
2234 handles traversal of template args and qualifier. \
2235 For explicit specializations ("template<> set<int> {...};"), \
2236 we traverse template args here since there is no EID. */ \
2237 if (D->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) { \
2238 const auto *ArgsWritten = D->getTemplateArgsAsWritten(); \
2239 TRY_TO(TraverseTemplateArgumentLocsHelper( \
2240 ArgsWritten->getTemplateArgs(), ArgsWritten->NumTemplateArgs)); \
2241 } else if (!getDerived().shouldVisitTemplateInstantiations()) { \
2242 /* Returning from here skips traversing the \
2243 declaration context of the *TemplateSpecializationDecl \
2244 (embedded in the DEF_TRAVERSE_DECL() macro) \
2245 which contains the instantiated members of the template. */ \
2246 return true; \
2247 } \
2248 \
2249 /* Traverse base definition for explicit specializations */ \
2250 TRY_TO(Traverse##DECLKIND##Helper(D)); \
2251 })
2252
2255
2256#define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
2257 DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, { \
2258 /* The partial specialization. */ \
2259 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
2260 /* The args that remains unspecialized. */ \
2261 TRY_TO(TraverseTemplateArgumentLocsHelper( \
2262 D->getTemplateArgsAsWritten()->getTemplateArgs(), \
2263 D->getTemplateArgsAsWritten()->NumTemplateArgs)); \
2264 \
2265 /* Don't need the *TemplatePartialSpecializationHelper, even \
2266 though that's our parent class -- we already visit all the \
2267 template args here. */ \
2268 TRY_TO(Traverse##DECLKIND##Helper(D)); \
2269 \
2270 /* Instantiations will have been visited with the primary template. */ \
2271 })
2272
2275
2276DEF_TRAVERSE_DECL(EnumConstantDecl, { TRY_TO(TraverseStmt(D->getInitExpr())); })
2277
2279 // Like UnresolvedUsingTypenameDecl, but without the 'typename':
2280 // template <class T> Class A : public Base<T> { using Base<T>::foo; };
2281 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2282 TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
2283})
2284
2286
2287template <typename Derived>
2288bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
2289 TRY_TO(TraverseDeclTemplateParameterLists(D));
2290 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2291 if (D->getTypeSourceInfo())
2292 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
2293 else
2294 TRY_TO(TraverseType(D->getType()));
2295 return true;
2296}
2297
2299 TRY_TO(TraverseVarHelper(D));
2300 for (auto *Binding : D->bindings()) {
2301 TRY_TO(TraverseDecl(Binding));
2302 }
2303})
2304
2306 if (getDerived().shouldVisitImplicitCode()) {
2307 TRY_TO(TraverseStmt(D->getBinding()));
2308 if (const auto HoldingVar = D->getHoldingVar())
2309 TRY_TO(TraverseDecl(HoldingVar));
2310 }
2311})
2312
2313DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
2314
2317
2319
2321 TRY_TO(TraverseDeclaratorHelper(D));
2322 if (D->isBitField())
2323 TRY_TO(TraverseStmt(D->getBitWidth()));
2324 if (D->hasInClassInitializer())
2325 TRY_TO(TraverseStmt(D->getInClassInitializer()));
2326})
2327
2329 TRY_TO(TraverseDeclaratorHelper(D));
2330 if (D->isBitField())
2331 TRY_TO(TraverseStmt(D->getBitWidth()));
2332 // FIXME: implement the rest.
2333})
2334
2336 TRY_TO(TraverseDeclaratorHelper(D));
2337 if (D->isBitField())
2338 TRY_TO(TraverseStmt(D->getBitWidth()));
2339 // FIXME: implement the rest.
2340})
2341
2342template <typename Derived>
2343bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
2344 TRY_TO(TraverseDeclTemplateParameterLists(D));
2345 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2346 TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
2347
2348 // If we're an explicit template specialization, iterate over the
2349 // template args that were explicitly specified. If we were doing
2350 // this in typing order, we'd do it between the return type and
2351 // the function args, but both are handled by the FunctionTypeLoc
2352 // above, so we have to choose one side. I've decided to do before.
2353 if (const FunctionTemplateSpecializationInfo *FTSI =
2354 D->getTemplateSpecializationInfo()) {
2355 if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared &&
2356 FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
2357 // A specialization might not have explicit template arguments if it has
2358 // a templated return type and concrete arguments.
2359 if (const ASTTemplateArgumentListInfo *TALI =
2360 FTSI->TemplateArgumentsAsWritten) {
2361 TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
2362 TALI->NumTemplateArgs));
2363 }
2364 }
2365 } else if (const DependentFunctionTemplateSpecializationInfo *DFSI =
2366 D->getDependentSpecializationInfo()) {
2367 if (const ASTTemplateArgumentListInfo *TALI =
2368 DFSI->TemplateArgumentsAsWritten) {
2369 TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
2370 TALI->NumTemplateArgs));
2371 }
2372 }
2373
2374 // Visit the function type itself, which can be either
2375 // FunctionNoProtoType or FunctionProtoType, or a typedef. This
2376 // also covers the return type and the function parameters,
2377 // including exception specifications.
2378 if (TypeSourceInfo *TSI = D->getTypeSourceInfo()) {
2379 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
2380 } else if (getDerived().shouldVisitImplicitCode()) {
2381 // Visit parameter variable declarations of the implicit function
2382 // if the traverser is visiting implicit code. Parameter variable
2383 // declarations do not have valid TypeSourceInfo, so to visit them
2384 // we need to traverse the declarations explicitly.
2385 for (ParmVarDecl *Parameter : D->parameters()) {
2386 TRY_TO(TraverseDecl(Parameter));
2387 }
2388 }
2389
2390 // Visit the trailing requires clause, if any.
2391 if (const AssociatedConstraint &TrailingRequiresClause =
2392 D->getTrailingRequiresClause()) {
2393 TRY_TO(TraverseStmt(
2394 const_cast<Expr *>(TrailingRequiresClause.ConstraintExpr)));
2395 }
2396
2397 if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
2398 // Constructor initializers.
2399 for (auto *I : Ctor->inits()) {
2400 if (I->isWritten() || getDerived().shouldVisitImplicitCode())
2401 TRY_TO(TraverseConstructorInitializer(I));
2402 }
2403 }
2404
2405 bool VisitBody =
2406 D->isThisDeclarationADefinition() &&
2407 // Don't visit the function body if the function definition is generated
2408 // by clang.
2409 (!D->isDefaulted() || getDerived().shouldVisitImplicitCode());
2410
2411 if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
2412 if (const CXXRecordDecl *RD = MD->getParent()) {
2413 if (RD->isLambda() &&
2414 declaresSameEntity(RD->getLambdaCallOperator(), MD)) {
2415 VisitBody = VisitBody && getDerived().shouldVisitLambdaBody();
2416 }
2417 }
2418 }
2419
2420 if (VisitBody) {
2421 TRY_TO(TraverseStmt(D->getBody()));
2422 // Body may contain using declarations whose shadows are parented to the
2423 // FunctionDecl itself.
2424 for (auto *Child : D->decls()) {
2425 if (isa<UsingShadowDecl>(Child))
2426 TRY_TO(TraverseDecl(Child));
2427 }
2428 }
2429 return true;
2430}
2431
2433 // We skip decls_begin/decls_end, which are already covered by
2434 // TraverseFunctionHelper().
2435 ShouldVisitChildren = false;
2436 ReturnValue = TraverseFunctionHelper(D);
2437})
2438
2440 // We skip decls_begin/decls_end, which are already covered by
2441 // TraverseFunctionHelper().
2442 ShouldVisitChildren = false;
2443 ReturnValue = TraverseFunctionHelper(D);
2444})
2445
2447 // We skip decls_begin/decls_end, which are already covered by
2448 // TraverseFunctionHelper().
2449 ShouldVisitChildren = false;
2450 ReturnValue = TraverseFunctionHelper(D);
2451})
2452
2454 // We skip decls_begin/decls_end, which are already covered by
2455 // TraverseFunctionHelper().
2456 ShouldVisitChildren = false;
2457 ReturnValue = TraverseFunctionHelper(D);
2458})
2459
2460// CXXConversionDecl is the declaration of a type conversion operator.
2461// It's not a cast expression.
2463 // We skip decls_begin/decls_end, which are already covered by
2464 // TraverseFunctionHelper().
2465 ShouldVisitChildren = false;
2466 ReturnValue = TraverseFunctionHelper(D);
2467})
2468
2470 // We skip decls_begin/decls_end, which are already covered by
2471 // TraverseFunctionHelper().
2472 ShouldVisitChildren = false;
2473 ReturnValue = TraverseFunctionHelper(D);
2474})
2475
2476template <typename Derived>
2477bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
2478 TRY_TO(TraverseDeclaratorHelper(D));
2479 // Default params are taken care of when we traverse the ParmVarDecl.
2480 if (!isa<ParmVarDecl>(D) &&
2481 (!D->isCXXForRangeDecl() || getDerived().shouldVisitImplicitCode()))
2482 TRY_TO(TraverseStmt(D->getInit()));
2483 return true;
2484}
2485
2486DEF_TRAVERSE_DECL(VarDecl, { TRY_TO(TraverseVarHelper(D)); })
2487
2488DEF_TRAVERSE_DECL(ImplicitParamDecl, { TRY_TO(TraverseVarHelper(D)); })
2489
2491 // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
2492 TRY_TO(TraverseDeclaratorHelper(D));
2493 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
2494 TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
2495})
2496
2498 TRY_TO(TraverseVarHelper(D));
2499
2500 if (D->hasDefaultArg() && D->hasUninstantiatedDefaultArg() &&
2501 !D->hasUnparsedDefaultArg())
2502 TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
2503
2504 if (D->hasDefaultArg() && !D->hasUninstantiatedDefaultArg() &&
2505 !D->hasUnparsedDefaultArg())
2506 TRY_TO(TraverseStmt(D->getDefaultArg()));
2507})
2508
2510
2512 TRY_TO(TraverseTemplateArguments(D->getTemplateArguments()));
2513})
2514
2515#undef DEF_TRAVERSE_DECL
2516
2517// ----------------- Stmt traversal -----------------
2518//
2519// For stmts, we automate (in the DEF_TRAVERSE_STMT macro) iterating
2520// over the children defined in children() (every stmt defines these,
2521// though sometimes the range is empty). Each individual Traverse*
2522// method only needs to worry about children other than those. To see
2523// what children() does for a given class, see, e.g.,
2524// http://clang.llvm.org/doxygen/Stmt_8cpp_source.html
2525
2526// This macro makes available a variable S, the passed-in stmt.
2527#define DEF_TRAVERSE_STMT(STMT, CODE) \
2528 template <typename Derived> \
2530 STMT *S, DataRecursionQueue *Queue) { \
2531 bool ShouldVisitChildren = true; \
2532 bool ReturnValue = true; \
2533 if (!getDerived().shouldTraversePostOrder()) \
2534 TRY_TO(WalkUpFrom##STMT(S)); \
2535 { CODE; } \
2536 if (ShouldVisitChildren) { \
2537 for (Stmt * SubStmt : getDerived().getStmtChildren(S)) { \
2538 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); \
2539 } \
2540 } \
2541 /* Call WalkUpFrom if TRY_TO_TRAVERSE_OR_ENQUEUE_STMT has traversed the \
2542 * children already. If TRY_TO_TRAVERSE_OR_ENQUEUE_STMT only enqueued the \
2543 * children, PostVisitStmt will call WalkUpFrom after we are done visiting \
2544 * children. */ \
2545 if (!Queue && ReturnValue && getDerived().shouldTraversePostOrder()) { \
2546 TRY_TO(WalkUpFrom##STMT(S)); \
2547 } \
2548 return ReturnValue; \
2549 }
2550
2552 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAsmStringExpr());
2553 for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
2554 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInputConstraintExpr(I));
2555 }
2556 for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
2557 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOutputConstraintExpr(I));
2558 }
2559 for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
2560 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getClobberExpr(I));
2561 }
2562 // children() iterates over inputExpr and outputExpr.
2563})
2564
2566 MSAsmStmt,
2567 {// FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc. Once
2568 // added this needs to be implemented.
2569 })
2570
2572 TRY_TO(TraverseDecl(S->getExceptionDecl()));
2573 // children() iterates over the handler block.
2574})
2575
2577 TRY_TO(TraverseDecl(S->getCatchParamDecl()));
2578 // children() iterates over the handler block.
2579})
2580
2582 for (auto *I : S->decls()) {
2583 TRY_TO(TraverseDecl(I));
2584 }
2585 // Suppress the default iteration over children() by
2586 // returning. Here's why: A DeclStmt looks like 'type var [=
2587 // initializer]'. The decls above already traverse over the
2588 // initializers, so we don't have to do it again (which
2589 // children() would do).
2590 ShouldVisitChildren = false;
2591})
2592
2593// These non-expr stmts (most of them), do not need any action except
2594// iterating over the children.
2616
2618 if (!getDerived().shouldVisitImplicitCode()) {
2619 if (S->getInit())
2620 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInit());
2621 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLoopVarStmt());
2622 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRangeInit());
2623 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
2624 // Visit everything else only if shouldVisitImplicitCode().
2625 ShouldVisitChildren = false;
2626 }
2627})
2628
2630 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2631 TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
2632})
2633
2637
2639
2641 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2642 TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
2643 if (S->hasExplicitTemplateArgs()) {
2644 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2645 S->getNumTemplateArgs()));
2646 }
2647})
2648
2650 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2651 TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
2652 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2653 S->getNumTemplateArgs()));
2654})
2655
2657 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2658 TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
2659 if (S->hasExplicitTemplateArgs()) {
2660 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2661 S->getNumTemplateArgs()));
2662 }
2663})
2664
2666 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2667 TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
2668 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2669 S->getNumTemplateArgs()));
2670})
2671
2674 {// We don't traverse the cast type, as it's not written in the
2675 // source code.
2676 })
2677
2679 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2680})
2681
2683 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2684})
2685
2687 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2688})
2689
2691 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2692})
2693
2695 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2696})
2697
2699 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2700})
2701
2703 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2704})
2705
2707 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2708})
2709
2710template <typename Derived>
2712 InitListExpr *S, DataRecursionQueue *Queue) {
2713 if (S) {
2714 // Skip this if we traverse postorder. We will visit it later
2715 // in PostVisitStmt.
2716 if (!getDerived().shouldTraversePostOrder())
2717 TRY_TO(WalkUpFromInitListExpr(S));
2718
2719 // All we need are the default actions. FIXME: use a helper function.
2720 for (Stmt *SubStmt : S->children()) {
2722 }
2723
2724 if (!Queue && getDerived().shouldTraversePostOrder())
2725 TRY_TO(WalkUpFromInitListExpr(S));
2726 }
2727 return true;
2728}
2729
2730template <typename Derived>
2732 ObjCProtocolLoc ProtocolLoc) {
2733 return true;
2734}
2735
2736template <typename Derived>
2738 ConceptReference *CR) {
2739 if (!getDerived().shouldTraversePostOrder())
2740 TRY_TO(VisitConceptReference(CR));
2741 TRY_TO(TraverseNestedNameSpecifierLoc(CR->getNestedNameSpecifierLoc()));
2742 TRY_TO(TraverseDeclarationNameInfo(CR->getConceptNameInfo()));
2743 if (CR->hasExplicitTemplateArgs())
2744 TRY_TO(TraverseTemplateArgumentLocsHelper(
2745 CR->getTemplateArgsAsWritten()->getTemplateArgs(),
2746 CR->getTemplateArgsAsWritten()->NumTemplateArgs));
2747 if (getDerived().shouldTraversePostOrder())
2748 TRY_TO(VisitConceptReference(CR));
2749 return true;
2750}
2751
2752template <typename Derived>
2754 const OffsetOfNode *Node) {
2755 TRY_TO(VisitOffsetOfNode(Node));
2756 return true;
2757}
2758
2759// If shouldVisitImplicitCode() returns false, this method traverses only the
2760// syntactic form of InitListExpr.
2761// If shouldVisitImplicitCode() return true, this method is called once for
2762// each pair of syntactic and semantic InitListExpr, and it traverses the
2763// subtrees defined by the two forms. This may cause some of the children to be
2764// visited twice, if they appear both in the syntactic and the semantic form.
2765//
2766// There is no guarantee about which form \p S takes when this method is called.
2767template <typename Derived>
2769 InitListExpr *S, DataRecursionQueue *Queue) {
2770 if (S->isSemanticForm() && S->isSyntacticForm()) {
2771 // `S` does not have alternative forms, traverse only once.
2772 TRY_TO(TraverseSynOrSemInitListExpr(S, Queue));
2773 return true;
2774 }
2775 TRY_TO(TraverseSynOrSemInitListExpr(
2776 S->isSemanticForm() ? S->getSyntacticForm() : S, Queue));
2777 if (getDerived().shouldVisitImplicitCode()) {
2778 // Only visit the semantic form if the clients are interested in implicit
2779 // compiler-generated.
2780 TRY_TO(TraverseSynOrSemInitListExpr(
2781 S->isSemanticForm() ? S : S->getSemanticForm(), Queue));
2782 }
2783 return true;
2784}
2785
2786// GenericSelectionExpr is a special case because the types and expressions
2787// are interleaved. We also need to watch out for null types (default
2788// generic associations).
2790 if (S->isExprPredicate())
2791 TRY_TO(TraverseStmt(S->getControllingExpr()));
2792 else
2793 TRY_TO(TraverseTypeLoc(S->getControllingType()->getTypeLoc()));
2794
2795 for (const GenericSelectionExpr::Association Assoc : S->associations()) {
2796 if (TypeSourceInfo *TSI = Assoc.getTypeSourceInfo())
2797 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
2798 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(Assoc.getAssociationExpr());
2799 }
2800 ShouldVisitChildren = false;
2801})
2802
2803// PseudoObjectExpr is a special case because of the weirdness with
2804// syntactic expressions and opaque values.
2806 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getSyntacticForm());
2807 for (PseudoObjectExpr::semantics_iterator i = S->semantics_begin(),
2808 e = S->semantics_end();
2809 i != e; ++i) {
2810 Expr *sub = *i;
2811 if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub))
2812 sub = OVE->getSourceExpr();
2814 }
2815 ShouldVisitChildren = false;
2816})
2817
2819 // This is called for code like 'return T()' where T is a built-in
2820 // (i.e. non-class) type.
2821 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2822})
2823
2825 // The child-iterator will pick up the other arguments.
2826 TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc()));
2827})
2828
2830 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2831 // Visit each designator component (e.g. the `a`, `b`, `c` in
2832 // offsetof(Foo, a.b.c)). Array index expressions are reached through the
2833 // child-iterator, which DEF_TRAVERSE_STMT walks automatically.
2834 for (unsigned I = 0, E = S->getNumComponents(); I != E; ++I)
2835 TRY_TO(TraverseOffsetOfNode(&S->getComponent(I)));
2836})
2837
2839 // The child-iterator will pick up the arg if it's an expression,
2840 // but not if it's a type.
2841 if (S->isArgumentType())
2842 TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
2843})
2844
2846 // The child-iterator will pick up the arg if it's an expression,
2847 // but not if it's a type.
2848 if (S->isTypeOperand())
2849 TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
2850})
2851
2853 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2854})
2855
2857
2859 // The child-iterator will pick up the arg if it's an expression,
2860 // but not if it's a type.
2861 if (S->isTypeOperand())
2862 TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
2863})
2864
2866 for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
2867 TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc()));
2868})
2869
2871 TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
2872})
2873
2875 { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getQueriedExpression()); })
2876
2878 // The child-iterator will pick up the expression argument.
2879 TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
2880})
2881
2883 // This is called for code like 'return T()' where T is a class type.
2884 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2885})
2886
2887// Walk only the visible parts of lambda expressions.
2889 // Visit the capture list.
2890 for (unsigned I = 0, N = S->capture_size(); I != N; ++I) {
2891 const LambdaCapture *C = S->capture_begin() + I;
2892 if (C->isExplicit() || getDerived().shouldVisitImplicitCode()) {
2893 TRY_TO(TraverseLambdaCapture(S, C, S->capture_init_begin()[I]));
2894 }
2895 }
2896
2897 if (getDerived().shouldVisitImplicitCode()) {
2898 // The implicit model is simple: everything else is in the lambda class.
2899 TRY_TO(TraverseDecl(S->getLambdaClass()));
2900 } else {
2901 // We need to poke around to find the bits that might be explicitly written.
2902 TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2904
2905 TRY_TO(TraverseTemplateParameterListHelper(S->getTemplateParameterList()));
2906 if (S->hasExplicitParameters()) {
2907 // Visit parameters.
2908 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2909 TRY_TO(TraverseDecl(Proto.getParam(I)));
2910 }
2911
2912 auto *T = Proto.getTypePtr();
2913 for (const auto &E : T->exceptions())
2914 TRY_TO(TraverseType(E));
2915
2916 if (Expr *NE = T->getNoexceptExpr())
2918
2919 if (S->hasExplicitResultType())
2920 TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
2922 const_cast<Expr *>(S->getTrailingRequiresClause().ConstraintExpr));
2923
2924 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
2925 }
2926 ShouldVisitChildren = false;
2927})
2928
2930 // This is called for code like 'T()', where T is a template argument.
2931 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2932})
2933
2935
2936// These expressions all might take explicit template arguments.
2937// We traverse those if so. FIXME: implement these.
2941
2942// These exprs (most of them), do not need any action except iterating
2943// over the children.
2951
2953 TRY_TO(TraverseDecl(S->getBlockDecl()));
2954 return true; // no child statements to loop through.
2955})
2956
2959 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2960})
2963
2965 if (getDerived().shouldVisitImplicitCode())
2966 TRY_TO(TraverseStmt(S->getExpr()));
2967})
2968
2970 if (getDerived().shouldVisitImplicitCode())
2971 TRY_TO(TraverseStmt(S->getExpr()));
2972})
2973
2979
2981 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2982 if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
2983 TRY_TO(TraverseTypeLoc(ScopeInfo->getTypeLoc()));
2984 if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo())
2985 TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc()));
2986})
2987
2999 // FIXME: The source expression of the OVE should be listed as
3000 // a child of the ArrayInitLoopExpr.
3001 if (OpaqueValueExpr *OVE = S->getCommonExpr())
3002 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(OVE->getSourceExpr());
3003})
3006
3008 if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
3009 TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
3010})
3011
3014
3016 if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo())
3017 TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
3018})
3019
3021 if (S->isClassReceiver()) {
3022 ObjCInterfaceDecl *IDecl = S->getClassReceiver();
3023 QualType Type = IDecl->getASTContext().getObjCInterfaceType(IDecl);
3025 Data.NameLoc = S->getReceiverLocation();
3026 Data.NameEndLoc = Data.NameLoc;
3027 TRY_TO(TraverseTypeLoc(TypeLoc(Type, &Data)));
3028 }
3029})
3034
3036 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
3037})
3038
3043 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
3044})
3046 if (getDerived().shouldVisitImplicitCode()) {
3047 TRY_TO(TraverseStmt(S->getOriginalStmt()));
3048 TRY_TO(TraverseStmt(S->getKernelLaunchIdExpr()));
3049 ShouldVisitChildren = false;
3050 }
3051})
3059 for (IntegerLiteral *IL : S->underlying_data_elements()) {
3061 }
3062})
3063
3065 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
3066 if (S->hasExplicitTemplateArgs()) {
3067 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
3068 S->getNumTemplateArgs()));
3069 }
3070})
3071
3073 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
3074 if (S->hasExplicitTemplateArgs()) {
3075 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
3076 S->getNumTemplateArgs()));
3077 }
3078})
3079
3084DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
3085
3087 if (getDerived().shouldVisitImplicitCode()) {
3088 TRY_TO(TraverseStmt(S->getOriginalStmt()));
3089 TRY_TO(TraverseStmt(S->getKernelLaunchStmt()));
3090 TRY_TO(TraverseDecl(S->getOutlinedFunctionDecl()));
3091 ShouldVisitChildren = false;
3092 }
3093})
3094
3097 if (!getDerived().shouldVisitImplicitCode()) {
3099 S->getDecomposedForm();
3100 TRY_TO(TraverseStmt(const_cast<Expr*>(Decomposed.LHS)));
3101 TRY_TO(TraverseStmt(const_cast<Expr*>(Decomposed.RHS)));
3102 ShouldVisitChildren = false;
3103 }
3104})
3108
3109// These operators (all of them) do not need any action except
3110// iterating over the children.
3126
3128 if (S->getLifetimeExtendedTemporaryDecl()) {
3129 TRY_TO(TraverseLifetimeExtendedTemporaryDecl(
3130 S->getLifetimeExtendedTemporaryDecl()));
3131 ShouldVisitChildren = false;
3132 }
3133})
3134// For coroutines expressions, traverse either the operand
3135// as written or the implied calls, depending on what the
3136// derived class requests.
3138 if (!getDerived().shouldVisitImplicitCode()) {
3139 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
3140 ShouldVisitChildren = false;
3141 }
3142})
3144 if (!getDerived().shouldVisitImplicitCode()) {
3145 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
3146 ShouldVisitChildren = false;
3147 }
3148})
3150 if (!getDerived().shouldVisitImplicitCode()) {
3151 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
3152 ShouldVisitChildren = false;
3153 }
3154})
3156 if (!getDerived().shouldVisitImplicitCode()) {
3157 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
3158 ShouldVisitChildren = false;
3159 }
3160})
3162 if (!getDerived().shouldVisitImplicitCode()) {
3163 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
3164 ShouldVisitChildren = false;
3165 }
3166})
3167
3169 TRY_TO(TraverseConceptReference(S->getConceptReference()));
3170})
3171
3173 TRY_TO(TraverseDecl(S->getBody()));
3174 for (ParmVarDecl *Parm : S->getLocalParameters())
3175 TRY_TO(TraverseDecl(Parm));
3176 for (concepts::Requirement *Req : S->getRequirements())
3177 TRY_TO(TraverseConceptRequirement(Req));
3178})
3179
3183
3184// These literals (all of them) do not need any action.
3195
3196// Traverse OpenCL: AsType, Convert.
3198
3199// OpenMP directives.
3200template <typename Derived>
3201bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
3202 OMPExecutableDirective *S) {
3203 for (auto *C : S->clauses()) {
3204 TRY_TO(TraverseOMPClause(C));
3205 }
3206 return true;
3207}
3208
3209DEF_TRAVERSE_STMT(OMPCanonicalLoop, {
3210 if (!getDerived().shouldVisitImplicitCode()) {
3211 // Visit only the syntactical loop.
3212 TRY_TO(TraverseStmt(S->getLoopStmt()));
3213 ShouldVisitChildren = false;
3214 }
3215})
3216
3217template <typename Derived>
3218bool
3219RecursiveASTVisitor<Derived>::TraverseOMPLoopDirective(OMPLoopDirective *S) {
3220 return TraverseOMPExecutableDirective(S);
3221}
3222
3223DEF_TRAVERSE_STMT(OMPMetaDirective,
3224 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3225
3226DEF_TRAVERSE_STMT(OMPParallelDirective,
3227 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3228
3229DEF_TRAVERSE_STMT(OMPSimdDirective,
3230 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3231
3232DEF_TRAVERSE_STMT(OMPTileDirective,
3233 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3234
3235DEF_TRAVERSE_STMT(OMPStripeDirective,
3236 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3237
3238DEF_TRAVERSE_STMT(OMPUnrollDirective,
3239 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3240
3241DEF_TRAVERSE_STMT(OMPReverseDirective,
3242 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3243
3244DEF_TRAVERSE_STMT(OMPFuseDirective,
3245 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3246
3247DEF_TRAVERSE_STMT(OMPInterchangeDirective,
3248 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3249
3250DEF_TRAVERSE_STMT(OMPSplitDirective,
3251 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3252
3253DEF_TRAVERSE_STMT(OMPForDirective,
3254 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3255
3256DEF_TRAVERSE_STMT(OMPForSimdDirective,
3257 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3258
3259DEF_TRAVERSE_STMT(OMPSectionsDirective,
3260 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3261
3262DEF_TRAVERSE_STMT(OMPSectionDirective,
3263 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3264
3265DEF_TRAVERSE_STMT(OMPScopeDirective,
3266 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3267
3268DEF_TRAVERSE_STMT(OMPSingleDirective,
3269 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3270
3271DEF_TRAVERSE_STMT(OMPMasterDirective,
3272 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3273
3274DEF_TRAVERSE_STMT(OMPCriticalDirective, {
3275 TRY_TO(TraverseDeclarationNameInfo(S->getDirectiveName()));
3276 TRY_TO(TraverseOMPExecutableDirective(S));
3277})
3278
3279DEF_TRAVERSE_STMT(OMPParallelForDirective,
3280 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3281
3282DEF_TRAVERSE_STMT(OMPParallelForSimdDirective,
3283 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3284
3285DEF_TRAVERSE_STMT(OMPParallelMasterDirective,
3286 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3287
3288DEF_TRAVERSE_STMT(OMPParallelMaskedDirective,
3289 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3290
3291DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
3292 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3293
3294DEF_TRAVERSE_STMT(OMPTaskDirective,
3295 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3296
3297DEF_TRAVERSE_STMT(OMPTaskyieldDirective,
3298 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3299
3300DEF_TRAVERSE_STMT(OMPBarrierDirective,
3301 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3302
3303DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
3304 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3305
3306DEF_TRAVERSE_STMT(OMPTaskgroupDirective,
3307 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3308
3309DEF_TRAVERSE_STMT(OMPCancellationPointDirective,
3310 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3311
3312DEF_TRAVERSE_STMT(OMPCancelDirective,
3313 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3314
3315DEF_TRAVERSE_STMT(OMPFlushDirective,
3316 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3317
3318DEF_TRAVERSE_STMT(OMPDepobjDirective,
3319 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3320
3321DEF_TRAVERSE_STMT(OMPScanDirective,
3322 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3323
3324DEF_TRAVERSE_STMT(OMPOrderedStandaloneDirective,
3325 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3326
3327DEF_TRAVERSE_STMT(OMPOrderedBlockAssocDirective,
3328 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3329
3330DEF_TRAVERSE_STMT(OMPAtomicDirective,
3331 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3332
3333DEF_TRAVERSE_STMT(OMPTargetDirective,
3334 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3335
3336DEF_TRAVERSE_STMT(OMPTargetDataDirective,
3337 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3338
3339DEF_TRAVERSE_STMT(OMPTargetEnterDataDirective,
3340 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3341
3342DEF_TRAVERSE_STMT(OMPTargetExitDataDirective,
3343 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3344
3345DEF_TRAVERSE_STMT(OMPTargetParallelDirective,
3346 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3347
3348DEF_TRAVERSE_STMT(OMPTargetParallelForDirective,
3349 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3350
3351DEF_TRAVERSE_STMT(OMPTeamsDirective,
3352 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3353
3354DEF_TRAVERSE_STMT(OMPTargetUpdateDirective,
3355 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3356
3357DEF_TRAVERSE_STMT(OMPTaskLoopDirective,
3358 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3359
3360DEF_TRAVERSE_STMT(OMPTaskLoopSimdDirective,
3361 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3362
3363DEF_TRAVERSE_STMT(OMPMasterTaskLoopDirective,
3364 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3365
3366DEF_TRAVERSE_STMT(OMPMasterTaskLoopSimdDirective,
3367 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3368
3369DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopDirective,
3370 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3371
3372DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopSimdDirective,
3373 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3374
3375DEF_TRAVERSE_STMT(OMPMaskedTaskLoopDirective,
3376 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3377
3378DEF_TRAVERSE_STMT(OMPMaskedTaskLoopSimdDirective,
3379 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3380
3381DEF_TRAVERSE_STMT(OMPParallelMaskedTaskLoopDirective,
3382 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3383
3384DEF_TRAVERSE_STMT(OMPParallelMaskedTaskLoopSimdDirective,
3385 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3386
3387DEF_TRAVERSE_STMT(OMPDistributeDirective,
3388 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3389
3390DEF_TRAVERSE_STMT(OMPDistributeParallelForDirective,
3391 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3392
3393DEF_TRAVERSE_STMT(OMPDistributeParallelForSimdDirective,
3394 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3395
3396DEF_TRAVERSE_STMT(OMPDistributeSimdDirective,
3397 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3398
3399DEF_TRAVERSE_STMT(OMPTargetParallelForSimdDirective,
3400 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3401
3402DEF_TRAVERSE_STMT(OMPTargetSimdDirective,
3403 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3404
3405DEF_TRAVERSE_STMT(OMPTeamsDistributeDirective,
3406 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3407
3408DEF_TRAVERSE_STMT(OMPTeamsDistributeSimdDirective,
3409 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3410
3411DEF_TRAVERSE_STMT(OMPTeamsDistributeParallelForSimdDirective,
3412 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3413
3414DEF_TRAVERSE_STMT(OMPTeamsDistributeParallelForDirective,
3415 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3416
3417DEF_TRAVERSE_STMT(OMPTargetTeamsDirective,
3418 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3419
3420DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeDirective,
3421 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3422
3423DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForDirective,
3424 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3425
3426DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForSimdDirective,
3427 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3428
3429DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeSimdDirective,
3430 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3431
3432DEF_TRAVERSE_STMT(OMPInteropDirective,
3433 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3434
3435DEF_TRAVERSE_STMT(OMPDispatchDirective,
3436 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3437
3438DEF_TRAVERSE_STMT(OMPMaskedDirective,
3439 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3440
3441DEF_TRAVERSE_STMT(OMPGenericLoopDirective,
3442 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3443
3444DEF_TRAVERSE_STMT(OMPTeamsGenericLoopDirective,
3445 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3446
3447DEF_TRAVERSE_STMT(OMPTargetTeamsGenericLoopDirective,
3448 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3449
3450DEF_TRAVERSE_STMT(OMPParallelGenericLoopDirective,
3451 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3452
3453DEF_TRAVERSE_STMT(OMPTargetParallelGenericLoopDirective,
3454 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3455
3456DEF_TRAVERSE_STMT(OMPAssumeDirective,
3457 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3458
3459DEF_TRAVERSE_STMT(OMPErrorDirective,
3460 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3461
3462// OpenMP clauses.
3463template <typename Derived>
3464bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
3465 if (!C)
3466 return true;
3467 switch (C->getClauseKind()) {
3468#define GEN_CLANG_CLAUSE_CLASS
3469#define CLAUSE_CLASS(Enum, Str, Class) \
3470 case llvm::omp::Clause::Enum: \
3471 TRY_TO(Visit##Class(static_cast<Class *>(C))); \
3472 break;
3473#define CLAUSE_NO_CLASS(Enum, Str) \
3474 case llvm::omp::Clause::Enum: \
3475 break;
3476#include "llvm/Frontend/OpenMP/OMP.inc"
3477 }
3478 return true;
3479}
3480
3481template <typename Derived>
3482bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPreInit(
3483 OMPClauseWithPreInit *Node) {
3484 TRY_TO(TraverseStmt(Node->getPreInitStmt()));
3485 return true;
3486}
3487
3488template <typename Derived>
3489bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPostUpdate(
3491 TRY_TO(VisitOMPClauseWithPreInit(Node));
3492 TRY_TO(TraverseStmt(Node->getPostUpdateExpr()));
3493 return true;
3494}
3495
3496template <typename Derived>
3499 TRY_TO(TraverseStmt(C->getAllocator()));
3500 return true;
3501}
3502
3503template <typename Derived>
3505 TRY_TO(TraverseStmt(C->getAllocator()));
3506 TRY_TO(VisitOMPClauseList(C));
3507 return true;
3508}
3509
3510template <typename Derived>
3512 TRY_TO(VisitOMPClauseWithPreInit(C));
3513 TRY_TO(TraverseStmt(C->getCondition()));
3514 return true;
3515}
3516
3517template <typename Derived>
3519 TRY_TO(VisitOMPClauseWithPreInit(C));
3520 TRY_TO(TraverseStmt(C->getCondition()));
3521 return true;
3522}
3523
3524template <typename Derived>
3525bool
3527 TRY_TO(VisitOMPClauseWithPreInit(C));
3528 TRY_TO(TraverseStmt(C->getNumThreads()));
3529 return true;
3530}
3531
3532template <typename Derived>
3534 TRY_TO(TraverseStmt(C->getAlignment()));
3535 return true;
3536}
3537
3538template <typename Derived>
3540 TRY_TO(TraverseStmt(C->getSafelen()));
3541 return true;
3542}
3543
3544template <typename Derived>
3546 TRY_TO(TraverseStmt(C->getSimdlen()));
3547 return true;
3548}
3549
3550template <typename Derived>
3552 for (Expr *E : C->getSizesRefs())
3553 TRY_TO(TraverseStmt(E));
3554 return true;
3555}
3556
3557template <typename Derived>
3559 for (Expr *E : C->getCountsRefs())
3560 TRY_TO(TraverseStmt(E));
3561 return true;
3562}
3563
3564template <typename Derived>
3567 for (Expr *E : C->getArgsRefs())
3568 TRY_TO(TraverseStmt(E));
3569 return true;
3570}
3571
3572template <typename Derived>
3574 return true;
3575}
3576
3577template <typename Derived>
3580 TRY_TO(TraverseStmt(C->getFirst()));
3581 TRY_TO(TraverseStmt(C->getCount()));
3582 return true;
3583}
3584
3585template <typename Derived>
3587 TRY_TO(TraverseStmt(C->getFactor()));
3588 return true;
3589}
3590
3591template <typename Derived>
3592bool
3594 TRY_TO(TraverseStmt(C->getNumForLoops()));
3595 return true;
3596}
3597
3598template <typename Derived>
3600 return true;
3601}
3602
3603template <typename Derived>
3606 return true;
3607}
3608
3609template <typename Derived>
3611 OMPTransparentClause *C) {
3612 TRY_TO(TraverseStmt(C->getImpexType()));
3613 return true;
3614}
3615
3616template <typename Derived>
3618 return true;
3619}
3620
3621template <typename Derived>
3623 OMPUnifiedAddressClause *) {
3624 return true;
3625}
3626
3627template <typename Derived>
3629 OMPUnifiedSharedMemoryClause *) {
3630 return true;
3631}
3632
3633template <typename Derived>
3635 OMPReverseOffloadClause *) {
3636 return true;
3637}
3638
3639template <typename Derived>
3641 OMPDynamicAllocatorsClause *) {
3642 return true;
3643}
3644
3645template <typename Derived>
3647 OMPAtomicDefaultMemOrderClause *) {
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 TRY_TO(TraverseStmt(C->getMessageString()));
3669 return true;
3670}
3671
3672template <typename Derived>
3673bool
3675 TRY_TO(VisitOMPClauseWithPreInit(C));
3676 TRY_TO(TraverseStmt(C->getChunkSize()));
3677 return true;
3678}
3679
3680template <typename Derived>
3682 TRY_TO(TraverseStmt(C->getNumForLoops()));
3683 return true;
3684}
3685
3686template <typename Derived>
3688 TRY_TO(TraverseStmt(C->getCondition()));
3689 return true;
3690}
3691
3692template <typename Derived>
3694 return true;
3695}
3696
3697template <typename Derived>
3698bool
3700 return true;
3701}
3702
3703template <typename Derived>
3705 return true;
3706}
3707
3708template <typename Derived>
3710 return true;
3711}
3712
3713template <typename Derived>
3715 return true;
3716}
3717
3718template <typename Derived>
3720 OMPUpdateDependObjectsClause *) {
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 return true;
3737}
3738
3739template <typename Derived>
3741 return true;
3742}
3743
3744template <typename Derived>
3746 return true;
3747}
3748
3749template <typename Derived>
3751 return true;
3752}
3753
3754template <typename Derived>
3756 return true;
3757}
3758
3759template <typename Derived>
3761 return true;
3762}
3763
3764template <typename Derived>
3766 return true;
3767}
3768
3769template <typename Derived>
3771 OMPNoOpenMPRoutinesClause *) {
3772 return true;
3773}
3774
3775template <typename Derived>
3777 OMPNoOpenMPConstructsClause *) {
3778 return true;
3779}
3780
3781template <typename Derived>
3783 OMPNoParallelismClause *) {
3784 return true;
3785}
3786
3787template <typename Derived>
3789 return true;
3790}
3791
3792template <typename Derived>
3794 return true;
3795}
3796
3797template <typename Derived>
3799 return true;
3800}
3801
3802template <typename Derived>
3804 return true;
3805}
3806
3807template <typename Derived>
3809 return true;
3810}
3811
3812template <typename Derived>
3814 return true;
3815}
3816
3817template <typename Derived>
3819 return true;
3820}
3821
3822template <typename Derived>
3824 TRY_TO(VisitOMPClauseList(C));
3825 // VisitOMPClauseList covers the interop var and the per-pref-spec fr exprs
3826 // (the varlist); the prefer_type attr() exprs live outside it.
3827 for (Expr *A : C->attrs())
3828 TRY_TO(TraverseStmt(A));
3829 return true;
3830}
3831
3832template <typename Derived>
3834 TRY_TO(TraverseStmt(C->getInteropVar()));
3835 return true;
3836}
3837
3838template <typename Derived>
3840 TRY_TO(TraverseStmt(C->getInteropVar()));
3841 return true;
3842}
3843
3844template <typename Derived>
3846 OMPNovariantsClause *C) {
3847 TRY_TO(VisitOMPClauseWithPreInit(C));
3848 TRY_TO(TraverseStmt(C->getCondition()));
3849 return true;
3850}
3851
3852template <typename Derived>
3854 OMPNocontextClause *C) {
3855 TRY_TO(VisitOMPClauseWithPreInit(C));
3856 TRY_TO(TraverseStmt(C->getCondition()));
3857 return true;
3858}
3859
3860template <typename Derived>
3861template <typename T>
3862bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
3863 for (auto *E : Node->varlist()) {
3864 TRY_TO(TraverseStmt(E));
3865 }
3866 return true;
3867}
3868
3869template <typename Derived>
3871 OMPInclusiveClause *C) {
3872 TRY_TO(VisitOMPClauseList(C));
3873 return true;
3874}
3875
3876template <typename Derived>
3878 OMPExclusiveClause *C) {
3879 TRY_TO(VisitOMPClauseList(C));
3880 return true;
3881}
3882
3883template <typename Derived>
3885 TRY_TO(VisitOMPClauseList(C));
3886 for (auto *E : C->private_copies()) {
3887 TRY_TO(TraverseStmt(E));
3888 }
3889 return true;
3890}
3891
3892template <typename Derived>
3894 OMPFirstprivateClause *C) {
3895 TRY_TO(VisitOMPClauseList(C));
3896 TRY_TO(VisitOMPClauseWithPreInit(C));
3897 for (auto *E : C->private_copies()) {
3898 TRY_TO(TraverseStmt(E));
3899 }
3900 for (auto *E : C->inits()) {
3901 TRY_TO(TraverseStmt(E));
3902 }
3903 return true;
3904}
3905
3906template <typename Derived>
3908 OMPLastprivateClause *C) {
3909 TRY_TO(VisitOMPClauseList(C));
3910 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3911 for (auto *E : C->private_copies()) {
3912 TRY_TO(TraverseStmt(E));
3913 }
3914 for (auto *E : C->source_exprs()) {
3915 TRY_TO(TraverseStmt(E));
3916 }
3917 for (auto *E : C->destination_exprs()) {
3918 TRY_TO(TraverseStmt(E));
3919 }
3920 for (auto *E : C->assignment_ops()) {
3921 TRY_TO(TraverseStmt(E));
3922 }
3923 return true;
3924}
3925
3926template <typename Derived>
3928 TRY_TO(VisitOMPClauseList(C));
3929 return true;
3930}
3931
3932template <typename Derived>
3934 TRY_TO(TraverseStmt(C->getStep()));
3935 TRY_TO(TraverseStmt(C->getCalcStep()));
3936 TRY_TO(VisitOMPClauseList(C));
3937 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3938 for (auto *E : C->privates()) {
3939 TRY_TO(TraverseStmt(E));
3940 }
3941 for (auto *E : C->inits()) {
3942 TRY_TO(TraverseStmt(E));
3943 }
3944 for (auto *E : C->updates()) {
3945 TRY_TO(TraverseStmt(E));
3946 }
3947 for (auto *E : C->finals()) {
3948 TRY_TO(TraverseStmt(E));
3949 }
3950 return true;
3951}
3952
3953template <typename Derived>
3955 TRY_TO(TraverseStmt(C->getAlignment()));
3956 TRY_TO(VisitOMPClauseList(C));
3957 return true;
3958}
3959
3960template <typename Derived>
3962 TRY_TO(VisitOMPClauseList(C));
3963 for (auto *E : C->source_exprs()) {
3964 TRY_TO(TraverseStmt(E));
3965 }
3966 for (auto *E : C->destination_exprs()) {
3967 TRY_TO(TraverseStmt(E));
3968 }
3969 for (auto *E : C->assignment_ops()) {
3970 TRY_TO(TraverseStmt(E));
3971 }
3972 return true;
3973}
3974
3975template <typename Derived>
3977 OMPCopyprivateClause *C) {
3978 TRY_TO(VisitOMPClauseList(C));
3979 for (auto *E : C->source_exprs()) {
3980 TRY_TO(TraverseStmt(E));
3981 }
3982 for (auto *E : C->destination_exprs()) {
3983 TRY_TO(TraverseStmt(E));
3984 }
3985 for (auto *E : C->assignment_ops()) {
3986 TRY_TO(TraverseStmt(E));
3987 }
3988 return true;
3989}
3990
3991template <typename Derived>
3992bool
3994 TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
3995 TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
3996 TRY_TO(VisitOMPClauseList(C));
3997 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3998 for (auto *E : C->privates()) {
3999 TRY_TO(TraverseStmt(E));
4000 }
4001 for (auto *E : C->lhs_exprs()) {
4002 TRY_TO(TraverseStmt(E));
4003 }
4004 for (auto *E : C->rhs_exprs()) {
4005 TRY_TO(TraverseStmt(E));
4006 }
4007 for (auto *E : C->reduction_ops()) {
4008 TRY_TO(TraverseStmt(E));
4009 }
4010 if (C->getModifier() == OMPC_REDUCTION_inscan) {
4011 for (auto *E : C->copy_ops()) {
4012 TRY_TO(TraverseStmt(E));
4013 }
4014 for (auto *E : C->copy_array_temps()) {
4015 TRY_TO(TraverseStmt(E));
4016 }
4017 for (auto *E : C->copy_array_elems()) {
4018 TRY_TO(TraverseStmt(E));
4019 }
4020 }
4021 return true;
4022}
4023
4024template <typename Derived>
4026 OMPTaskReductionClause *C) {
4027 TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
4028 TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
4029 TRY_TO(VisitOMPClauseList(C));
4030 TRY_TO(VisitOMPClauseWithPostUpdate(C));
4031 for (auto *E : C->privates()) {
4032 TRY_TO(TraverseStmt(E));
4033 }
4034 for (auto *E : C->lhs_exprs()) {
4035 TRY_TO(TraverseStmt(E));
4036 }
4037 for (auto *E : C->rhs_exprs()) {
4038 TRY_TO(TraverseStmt(E));
4039 }
4040 for (auto *E : C->reduction_ops()) {
4041 TRY_TO(TraverseStmt(E));
4042 }
4043 return true;
4044}
4045
4046template <typename Derived>
4048 OMPInReductionClause *C) {
4049 TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
4050 TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
4051 TRY_TO(VisitOMPClauseList(C));
4052 TRY_TO(VisitOMPClauseWithPostUpdate(C));
4053 for (auto *E : C->privates()) {
4054 TRY_TO(TraverseStmt(E));
4055 }
4056 for (auto *E : C->lhs_exprs()) {
4057 TRY_TO(TraverseStmt(E));
4058 }
4059 for (auto *E : C->rhs_exprs()) {
4060 TRY_TO(TraverseStmt(E));
4061 }
4062 for (auto *E : C->reduction_ops()) {
4063 TRY_TO(TraverseStmt(E));
4064 }
4065 for (auto *E : C->taskgroup_descriptors())
4066 TRY_TO(TraverseStmt(E));
4067 return true;
4068}
4069
4070template <typename Derived>
4072 TRY_TO(VisitOMPClauseList(C));
4073 return true;
4074}
4075
4076template <typename Derived>
4078 TRY_TO(TraverseStmt(C->getDepobj()));
4079 return true;
4080}
4081
4082template <typename Derived>
4084 TRY_TO(VisitOMPClauseList(C));
4085 return true;
4086}
4087
4088template <typename Derived>
4090 TRY_TO(VisitOMPClauseWithPreInit(C));
4091 TRY_TO(TraverseStmt(C->getDevice()));
4092 return true;
4093}
4094
4095template <typename Derived>
4097 TRY_TO(VisitOMPClauseList(C));
4098 return true;
4099}
4100
4101template <typename Derived>
4103 OMPNumTeamsClause *C) {
4104 if (auto *E = C->getModifierExpr())
4105 TRY_TO(VisitStmt(E));
4106 TRY_TO(VisitOMPClauseList(C));
4107 TRY_TO(VisitOMPClauseWithPreInit(C));
4108 return true;
4109}
4110
4111template <typename Derived>
4113 OMPThreadLimitClause *C) {
4114 if (auto *E = C->getModifierExpr())
4115 TRY_TO(VisitStmt(E));
4116 TRY_TO(VisitOMPClauseList(C));
4117 TRY_TO(VisitOMPClauseWithPreInit(C));
4118 return true;
4119}
4120
4121template <typename Derived>
4123 OMPPriorityClause *C) {
4124 TRY_TO(VisitOMPClauseWithPreInit(C));
4125 TRY_TO(TraverseStmt(C->getPriority()));
4126 return true;
4127}
4128
4129template <typename Derived>
4131 OMPGrainsizeClause *C) {
4132 TRY_TO(VisitOMPClauseWithPreInit(C));
4133 TRY_TO(TraverseStmt(C->getGrainsize()));
4134 return true;
4135}
4136
4137template <typename Derived>
4139 OMPNumTasksClause *C) {
4140 TRY_TO(VisitOMPClauseWithPreInit(C));
4141 TRY_TO(TraverseStmt(C->getNumTasks()));
4142 return true;
4143}
4144
4145template <typename Derived>
4147 TRY_TO(TraverseStmt(C->getHint()));
4148 return true;
4149}
4150
4151template <typename Derived>
4153 OMPDistScheduleClause *C) {
4154 TRY_TO(VisitOMPClauseWithPreInit(C));
4155 TRY_TO(TraverseStmt(C->getChunkSize()));
4156 return true;
4157}
4158
4159template <typename Derived>
4160bool
4162 return true;
4163}
4164
4165template <typename Derived>
4167 TRY_TO(VisitOMPClauseList(C));
4168 return true;
4169}
4170
4171template <typename Derived>
4173 TRY_TO(VisitOMPClauseList(C));
4174 return true;
4175}
4176
4177template <typename Derived>
4179 OMPUseDevicePtrClause *C) {
4180 TRY_TO(VisitOMPClauseList(C));
4181 return true;
4182}
4183
4184template <typename Derived>
4186 OMPUseDeviceAddrClause *C) {
4187 TRY_TO(VisitOMPClauseList(C));
4188 return true;
4189}
4190
4191template <typename Derived>
4193 OMPIsDevicePtrClause *C) {
4194 TRY_TO(VisitOMPClauseList(C));
4195 return true;
4196}
4197
4198template <typename Derived>
4200 OMPHasDeviceAddrClause *C) {
4201 TRY_TO(VisitOMPClauseList(C));
4202 return true;
4203}
4204
4205template <typename Derived>
4207 OMPNontemporalClause *C) {
4208 TRY_TO(VisitOMPClauseList(C));
4209 for (auto *E : C->private_refs()) {
4210 TRY_TO(TraverseStmt(E));
4211 }
4212 return true;
4213}
4214
4215template <typename Derived>
4217 return true;
4218}
4219
4220template <typename Derived>
4222 TRY_TO(TraverseStmt(C->getEventHandler()));
4223 return true;
4224}
4225
4226template <typename Derived>
4228 OMPUsesAllocatorsClause *C) {
4229 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
4230 const OMPUsesAllocatorsClause::Data Data = C->getAllocatorData(I);
4231 TRY_TO(TraverseStmt(Data.Allocator));
4232 TRY_TO(TraverseStmt(Data.AllocatorTraits));
4233 }
4234 return true;
4235}
4236
4237template <typename Derived>
4239 OMPAffinityClause *C) {
4240 TRY_TO(TraverseStmt(C->getModifier()));
4241 for (Expr *E : C->varlist())
4242 TRY_TO(TraverseStmt(E));
4243 return true;
4244}
4245
4246template <typename Derived>
4248 TRY_TO(VisitOMPClauseWithPreInit(C));
4249 TRY_TO(TraverseStmt(C->getThreadID()));
4250 return true;
4251}
4252
4253template <typename Derived>
4255 return true;
4256}
4257
4258template <typename Derived>
4260 OMPXDynCGroupMemClause *C) {
4261 TRY_TO(VisitOMPClauseWithPreInit(C));
4262 TRY_TO(TraverseStmt(C->getSize()));
4263 return true;
4264}
4265
4266template <typename Derived>
4268 OMPDynGroupprivateClause *C) {
4269 TRY_TO(VisitOMPClauseWithPreInit(C));
4270 TRY_TO(TraverseStmt(C->getSize()));
4271 return true;
4272}
4273
4274template <typename Derived>
4276 OMPDoacrossClause *C) {
4277 TRY_TO(VisitOMPClauseList(C));
4278 return true;
4279}
4280
4281template <typename Derived>
4283 OMPXAttributeClause *C) {
4284 return true;
4285}
4286
4287template <typename Derived>
4289 return true;
4290}
4291
4292template <typename Derived>
4293bool RecursiveASTVisitor<Derived>::TraverseOpenACCConstructStmt(
4295 TRY_TO(VisitOpenACCClauseList(C->clauses()));
4296 return true;
4297}
4298
4299template <typename Derived>
4300bool RecursiveASTVisitor<Derived>::TraverseOpenACCAssociatedStmtConstruct(
4302 TRY_TO(TraverseOpenACCConstructStmt(S));
4303 TRY_TO(TraverseStmt(S->getAssociatedStmt()));
4304 return true;
4305}
4306
4307template <typename Derived>
4308bool RecursiveASTVisitor<Derived>::VisitOpenACCClause(const OpenACCClause *C) {
4309 for (const Stmt *Child : C->children())
4310 TRY_TO(TraverseStmt(const_cast<Stmt *>(Child)));
4311 return true;
4312}
4313
4314template <typename Derived>
4315bool RecursiveASTVisitor<Derived>::VisitOpenACCClauseList(
4317
4318 for (const auto *C : Clauses)
4319 TRY_TO(VisitOpenACCClause(C));
4320 return true;
4321}
4322
4324 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4325DEF_TRAVERSE_STMT(OpenACCLoopConstruct,
4326 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4327DEF_TRAVERSE_STMT(OpenACCCombinedConstruct,
4328 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4329DEF_TRAVERSE_STMT(OpenACCDataConstruct,
4330 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4331DEF_TRAVERSE_STMT(OpenACCEnterDataConstruct,
4332 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4333DEF_TRAVERSE_STMT(OpenACCExitDataConstruct,
4334 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4335DEF_TRAVERSE_STMT(OpenACCHostDataConstruct,
4336 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4337DEF_TRAVERSE_STMT(OpenACCWaitConstruct, {
4338 if (S->hasDevNumExpr())
4339 TRY_TO(TraverseStmt(S->getDevNumExpr()));
4340 for (auto *E : S->getQueueIdExprs())
4341 TRY_TO(TraverseStmt(E));
4342 TRY_TO(VisitOpenACCClauseList(S->clauses()));
4343})
4344DEF_TRAVERSE_STMT(OpenACCInitConstruct,
4345 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4346DEF_TRAVERSE_STMT(OpenACCShutdownConstruct,
4347 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4348DEF_TRAVERSE_STMT(OpenACCSetConstruct,
4349 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4350DEF_TRAVERSE_STMT(OpenACCUpdateConstruct,
4351 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4352DEF_TRAVERSE_STMT(OpenACCAtomicConstruct,
4353 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4354DEF_TRAVERSE_STMT(OpenACCCacheConstruct, {
4355 for (auto *E : S->getVarList())
4356 TRY_TO(TraverseStmt(E));
4357})
4358
4359// Traverse HLSL: Out argument expression
4361
4362// FIXME: look at the following tricky-seeming exprs to see if we
4363// need to recurse on anything. These are ones that have methods
4364// returning decls or qualtypes or nestednamespecifier -- though I'm
4365// not sure if they own them -- or just seemed very complicated, or
4366// had lots of sub-types to explore.
4367//
4368// VisitOverloadExpr and its children: recurse on template args? etc?
4369
4370// FIXME: go through all the stmts and exprs again, and see which of them
4371// create new types, and recurse on the types (TypeLocs?) of those.
4372// Candidates:
4373//
4374// http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html
4375// http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html
4376// http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html
4377// Every class that has getQualifier.
4378
4379#undef DEF_TRAVERSE_STMT
4380#undef TRAVERSE_STMT
4381#undef TRAVERSE_STMT_BASE
4382
4383#undef TRY_TO
4384
4385} // end namespace clang
4386
4387#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:223
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:4561
Represents a type which was implicitly adjusted by the semantic engine for arbitrary reasons.
Definition TypeBase.h:3603
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Definition Expr.h:6038
Represents a loop initializing the elements of an array.
Definition Expr.h:5985
This class represents BOTH the OpenMP Array Section and OpenACC 'subarray', with a boolean differenti...
Definition Expr.h:7236
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition Expr.h:2732
Wrapper for source info for arrays.
Definition TypeLoc.h:1808
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
Definition ExprCXX.h:2999
AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2] This AST node provides support ...
Definition Expr.h:6750
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
Definition Expr.h:6945
Attr - This represents one attribute.
Definition Attr.h:46
Represents an attribute applied to a statement.
Definition Stmt.h:2212
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
Definition Expr.h:4464
A builtin binary operation expression such as "x + y" or "x <= y".
Definition Expr.h:4049
A binding in a decomposition declaration.
Definition DeclCXX.h:4210
A fixed int type of a specified bitwidth.
Definition TypeBase.h:8356
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition Decl.h:4806
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition Expr.h:6689
Pointer to a block type.
Definition TypeBase.h:3656
BreakStmt - This represents a break.
Definition Stmt.h:3144
Represents a C++2a __builtin_bit_cast(T, v) expression.
Definition ExprCXX.h:5475
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:3241
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Definition Expr.h:3980
Represents a call to a CUDA kernel function.
Definition ExprCXX.h:237
A C++ addrspace_cast expression (currently only enabled for OpenCL).
Definition ExprCXX.h:607
Represents a base class of a C++ class.
Definition DeclCXX.h:146
Represents binding an expression to a temporary.
Definition ExprCXX.h:1496
A boolean literal, per ([C++ lex.bool] Boolean literals).
Definition ExprCXX.h:726
CXXCatchStmt - This represents a C++ catch block.
Definition StmtCXX.h:29
A C++ const_cast expression (C++ [expr.const.cast]).
Definition ExprCXX.h:569
Represents a call to a C++ constructor.
Definition ExprCXX.h:1551
Represents a C++ constructor within a class.
Definition DeclCXX.h:2637
Represents a C++ conversion function within a class.
Definition DeclCXX.h:2972
Represents a C++ base or member initializer.
Definition DeclCXX.h:2402
Represents a C++ deduction guide declaration.
Definition DeclCXX.h:1996
A default argument (C++ [dcl.fct.default]).
Definition ExprCXX.h:1273
A use of a default initializer in a constructor or in aggregate initialization.
Definition ExprCXX.h:1380
Represents a delete expression for memory deallocation and destructor calls, e.g.
Definition ExprCXX.h:2629
Represents a C++ member access expression where the actual member referenced could not be resolved be...
Definition ExprCXX.h:3869
Represents a C++ destructor within a class.
Definition DeclCXX.h:2902
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
Definition ExprCXX.h:484
Helper that selects an expression from an InitListExpr depending on the current expansion index.
Definition ExprCXX.h:5557
Represents a C++26 expansion statement declaration.
Represents the code generated for an expanded expansion statement.
Definition StmtCXX.h:1028
CXXExpansionStmtPattern - Represents an unexpanded C++ expansion statement.
Definition StmtCXX.h:675
Represents a folding of a pack over an operator.
Definition ExprCXX.h:5031
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
Definition StmtCXX.h:136
Represents an explicit C++ type conversion that uses "functional" notation (C++ [expr....
Definition ExprCXX.h:1834
Represents a call to an inherited base class constructor from an inheriting constructor.
Definition ExprCXX.h:1754
Represents a call to a member function that may be written either with member call syntax (e....
Definition ExprCXX.h:182
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2145
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition ExprCXX.h:2358
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
Definition ExprCXX.h:4308
The null pointer literal (C++11 [lex.nullptr])
Definition ExprCXX.h:771
A call to an overloaded operator written using operator syntax.
Definition ExprCXX.h:84
Represents a list-initialization with parenthesis.
Definition ExprCXX.h:5140
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
Definition ExprCXX.h:2748
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
Represents a C++26 reflect expression [expr.reflect].
Definition ExprCXX.h:5507
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
Definition ExprCXX.h:529
A rewritten comparison expression that was originally written using operator syntax.
Definition ExprCXX.h:289
An expression "T()" which creates an rvalue of a non-class type T.
Definition ExprCXX.h:2199
A C++ static_cast expression (C++ [expr.static.cast]).
Definition ExprCXX.h:439
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
Definition ExprCXX.h:803
Represents a C++ functional cast expression that builds a temporary object.
Definition ExprCXX.h:1902
Represents the this expression in C++.
Definition ExprCXX.h:1157
A C++ throw-expression (C++ [except.throw]).
Definition ExprCXX.h:1211
CXXTryStmt - A C++ try block, including all handlers.
Definition StmtCXX.h:70
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
Definition ExprCXX.h:851
Describes an explicit type conversion that uses functional notion but could not be resolved because o...
Definition ExprCXX.h:3743
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
Definition ExprCXX.h:1071
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:2954
Represents the body of a CapturedStmt, and serves as its DeclContext.
Definition Decl.h:5078
This captures a statement into a function.
Definition Stmt.h:3946
CaseStmt - Represent a case statement.
Definition Stmt.h:1929
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Definition Expr.h:4859
Declaration of a class template.
Represents a 'co_await' expression.
Definition ExprCXX.h:5368
Complex values, per C99 6.2.5p11.
Definition TypeBase.h:3355
CompoundAssignOperator - For compound assignments (e.g.
Definition Expr.h:4311
CompoundLiteralExpr - [C99 6.5.2.5].
Definition Expr.h:3616
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition Stmt.h:1749
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:4402
Represents the canonical version of C arrays with a specified constant size.
Definition TypeBase.h:3874
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Definition Expr.h:1093
Represents a concrete matrix type with constant number of rows and columns.
Definition TypeBase.h:4501
Represents a shadow constructor declaration introduced into a class by a C++11 using-declaration that...
Definition DeclCXX.h:3702
ContinueStmt - This represents a continue.
Definition Stmt.h:3128
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Definition Expr.h:4730
Represents a 'co_return' statement in the C++ Coroutines TS.
Definition StmtCXX.h:474
Represents the body of a coroutine.
Definition StmtCXX.h:321
Represents a 'co_yield' expression.
Definition ExprCXX.h:5449
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1466
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2126
A reference to a declared variable, function, enum, etc.
Definition Expr.h:1281
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition Stmt.h:1640
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition DeclBase.h:601
Kind getKind() const
Definition DeclBase.h:450
TemplateDecl * getCXXDeductionGuideTemplate() const
If this name is the name of a C++ deduction guide, return the template associated with that name.
NameKind getNameKind() const
Determine what kind of name this is.
Represents a ValueDecl that came out of a declarator.
Definition Decl.h:780
A decomposition declaration.
Definition DeclCXX.h:4274
DeferStmt - This represents a deferred statement.
Definition Stmt.h:3245
Represents a 'co_await' expression while the type of the promise is dependent.
Definition ExprCXX.h:5400
Provides information about a dependent function-template specialization declaration.
A qualified reference to a name whose declaration cannot yet be resolved.
Definition ExprCXX.h:3509
Represents an array type in C++ whose size is a value-dependent expression.
Definition TypeBase.h:4125
Represents an extended vector type where either the type or size is dependent.
Definition TypeBase.h:4215
Represents a vector type where either the type or size is dependent.
Definition TypeBase.h:4341
Represents a C99 designated initializer expression.
Definition Expr.h:5568
DoStmt - This represents a 'do/while' stmt.
Definition Stmt.h:2841
Represents a reference to emded data.
Definition Expr.h:5146
Represents an empty-declaration.
Definition Decl.h:5313
An instance of this object exists for each enum constant that is defined.
Definition Decl.h:3557
Represents an enum.
Definition Decl.h:4145
Represents an explicit instantiation of a template entity in source code.
Represents a standard C++ module export declaration.
Definition Decl.h:5266
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
Definition ExprCXX.h:3660
This represents one expression.
Definition Expr.h:112
An expression trait intrinsic.
Definition ExprCXX.h:3072
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
Definition Expr.h:6627
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:3294
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Definition Stmt.h:2897
FriendDecl - Represents the declaration of a friend entity, which can be a function,...
Definition DeclFriend.h:46
Declaration of a friend template.
Represents a function declaration or definition.
Definition Decl.h:2058
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Definition TypeBase.h:4999
Represents a reference to a function parameter pack, init-capture pack, or binding pack that has been...
Definition ExprCXX.h:4840
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5421
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:3455
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Definition Expr.h:4934
Represents a C11 generic selection.
Definition Expr.h:6199
AssociationTy< false > Association
Definition Expr.h:6432
GotoStmt - This represents a direct goto.
Definition Stmt.h:2978
HLSLBufferDecl - Represent a cbuffer or tbuffer declaration.
Definition Decl.h:5328
This class represents temporary values used to represent inout and out arguments in HLSL.
Definition Expr.h:7414
IfStmt - This represents an if/then/else.
Definition Stmt.h:2268
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
Definition Expr.h:1742
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Definition Expr.h:3864
Represents an implicitly-generated value initialization of an object of a given type.
Definition Expr.h:6074
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Definition Decl.h:5187
Represents a C array with an unspecified size.
Definition TypeBase.h:4023
Represents a field injected from an anonymous union/struct into the parent scope.
Definition Decl.h:3601
IndirectGotoStmt - This represents an indirect goto.
Definition Stmt.h:3017
Describes an C or C++ initializer list.
Definition Expr.h:5319
Represents the declaration of a label.
Definition Decl.h:524
LabelStmt - Represents a label, which has a substatement.
Definition Stmt.h:2155
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:1971
Represents a placeholder type for late-parsed type attributes.
Definition TypeBase.h:3575
Implicit declaration of a temporary that was materialized by a MaterializeTemporaryExpr and lifetime-...
Definition DeclCXX.h:3333
Represents a linkage specification.
Definition DeclCXX.h:3040
This represents a Microsoft inline-assembly statement extension.
Definition Stmt.h:3674
Representation of a Microsoft __if_exists or __if_not_exists statement with a dependent name.
Definition StmtCXX.h:254
A global _GUID constant.
Definition DeclCXX.h:4428
An instance of this class represents the declaration of a property member.
Definition DeclCXX.h:4374
A member reference to an MSPropertyDecl.
Definition ExprCXX.h:939
MS property subscript expression.
Definition ExprCXX.h:1009
Sugar type that represents a type that was qualified by a qualifier written as a macro invocation.
Definition TypeBase.h:6300
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition ExprCXX.h:4919
MatrixSingleSubscriptExpr - Matrix single subscript expression for the MatrixType extension when you ...
Definition Expr.h:2806
MatrixSubscriptExpr - Matrix subscript expression for the MatrixType extension.
Definition Expr.h:2876
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition Expr.h:3375
This represents a decl that may have a name.
Definition Decl.h:274
Represents a C++ namespace alias.
Definition DeclCXX.h:3226
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:5894
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
NullStmt - This is the null statement ";": C99 6.8.3p3.
Definition Stmt.h:1712
This represents the 'align' clause in the 'pragma omp allocate' directive.
This represents clause 'allocate' in the 'pragma omp ...' directives.
This represents 'pragma omp allocate ...' directive.
Definition DeclOpenMP.h:536
This represents 'allocator' clause in the 'pragma omp ...' directive.
An explicit cast in C or a C-style cast in C++, which uses the syntax ([s1][s2]......
Definition ExprOpenMP.h:24
Pseudo declaration for capturing expressions.
Definition DeclOpenMP.h:445
Class that handles post-update expression for some clauses, like 'lastprivate', 'reduction' etc.
Class that handles pre-initialization statement for some clauses, like 'schedule',...
This is a basic class for representing single OpenMP clause.
This represents 'collapse' clause in the 'pragma omp ...' directive.
This represents the 'counts' clause in the 'pragma omp split' directive.
This represents 'pragma omp declare mapper ...' directive.
Definition DeclOpenMP.h:349
This represents 'pragma omp declare reduction ...' directive.
Definition DeclOpenMP.h:239
This represents 'default' clause in the 'pragma omp ...' directive.
This represents 'final' clause in the 'pragma omp ...' directive.
Representation of the 'full' clause of the 'pragma omp unroll' directive.
This represents 'pragma omp groupprivate ...' directive.
Definition DeclOpenMP.h:173
This represents 'if' clause in the 'pragma omp ...' directive.
OpenMP 5.0 [2.1.6 Iterators] Iterators are identifiers that expand to multiple values in the clause o...
Definition ExprOpenMP.h:151
This class represents the 'looprange' clause in the 'pragma omp fuse' directive.
This represents 'num_threads' clause in the 'pragma omp ...' directive.
Representation of the 'partial' clause of the 'pragma omp unroll' directive.
This class represents the 'permutation' clause in the 'pragma omp interchange' directive.
This represents 'pragma omp requires...' directive.
Definition DeclOpenMP.h:479
This represents 'safelen' clause in the 'pragma omp ...' directive.
This represents 'simdlen' clause in the 'pragma omp ...' directive.
This represents the 'sizes' clause in the 'pragma omp tile' directive.
This represents 'pragma omp threadprivate ...' directive.
Definition DeclOpenMP.h:110
This represents 'threadset' clause in the 'pragma omp task ...' directive.
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
Definition ExprObjC.h:220
Represents Objective-C's @catch statement.
Definition StmtObjC.h:77
Represents a field declaration created by an @defs(...).
Definition DeclObjC.h:2036
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:1736
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
Definition ExprObjC.h:119
ObjCBoxedExpr - used for generalized expression boxing.
Definition ExprObjC.h:159
An Objective-C "bridged" cast expression, which casts between Objective-C pointers and C pointers,...
Definition ExprObjC.h:1676
ObjCCategoryDecl - Represents a category declaration.
Definition DeclObjC.h:2335
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
Definition DeclObjC.h:2551
ObjCCompatibleAliasDecl - Represents alias of a class.
Definition DeclObjC.h:2781
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
Definition ExprObjC.h:342
ObjCEncodeExpr, used for @encode in Objective-C.
Definition ExprObjC.h:441
Represents Objective-C's collection statement.
Definition StmtObjC.h:23
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Definition DeclObjC.h:2603
ObjCIndirectCopyRestoreExpr - Represents the passing of a function argument by indirect copy-restore ...
Definition ExprObjC.h:1615
Represents an ObjC class declaration.
Definition DeclObjC.h:1160
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
Definition TypeBase.h:8066
ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
Definition ExprObjC.h:1531
ObjCIvarDecl - Represents an ObjC instance variable.
Definition DeclObjC.h:1958
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Definition ExprObjC.h:582
An expression that sends a message to the given Objective-C object or class.
Definition ExprObjC.h:973
ObjCMethodDecl - Represents an instance or class method declaration.
Definition DeclObjC.h:140
Represents a pointer to an Objective C object.
Definition TypeBase.h:8122
Represents one property declaration in an Objective-C interface.
Definition DeclObjC.h:734
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
Definition DeclObjC.h:2811
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
Definition ExprObjC.h:650
Represents an Objective-C protocol declaration.
Definition DeclObjC.h:2090
ObjCProtocolExpr used for protocol expression in Objective-C.
Definition ExprObjC.h:538
ObjCSelectorExpr used for @selector in Objective-C.
Definition ExprObjC.h:486
ObjCStringLiteral, used for Objective-C string literals i.e.
Definition ExprObjC.h:84
ObjCSubscriptRefExpr - used for array and dictionary subscripting.
Definition ExprObjC.h:872
Represents the declaration of an Objective-C type parameter.
Definition DeclObjC.h:581
Stores a list of Objective-C type parameters for a parameterized class or a category/extension thereo...
Definition DeclObjC.h:665
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition Expr.h:2538
Helper class for OffsetOfExpr.
Definition Expr.h:2432
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition Expr.h:1189
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:2101
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:5013
Represents a C++11 pack expansion that produces a sequence of expressions.
Definition ExprCXX.h:4362
ParenExpr - This represents a parenthesized expression, e.g.
Definition Expr.h:2193
Sugar for parentheses used when specifying types.
Definition TypeBase.h:3382
Represents a parameter to a function.
Definition Decl.h:1819
PipeType - OpenCL20.
Definition TypeBase.h:8322
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:2016
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition Expr.h:6821
Expr *const * semantics_iterator
Definition Expr.h:6880
A (possibly-)qualified type.
Definition TypeBase.h:938
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:3749
Represents a struct/union/class.
Definition Decl.h:4459
Frontend produces RecoveryExprs on semantic errors that prevent creating other well-formed expression...
Definition Expr.h:7520
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 TraverseOffsetOfNode(const OffsetOfNode *Node)
Recursively visit a single component of an __builtin_offsetof designator (a field,...
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 VisitOffsetOfNode(const OffsetOfNode *Node)
Visit a single component of an __builtin_offsetof designator.
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:2114
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:3169
Represents a __leave statement.
Definition Stmt.h:3907
SYCLKernelCallStmt represents the transformation that is applied to the body of a function declared w...
Definition StmtSYCL.h:36
Scope - A scope is a transient data structure that is used while parsing the program.
Definition Scope.h:41
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Definition Expr.h:4654
Represents an expression that computes the length of a parameter pack.
Definition ExprCXX.h:4440
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
Definition Expr.h:5037
Represents a C++11 static_assert declaration.
Definition DeclCXX.h:4161
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
Definition Expr.h:4606
Stmt - This represents one statement.
Definition Stmt.h:85
@ NoStmtClass
Definition Stmt.h:88
child_range children()
Definition Stmt.cpp:304
StmtClass getStmtClass() const
Definition Stmt.h:1502
llvm::iterator_range< child_iterator > child_range
Definition Stmt.h:1591
StringLiteral - This represents a string literal expression, e.g.
Definition Expr.h:1810
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Definition ExprCXX.h:4663
Represents a reference to a non-type template parameter pack that has been substituted with a non-tem...
Definition ExprCXX.h:4753
Abstract type representing delayed type pack expansions.
Definition TypeLoc.h:986
SwitchStmt - This represents a 'switch' stmt.
Definition Stmt.h:2518
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.
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:4769
The top declaration context.
Definition Decl.h:105
Represents the declaration of a typedef-name via a C++11 alias-declaration.
Definition Decl.h:3822
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:475
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:2766
A container of type source information.
Definition TypeBase.h:8475
A type trait used in the implementation of various C++11 and Library TR1 trait templates.
Definition ExprCXX.h:2899
The base class of the type hierarchy.
Definition TypeBase.h:1879
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Definition Decl.h:3801
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition Expr.h:2636
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition Expr.h:2255
An artificial decl, representing a global anonymous constant value which is uniquified by value withi...
Definition DeclCXX.h:4485
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:3389
Represents a C++ member access expression for which lookup produced a set of overloaded functions.
Definition ExprCXX.h:4125
This node is generated when a using-declaration that was annotated with attribute((using_if_exists)) ...
Definition DeclCXX.h:4143
Represents a dependent using declaration which was marked with typename.
Definition DeclCXX.h:4062
Represents a dependent using declaration which was not marked with typename.
Definition DeclCXX.h:3965
A call to a literal operator (C++11 [over.literal]) written as a user-defined literal (C++11 [lit....
Definition ExprCXX.h:643
Represents a C++ using-declaration.
Definition DeclCXX.h:3616
Represents C++ using-directive.
Definition DeclCXX.h:3121
Represents a C++ using-enum-declaration.
Definition DeclCXX.h:3817
Represents a pack of using declarations that a single using-declarator pack-expanded into.
Definition DeclCXX.h:3898
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Definition DeclCXX.h:3424
Represents a call to the builtin function __builtin_va_arg.
Definition Expr.h:4968
Represents a variable declaration or definition.
Definition Decl.h:932
Declaration of a variable template.
Represents a GCC generic vector type.
Definition TypeBase.h:4289
WhileStmt - This represents a 'while' stmt.
Definition Stmt.h:2706
A requires-expression requirement which queries the validity and properties of an expression ('simple...
A requires-expression requirement which is satisfied when a general constraint expression is satisfie...
A static requirement that can be used in a requires-expression to check properties of types and expre...
A requires-expression requirement which queries the existence of a type name or type template special...
LLVM_ATTRIBUTE_ALWAYS_INLINE LLVM_ATTRIBUTE_NODEBUG auto isSameMethod(FirstMethodPtrTy FirstMethodPtr, SecondMethodPtrTy SecondMethodPtr) -> bool
Returns true if and only if FirstMethodPtr and SecondMethodPtr are pointers to the same non-static me...
Top level wrappers for InstallAPI frontend operations.
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:909
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:1305
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
Definition Specifiers.h:207
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
Definition Specifiers.h:203
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition Specifiers.h:199
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
Definition Specifiers.h:195
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition Specifiers.h:192
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Class
The "class" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:6031
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