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 if (D->getFriendType())
1743 TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
1744 else
1745 TRY_TO(TraverseDecl(D->getFriendDecl()));
1746 for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
1747 TemplateParameterList *TPL = D->getTemplateParameterList(I);
1748 for (TemplateParameterList::iterator ITPL = TPL->begin(), ETPL = TPL->end();
1749 ITPL != ETPL; ++ITPL) {
1750 TRY_TO(TraverseDecl(*ITPL));
1751 }
1752 }
1753})
1754
1756
1758
1759DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {// FIXME: implement this
1760 })
1761
1763 TRY_TO(TraverseStmt(D->getAssertExpr()));
1764 TRY_TO(TraverseStmt(D->getMessage()));
1765})
1766
1768 // No double visiting: getTypeAsWritten() returns null for class
1769 // templates/nested classes where the qualifier lives inside the TSI.
1770 if (D->getQualifierLoc())
1771 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1772 if (TypeSourceInfo *TSI = D->getTypeAsWritten())
1773 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
1774 if (auto NumArgs = D->getNumTemplateArgs())
1775 for (unsigned I = 0; I != *NumArgs; ++I)
1776 TRY_TO(TraverseTemplateArgumentLoc(D->getTemplateArg(I)));
1777})
1778
1780 // Code in an unnamed namespace shows up automatically in
1781 // decls_begin()/decls_end(). Thus we don't need to recurse on
1782 // D->getAnonymousNamespace().
1783
1784 // If the traversal scope is set, then consider them to be the children of
1785 // the TUDecl, rather than traversing (and loading?) all top-level decls.
1786 auto Scope = D->getASTContext().getTraversalScope();
1787 bool HasLimitedScope =
1788 Scope.size() != 1 || !isa<TranslationUnitDecl>(Scope.front());
1789 if (HasLimitedScope) {
1790 ShouldVisitChildren = false; // we'll do that here instead
1791 for (auto *Child : Scope) {
1792 if (!canIgnoreChildDeclWhileTraversingDeclContext(Child))
1793 TRY_TO(TraverseDecl(Child));
1794 }
1795 }
1796})
1797
1799
1801
1803
1805 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1806
1807 // We shouldn't traverse an aliased namespace, since it will be
1808 // defined (and, therefore, traversed) somewhere else.
1809 ShouldVisitChildren = false;
1810})
1811
1812DEF_TRAVERSE_DECL(LabelDecl, {// There is no code in a LabelDecl.
1813 })
1814
1817 {// Code in an unnamed namespace shows up automatically in
1818 // decls_begin()/decls_end(). Thus we don't need to recurse on
1819 // D->getAnonymousNamespace().
1820 })
1821
1822DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement
1823 })
1824
1826 if (ObjCTypeParamList *typeParamList = D->getTypeParamList()) {
1827 for (auto typeParam : *typeParamList) {
1828 TRY_TO(TraverseObjCTypeParamDecl(typeParam));
1829 }
1830 }
1831 for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
1832 ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
1833 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1834 }
1835})
1836
1837DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement
1838 })
1839
1840DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement
1841 })
1842
1844 if (ObjCTypeParamList *typeParamList = D->getTypeParamListAsWritten()) {
1845 for (auto typeParam : *typeParamList) {
1846 TRY_TO(TraverseObjCTypeParamDecl(typeParam));
1847 }
1848 }
1849
1850 if (TypeSourceInfo *superTInfo = D->getSuperClassTInfo()) {
1851 TRY_TO(TraverseTypeLoc(superTInfo->getTypeLoc()));
1852 }
1853 if (D->isThisDeclarationADefinition()) {
1854 for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
1855 ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
1856 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1857 }
1858 }
1859})
1860
1862 if (D->isThisDeclarationADefinition()) {
1863 for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
1864 ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
1865 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1866 }
1867 }
1868})
1869
1871 if (D->getReturnTypeSourceInfo()) {
1872 TRY_TO(TraverseTypeLoc(D->getReturnTypeSourceInfo()->getTypeLoc()));
1873 }
1874 for (ParmVarDecl *Parameter : D->parameters()) {
1875 TRY_TO(TraverseDecl(Parameter));
1876 }
1877 if (D->isThisDeclarationADefinition()) {
1878 TRY_TO(TraverseStmt(D->getBody()));
1879 }
1880 ShouldVisitChildren = false;
1881})
1882
1884 if (D->hasExplicitBound()) {
1885 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
1886 // We shouldn't traverse D->getTypeForDecl(); it's a result of
1887 // declaring the type alias, not something that was written in the
1888 // source.
1889 }
1890})
1891
1893 if (D->getTypeSourceInfo())
1894 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
1895 else
1896 TRY_TO(TraverseType(D->getType()));
1897 ShouldVisitChildren = false;
1898})
1899
1901 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1902 TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
1903})
1904
1906 { TRY_TO(TraverseTypeLoc(D->getEnumTypeLoc())); })
1907
1909
1911 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1912})
1913
1915
1917
1919 if (D->getInstantiations() &&
1920 getDerived().shouldVisitTemplateInstantiations())
1921 TRY_TO(TraverseStmt(D->getInstantiations()));
1922
1923 TRY_TO(TraverseStmt(D->getExpansionPattern()));
1924})
1925
1927 for (auto *I : D->varlist()) {
1928 TRY_TO(TraverseStmt(I));
1929 }
1930})
1931
1933 for (auto *I : D->varlist()) {
1934 TRY_TO(TraverseStmt(I));
1935 }
1936})
1937
1939 for (auto *C : D->clauselists()) {
1940 TRY_TO(TraverseOMPClause(C));
1941 }
1942})
1943
1945 TRY_TO(TraverseStmt(D->getCombiner()));
1946 if (auto *Initializer = D->getInitializer())
1947 TRY_TO(TraverseStmt(Initializer));
1948 TRY_TO(TraverseType(D->getType()));
1949 return true;
1950})
1951
1953 for (auto *C : D->clauselists())
1954 TRY_TO(TraverseOMPClause(C));
1955 TRY_TO(TraverseType(D->getType()));
1956 return true;
1957})
1958
1959DEF_TRAVERSE_DECL(OMPCapturedExprDecl, { TRY_TO(TraverseVarHelper(D)); })
1960
1962 for (auto *I : D->varlist())
1963 TRY_TO(TraverseStmt(I));
1964 for (auto *C : D->clauselists())
1965 TRY_TO(TraverseOMPClause(C));
1966})
1967
1969 { TRY_TO(VisitOpenACCClauseList(D->clauses())); })
1970
1972 TRY_TO(TraverseStmt(D->getFunctionReference()));
1973 TRY_TO(VisitOpenACCClauseList(D->clauses()));
1974})
1975
1976// A helper method for TemplateDecl's children.
1977template <typename Derived>
1978bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
1979 TemplateParameterList *TPL) {
1980 if (TPL) {
1981 for (NamedDecl *D : *TPL) {
1982 TRY_TO(TraverseDecl(D));
1983 }
1984 if (Expr *RequiresClause = TPL->getRequiresClause()) {
1985 TRY_TO(TraverseStmt(RequiresClause));
1986 }
1987 }
1988 return true;
1989}
1990
1991template <typename Derived>
1992template <typename T>
1993bool RecursiveASTVisitor<Derived>::TraverseDeclTemplateParameterLists(T *D) {
1994 for (TemplateParameterList *TPL : D->getTemplateParameterLists())
1995 TraverseTemplateParameterListHelper(TPL);
1996 return true;
1997}
1998
1999template <typename Derived>
2001 ClassTemplateDecl *D) {
2002 for (auto *SD : D->specializations()) {
2003 for (auto *RD : SD->redecls()) {
2004 assert(!cast<CXXRecordDecl>(RD)->isInjectedClassName());
2005 switch (
2006 cast<ClassTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
2007 // Visit the implicit instantiations with the requested pattern.
2008 case TSK_Undeclared:
2010 TRY_TO(TraverseDecl(RD));
2011 break;
2012
2013 // We don't need to do anything on an explicit instantiation
2014 // or explicit specialization because there will be an explicit
2015 // node for it elsewhere.
2019 break;
2020 }
2021 }
2022 }
2023
2024 return true;
2025}
2026
2027template <typename Derived>
2029 VarTemplateDecl *D) {
2030 for (auto *SD : D->specializations()) {
2031 for (auto *RD : SD->redecls()) {
2032 switch (
2033 cast<VarTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
2034 case TSK_Undeclared:
2036 TRY_TO(TraverseDecl(RD));
2037 break;
2038
2042 break;
2043 }
2044 }
2045 }
2046
2047 return true;
2048}
2049
2050// A helper method for traversing the instantiations of a
2051// function while skipping its specializations.
2052template <typename Derived>
2055 for (auto *FD : D->specializations()) {
2056 for (auto *RD : FD->redecls()) {
2057 switch (RD->getTemplateSpecializationKind()) {
2058 case TSK_Undeclared:
2060 // We don't know what kind of FunctionDecl this is.
2061 TRY_TO(TraverseDecl(RD));
2062 break;
2063
2064 // Unlike class/variable template specializations, function template
2065 // specializations are not independent children of the DeclContext —
2066 // they are only reachable via FunctionTemplateDecl::specializations().
2067 // We must traverse them here so visitors can see the instantiated body.
2070 TRY_TO(TraverseDecl(RD));
2071 break;
2072
2074 break;
2075 }
2076 }
2077 }
2078
2079 return true;
2080}
2081
2082// This macro unifies the traversal of class, variable and function
2083// template declarations.
2084#define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND) \
2085 DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, { \
2086 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
2087 TRY_TO(TraverseDecl(D->getTemplatedDecl())); \
2088 \
2089 /* By default, we do not traverse the instantiations of \
2090 class templates since they do not appear in the user code. The \
2091 following code optionally traverses them. \
2092 \
2093 We only traverse the class instantiations when we see the canonical \
2094 declaration of the template, to ensure we only visit them once. */ \
2095 if (getDerived().shouldVisitTemplateInstantiations() && \
2096 D == D->getCanonicalDecl()) \
2097 TRY_TO(TraverseTemplateInstantiations(D)); \
2098 \
2099 /* Note that getInstantiatedFromMemberTemplate() is just a link \
2100 from a template instantiation back to the template from which \
2101 it was instantiated, and thus should not be traversed. */ \
2102 })
2103
2107
2109 // D is the "T" in something like
2110 // template <template <typename> class T> class container { };
2111 TRY_TO(TraverseDecl(D->getTemplatedDecl()));
2112 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
2113 TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
2114 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
2115})
2116
2118 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
2119})
2120
2121template <typename Derived>
2122bool RecursiveASTVisitor<Derived>::TraverseTemplateTypeParamDeclConstraints(
2123 const TemplateTypeParmDecl *D) {
2124 if (const auto *TC = D->getTypeConstraint())
2125 TRY_TO(TraverseTypeConstraint(TC));
2126 return true;
2127}
2128
2130 // D is the "T" in something like "template<typename T> class vector;"
2131 if (D->getTypeForDecl())
2132 TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
2133 TRY_TO(TraverseTemplateTypeParamDeclConstraints(D));
2134 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
2135 TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
2136})
2137
2139 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
2140 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2141 // declaring the typedef, not something that was written in the
2142 // source.
2143})
2144
2146 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
2147 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2148 // declaring the type alias, not something that was written in the
2149 // source.
2150})
2151
2153 TRY_TO(TraverseDecl(D->getTemplatedDecl()));
2154 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
2155})
2156
2158 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
2159 TRY_TO(TraverseStmt(D->getConstraintExpr()));
2160})
2161
2163 // A dependent using declaration which was marked with 'typename'.
2164 // template<class T> class A : public B<T> { using typename B<T>::foo; };
2165 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2166 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2167 // declaring the type, not something that was written in the
2168 // source.
2169})
2170
2172
2174 TRY_TO(TraverseDeclTemplateParameterLists(D));
2175
2176 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2177 if (auto *TSI = D->getIntegerTypeSourceInfo())
2178 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
2179 // The enumerators are already traversed by
2180 // decls_begin()/decls_end().
2181})
2182
2183// Helper methods for RecordDecl and its children.
2184template <typename Derived>
2185bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) {
2186 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2187 // declaring the type, not something that was written in the source.
2188
2189 TRY_TO(TraverseDeclTemplateParameterLists(D));
2190 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2191 return true;
2192}
2193
2194template <typename Derived>
2196 const CXXBaseSpecifier &Base) {
2197 TRY_TO(TraverseTypeLoc(Base.getTypeSourceInfo()->getTypeLoc()));
2198 return true;
2199}
2200
2201template <typename Derived>
2202bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(CXXRecordDecl *D) {
2203 if (!TraverseRecordHelper(D))
2204 return false;
2205 if (D->isCompleteDefinition()) {
2206 for (const auto &I : D->bases()) {
2207 TRY_TO(TraverseCXXBaseSpecifier(I));
2208 }
2209 // We don't traverse the friends or the conversions, as they are
2210 // already in decls_begin()/decls_end().
2211 }
2212 return true;
2213}
2214
2215DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); })
2216
2217DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
2218
2219template <typename Derived>
2220bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
2221 const TemplateArgumentLoc *TAL, unsigned Count) {
2222 for (unsigned I = 0; I < Count; ++I) {
2223 TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
2224 }
2225 return true;
2226}
2227
2228#define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
2229 DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, { \
2230 /* For implicit instantiations ("set<int> x;"), we don't want to \
2231 recurse at all, since the instatiated template isn't written in \
2232 the source code anywhere. (Note the instatiated *type* -- \
2233 set<int> -- is written, and will still get a callback of \
2234 TemplateSpecializationType). For explicit instantiations \
2235 ("template set<int>;"), the ExplicitInstantiationDecl node \
2236 handles traversal of template args and qualifier. \
2237 For explicit specializations ("template<> set<int> {...};"), \
2238 we traverse template args here since there is no EID. */ \
2239 if (D->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) { \
2240 const auto *ArgsWritten = D->getTemplateArgsAsWritten(); \
2241 TRY_TO(TraverseTemplateArgumentLocsHelper( \
2242 ArgsWritten->getTemplateArgs(), ArgsWritten->NumTemplateArgs)); \
2243 } else if (!getDerived().shouldVisitTemplateInstantiations()) { \
2244 /* Returning from here skips traversing the \
2245 declaration context of the *TemplateSpecializationDecl \
2246 (embedded in the DEF_TRAVERSE_DECL() macro) \
2247 which contains the instantiated members of the template. */ \
2248 return true; \
2249 } \
2250 \
2251 /* Traverse base definition for explicit specializations */ \
2252 TRY_TO(Traverse##DECLKIND##Helper(D)); \
2253 })
2254
2257
2258#define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
2259 DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, { \
2260 /* The partial specialization. */ \
2261 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
2262 /* The args that remains unspecialized. */ \
2263 TRY_TO(TraverseTemplateArgumentLocsHelper( \
2264 D->getTemplateArgsAsWritten()->getTemplateArgs(), \
2265 D->getTemplateArgsAsWritten()->NumTemplateArgs)); \
2266 \
2267 /* Don't need the *TemplatePartialSpecializationHelper, even \
2268 though that's our parent class -- we already visit all the \
2269 template args here. */ \
2270 TRY_TO(Traverse##DECLKIND##Helper(D)); \
2271 \
2272 /* Instantiations will have been visited with the primary template. */ \
2273 })
2274
2277
2278DEF_TRAVERSE_DECL(EnumConstantDecl, { TRY_TO(TraverseStmt(D->getInitExpr())); })
2279
2281 // Like UnresolvedUsingTypenameDecl, but without the 'typename':
2282 // template <class T> Class A : public Base<T> { using Base<T>::foo; };
2283 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2284 TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
2285})
2286
2288
2289template <typename Derived>
2290bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
2291 TRY_TO(TraverseDeclTemplateParameterLists(D));
2292 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2293 if (D->getTypeSourceInfo())
2294 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
2295 else
2296 TRY_TO(TraverseType(D->getType()));
2297 return true;
2298}
2299
2301 TRY_TO(TraverseVarHelper(D));
2302 for (auto *Binding : D->bindings()) {
2303 TRY_TO(TraverseDecl(Binding));
2304 }
2305})
2306
2308 if (getDerived().shouldVisitImplicitCode()) {
2309 TRY_TO(TraverseStmt(D->getBinding()));
2310 if (const auto HoldingVar = D->getHoldingVar())
2311 TRY_TO(TraverseDecl(HoldingVar));
2312 }
2313})
2314
2315DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
2316
2319
2321
2323 TRY_TO(TraverseDeclaratorHelper(D));
2324 if (D->isBitField())
2325 TRY_TO(TraverseStmt(D->getBitWidth()));
2326 if (D->hasInClassInitializer())
2327 TRY_TO(TraverseStmt(D->getInClassInitializer()));
2328})
2329
2331 TRY_TO(TraverseDeclaratorHelper(D));
2332 if (D->isBitField())
2333 TRY_TO(TraverseStmt(D->getBitWidth()));
2334 // FIXME: implement the rest.
2335})
2336
2338 TRY_TO(TraverseDeclaratorHelper(D));
2339 if (D->isBitField())
2340 TRY_TO(TraverseStmt(D->getBitWidth()));
2341 // FIXME: implement the rest.
2342})
2343
2344template <typename Derived>
2345bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
2346 TRY_TO(TraverseDeclTemplateParameterLists(D));
2347 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2348 TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
2349
2350 // If we're an explicit template specialization, iterate over the
2351 // template args that were explicitly specified. If we were doing
2352 // this in typing order, we'd do it between the return type and
2353 // the function args, but both are handled by the FunctionTypeLoc
2354 // above, so we have to choose one side. I've decided to do before.
2355 if (const FunctionTemplateSpecializationInfo *FTSI =
2356 D->getTemplateSpecializationInfo()) {
2357 if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared &&
2358 FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
2359 // A specialization might not have explicit template arguments if it has
2360 // a templated return type and concrete arguments.
2361 if (const ASTTemplateArgumentListInfo *TALI =
2362 FTSI->TemplateArgumentsAsWritten) {
2363 TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
2364 TALI->NumTemplateArgs));
2365 }
2366 }
2367 } else if (const DependentFunctionTemplateSpecializationInfo *DFSI =
2368 D->getDependentSpecializationInfo()) {
2369 if (const ASTTemplateArgumentListInfo *TALI =
2370 DFSI->TemplateArgumentsAsWritten) {
2371 TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
2372 TALI->NumTemplateArgs));
2373 }
2374 }
2375
2376 // Visit the function type itself, which can be either
2377 // FunctionNoProtoType or FunctionProtoType, or a typedef. This
2378 // also covers the return type and the function parameters,
2379 // including exception specifications.
2380 if (TypeSourceInfo *TSI = D->getTypeSourceInfo()) {
2381 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
2382 } else if (getDerived().shouldVisitImplicitCode()) {
2383 // Visit parameter variable declarations of the implicit function
2384 // if the traverser is visiting implicit code. Parameter variable
2385 // declarations do not have valid TypeSourceInfo, so to visit them
2386 // we need to traverse the declarations explicitly.
2387 for (ParmVarDecl *Parameter : D->parameters()) {
2388 TRY_TO(TraverseDecl(Parameter));
2389 }
2390 }
2391
2392 // Visit the trailing requires clause, if any.
2393 if (const AssociatedConstraint &TrailingRequiresClause =
2394 D->getTrailingRequiresClause()) {
2395 TRY_TO(TraverseStmt(
2396 const_cast<Expr *>(TrailingRequiresClause.ConstraintExpr)));
2397 }
2398
2399 if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
2400 // Constructor initializers.
2401 for (auto *I : Ctor->inits()) {
2402 if (I->isWritten() || getDerived().shouldVisitImplicitCode())
2403 TRY_TO(TraverseConstructorInitializer(I));
2404 }
2405 }
2406
2407 bool VisitBody =
2408 D->isThisDeclarationADefinition() &&
2409 // Don't visit the function body if the function definition is generated
2410 // by clang.
2411 (!D->isDefaulted() || getDerived().shouldVisitImplicitCode());
2412
2413 if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
2414 if (const CXXRecordDecl *RD = MD->getParent()) {
2415 if (RD->isLambda() &&
2416 declaresSameEntity(RD->getLambdaCallOperator(), MD)) {
2417 VisitBody = VisitBody && getDerived().shouldVisitLambdaBody();
2418 }
2419 }
2420 }
2421
2422 if (VisitBody) {
2423 TRY_TO(TraverseStmt(D->getBody()));
2424 // Body may contain using declarations whose shadows are parented to the
2425 // FunctionDecl itself.
2426 for (auto *Child : D->decls()) {
2427 if (isa<UsingShadowDecl>(Child))
2428 TRY_TO(TraverseDecl(Child));
2429 }
2430 }
2431 return true;
2432}
2433
2435 // We skip decls_begin/decls_end, which are already covered by
2436 // TraverseFunctionHelper().
2437 ShouldVisitChildren = false;
2438 ReturnValue = TraverseFunctionHelper(D);
2439})
2440
2442 // We skip decls_begin/decls_end, which are already covered by
2443 // TraverseFunctionHelper().
2444 ShouldVisitChildren = false;
2445 ReturnValue = TraverseFunctionHelper(D);
2446})
2447
2449 // We skip decls_begin/decls_end, which are already covered by
2450 // TraverseFunctionHelper().
2451 ShouldVisitChildren = false;
2452 ReturnValue = TraverseFunctionHelper(D);
2453})
2454
2456 // We skip decls_begin/decls_end, which are already covered by
2457 // TraverseFunctionHelper().
2458 ShouldVisitChildren = false;
2459 ReturnValue = TraverseFunctionHelper(D);
2460})
2461
2462// CXXConversionDecl is the declaration of a type conversion operator.
2463// It's not a cast expression.
2465 // We skip decls_begin/decls_end, which are already covered by
2466 // TraverseFunctionHelper().
2467 ShouldVisitChildren = false;
2468 ReturnValue = TraverseFunctionHelper(D);
2469})
2470
2472 // We skip decls_begin/decls_end, which are already covered by
2473 // TraverseFunctionHelper().
2474 ShouldVisitChildren = false;
2475 ReturnValue = TraverseFunctionHelper(D);
2476})
2477
2478template <typename Derived>
2479bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
2480 TRY_TO(TraverseDeclaratorHelper(D));
2481 // Default params are taken care of when we traverse the ParmVarDecl.
2482 if (!isa<ParmVarDecl>(D) &&
2483 (!D->isCXXForRangeDecl() || getDerived().shouldVisitImplicitCode()))
2484 TRY_TO(TraverseStmt(D->getInit()));
2485 return true;
2486}
2487
2488DEF_TRAVERSE_DECL(VarDecl, { TRY_TO(TraverseVarHelper(D)); })
2489
2490DEF_TRAVERSE_DECL(ImplicitParamDecl, { TRY_TO(TraverseVarHelper(D)); })
2491
2493 // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
2494 TRY_TO(TraverseDeclaratorHelper(D));
2495 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
2496 TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
2497})
2498
2500 TRY_TO(TraverseVarHelper(D));
2501
2502 if (D->hasDefaultArg() && D->hasUninstantiatedDefaultArg() &&
2503 !D->hasUnparsedDefaultArg())
2504 TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
2505
2506 if (D->hasDefaultArg() && !D->hasUninstantiatedDefaultArg() &&
2507 !D->hasUnparsedDefaultArg())
2508 TRY_TO(TraverseStmt(D->getDefaultArg()));
2509})
2510
2512
2514 TRY_TO(TraverseTemplateArguments(D->getTemplateArguments()));
2515})
2516
2517#undef DEF_TRAVERSE_DECL
2518
2519// ----------------- Stmt traversal -----------------
2520//
2521// For stmts, we automate (in the DEF_TRAVERSE_STMT macro) iterating
2522// over the children defined in children() (every stmt defines these,
2523// though sometimes the range is empty). Each individual Traverse*
2524// method only needs to worry about children other than those. To see
2525// what children() does for a given class, see, e.g.,
2526// http://clang.llvm.org/doxygen/Stmt_8cpp_source.html
2527
2528// This macro makes available a variable S, the passed-in stmt.
2529#define DEF_TRAVERSE_STMT(STMT, CODE) \
2530 template <typename Derived> \
2532 STMT *S, DataRecursionQueue *Queue) { \
2533 bool ShouldVisitChildren = true; \
2534 bool ReturnValue = true; \
2535 if (!getDerived().shouldTraversePostOrder()) \
2536 TRY_TO(WalkUpFrom##STMT(S)); \
2537 { CODE; } \
2538 if (ShouldVisitChildren) { \
2539 for (Stmt * SubStmt : getDerived().getStmtChildren(S)) { \
2540 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); \
2541 } \
2542 } \
2543 /* Call WalkUpFrom if TRY_TO_TRAVERSE_OR_ENQUEUE_STMT has traversed the \
2544 * children already. If TRY_TO_TRAVERSE_OR_ENQUEUE_STMT only enqueued the \
2545 * children, PostVisitStmt will call WalkUpFrom after we are done visiting \
2546 * children. */ \
2547 if (!Queue && ReturnValue && getDerived().shouldTraversePostOrder()) { \
2548 TRY_TO(WalkUpFrom##STMT(S)); \
2549 } \
2550 return ReturnValue; \
2551 }
2552
2554 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAsmStringExpr());
2555 for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
2556 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInputConstraintExpr(I));
2557 }
2558 for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
2559 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOutputConstraintExpr(I));
2560 }
2561 for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
2562 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getClobberExpr(I));
2563 }
2564 // children() iterates over inputExpr and outputExpr.
2565})
2566
2568 MSAsmStmt,
2569 {// FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc. Once
2570 // added this needs to be implemented.
2571 })
2572
2574 TRY_TO(TraverseDecl(S->getExceptionDecl()));
2575 // children() iterates over the handler block.
2576})
2577
2579 for (auto *I : S->decls()) {
2580 TRY_TO(TraverseDecl(I));
2581 }
2582 // Suppress the default iteration over children() by
2583 // returning. Here's why: A DeclStmt looks like 'type var [=
2584 // initializer]'. The decls above already traverse over the
2585 // initializers, so we don't have to do it again (which
2586 // children() would do).
2587 ShouldVisitChildren = false;
2588})
2589
2590// These non-expr stmts (most of them), do not need any action except
2591// iterating over the children.
2614
2616 if (!getDerived().shouldVisitImplicitCode()) {
2617 if (S->getInit())
2618 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInit());
2619 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLoopVarStmt());
2620 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRangeInit());
2621 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
2622 // Visit everything else only if shouldVisitImplicitCode().
2623 ShouldVisitChildren = false;
2624 }
2625})
2626
2628 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2629 TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
2630})
2631
2635
2637
2639 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2640 TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
2641 if (S->hasExplicitTemplateArgs()) {
2642 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2643 S->getNumTemplateArgs()));
2644 }
2645})
2646
2648 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2649 TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
2650 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2651 S->getNumTemplateArgs()));
2652})
2653
2655 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2656 TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
2657 if (S->hasExplicitTemplateArgs()) {
2658 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2659 S->getNumTemplateArgs()));
2660 }
2661})
2662
2664 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2665 TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
2666 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2667 S->getNumTemplateArgs()));
2668})
2669
2672 {// We don't traverse the cast type, as it's not written in the
2673 // source code.
2674 })
2675
2677 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2678})
2679
2681 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2682})
2683
2685 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2686})
2687
2689 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2690})
2691
2693 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2694})
2695
2697 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2698})
2699
2701 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2702})
2703
2705 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2706})
2707
2708template <typename Derived>
2710 InitListExpr *S, DataRecursionQueue *Queue) {
2711 if (S) {
2712 // Skip this if we traverse postorder. We will visit it later
2713 // in PostVisitStmt.
2714 if (!getDerived().shouldTraversePostOrder())
2715 TRY_TO(WalkUpFromInitListExpr(S));
2716
2717 // All we need are the default actions. FIXME: use a helper function.
2718 for (Stmt *SubStmt : S->children()) {
2720 }
2721
2722 if (!Queue && getDerived().shouldTraversePostOrder())
2723 TRY_TO(WalkUpFromInitListExpr(S));
2724 }
2725 return true;
2726}
2727
2728template <typename Derived>
2730 ObjCProtocolLoc ProtocolLoc) {
2731 return true;
2732}
2733
2734template <typename Derived>
2736 ConceptReference *CR) {
2737 if (!getDerived().shouldTraversePostOrder())
2738 TRY_TO(VisitConceptReference(CR));
2739 TRY_TO(TraverseNestedNameSpecifierLoc(CR->getNestedNameSpecifierLoc()));
2740 TRY_TO(TraverseDeclarationNameInfo(CR->getConceptNameInfo()));
2741 if (CR->hasExplicitTemplateArgs())
2742 TRY_TO(TraverseTemplateArgumentLocsHelper(
2743 CR->getTemplateArgsAsWritten()->getTemplateArgs(),
2744 CR->getTemplateArgsAsWritten()->NumTemplateArgs));
2745 if (getDerived().shouldTraversePostOrder())
2746 TRY_TO(VisitConceptReference(CR));
2747 return true;
2748}
2749
2750template <typename Derived>
2752 const OffsetOfNode *Node) {
2753 TRY_TO(VisitOffsetOfNode(Node));
2754 return true;
2755}
2756
2757// If shouldVisitImplicitCode() returns false, this method traverses only the
2758// syntactic form of InitListExpr.
2759// If shouldVisitImplicitCode() return true, this method is called once for
2760// each pair of syntactic and semantic InitListExpr, and it traverses the
2761// subtrees defined by the two forms. This may cause some of the children to be
2762// visited twice, if they appear both in the syntactic and the semantic form.
2763//
2764// There is no guarantee about which form \p S takes when this method is called.
2765template <typename Derived>
2767 InitListExpr *S, DataRecursionQueue *Queue) {
2768 if (S->isSemanticForm() && S->isSyntacticForm()) {
2769 // `S` does not have alternative forms, traverse only once.
2770 TRY_TO(TraverseSynOrSemInitListExpr(S, Queue));
2771 return true;
2772 }
2773 TRY_TO(TraverseSynOrSemInitListExpr(
2774 S->isSemanticForm() ? S->getSyntacticForm() : S, Queue));
2775 if (getDerived().shouldVisitImplicitCode()) {
2776 // Only visit the semantic form if the clients are interested in implicit
2777 // compiler-generated.
2778 TRY_TO(TraverseSynOrSemInitListExpr(
2779 S->isSemanticForm() ? S : S->getSemanticForm(), Queue));
2780 }
2781 return true;
2782}
2783
2784// GenericSelectionExpr is a special case because the types and expressions
2785// are interleaved. We also need to watch out for null types (default
2786// generic associations).
2788 if (S->isExprPredicate())
2789 TRY_TO(TraverseStmt(S->getControllingExpr()));
2790 else
2791 TRY_TO(TraverseTypeLoc(S->getControllingType()->getTypeLoc()));
2792
2793 for (const GenericSelectionExpr::Association Assoc : S->associations()) {
2794 if (TypeSourceInfo *TSI = Assoc.getTypeSourceInfo())
2795 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
2796 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(Assoc.getAssociationExpr());
2797 }
2798 ShouldVisitChildren = false;
2799})
2800
2801// PseudoObjectExpr is a special case because of the weirdness with
2802// syntactic expressions and opaque values.
2804 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getSyntacticForm());
2805 for (PseudoObjectExpr::semantics_iterator i = S->semantics_begin(),
2806 e = S->semantics_end();
2807 i != e; ++i) {
2808 Expr *sub = *i;
2809 if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub))
2810 sub = OVE->getSourceExpr();
2812 }
2813 ShouldVisitChildren = false;
2814})
2815
2817 // This is called for code like 'return T()' where T is a built-in
2818 // (i.e. non-class) type.
2819 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2820})
2821
2823 // The child-iterator will pick up the other arguments.
2824 TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc()));
2825})
2826
2828 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2829 // Visit each designator component (e.g. the `a`, `b`, `c` in
2830 // offsetof(Foo, a.b.c)). Array index expressions are reached through the
2831 // child-iterator, which DEF_TRAVERSE_STMT walks automatically.
2832 for (unsigned I = 0, E = S->getNumComponents(); I != E; ++I)
2833 TRY_TO(TraverseOffsetOfNode(&S->getComponent(I)));
2834})
2835
2837 // The child-iterator will pick up the arg if it's an expression,
2838 // but not if it's a type.
2839 if (S->isArgumentType())
2840 TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
2841})
2842
2844 // The child-iterator will pick up the arg if it's an expression,
2845 // but not if it's a type.
2846 if (S->isTypeOperand())
2847 TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
2848})
2849
2851 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2852})
2853
2855
2857 // The child-iterator will pick up the arg if it's an expression,
2858 // but not if it's a type.
2859 if (S->isTypeOperand())
2860 TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
2861})
2862
2864 for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
2865 TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc()));
2866})
2867
2869 TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
2870})
2871
2873 { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getQueriedExpression()); })
2874
2876 // The child-iterator will pick up the expression argument.
2877 TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
2878})
2879
2881 // This is called for code like 'return T()' where T is a class type.
2882 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2883})
2884
2885// Walk only the visible parts of lambda expressions.
2887 // Visit the capture list.
2888 for (unsigned I = 0, N = S->capture_size(); I != N; ++I) {
2889 const LambdaCapture *C = S->capture_begin() + I;
2890 if (C->isExplicit() || getDerived().shouldVisitImplicitCode()) {
2891 TRY_TO(TraverseLambdaCapture(S, C, S->capture_init_begin()[I]));
2892 }
2893 }
2894
2895 if (getDerived().shouldVisitImplicitCode()) {
2896 // The implicit model is simple: everything else is in the lambda class.
2897 TRY_TO(TraverseDecl(S->getLambdaClass()));
2898 } else {
2899 // We need to poke around to find the bits that might be explicitly written.
2900 TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2902
2903 TRY_TO(TraverseTemplateParameterListHelper(S->getTemplateParameterList()));
2904 if (S->hasExplicitParameters()) {
2905 // Visit parameters.
2906 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2907 TRY_TO(TraverseDecl(Proto.getParam(I)));
2908 }
2909
2910 auto *T = Proto.getTypePtr();
2911 for (const auto &E : T->exceptions())
2912 TRY_TO(TraverseType(E));
2913
2914 if (Expr *NE = T->getNoexceptExpr())
2916
2917 if (S->hasExplicitResultType())
2918 TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
2920 const_cast<Expr *>(S->getTrailingRequiresClause().ConstraintExpr));
2921
2922 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
2923 }
2924 ShouldVisitChildren = false;
2925})
2926
2928 // This is called for code like 'T()', where T is a template argument.
2929 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2930})
2931
2933
2934// These expressions all might take explicit template arguments.
2935// We traverse those if so. FIXME: implement these.
2939
2940// These exprs (most of them), do not need any action except iterating
2941// over the children.
2949
2951 TRY_TO(TraverseDecl(S->getBlockDecl()));
2952 return true; // no child statements to loop through.
2953})
2954
2957 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2958})
2961
2963 if (getDerived().shouldVisitImplicitCode())
2964 TRY_TO(TraverseStmt(S->getExpr()));
2965})
2966
2968 if (getDerived().shouldVisitImplicitCode())
2969 TRY_TO(TraverseStmt(S->getExpr()));
2970})
2971
2977
2979 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2980 if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
2981 TRY_TO(TraverseTypeLoc(ScopeInfo->getTypeLoc()));
2982 if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo())
2983 TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc()));
2984})
2985
2997 // FIXME: The source expression of the OVE should be listed as
2998 // a child of the ArrayInitLoopExpr.
2999 if (OpaqueValueExpr *OVE = S->getCommonExpr())
3000 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(OVE->getSourceExpr());
3001})
3004
3006 if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
3007 TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
3008})
3009
3012
3014 if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo())
3015 TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
3016})
3017
3019 if (S->isClassReceiver()) {
3020 ObjCInterfaceDecl *IDecl = S->getClassReceiver();
3021 QualType Type = IDecl->getASTContext().getObjCInterfaceType(IDecl);
3023 Data.NameLoc = S->getReceiverLocation();
3024 Data.NameEndLoc = Data.NameLoc;
3025 TRY_TO(TraverseTypeLoc(TypeLoc(Type, &Data)));
3026 }
3027})
3032
3034 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
3035})
3036
3041 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
3042})
3044 if (getDerived().shouldVisitImplicitCode()) {
3045 TRY_TO(TraverseStmt(S->getOriginalStmt()));
3046 TRY_TO(TraverseStmt(S->getKernelLaunchIdExpr()));
3047 ShouldVisitChildren = false;
3048 }
3049})
3057 for (IntegerLiteral *IL : S->underlying_data_elements()) {
3059 }
3060})
3061
3063 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
3064 if (S->hasExplicitTemplateArgs()) {
3065 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
3066 S->getNumTemplateArgs()));
3067 }
3068})
3069
3071 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
3072 if (S->hasExplicitTemplateArgs()) {
3073 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
3074 S->getNumTemplateArgs()));
3075 }
3076})
3077
3082DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
3083
3085 if (getDerived().shouldVisitImplicitCode()) {
3086 TRY_TO(TraverseStmt(S->getOriginalStmt()));
3087 TRY_TO(TraverseStmt(S->getKernelLaunchStmt()));
3088 TRY_TO(TraverseDecl(S->getOutlinedFunctionDecl()));
3089 ShouldVisitChildren = false;
3090 }
3091})
3092
3095 if (!getDerived().shouldVisitImplicitCode()) {
3097 S->getDecomposedForm();
3098 TRY_TO(TraverseStmt(const_cast<Expr*>(Decomposed.LHS)));
3099 TRY_TO(TraverseStmt(const_cast<Expr*>(Decomposed.RHS)));
3100 ShouldVisitChildren = false;
3101 }
3102})
3106
3107// These operators (all of them) do not need any action except
3108// iterating over the children.
3124
3126 if (S->getLifetimeExtendedTemporaryDecl()) {
3127 TRY_TO(TraverseLifetimeExtendedTemporaryDecl(
3128 S->getLifetimeExtendedTemporaryDecl()));
3129 ShouldVisitChildren = false;
3130 }
3131})
3132// For coroutines expressions, traverse either the operand
3133// as written or the implied calls, depending on what the
3134// derived class requests.
3136 if (!getDerived().shouldVisitImplicitCode()) {
3137 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
3138 ShouldVisitChildren = false;
3139 }
3140})
3142 if (!getDerived().shouldVisitImplicitCode()) {
3143 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
3144 ShouldVisitChildren = false;
3145 }
3146})
3148 if (!getDerived().shouldVisitImplicitCode()) {
3149 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
3150 ShouldVisitChildren = false;
3151 }
3152})
3154 if (!getDerived().shouldVisitImplicitCode()) {
3155 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
3156 ShouldVisitChildren = false;
3157 }
3158})
3160 if (!getDerived().shouldVisitImplicitCode()) {
3161 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
3162 ShouldVisitChildren = false;
3163 }
3164})
3165
3167 TRY_TO(TraverseConceptReference(S->getConceptReference()));
3168})
3169
3171 TRY_TO(TraverseDecl(S->getBody()));
3172 for (ParmVarDecl *Parm : S->getLocalParameters())
3173 TRY_TO(TraverseDecl(Parm));
3174 for (concepts::Requirement *Req : S->getRequirements())
3175 TRY_TO(TraverseConceptRequirement(Req));
3176})
3177
3181
3182// These literals (all of them) do not need any action.
3193
3194// Traverse OpenCL: AsType, Convert.
3196
3197// OpenMP directives.
3198template <typename Derived>
3199bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
3200 OMPExecutableDirective *S) {
3201 for (auto *C : S->clauses()) {
3202 TRY_TO(TraverseOMPClause(C));
3203 }
3204 return true;
3205}
3206
3207DEF_TRAVERSE_STMT(OMPCanonicalLoop, {
3208 if (!getDerived().shouldVisitImplicitCode()) {
3209 // Visit only the syntactical loop.
3210 TRY_TO(TraverseStmt(S->getLoopStmt()));
3211 ShouldVisitChildren = false;
3212 }
3213})
3214
3215template <typename Derived>
3216bool
3217RecursiveASTVisitor<Derived>::TraverseOMPLoopDirective(OMPLoopDirective *S) {
3218 return TraverseOMPExecutableDirective(S);
3219}
3220
3221DEF_TRAVERSE_STMT(OMPMetaDirective,
3222 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3223
3224DEF_TRAVERSE_STMT(OMPParallelDirective,
3225 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3226
3227DEF_TRAVERSE_STMT(OMPSimdDirective,
3228 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3229
3230DEF_TRAVERSE_STMT(OMPTileDirective,
3231 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3232
3233DEF_TRAVERSE_STMT(OMPStripeDirective,
3234 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3235
3236DEF_TRAVERSE_STMT(OMPUnrollDirective,
3237 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3238
3239DEF_TRAVERSE_STMT(OMPReverseDirective,
3240 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3241
3242DEF_TRAVERSE_STMT(OMPFuseDirective,
3243 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3244
3245DEF_TRAVERSE_STMT(OMPInterchangeDirective,
3246 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3247
3248DEF_TRAVERSE_STMT(OMPSplitDirective,
3249 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3250
3251DEF_TRAVERSE_STMT(OMPForDirective,
3252 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3253
3254DEF_TRAVERSE_STMT(OMPForSimdDirective,
3255 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3256
3257DEF_TRAVERSE_STMT(OMPSectionsDirective,
3258 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3259
3260DEF_TRAVERSE_STMT(OMPSectionDirective,
3261 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3262
3263DEF_TRAVERSE_STMT(OMPScopeDirective,
3264 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3265
3266DEF_TRAVERSE_STMT(OMPSingleDirective,
3267 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3268
3269DEF_TRAVERSE_STMT(OMPMasterDirective,
3270 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3271
3272DEF_TRAVERSE_STMT(OMPCriticalDirective, {
3273 TRY_TO(TraverseDeclarationNameInfo(S->getDirectiveName()));
3274 TRY_TO(TraverseOMPExecutableDirective(S));
3275})
3276
3277DEF_TRAVERSE_STMT(OMPParallelForDirective,
3278 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3279
3280DEF_TRAVERSE_STMT(OMPParallelForSimdDirective,
3281 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3282
3283DEF_TRAVERSE_STMT(OMPParallelMasterDirective,
3284 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3285
3286DEF_TRAVERSE_STMT(OMPParallelMaskedDirective,
3287 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3288
3289DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
3290 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3291
3292DEF_TRAVERSE_STMT(OMPTaskDirective,
3293 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3294
3295DEF_TRAVERSE_STMT(OMPTaskyieldDirective,
3296 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3297
3298DEF_TRAVERSE_STMT(OMPBarrierDirective,
3299 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3300
3301DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
3302 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3303
3304DEF_TRAVERSE_STMT(OMPTaskgroupDirective,
3305 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3306
3307DEF_TRAVERSE_STMT(OMPCancellationPointDirective,
3308 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3309
3310DEF_TRAVERSE_STMT(OMPCancelDirective,
3311 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3312
3313DEF_TRAVERSE_STMT(OMPFlushDirective,
3314 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3315
3316DEF_TRAVERSE_STMT(OMPDepobjDirective,
3317 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3318
3319DEF_TRAVERSE_STMT(OMPScanDirective,
3320 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3321
3322DEF_TRAVERSE_STMT(OMPOrderedDirective,
3323 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3324
3325DEF_TRAVERSE_STMT(OMPAtomicDirective,
3326 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3327
3328DEF_TRAVERSE_STMT(OMPTargetDirective,
3329 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3330
3331DEF_TRAVERSE_STMT(OMPTargetDataDirective,
3332 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3333
3334DEF_TRAVERSE_STMT(OMPTargetEnterDataDirective,
3335 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3336
3337DEF_TRAVERSE_STMT(OMPTargetExitDataDirective,
3338 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3339
3340DEF_TRAVERSE_STMT(OMPTargetParallelDirective,
3341 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3342
3343DEF_TRAVERSE_STMT(OMPTargetParallelForDirective,
3344 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3345
3346DEF_TRAVERSE_STMT(OMPTeamsDirective,
3347 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3348
3349DEF_TRAVERSE_STMT(OMPTargetUpdateDirective,
3350 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3351
3352DEF_TRAVERSE_STMT(OMPTaskLoopDirective,
3353 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3354
3355DEF_TRAVERSE_STMT(OMPTaskLoopSimdDirective,
3356 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3357
3358DEF_TRAVERSE_STMT(OMPMasterTaskLoopDirective,
3359 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3360
3361DEF_TRAVERSE_STMT(OMPMasterTaskLoopSimdDirective,
3362 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3363
3364DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopDirective,
3365 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3366
3367DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopSimdDirective,
3368 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3369
3370DEF_TRAVERSE_STMT(OMPMaskedTaskLoopDirective,
3371 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3372
3373DEF_TRAVERSE_STMT(OMPMaskedTaskLoopSimdDirective,
3374 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3375
3376DEF_TRAVERSE_STMT(OMPParallelMaskedTaskLoopDirective,
3377 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3378
3379DEF_TRAVERSE_STMT(OMPParallelMaskedTaskLoopSimdDirective,
3380 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3381
3382DEF_TRAVERSE_STMT(OMPDistributeDirective,
3383 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3384
3385DEF_TRAVERSE_STMT(OMPDistributeParallelForDirective,
3386 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3387
3388DEF_TRAVERSE_STMT(OMPDistributeParallelForSimdDirective,
3389 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3390
3391DEF_TRAVERSE_STMT(OMPDistributeSimdDirective,
3392 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3393
3394DEF_TRAVERSE_STMT(OMPTargetParallelForSimdDirective,
3395 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3396
3397DEF_TRAVERSE_STMT(OMPTargetSimdDirective,
3398 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3399
3400DEF_TRAVERSE_STMT(OMPTeamsDistributeDirective,
3401 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3402
3403DEF_TRAVERSE_STMT(OMPTeamsDistributeSimdDirective,
3404 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3405
3406DEF_TRAVERSE_STMT(OMPTeamsDistributeParallelForSimdDirective,
3407 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3408
3409DEF_TRAVERSE_STMT(OMPTeamsDistributeParallelForDirective,
3410 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3411
3412DEF_TRAVERSE_STMT(OMPTargetTeamsDirective,
3413 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3414
3415DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeDirective,
3416 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3417
3418DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForDirective,
3419 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3420
3421DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForSimdDirective,
3422 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3423
3424DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeSimdDirective,
3425 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3426
3427DEF_TRAVERSE_STMT(OMPInteropDirective,
3428 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3429
3430DEF_TRAVERSE_STMT(OMPDispatchDirective,
3431 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3432
3433DEF_TRAVERSE_STMT(OMPMaskedDirective,
3434 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3435
3436DEF_TRAVERSE_STMT(OMPGenericLoopDirective,
3437 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3438
3439DEF_TRAVERSE_STMT(OMPTeamsGenericLoopDirective,
3440 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3441
3442DEF_TRAVERSE_STMT(OMPTargetTeamsGenericLoopDirective,
3443 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3444
3445DEF_TRAVERSE_STMT(OMPParallelGenericLoopDirective,
3446 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3447
3448DEF_TRAVERSE_STMT(OMPTargetParallelGenericLoopDirective,
3449 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3450
3451DEF_TRAVERSE_STMT(OMPAssumeDirective,
3452 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3453
3454DEF_TRAVERSE_STMT(OMPErrorDirective,
3455 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3456
3457// OpenMP clauses.
3458template <typename Derived>
3459bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
3460 if (!C)
3461 return true;
3462 switch (C->getClauseKind()) {
3463#define GEN_CLANG_CLAUSE_CLASS
3464#define CLAUSE_CLASS(Enum, Str, Class) \
3465 case llvm::omp::Clause::Enum: \
3466 TRY_TO(Visit##Class(static_cast<Class *>(C))); \
3467 break;
3468#define CLAUSE_NO_CLASS(Enum, Str) \
3469 case llvm::omp::Clause::Enum: \
3470 break;
3471#include "llvm/Frontend/OpenMP/OMP.inc"
3472 }
3473 return true;
3474}
3475
3476template <typename Derived>
3477bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPreInit(
3478 OMPClauseWithPreInit *Node) {
3479 TRY_TO(TraverseStmt(Node->getPreInitStmt()));
3480 return true;
3481}
3482
3483template <typename Derived>
3484bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPostUpdate(
3486 TRY_TO(VisitOMPClauseWithPreInit(Node));
3487 TRY_TO(TraverseStmt(Node->getPostUpdateExpr()));
3488 return true;
3489}
3490
3491template <typename Derived>
3494 TRY_TO(TraverseStmt(C->getAllocator()));
3495 return true;
3496}
3497
3498template <typename Derived>
3500 TRY_TO(TraverseStmt(C->getAllocator()));
3501 TRY_TO(VisitOMPClauseList(C));
3502 return true;
3503}
3504
3505template <typename Derived>
3507 TRY_TO(VisitOMPClauseWithPreInit(C));
3508 TRY_TO(TraverseStmt(C->getCondition()));
3509 return true;
3510}
3511
3512template <typename Derived>
3514 TRY_TO(VisitOMPClauseWithPreInit(C));
3515 TRY_TO(TraverseStmt(C->getCondition()));
3516 return true;
3517}
3518
3519template <typename Derived>
3520bool
3522 TRY_TO(VisitOMPClauseWithPreInit(C));
3523 TRY_TO(TraverseStmt(C->getNumThreads()));
3524 return true;
3525}
3526
3527template <typename Derived>
3529 TRY_TO(TraverseStmt(C->getAlignment()));
3530 return true;
3531}
3532
3533template <typename Derived>
3535 TRY_TO(TraverseStmt(C->getSafelen()));
3536 return true;
3537}
3538
3539template <typename Derived>
3541 TRY_TO(TraverseStmt(C->getSimdlen()));
3542 return true;
3543}
3544
3545template <typename Derived>
3547 for (Expr *E : C->getSizesRefs())
3548 TRY_TO(TraverseStmt(E));
3549 return true;
3550}
3551
3552template <typename Derived>
3554 for (Expr *E : C->getCountsRefs())
3555 TRY_TO(TraverseStmt(E));
3556 return true;
3557}
3558
3559template <typename Derived>
3562 for (Expr *E : C->getArgsRefs())
3563 TRY_TO(TraverseStmt(E));
3564 return true;
3565}
3566
3567template <typename Derived>
3569 return true;
3570}
3571
3572template <typename Derived>
3575 TRY_TO(TraverseStmt(C->getFirst()));
3576 TRY_TO(TraverseStmt(C->getCount()));
3577 return true;
3578}
3579
3580template <typename Derived>
3582 TRY_TO(TraverseStmt(C->getFactor()));
3583 return true;
3584}
3585
3586template <typename Derived>
3587bool
3589 TRY_TO(TraverseStmt(C->getNumForLoops()));
3590 return true;
3591}
3592
3593template <typename Derived>
3595 return true;
3596}
3597
3598template <typename Derived>
3601 return true;
3602}
3603
3604template <typename Derived>
3606 OMPTransparentClause *C) {
3607 TRY_TO(TraverseStmt(C->getImpexType()));
3608 return true;
3609}
3610
3611template <typename Derived>
3613 return true;
3614}
3615
3616template <typename Derived>
3618 OMPUnifiedAddressClause *) {
3619 return true;
3620}
3621
3622template <typename Derived>
3624 OMPUnifiedSharedMemoryClause *) {
3625 return true;
3626}
3627
3628template <typename Derived>
3630 OMPReverseOffloadClause *) {
3631 return true;
3632}
3633
3634template <typename Derived>
3636 OMPDynamicAllocatorsClause *) {
3637 return true;
3638}
3639
3640template <typename Derived>
3642 OMPAtomicDefaultMemOrderClause *) {
3643 return true;
3644}
3645
3646template <typename Derived>
3648 return true;
3649}
3650
3651template <typename Derived>
3653 return true;
3654}
3655
3656template <typename Derived>
3658 return true;
3659}
3660
3661template <typename Derived>
3663 TRY_TO(TraverseStmt(C->getMessageString()));
3664 return true;
3665}
3666
3667template <typename Derived>
3668bool
3670 TRY_TO(VisitOMPClauseWithPreInit(C));
3671 TRY_TO(TraverseStmt(C->getChunkSize()));
3672 return true;
3673}
3674
3675template <typename Derived>
3677 TRY_TO(TraverseStmt(C->getNumForLoops()));
3678 return true;
3679}
3680
3681template <typename Derived>
3683 TRY_TO(TraverseStmt(C->getCondition()));
3684 return true;
3685}
3686
3687template <typename Derived>
3689 return true;
3690}
3691
3692template <typename Derived>
3693bool
3695 return true;
3696}
3697
3698template <typename Derived>
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 return true;
3721}
3722
3723template <typename Derived>
3725 return true;
3726}
3727
3728template <typename Derived>
3730 return true;
3731}
3732
3733template <typename Derived>
3735 return true;
3736}
3737
3738template <typename Derived>
3740 return true;
3741}
3742
3743template <typename Derived>
3745 return true;
3746}
3747
3748template <typename Derived>
3750 return true;
3751}
3752
3753template <typename Derived>
3755 return true;
3756}
3757
3758template <typename Derived>
3760 OMPNoOpenMPRoutinesClause *) {
3761 return true;
3762}
3763
3764template <typename Derived>
3766 OMPNoOpenMPConstructsClause *) {
3767 return true;
3768}
3769
3770template <typename Derived>
3772 OMPNoParallelismClause *) {
3773 return true;
3774}
3775
3776template <typename Derived>
3778 return true;
3779}
3780
3781template <typename Derived>
3783 return true;
3784}
3785
3786template <typename Derived>
3788 return true;
3789}
3790
3791template <typename Derived>
3793 return true;
3794}
3795
3796template <typename Derived>
3798 return true;
3799}
3800
3801template <typename Derived>
3803 return true;
3804}
3805
3806template <typename Derived>
3808 return true;
3809}
3810
3811template <typename Derived>
3813 TRY_TO(VisitOMPClauseList(C));
3814 // VisitOMPClauseList covers the interop var and the per-pref-spec fr exprs
3815 // (the varlist); the prefer_type attr() exprs live outside it.
3816 for (Expr *A : C->attrs())
3817 TRY_TO(TraverseStmt(A));
3818 return true;
3819}
3820
3821template <typename Derived>
3823 TRY_TO(TraverseStmt(C->getInteropVar()));
3824 return true;
3825}
3826
3827template <typename Derived>
3829 TRY_TO(TraverseStmt(C->getInteropVar()));
3830 return true;
3831}
3832
3833template <typename Derived>
3835 OMPNovariantsClause *C) {
3836 TRY_TO(VisitOMPClauseWithPreInit(C));
3837 TRY_TO(TraverseStmt(C->getCondition()));
3838 return true;
3839}
3840
3841template <typename Derived>
3843 OMPNocontextClause *C) {
3844 TRY_TO(VisitOMPClauseWithPreInit(C));
3845 TRY_TO(TraverseStmt(C->getCondition()));
3846 return true;
3847}
3848
3849template <typename Derived>
3850template <typename T>
3851bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
3852 for (auto *E : Node->varlist()) {
3853 TRY_TO(TraverseStmt(E));
3854 }
3855 return true;
3856}
3857
3858template <typename Derived>
3860 OMPInclusiveClause *C) {
3861 TRY_TO(VisitOMPClauseList(C));
3862 return true;
3863}
3864
3865template <typename Derived>
3867 OMPExclusiveClause *C) {
3868 TRY_TO(VisitOMPClauseList(C));
3869 return true;
3870}
3871
3872template <typename Derived>
3874 TRY_TO(VisitOMPClauseList(C));
3875 for (auto *E : C->private_copies()) {
3876 TRY_TO(TraverseStmt(E));
3877 }
3878 return true;
3879}
3880
3881template <typename Derived>
3883 OMPFirstprivateClause *C) {
3884 TRY_TO(VisitOMPClauseList(C));
3885 TRY_TO(VisitOMPClauseWithPreInit(C));
3886 for (auto *E : C->private_copies()) {
3887 TRY_TO(TraverseStmt(E));
3888 }
3889 for (auto *E : C->inits()) {
3890 TRY_TO(TraverseStmt(E));
3891 }
3892 return true;
3893}
3894
3895template <typename Derived>
3897 OMPLastprivateClause *C) {
3898 TRY_TO(VisitOMPClauseList(C));
3899 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3900 for (auto *E : C->private_copies()) {
3901 TRY_TO(TraverseStmt(E));
3902 }
3903 for (auto *E : C->source_exprs()) {
3904 TRY_TO(TraverseStmt(E));
3905 }
3906 for (auto *E : C->destination_exprs()) {
3907 TRY_TO(TraverseStmt(E));
3908 }
3909 for (auto *E : C->assignment_ops()) {
3910 TRY_TO(TraverseStmt(E));
3911 }
3912 return true;
3913}
3914
3915template <typename Derived>
3917 TRY_TO(VisitOMPClauseList(C));
3918 return true;
3919}
3920
3921template <typename Derived>
3923 TRY_TO(TraverseStmt(C->getStep()));
3924 TRY_TO(TraverseStmt(C->getCalcStep()));
3925 TRY_TO(VisitOMPClauseList(C));
3926 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3927 for (auto *E : C->privates()) {
3928 TRY_TO(TraverseStmt(E));
3929 }
3930 for (auto *E : C->inits()) {
3931 TRY_TO(TraverseStmt(E));
3932 }
3933 for (auto *E : C->updates()) {
3934 TRY_TO(TraverseStmt(E));
3935 }
3936 for (auto *E : C->finals()) {
3937 TRY_TO(TraverseStmt(E));
3938 }
3939 return true;
3940}
3941
3942template <typename Derived>
3944 TRY_TO(TraverseStmt(C->getAlignment()));
3945 TRY_TO(VisitOMPClauseList(C));
3946 return true;
3947}
3948
3949template <typename Derived>
3951 TRY_TO(VisitOMPClauseList(C));
3952 for (auto *E : C->source_exprs()) {
3953 TRY_TO(TraverseStmt(E));
3954 }
3955 for (auto *E : C->destination_exprs()) {
3956 TRY_TO(TraverseStmt(E));
3957 }
3958 for (auto *E : C->assignment_ops()) {
3959 TRY_TO(TraverseStmt(E));
3960 }
3961 return true;
3962}
3963
3964template <typename Derived>
3966 OMPCopyprivateClause *C) {
3967 TRY_TO(VisitOMPClauseList(C));
3968 for (auto *E : C->source_exprs()) {
3969 TRY_TO(TraverseStmt(E));
3970 }
3971 for (auto *E : C->destination_exprs()) {
3972 TRY_TO(TraverseStmt(E));
3973 }
3974 for (auto *E : C->assignment_ops()) {
3975 TRY_TO(TraverseStmt(E));
3976 }
3977 return true;
3978}
3979
3980template <typename Derived>
3981bool
3983 TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
3984 TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
3985 TRY_TO(VisitOMPClauseList(C));
3986 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3987 for (auto *E : C->privates()) {
3988 TRY_TO(TraverseStmt(E));
3989 }
3990 for (auto *E : C->lhs_exprs()) {
3991 TRY_TO(TraverseStmt(E));
3992 }
3993 for (auto *E : C->rhs_exprs()) {
3994 TRY_TO(TraverseStmt(E));
3995 }
3996 for (auto *E : C->reduction_ops()) {
3997 TRY_TO(TraverseStmt(E));
3998 }
3999 if (C->getModifier() == OMPC_REDUCTION_inscan) {
4000 for (auto *E : C->copy_ops()) {
4001 TRY_TO(TraverseStmt(E));
4002 }
4003 for (auto *E : C->copy_array_temps()) {
4004 TRY_TO(TraverseStmt(E));
4005 }
4006 for (auto *E : C->copy_array_elems()) {
4007 TRY_TO(TraverseStmt(E));
4008 }
4009 }
4010 return true;
4011}
4012
4013template <typename Derived>
4015 OMPTaskReductionClause *C) {
4016 TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
4017 TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
4018 TRY_TO(VisitOMPClauseList(C));
4019 TRY_TO(VisitOMPClauseWithPostUpdate(C));
4020 for (auto *E : C->privates()) {
4021 TRY_TO(TraverseStmt(E));
4022 }
4023 for (auto *E : C->lhs_exprs()) {
4024 TRY_TO(TraverseStmt(E));
4025 }
4026 for (auto *E : C->rhs_exprs()) {
4027 TRY_TO(TraverseStmt(E));
4028 }
4029 for (auto *E : C->reduction_ops()) {
4030 TRY_TO(TraverseStmt(E));
4031 }
4032 return true;
4033}
4034
4035template <typename Derived>
4037 OMPInReductionClause *C) {
4038 TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
4039 TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
4040 TRY_TO(VisitOMPClauseList(C));
4041 TRY_TO(VisitOMPClauseWithPostUpdate(C));
4042 for (auto *E : C->privates()) {
4043 TRY_TO(TraverseStmt(E));
4044 }
4045 for (auto *E : C->lhs_exprs()) {
4046 TRY_TO(TraverseStmt(E));
4047 }
4048 for (auto *E : C->rhs_exprs()) {
4049 TRY_TO(TraverseStmt(E));
4050 }
4051 for (auto *E : C->reduction_ops()) {
4052 TRY_TO(TraverseStmt(E));
4053 }
4054 for (auto *E : C->taskgroup_descriptors())
4055 TRY_TO(TraverseStmt(E));
4056 return true;
4057}
4058
4059template <typename Derived>
4061 TRY_TO(VisitOMPClauseList(C));
4062 return true;
4063}
4064
4065template <typename Derived>
4067 TRY_TO(TraverseStmt(C->getDepobj()));
4068 return true;
4069}
4070
4071template <typename Derived>
4073 TRY_TO(VisitOMPClauseList(C));
4074 return true;
4075}
4076
4077template <typename Derived>
4079 TRY_TO(VisitOMPClauseWithPreInit(C));
4080 TRY_TO(TraverseStmt(C->getDevice()));
4081 return true;
4082}
4083
4084template <typename Derived>
4086 TRY_TO(VisitOMPClauseList(C));
4087 return true;
4088}
4089
4090template <typename Derived>
4092 OMPNumTeamsClause *C) {
4093 if (auto *E = C->getModifierExpr())
4094 TRY_TO(VisitStmt(E));
4095 TRY_TO(VisitOMPClauseList(C));
4096 TRY_TO(VisitOMPClauseWithPreInit(C));
4097 return true;
4098}
4099
4100template <typename Derived>
4102 OMPThreadLimitClause *C) {
4103 if (auto *E = C->getModifierExpr())
4104 TRY_TO(VisitStmt(E));
4105 TRY_TO(VisitOMPClauseList(C));
4106 TRY_TO(VisitOMPClauseWithPreInit(C));
4107 return true;
4108}
4109
4110template <typename Derived>
4112 OMPPriorityClause *C) {
4113 TRY_TO(VisitOMPClauseWithPreInit(C));
4114 TRY_TO(TraverseStmt(C->getPriority()));
4115 return true;
4116}
4117
4118template <typename Derived>
4120 OMPGrainsizeClause *C) {
4121 TRY_TO(VisitOMPClauseWithPreInit(C));
4122 TRY_TO(TraverseStmt(C->getGrainsize()));
4123 return true;
4124}
4125
4126template <typename Derived>
4128 OMPNumTasksClause *C) {
4129 TRY_TO(VisitOMPClauseWithPreInit(C));
4130 TRY_TO(TraverseStmt(C->getNumTasks()));
4131 return true;
4132}
4133
4134template <typename Derived>
4136 TRY_TO(TraverseStmt(C->getHint()));
4137 return true;
4138}
4139
4140template <typename Derived>
4142 OMPDistScheduleClause *C) {
4143 TRY_TO(VisitOMPClauseWithPreInit(C));
4144 TRY_TO(TraverseStmt(C->getChunkSize()));
4145 return true;
4146}
4147
4148template <typename Derived>
4149bool
4151 return true;
4152}
4153
4154template <typename Derived>
4156 TRY_TO(VisitOMPClauseList(C));
4157 return true;
4158}
4159
4160template <typename Derived>
4162 TRY_TO(VisitOMPClauseList(C));
4163 return true;
4164}
4165
4166template <typename Derived>
4168 OMPUseDevicePtrClause *C) {
4169 TRY_TO(VisitOMPClauseList(C));
4170 return true;
4171}
4172
4173template <typename Derived>
4175 OMPUseDeviceAddrClause *C) {
4176 TRY_TO(VisitOMPClauseList(C));
4177 return true;
4178}
4179
4180template <typename Derived>
4182 OMPIsDevicePtrClause *C) {
4183 TRY_TO(VisitOMPClauseList(C));
4184 return true;
4185}
4186
4187template <typename Derived>
4189 OMPHasDeviceAddrClause *C) {
4190 TRY_TO(VisitOMPClauseList(C));
4191 return true;
4192}
4193
4194template <typename Derived>
4196 OMPNontemporalClause *C) {
4197 TRY_TO(VisitOMPClauseList(C));
4198 for (auto *E : C->private_refs()) {
4199 TRY_TO(TraverseStmt(E));
4200 }
4201 return true;
4202}
4203
4204template <typename Derived>
4206 return true;
4207}
4208
4209template <typename Derived>
4211 TRY_TO(TraverseStmt(C->getEventHandler()));
4212 return true;
4213}
4214
4215template <typename Derived>
4217 OMPUsesAllocatorsClause *C) {
4218 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
4219 const OMPUsesAllocatorsClause::Data Data = C->getAllocatorData(I);
4220 TRY_TO(TraverseStmt(Data.Allocator));
4221 TRY_TO(TraverseStmt(Data.AllocatorTraits));
4222 }
4223 return true;
4224}
4225
4226template <typename Derived>
4228 OMPAffinityClause *C) {
4229 TRY_TO(TraverseStmt(C->getModifier()));
4230 for (Expr *E : C->varlist())
4231 TRY_TO(TraverseStmt(E));
4232 return true;
4233}
4234
4235template <typename Derived>
4237 TRY_TO(VisitOMPClauseWithPreInit(C));
4238 TRY_TO(TraverseStmt(C->getThreadID()));
4239 return true;
4240}
4241
4242template <typename Derived>
4244 return true;
4245}
4246
4247template <typename Derived>
4249 OMPXDynCGroupMemClause *C) {
4250 TRY_TO(VisitOMPClauseWithPreInit(C));
4251 TRY_TO(TraverseStmt(C->getSize()));
4252 return true;
4253}
4254
4255template <typename Derived>
4257 OMPDynGroupprivateClause *C) {
4258 TRY_TO(VisitOMPClauseWithPreInit(C));
4259 TRY_TO(TraverseStmt(C->getSize()));
4260 return true;
4261}
4262
4263template <typename Derived>
4265 OMPDoacrossClause *C) {
4266 TRY_TO(VisitOMPClauseList(C));
4267 return true;
4268}
4269
4270template <typename Derived>
4272 OMPXAttributeClause *C) {
4273 return true;
4274}
4275
4276template <typename Derived>
4278 return true;
4279}
4280
4281template <typename Derived>
4282bool RecursiveASTVisitor<Derived>::TraverseOpenACCConstructStmt(
4284 TRY_TO(VisitOpenACCClauseList(C->clauses()));
4285 return true;
4286}
4287
4288template <typename Derived>
4289bool RecursiveASTVisitor<Derived>::TraverseOpenACCAssociatedStmtConstruct(
4291 TRY_TO(TraverseOpenACCConstructStmt(S));
4292 TRY_TO(TraverseStmt(S->getAssociatedStmt()));
4293 return true;
4294}
4295
4296template <typename Derived>
4297bool RecursiveASTVisitor<Derived>::VisitOpenACCClause(const OpenACCClause *C) {
4298 for (const Stmt *Child : C->children())
4299 TRY_TO(TraverseStmt(const_cast<Stmt *>(Child)));
4300 return true;
4301}
4302
4303template <typename Derived>
4304bool RecursiveASTVisitor<Derived>::VisitOpenACCClauseList(
4306
4307 for (const auto *C : Clauses)
4308 TRY_TO(VisitOpenACCClause(C));
4309 return true;
4310}
4311
4313 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4314DEF_TRAVERSE_STMT(OpenACCLoopConstruct,
4315 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4316DEF_TRAVERSE_STMT(OpenACCCombinedConstruct,
4317 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4318DEF_TRAVERSE_STMT(OpenACCDataConstruct,
4319 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4320DEF_TRAVERSE_STMT(OpenACCEnterDataConstruct,
4321 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4322DEF_TRAVERSE_STMT(OpenACCExitDataConstruct,
4323 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4324DEF_TRAVERSE_STMT(OpenACCHostDataConstruct,
4325 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4326DEF_TRAVERSE_STMT(OpenACCWaitConstruct, {
4327 if (S->hasDevNumExpr())
4328 TRY_TO(TraverseStmt(S->getDevNumExpr()));
4329 for (auto *E : S->getQueueIdExprs())
4330 TRY_TO(TraverseStmt(E));
4331 TRY_TO(VisitOpenACCClauseList(S->clauses()));
4332})
4333DEF_TRAVERSE_STMT(OpenACCInitConstruct,
4334 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4335DEF_TRAVERSE_STMT(OpenACCShutdownConstruct,
4336 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4337DEF_TRAVERSE_STMT(OpenACCSetConstruct,
4338 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4339DEF_TRAVERSE_STMT(OpenACCUpdateConstruct,
4340 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4341DEF_TRAVERSE_STMT(OpenACCAtomicConstruct,
4342 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4343DEF_TRAVERSE_STMT(OpenACCCacheConstruct, {
4344 for (auto *E : S->getVarList())
4345 TRY_TO(TraverseStmt(E));
4346})
4347
4348// Traverse HLSL: Out argument expression
4350
4351// FIXME: look at the following tricky-seeming exprs to see if we
4352// need to recurse on anything. These are ones that have methods
4353// returning decls or qualtypes or nestednamespecifier -- though I'm
4354// not sure if they own them -- or just seemed very complicated, or
4355// had lots of sub-types to explore.
4356//
4357// VisitOverloadExpr and its children: recurse on template args? etc?
4358
4359// FIXME: go through all the stmts and exprs again, and see which of them
4360// create new types, and recurse on the types (TypeLocs?) of those.
4361// Candidates:
4362//
4363// http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html
4364// http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html
4365// http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html
4366// Every class that has getQualifier.
4367
4368#undef DEF_TRAVERSE_STMT
4369#undef TRAVERSE_STMT
4370#undef TRAVERSE_STMT_BASE
4371
4372#undef TRY_TO
4373
4374} // end namespace clang
4375
4376#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:4556
Represents a type which was implicitly adjusted by the semantic engine for arbitrary reasons.
Definition TypeBase.h:3588
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Definition Expr.h:6033
Represents a loop initializing the elements of an array.
Definition Expr.h:5980
This class represents BOTH the OpenMP Array Section and OpenACC 'subarray', with a boolean differenti...
Definition Expr.h:7231
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition Expr.h:2727
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:6745
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
Definition Expr.h:6940
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:4459
A builtin binary operation expression such as "x + y" or "x <= y".
Definition Expr.h:4044
A binding in a decomposition declaration.
Definition DeclCXX.h:4206
A fixed int type of a specified bitwidth.
Definition TypeBase.h:8341
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition Decl.h:4716
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition Expr.h:6684
Pointer to a block type.
Definition TypeBase.h:3641
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:3229
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Definition Expr.h:3975
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:2633
Represents a C++ conversion function within a class.
Definition DeclCXX.h:2968
Represents a C++ base or member initializer.
Definition DeclCXX.h:2398
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:2898
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:2949
Represents the body of a CapturedStmt, and serves as its DeclContext.
Definition Decl.h:4988
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:4854
Declaration of a class template.
Represents a 'co_await' expression.
Definition ExprCXX.h:5368
Complex values, per C99 6.2.5p11.
Definition TypeBase.h:3340
CompoundAssignOperator - For compound assignments (e.g.
Definition Expr.h:4306
CompoundLiteralExpr - [C99 6.5.2.5].
Definition Expr.h:3611
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:4397
Represents the canonical version of C arrays with a specified constant size.
Definition TypeBase.h:3859
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Definition Expr.h:1088
Represents a concrete matrix type with constant number of rows and columns.
Definition TypeBase.h:4486
Represents a shadow constructor declaration introduced into a class by a C++11 using-declaration that...
Definition DeclCXX.h:3698
ContinueStmt - This represents a continue.
Definition Stmt.h:3128
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Definition Expr.h:4725
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:1276
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:4270
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:4110
Represents an extended vector type where either the type or size is dependent.
Definition TypeBase.h:4200
Represents a vector type where either the type or size is dependent.
Definition TypeBase.h:4326
Represents a C99 designated initializer expression.
Definition Expr.h:5563
DoStmt - This represents a 'do/while' stmt.
Definition Stmt.h:2841
Represents a reference to emded data.
Definition Expr.h:5141
Represents an empty-declaration.
Definition Decl.h:5223
An instance of this object exists for each enum constant that is defined.
Definition Decl.h:3467
Represents an enum.
Definition Decl.h:4055
Represents an explicit instantiation of a template entity in source code.
Represents a standard C++ module export declaration.
Definition Decl.h:5176
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:6622
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:3204
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:54
Declaration of a friend template.
Represents a function declaration or definition.
Definition Decl.h:2029
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Definition TypeBase.h:4984
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:5406
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:4929
Represents a C11 generic selection.
Definition Expr.h:6194
AssociationTy< false > Association
Definition Expr.h:6427
GotoStmt - This represents a direct goto.
Definition Stmt.h:2978
HLSLBufferDecl - Represent a cbuffer or tbuffer declaration.
Definition Decl.h:5238
This class represents temporary values used to represent inout and out arguments in HLSL.
Definition Expr.h:7409
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:1737
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Definition Expr.h:3859
Represents an implicitly-generated value initialization of an object of a given type.
Definition Expr.h:6069
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Definition Decl.h:5097
Represents a C array with an unspecified size.
Definition TypeBase.h:4008
Represents a field injected from an anonymous union/struct into the parent scope.
Definition Decl.h:3511
IndirectGotoStmt - This represents an indirect goto.
Definition Stmt.h:3017
Describes an C or C++ initializer list.
Definition Expr.h:5314
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:3560
Implicit declaration of a temporary that was materialized by a MaterializeTemporaryExpr and lifetime-...
Definition DeclCXX.h:3329
Represents a linkage specification.
Definition DeclCXX.h:3036
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:4424
An instance of this class represents the declaration of a property member.
Definition DeclCXX.h:4370
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:6285
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:2801
MatrixSubscriptExpr - Matrix subscript expression for the MatrixType extension.
Definition Expr.h:2871
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition Expr.h:3370
This represents a decl that may have a name.
Definition Decl.h:274
Represents a C++ namespace alias.
Definition DeclCXX.h:3222
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:5889
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:2030
Represents Objective-C's @finally statement.
Definition StmtObjC.h:127
Represents Objective-C's @synchronized statement.
Definition StmtObjC.h:303
Represents Objective-C's @throw statement.
Definition StmtObjC.h:358
Represents Objective-C's @try ... @catch ... @finally statement.
Definition StmtObjC.h:167
Represents Objective-C's @autoreleasepool Statement.
Definition StmtObjC.h:394
A runtime availability query.
Definition ExprObjC.h: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:2329
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
Definition DeclObjC.h:2545
ObjCCompatibleAliasDecl - Represents alias of a class.
Definition DeclObjC.h:2775
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
Definition ExprObjC.h:342
ObjCEncodeExpr, used for @encode in Objective-C.
Definition ExprObjC.h:441
Represents Objective-C's collection statement.
Definition StmtObjC.h:23
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Definition DeclObjC.h:2597
ObjCIndirectCopyRestoreExpr - Represents the passing of a function argument by indirect copy-restore ...
Definition ExprObjC.h:1615
Represents an ObjC class declaration.
Definition DeclObjC.h:1154
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
Definition TypeBase.h:8051
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:1952
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:8107
Represents one property declaration in an Objective-C interface.
Definition DeclObjC.h:731
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
Definition DeclObjC.h:2805
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
Definition ExprObjC.h:650
Represents an Objective-C protocol declaration.
Definition DeclObjC.h:2084
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:578
Stores a list of Objective-C type parameters for a parameterized class or a category/extension thereo...
Definition DeclObjC.h:662
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition Expr.h:2533
Helper class for OffsetOfExpr.
Definition Expr.h:2427
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition Expr.h:1184
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:2096
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:4923
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:2188
Sugar for parentheses used when specifying types.
Definition TypeBase.h:3367
Represents a parameter to a function.
Definition Decl.h:1819
PipeType - OpenCL20.
Definition TypeBase.h:8307
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:2011
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition Expr.h:6816
Expr *const * semantics_iterator
Definition Expr.h:6875
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:3734
Represents a struct/union/class.
Definition Decl.h:4369
Frontend produces RecoveryExprs on semantic errors that prevent creating other well-formed expression...
Definition Expr.h:7515
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:4649
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:5032
Represents a C++11 static_assert declaration.
Definition DeclCXX.h:4157
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
Definition Expr.h:4601
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:1805
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.
NamedDecl ** iterator
Iterates through the template parameters in this list.
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
Declaration of a template type parameter.
A declaration that models statements at global scope.
Definition Decl.h:4679
The top declaration context.
Definition Decl.h:105
Represents the declaration of a typedef-name via a C++11 alias-declaration.
Definition Decl.h:3732
Declaration of an alias template.
Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...
Definition ASTConcept.h:227
Base wrapper for a particular "section" of type source info.
Definition TypeLoc.h:59
UnqualTypeLoc getUnqualifiedLoc() const
Skips past any qualifiers, if this is qualified.
Definition TypeLoc.h:349
NestedNameSpecifierLoc getPrefix() const
If this type represents a qualified-id, this returns it's nested name specifier.
Definition TypeLoc.cpp:473
TypeLocClass getTypeLocClass() const
Definition TypeLoc.h:116
bool isNull() const
Definition TypeLoc.h:121
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
Definition TypeLoc.h:2766
A container of type source information.
Definition TypeBase.h:8460
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:1876
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Definition Decl.h:3711
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition Expr.h:2631
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition Expr.h:2250
An artificial decl, representing a global anonymous constant value which is uniquified by value withi...
Definition DeclCXX.h:4481
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:4139
Represents a dependent using declaration which was marked with typename.
Definition DeclCXX.h:4058
Represents a dependent using declaration which was not marked with typename.
Definition DeclCXX.h:3961
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:3612
Represents C++ using-directive.
Definition DeclCXX.h:3117
Represents a C++ using-enum-declaration.
Definition DeclCXX.h:3813
Represents a pack of using declarations that a single using-declarator pack-expanded into.
Definition DeclCXX.h:3894
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Definition DeclCXX.h:3420
Represents a call to the builtin function __builtin_va_arg.
Definition Expr.h:4963
Represents a variable declaration or definition.
Definition Decl.h:932
Declaration of a variable template.
Represents a GCC generic vector type.
Definition TypeBase.h:4274
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...
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
TRY_TO(TraverseNestedNameSpecifier(Qualifier))
DEF_TRAVERSE_TYPELOC(ComplexType, { TRY_TO(TraverseType(TL.getTypePtr() ->getElementType()));}) DEF_TRAVERSE_TYPELOC(PointerType
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
Definition Parser.h:61
OpenACCComputeConstruct(OpenACCDirectiveKind K, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses, Stmt *StructuredBlock)
@ Parameter
The parameter type of a method or function.
Definition TypeBase.h: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:6016
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