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