clang 23.0.0git
RecursiveASTVisitor.h
Go to the documentation of this file.
1//===--- RecursiveASTVisitor.h - Recursive AST Visitor ----------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file defines the RecursiveASTVisitor interface, which recursively
10// traverses the entire AST.
11//
12//===----------------------------------------------------------------------===//
13#ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
14#define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
15
17#include "clang/AST/Attr.h"
18#include "clang/AST/Decl.h"
19#include "clang/AST/DeclBase.h"
20#include "clang/AST/DeclCXX.h"
22#include "clang/AST/DeclObjC.h"
27#include "clang/AST/Expr.h"
28#include "clang/AST/ExprCXX.h"
30#include "clang/AST/ExprObjC.h"
36#include "clang/AST/Stmt.h"
37#include "clang/AST/StmtCXX.h"
38#include "clang/AST/StmtObjC.h"
41#include "clang/AST/StmtSYCL.h"
44#include "clang/AST/Type.h"
45#include "clang/AST/TypeLoc.h"
46#include "clang/Basic/LLVM.h"
49#include "llvm/ADT/PointerIntPair.h"
50#include "llvm/ADT/SmallVector.h"
51#include "llvm/Support/Casting.h"
52#include <algorithm>
53#include <cstddef>
54#include <type_traits>
55
56namespace clang {
57
58// A helper macro to implement short-circuiting when recursing. It
59// invokes CALL_EXPR, which must be a method call, on the derived
60// object (s.t. a user of RecursiveASTVisitor can override the method
61// in CALL_EXPR).
62#define TRY_TO(CALL_EXPR) \
63 do { \
64 if (!getDerived().CALL_EXPR) \
65 return false; \
66 } while (false)
67
68namespace detail {
69
70template <typename T, typename U>
71struct has_same_member_pointer_type : std::false_type {};
72template <typename T, typename U, typename R, typename... P>
73struct has_same_member_pointer_type<R (T::*)(P...), R (U::*)(P...)>
74 : std::true_type {};
75
76/// Returns true if and only if \p FirstMethodPtr and \p SecondMethodPtr
77/// are pointers to the same non-static member function.
78template <typename FirstMethodPtrTy, typename SecondMethodPtrTy>
79LLVM_ATTRIBUTE_ALWAYS_INLINE LLVM_ATTRIBUTE_NODEBUG auto
80isSameMethod([[maybe_unused]] FirstMethodPtrTy FirstMethodPtr,
81 [[maybe_unused]] SecondMethodPtrTy SecondMethodPtr)
82 -> bool {
83 if constexpr (has_same_member_pointer_type<FirstMethodPtrTy,
84 SecondMethodPtrTy>::value)
85 return FirstMethodPtr == SecondMethodPtr;
86 return false;
87}
88
89} // end namespace detail
90
91/// A class that does preorder or postorder
92/// depth-first traversal on the entire Clang AST and visits each node.
93///
94/// This class performs three distinct tasks:
95/// 1. traverse the AST (i.e. go to each node);
96/// 2. at a given node, walk up the class hierarchy, starting from
97/// the node's dynamic type, until the top-most class (e.g. Stmt,
98/// Decl, or Type) is reached.
99/// 3. given a (node, class) combination, where 'class' is some base
100/// class of the dynamic type of 'node', call a user-overridable
101/// function to actually visit the node.
102///
103/// These tasks are done by three groups of methods, respectively:
104/// 1. TraverseDecl(Decl *x) does task #1. It is the entry point
105/// for traversing an AST rooted at x. This method simply
106/// dispatches (i.e. forwards) to TraverseFoo(Foo *x) where Foo
107/// is the dynamic type of *x, which calls WalkUpFromFoo(x) and
108/// then recursively visits the child nodes of x.
109/// TraverseStmt(Stmt *x) and TraverseType(QualType x) work
110/// similarly.
111/// 2. WalkUpFromFoo(Foo *x) does task #2. It does not try to visit
112/// any child node of x. Instead, it first calls WalkUpFromBar(x)
113/// where Bar is the direct parent class of Foo (unless Foo has
114/// no parent), and then calls VisitFoo(x) (see the next list item).
115/// 3. VisitFoo(Foo *x) does task #3.
116///
117/// These three method groups are tiered (Traverse* > WalkUpFrom* >
118/// Visit*). A method (e.g. Traverse*) may call methods from the same
119/// tier (e.g. other Traverse*) or one tier lower (e.g. WalkUpFrom*).
120/// It may not call methods from a higher tier.
121///
122/// Note that since WalkUpFromFoo() calls WalkUpFromBar() (where Bar
123/// is Foo's super class) before calling VisitFoo(), the result is
124/// that the Visit*() methods for a given node are called in the
125/// top-down order (e.g. for a node of type NamespaceDecl, the order will
126/// be VisitDecl(), VisitNamedDecl(), and then VisitNamespaceDecl()).
127///
128/// This scheme guarantees that all Visit*() calls for the same AST
129/// node are grouped together. In other words, Visit*() methods for
130/// different nodes are never interleaved.
131///
132/// Clients of this visitor should subclass the visitor (providing
133/// themselves as the template argument, using the curiously recurring
134/// template pattern) and override any of the Traverse*, WalkUpFrom*,
135/// and Visit* methods for declarations, types, statements,
136/// expressions, or other AST nodes where the visitor should customize
137/// behavior. Most users only need to override Visit*. Advanced
138/// users may override Traverse* and WalkUpFrom* to implement custom
139/// traversal strategies. Returning false from one of these overridden
140/// functions will abort the entire traversal.
141///
142/// By default, this visitor tries to visit every part of the explicit
143/// source code exactly once. The default policy towards templates
144/// is to descend into the 'pattern' class or function body, not any
145/// explicit or implicit instantiations. Explicit specializations
146/// are still visited, and the patterns of partial specializations
147/// are visited separately. This behavior can be changed by
148/// overriding shouldVisitTemplateInstantiations() in the derived class
149/// to return true, in which case all known implicit and explicit
150/// instantiations will be visited at the same time as the pattern
151/// from which they were produced.
152///
153/// By default, this visitor preorder traverses the AST. If postorder traversal
154/// is needed, the \c shouldTraversePostOrder method needs to be overridden
155/// to return \c true.
156template <typename Derived> class RecursiveASTVisitor {
157public:
158 /// A queue used for performing data recursion over statements.
159 /// Parameters involving this type are used to implement data
160 /// recursion over Stmts and Exprs within this class, and should
161 /// typically not be explicitly specified by derived classes.
162 /// The bool bit indicates whether the statement has been traversed or not.
165
166 /// Return a reference to the derived class.
167 Derived &getDerived() { return *static_cast<Derived *>(this); }
168
169 /// Return whether this visitor should recurse into
170 /// template instantiations.
171 bool shouldVisitTemplateInstantiations() const { return false; }
172
173 /// Return whether this visitor should recurse into the types of
174 /// TypeLocs.
175 bool shouldWalkTypesOfTypeLocs() const { return true; }
176
177 /// Return whether this visitor should recurse into implicit
178 /// code, e.g., implicit constructors and destructors.
179 bool shouldVisitImplicitCode() const { return false; }
180
181 /// Return whether this visitor should recurse into lambda body
182 bool shouldVisitLambdaBody() const { return true; }
183
184 /// Return whether this visitor should traverse post-order.
185 bool shouldTraversePostOrder() const { return false; }
186
187 /// Recursively visits an entire AST, starting from the TranslationUnitDecl.
188 /// \returns false if visitation was terminated early.
190 // Currently just an alias for TraverseDecl(TUDecl), but kept in case
191 // we change the implementation again.
192 return getDerived().TraverseDecl(AST.getTranslationUnitDecl());
193 }
194
195 /// Recursively visit a statement or expression, by
196 /// dispatching to Traverse*() based on the argument's dynamic type.
197 ///
198 /// \returns false if the visitation was terminated early, true
199 /// otherwise (including when the argument is nullptr).
200 bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue = nullptr);
201
202 /// Invoked before visiting a statement or expression via data recursion.
203 ///
204 /// \returns false to skip visiting the node, true otherwise.
205 bool dataTraverseStmtPre(Stmt *S) { return true; }
206
207 /// Invoked after visiting a statement or expression via data recursion.
208 /// This is not invoked if the previously invoked \c dataTraverseStmtPre
209 /// returned false.
210 ///
211 /// \returns false if the visitation was terminated early, true otherwise.
212 bool dataTraverseStmtPost(Stmt *S) { return true; }
213
214 /// Recursively visit a type, by dispatching to
215 /// Traverse*Type() based on the argument's getTypeClass() property.
216 ///
217 /// \returns false if the visitation was terminated early, true
218 /// otherwise (including when the argument is a Null type).
219 bool TraverseType(QualType T, bool TraverseQualifier = true);
220
221 /// Recursively visit a type with location, by dispatching to
222 /// Traverse*TypeLoc() based on the argument type's getTypeClass() property.
223 ///
224 /// \returns false if the visitation was terminated early, true
225 /// otherwise (including when the argument is a Null type location).
226 bool TraverseTypeLoc(TypeLoc TL, bool TraverseQualifier = true);
227
228 /// Recursively visit an attribute, by dispatching to
229 /// Traverse*Attr() based on the argument's dynamic type.
230 ///
231 /// \returns false if the visitation was terminated early, true
232 /// otherwise (including when the argument is a Null type location).
234
235 /// Recursively visit a declaration, by dispatching to
236 /// Traverse*Decl() based on the argument's dynamic type.
237 ///
238 /// \returns false if the visitation was terminated early, true
239 /// otherwise (including when the argument is NULL).
241
242 /// Recursively visit a C++ nested-name-specifier.
243 ///
244 /// \returns false if the visitation was terminated early, true otherwise.
246
247 /// Recursively visit a C++ nested-name-specifier with location
248 /// information.
249 ///
250 /// \returns false if the visitation was terminated early, true otherwise.
252
253 /// Recursively visit a name with its location information.
254 ///
255 /// \returns false if the visitation was terminated early, true otherwise.
257
258 /// Recursively visit a template name and dispatch to the
259 /// appropriate method.
260 ///
261 /// \returns false if the visitation was terminated early, true otherwise.
263
264 /// Recursively visit a template argument and dispatch to the
265 /// appropriate method for the argument type.
266 ///
267 /// \returns false if the visitation was terminated early, true otherwise.
268 // FIXME: migrate callers to TemplateArgumentLoc instead.
270
271 /// Recursively visit a template argument location and dispatch to the
272 /// appropriate method for the argument type.
273 ///
274 /// \returns false if the visitation was terminated early, true otherwise.
276
277 /// Recursively visit a set of template arguments.
278 /// This can be overridden by a subclass, but it's not expected that
279 /// will be needed -- this visitor always dispatches to another.
280 ///
281 /// \returns false if the visitation was terminated early, true otherwise.
282 // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead.
284
285 /// Recursively visit a base specifier. This can be overridden by a
286 /// subclass.
287 ///
288 /// \returns false if the visitation was terminated early, true otherwise.
290
291 /// Recursively visit a constructor initializer. This
292 /// automatically dispatches to another visitor for the initializer
293 /// expression, but not for the name of the initializer, so may
294 /// be overridden for clients that need access to the name.
295 ///
296 /// \returns false if the visitation was terminated early, true otherwise.
298
299 /// Recursively visit a lambda capture. \c Init is the expression that
300 /// will be used to initialize the capture.
301 ///
302 /// \returns false if the visitation was terminated early, true otherwise.
304 Expr *Init);
305
306 /// Recursively visit the syntactic or semantic form of an
307 /// initialization list.
308 ///
309 /// \returns false if the visitation was terminated early, true otherwise.
311 DataRecursionQueue *Queue = nullptr);
312
313 /// Recursively visit an Objective-C protocol reference with location
314 /// information.
315 ///
316 /// \returns false if the visitation was terminated early, true otherwise.
318
319 /// Recursively visit concept reference with location information.
320 ///
321 /// \returns false if the visitation was terminated early, true otherwise.
323
324 // Visit concept reference.
325 bool VisitConceptReference(ConceptReference *CR) { return true; }
326
327 /// Recursively visit a single component of an __builtin_offsetof
328 /// designator (a field, identifier, base-class, or array-index node).
329 ///
330 /// \returns false if the visitation was terminated early, true otherwise.
332
333 /// Visit a single component of an __builtin_offsetof designator.
334 bool VisitOffsetOfNode(const OffsetOfNode *Node) { return true; }
335
336 // ---- Methods on Attrs ----
337
338 // Visit an attribute.
339 bool VisitAttr(Attr *A) { return true; }
340
341// Declare Traverse* and empty Visit* for all Attr classes.
342#define ATTR_VISITOR_DECLS_ONLY
343#include "clang/AST/AttrVisitor.inc"
344#undef ATTR_VISITOR_DECLS_ONLY
345
346// ---- Methods on Stmts ----
347
349
350private:
351 // Traverse the given statement. If the most-derived traverse function takes a
352 // data recursion queue, pass it on; otherwise, discard it. Note that the
353 // first branch of this conditional must compile whether or not the derived
354 // class can take a queue, so if we're taking the second arm, make the first
355 // arm call our function rather than the derived class version.
356#define TRAVERSE_STMT_BASE(NAME, CLASS, VAR, QUEUE) \
357 (::clang::detail::has_same_member_pointer_type< \
358 decltype(&RecursiveASTVisitor::Traverse##NAME), \
359 decltype(&Derived::Traverse##NAME)>::value \
360 ? static_cast<std::conditional_t< \
361 ::clang::detail::has_same_member_pointer_type< \
362 decltype(&RecursiveASTVisitor::Traverse##NAME), \
363 decltype(&Derived::Traverse##NAME)>::value, \
364 Derived &, RecursiveASTVisitor &>>(*this) \
365 .Traverse##NAME(static_cast<CLASS *>(VAR), QUEUE) \
366 : getDerived().Traverse##NAME(static_cast<CLASS *>(VAR)))
367
368// Try to traverse the given statement, or enqueue it if we're performing data
369// recursion in the middle of traversing another statement. Can only be called
370// from within a DEF_TRAVERSE_STMT body or similar context.
371#define TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S) \
372 do { \
373 if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S, Queue)) \
374 return false; \
375 } while (false)
376
377public:
378// Declare Traverse*() for all concrete Stmt classes.
379#define ABSTRACT_STMT(STMT)
380#define STMT(CLASS, PARENT) \
381 bool Traverse##CLASS(CLASS *S, DataRecursionQueue *Queue = nullptr);
382#include "clang/AST/StmtNodes.inc"
383 // The above header #undefs ABSTRACT_STMT and STMT upon exit.
384
385 // Define WalkUpFrom*() and empty Visit*() for all Stmt classes.
386 bool WalkUpFromStmt(Stmt *S) { return getDerived().VisitStmt(S); }
387 bool VisitStmt(Stmt *S) { return true; }
388#define STMT(CLASS, PARENT) \
389 bool WalkUpFrom##CLASS(CLASS *S) { \
390 TRY_TO(WalkUpFrom##PARENT(S)); \
391 TRY_TO(Visit##CLASS(S)); \
392 return true; \
393 } \
394 bool Visit##CLASS(CLASS *S) { return true; }
395#include "clang/AST/StmtNodes.inc"
396
397// ---- Methods on Types ----
398// FIXME: revamp to take TypeLoc's rather than Types.
399
400// Declare Traverse*() for all concrete Type classes.
401#define ABSTRACT_TYPE(CLASS, BASE)
402#define TYPE(CLASS, BASE) \
403 bool Traverse##CLASS##Type(CLASS##Type *T, bool TraverseQualifier);
404#include "clang/AST/TypeNodes.inc"
405 // The above header #undefs ABSTRACT_TYPE and TYPE upon exit.
406
407 // Define WalkUpFrom*() and empty Visit*() for all Type classes.
408 bool WalkUpFromType(Type *T) { return getDerived().VisitType(T); }
409 bool VisitType(Type *T) { return true; }
410#define TYPE(CLASS, BASE) \
411 bool WalkUpFrom##CLASS##Type(CLASS##Type *T) { \
412 TRY_TO(WalkUpFrom##BASE(T)); \
413 TRY_TO(Visit##CLASS##Type(T)); \
414 return true; \
415 } \
416 bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
417#include "clang/AST/TypeNodes.inc"
418
419// ---- Methods on TypeLocs ----
420// FIXME: this currently just calls the matching Type methods
421
422// Declare Traverse*() for all concrete TypeLoc classes.
423#define ABSTRACT_TYPELOC(CLASS, BASE)
424#define TYPELOC(CLASS, BASE) \
425 bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL, bool TraverseQualifier);
426#include "clang/AST/TypeLocNodes.def"
427 // The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit.
428
429 // Define WalkUpFrom*() and empty Visit*() for all TypeLoc classes.
430 bool WalkUpFromTypeLoc(TypeLoc TL) { return getDerived().VisitTypeLoc(TL); }
431 bool VisitTypeLoc(TypeLoc TL) { return true; }
432
433 // QualifiedTypeLoc and UnqualTypeLoc are not declared in
434 // TypeNodes.inc and thus need to be handled specially.
436 return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
437 }
438 bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { return true; }
440 return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
441 }
442 bool VisitUnqualTypeLoc(UnqualTypeLoc TL) { return true; }
443
444// Note that BASE includes trailing 'Type' which CLASS doesn't.
445#define TYPE(CLASS, BASE) \
446 bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
447 TRY_TO(WalkUpFrom##BASE##Loc(TL)); \
448 TRY_TO(Visit##CLASS##TypeLoc(TL)); \
449 return true; \
450 } \
451 bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
452#include "clang/AST/TypeNodes.inc"
453
454// ---- Methods on Decls ----
455
456// Declare Traverse*() for all concrete Decl classes.
457#define ABSTRACT_DECL(DECL)
458#define DECL(CLASS, BASE) bool Traverse##CLASS##Decl(CLASS##Decl *D);
459#include "clang/AST/DeclNodes.inc"
460 // The above header #undefs ABSTRACT_DECL and DECL upon exit.
461
462 // Define WalkUpFrom*() and empty Visit*() for all Decl classes.
463 bool WalkUpFromDecl(Decl *D) { return getDerived().VisitDecl(D); }
464 bool VisitDecl(Decl *D) { return true; }
465#define DECL(CLASS, BASE) \
466 bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) { \
467 TRY_TO(WalkUpFrom##BASE(D)); \
468 TRY_TO(Visit##CLASS##Decl(D)); \
469 return true; \
470 } \
471 bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
472#include "clang/AST/DeclNodes.inc"
473
475
476#define DEF_TRAVERSE_TMPL_INST(TMPLDECLKIND) \
477 bool TraverseTemplateInstantiations(TMPLDECLKIND##TemplateDecl *D);
480 DEF_TRAVERSE_TMPL_INST(Function)
481#undef DEF_TRAVERSE_TMPL_INST
482
484
489
491
492private:
493 // These are helper methods used by more than one Traverse* method.
494 bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
495
496 // Traverses template parameter lists of either a DeclaratorDecl or TagDecl.
497 template <typename T>
498 bool TraverseDeclTemplateParameterLists(T *D);
499
500 bool TraverseTemplateTypeParamDeclConstraints(const TemplateTypeParmDecl *D);
501
502 bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL,
503 unsigned Count);
504 bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL);
505 bool TraverseSubstPackTypeHelper(SubstPackType *T);
506 bool TraverseSubstPackTypeLocHelper(SubstPackTypeLoc TL);
507 bool TraverseRecordHelper(RecordDecl *D);
508 bool TraverseCXXRecordHelper(CXXRecordDecl *D);
509 bool TraverseDeclaratorHelper(DeclaratorDecl *D);
510 bool TraverseDeclContextHelper(DeclContext *DC);
511 bool TraverseFunctionHelper(FunctionDecl *D);
512 bool TraverseVarHelper(VarDecl *D);
513 bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
514 bool TraverseOMPLoopDirective(OMPLoopDirective *S);
515 bool TraverseOMPClause(OMPClause *C);
516 bool TraverseTagType(TagType *T, bool TraverseQualifier);
517 bool TraverseTagTypeLoc(TagTypeLoc TL, bool TraverseQualifier);
518#define GEN_CLANG_CLAUSE_CLASS
519#define CLAUSE_CLASS(Enum, Str, Class) bool Visit##Class(Class *C);
520#include "llvm/Frontend/OpenMP/OMP.inc"
521 /// Process clauses with list of variables.
522 template <typename T> bool VisitOMPClauseList(T *Node);
523 /// Process clauses with pre-initis.
524 bool VisitOMPClauseWithPreInit(OMPClauseWithPreInit *Node);
525 bool VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *Node);
526
527 bool PostVisitStmt(Stmt *S);
528 bool TraverseOpenACCConstructStmt(OpenACCConstructStmt *S);
529 bool
530 TraverseOpenACCAssociatedStmtConstruct(OpenACCAssociatedStmtConstruct *S);
531 bool VisitOpenACCClauseList(ArrayRef<const OpenACCClause *>);
532 bool VisitOpenACCClause(const OpenACCClause *);
533};
534
535template <typename Derived>
537 const TypeConstraint *C) {
539 TRY_TO(TraverseConceptReference(C->getConceptReference()));
540 return true;
541 }
542 if (Expr *IDC = C->getImmediatelyDeclaredConstraint()) {
543 TRY_TO(TraverseStmt(IDC));
544 } else {
545 // Avoid traversing the ConceptReference in the TypeConstraint
546 // if we have an immediately-declared-constraint, otherwise
547 // we'll end up visiting the concept and the arguments in
548 // the TC twice.
549 TRY_TO(TraverseConceptReference(C->getConceptReference()));
550 }
551 return true;
552}
553
554template <typename Derived>
557 switch (R->getKind()) {
559 return getDerived().TraverseConceptTypeRequirement(
563 return getDerived().TraverseConceptExprRequirement(
566 return getDerived().TraverseConceptNestedRequirement(
568 }
569 llvm_unreachable("unexpected case");
570}
571
572template <typename Derived>
574 DataRecursionQueue *Queue) {
575 // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
576 switch (S->getStmtClass()) {
578 break;
579#define ABSTRACT_STMT(STMT)
580#define STMT(CLASS, PARENT) \
581 case Stmt::CLASS##Class: \
582 return TRAVERSE_STMT_BASE(CLASS, CLASS, S, Queue);
583#include "clang/AST/StmtNodes.inc"
584 }
585
586 return true;
587}
588
589#undef DISPATCH_STMT
590
591template <typename Derived>
594 if (R->isSubstitutionFailure())
595 return true;
596 return getDerived().TraverseTypeLoc(R->getType()->getTypeLoc());
597}
598
599template <typename Derived>
602 if (!R->isExprSubstitutionFailure())
603 TRY_TO(TraverseStmt(R->getExpr()));
604 auto &RetReq = R->getReturnTypeRequirement();
605 if (RetReq.isTypeConstraint()) {
607 TRY_TO(TraverseTemplateParameterListHelper(
608 RetReq.getTypeConstraintTemplateParameterList()));
609 } else {
610 // Template parameter list is implicit, visit constraint directly.
611 TRY_TO(TraverseTypeConstraint(RetReq.getTypeConstraint()));
612 }
613 }
614 return true;
615}
616
617template <typename Derived>
620 if (!R->hasInvalidConstraint())
621 return getDerived().TraverseStmt(R->getConstraintExpr());
622 return true;
623}
624
625template <typename Derived>
626bool RecursiveASTVisitor<Derived>::PostVisitStmt(Stmt *S) {
627 // In pre-order traversal mode, each Traverse##STMT method is responsible for
628 // calling WalkUpFrom. Therefore, if the user overrides Traverse##STMT and
629 // does not call the default implementation, the WalkUpFrom callback is not
630 // called. Post-order traversal mode should provide the same behavior
631 // regarding method overrides.
632 //
633 // In post-order traversal mode the Traverse##STMT method, when it receives a
634 // DataRecursionQueue, can't call WalkUpFrom after traversing children because
635 // it only enqueues the children and does not traverse them. TraverseStmt
636 // traverses the enqueued children, and we call WalkUpFrom here.
637 //
638 // However, to make pre-order and post-order modes identical with regards to
639 // whether they call WalkUpFrom at all, we call WalkUpFrom if and only if the
640 // user did not override the Traverse##STMT method. We implement the override
641 // check with isSameMethod calls below.
642
643 switch (S->getStmtClass()) {
645 break;
646#define ABSTRACT_STMT(STMT)
647#define STMT(CLASS, PARENT) \
648 case Stmt::CLASS##Class: \
649 if (::clang::detail::isSameMethod(&RecursiveASTVisitor::Traverse##CLASS, \
650 &Derived::Traverse##CLASS)) { \
651 TRY_TO(WalkUpFrom##CLASS(static_cast<CLASS *>(S))); \
652 } \
653 break;
654#define INITLISTEXPR(CLASS, PARENT) \
655 case Stmt::CLASS##Class: \
656 if (::clang::detail::isSameMethod(&RecursiveASTVisitor::Traverse##CLASS, \
657 &Derived::Traverse##CLASS)) { \
658 auto ILE = static_cast<CLASS *>(S); \
659 if (auto Syn = ILE->isSemanticForm() ? ILE->getSyntacticForm() : ILE) \
660 TRY_TO(WalkUpFrom##CLASS(Syn)); \
661 if (auto Sem = ILE->isSemanticForm() ? ILE : ILE->getSemanticForm()) \
662 TRY_TO(WalkUpFrom##CLASS(Sem)); \
663 } \
664 break;
665#include "clang/AST/StmtNodes.inc"
666 }
667
668 return true;
669}
670
671#undef DISPATCH_STMT
672
673// Inlining this method can lead to large code size and compile-time increases
674// without any benefit to runtime performance.
675template <typename Derived>
676LLVM_ATTRIBUTE_NOINLINE bool
678 if (!S)
679 return true;
680
681 if (Queue) {
682 Queue->push_back({S, false});
683 return true;
684 }
685
687 LocalQueue.push_back({S, false});
688
689 while (!LocalQueue.empty()) {
690 auto &CurrSAndVisited = LocalQueue.back();
691 Stmt *CurrS = CurrSAndVisited.getPointer();
692 bool Visited = CurrSAndVisited.getInt();
693 if (Visited) {
694 LocalQueue.pop_back();
697 TRY_TO(PostVisitStmt(CurrS));
698 }
699 continue;
700 }
701
702 if (getDerived().dataTraverseStmtPre(CurrS)) {
703 CurrSAndVisited.setInt(true);
704 size_t N = LocalQueue.size();
705 TRY_TO(dataTraverseNode(CurrS, &LocalQueue));
706 // Process new children in the order they were added.
707 std::reverse(LocalQueue.begin() + N, LocalQueue.end());
708 } else {
709 LocalQueue.pop_back();
710 }
711 }
712
713 return true;
714}
715
716template <typename Derived>
718 bool TraverseQualifier) {
719 if (T.isNull())
720 return true;
721
722 switch (T->getTypeClass()) {
723#define ABSTRACT_TYPE(CLASS, BASE)
724#define TYPE(CLASS, BASE) \
725 case Type::CLASS: \
726 return getDerived().Traverse##CLASS##Type( \
727 static_cast<CLASS##Type *>(const_cast<Type *>(T.getTypePtr())), \
728 TraverseQualifier);
729#include "clang/AST/TypeNodes.inc"
730 }
731
732 return true;
733}
734
735template <typename Derived>
737 bool TraverseQualifier) {
738 if (TL.isNull())
739 return true;
740
741 switch (TL.getTypeLocClass()) {
742#define ABSTRACT_TYPELOC(CLASS, BASE)
743#define TYPELOC(CLASS, BASE) \
744 case TypeLoc::CLASS: \
745 return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>(), \
746 TraverseQualifier);
747#include "clang/AST/TypeLocNodes.def"
748 }
749
750 return true;
751}
752
753// Define the Traverse*Attr(Attr* A) methods
754#define VISITORCLASS RecursiveASTVisitor
755#include "clang/AST/AttrVisitor.inc"
756#undef VISITORCLASS
757
758template <typename Derived>
760 if (!D)
761 return true;
762
763 // As a syntax visitor, by default we want to ignore declarations for
764 // implicit declarations (ones not typed explicitly by the user).
766 if (D->isImplicit()) {
767 // For an implicit template type parameter, its type constraints are not
768 // implicit and are not represented anywhere else. We still need to visit
769 // them.
770 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(D))
771 return TraverseTemplateTypeParamDeclConstraints(TTPD);
772 return true;
773 }
774
775 // Deduction guides for alias templates are always synthesized, so they
776 // should not be traversed unless shouldVisitImplicitCode() returns true.
777 //
778 // It's important to note that checking the implicit bit is not efficient
779 // for the alias case. For deduction guides synthesized from explicit
780 // user-defined deduction guides, we must maintain the explicit bit to
781 // ensure correct overload resolution.
782 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
783 if (llvm::isa_and_present<TypeAliasTemplateDecl>(
784 FTD->getDeclName().getCXXDeductionGuideTemplate()))
785 return true;
786 }
787
788 switch (D->getKind()) {
789#define ABSTRACT_DECL(DECL)
790#define DECL(CLASS, BASE) \
791 case Decl::CLASS: \
792 if (!getDerived().Traverse##CLASS##Decl(static_cast<CLASS##Decl *>(D))) \
793 return false; \
794 break;
795#include "clang/AST/DeclNodes.inc"
796 }
797 return true;
798}
799
800template <typename Derived>
803 switch (NNS.getKind()) {
807 return true;
810 return true;
812 auto *T = const_cast<Type *>(NNS.getAsType());
813 TRY_TO(TraverseNestedNameSpecifier(T->getPrefix()));
814 TRY_TO(TraverseType(QualType(T, 0), /*TraverseQualifier=*/false));
815 return true;
816 }
817 }
818 llvm_unreachable("unhandled kind");
819}
820
821template <typename Derived>
843
844template <typename Derived>
872
873template <typename Derived>
875 if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
876 TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier()));
877 } else if (QualifiedTemplateName *QTN =
878 Template.getAsQualifiedTemplateName()) {
879 if (QTN->getQualifier()) {
880 TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier()));
881 }
882 }
883
884 return true;
885}
886
887template <typename Derived>
889 const TemplateArgument &Arg) {
890 switch (Arg.getKind()) {
896 return true;
897
899 return getDerived().TraverseType(Arg.getAsType());
900
903 return getDerived().TraverseTemplateName(
905
907 return getDerived().TraverseStmt(Arg.getAsExpr());
908
910 return getDerived().TraverseTemplateArguments(Arg.pack_elements());
911 }
912
913 return true;
914}
915
916// FIXME: no template name location?
917// FIXME: no source locations for a template argument pack?
918template <typename Derived>
920 const TemplateArgumentLoc &ArgLoc) {
921 const TemplateArgument &Arg = ArgLoc.getArgument();
922
923 switch (Arg.getKind()) {
929 return true;
930
932 // FIXME: how can TSI ever be NULL?
933 if (TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo())
934 return getDerived().TraverseTypeLoc(TSI->getTypeLoc());
935 else
936 return getDerived().TraverseType(Arg.getAsType());
937 }
938
941 if (ArgLoc.getTemplateQualifierLoc())
943 ArgLoc.getTemplateQualifierLoc()));
944 return getDerived().TraverseTemplateName(
946
948 return getDerived().TraverseStmt(ArgLoc.getSourceExpression());
949
951 return getDerived().TraverseTemplateArguments(Arg.pack_elements());
952 }
953
954 return true;
955}
956
957template <typename Derived>
960 for (const TemplateArgument &Arg : Args)
962
963 return true;
964}
965
966template <typename Derived>
969 if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo())
970 TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
971
972 if (Init->isWritten() || getDerived().shouldVisitImplicitCode())
973 TRY_TO(TraverseStmt(Init->getInit()));
974
975 return true;
976}
977
978template <typename Derived>
979bool
981 const LambdaCapture *C,
982 Expr *Init) {
983 if (LE->isInitCapture(C))
984 TRY_TO(TraverseDecl(C->getCapturedVar()));
985 else
987 return true;
988}
989
990// ----------------- Type traversal -----------------
991
992// This macro makes available a variable T, the passed-in type.
993#define DEF_TRAVERSE_TYPE(TYPE, CODE) \
994 template <typename Derived> \
995 bool RecursiveASTVisitor<Derived>::Traverse##TYPE(TYPE *T, \
996 bool TraverseQualifier) { \
997 if (!getDerived().shouldTraversePostOrder()) \
998 TRY_TO(WalkUpFrom##TYPE(T)); \
999 { \
1000 CODE; \
1001 } \
1002 if (getDerived().shouldTraversePostOrder()) \
1003 TRY_TO(WalkUpFrom##TYPE(T)); \
1004 return true; \
1005 }
1006
1007DEF_TRAVERSE_TYPE(BuiltinType, {})
1008
1009DEF_TRAVERSE_TYPE(ComplexType, { TRY_TO(TraverseType(T->getElementType())); })
1010
1011DEF_TRAVERSE_TYPE(PointerType, { TRY_TO(TraverseType(T->getPointeeType())); })
1012
1014 { TRY_TO(TraverseType(T->getPointeeType())); })
1015
1016DEF_TRAVERSE_TYPE(LValueReferenceType,
1017 { TRY_TO(TraverseType(T->getPointeeType())); })
1018
1020 { TRY_TO(TraverseType(T->getPointeeType())); })
1021
1022DEF_TRAVERSE_TYPE(MemberPointerType, {
1023 NestedNameSpecifier Qualifier =
1024 T->isSugared() ? cast<MemberPointerType>(T->getCanonicalTypeUnqualified())
1025 ->getQualifier()
1026 : T->getQualifier();
1027 TRY_TO(TraverseNestedNameSpecifier(Qualifier));
1028 TRY_TO(TraverseType(T->getPointeeType()));
1029})
1030
1031DEF_TRAVERSE_TYPE(AdjustedType, { TRY_TO(TraverseType(T->getOriginalType())); })
1032
1033DEF_TRAVERSE_TYPE(DecayedType, { TRY_TO(TraverseType(T->getOriginalType())); })
1034
1036 TRY_TO(TraverseType(T->getElementType()));
1037 if (T->getSizeExpr())
1038 TRY_TO(TraverseStmt(const_cast<Expr*>(T->getSizeExpr())));
1039})
1040
1041DEF_TRAVERSE_TYPE(ArrayParameterType, {
1042 TRY_TO(TraverseType(T->getElementType()));
1043 if (T->getSizeExpr())
1044 TRY_TO(TraverseStmt(const_cast<Expr *>(T->getSizeExpr())));
1045})
1046
1048 { TRY_TO(TraverseType(T->getElementType())); })
1049
1050DEF_TRAVERSE_TYPE(VariableArrayType, {
1051 TRY_TO(TraverseType(T->getElementType()));
1052 TRY_TO(TraverseStmt(T->getSizeExpr()));
1053})
1054
1056 TRY_TO(TraverseType(T->getElementType()));
1057 if (T->getSizeExpr())
1058 TRY_TO(TraverseStmt(T->getSizeExpr()));
1059})
1060
1061DEF_TRAVERSE_TYPE(DependentAddressSpaceType, {
1062 TRY_TO(TraverseStmt(T->getAddrSpaceExpr()));
1063 TRY_TO(TraverseType(T->getPointeeType()));
1064})
1065
1067 if (T->getSizeExpr())
1068 TRY_TO(TraverseStmt(T->getSizeExpr()));
1069 TRY_TO(TraverseType(T->getElementType()));
1070})
1071
1072DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
1073 if (T->getSizeExpr())
1074 TRY_TO(TraverseStmt(T->getSizeExpr()));
1075 TRY_TO(TraverseType(T->getElementType()));
1076})
1077
1078DEF_TRAVERSE_TYPE(VectorType, { TRY_TO(TraverseType(T->getElementType())); })
1079
1080DEF_TRAVERSE_TYPE(ExtVectorType, { TRY_TO(TraverseType(T->getElementType())); })
1081
1083 { TRY_TO(TraverseType(T->getElementType())); })
1084
1085DEF_TRAVERSE_TYPE(DependentSizedMatrixType, {
1086 if (T->getRowExpr())
1087 TRY_TO(TraverseStmt(T->getRowExpr()));
1088 if (T->getColumnExpr())
1089 TRY_TO(TraverseStmt(T->getColumnExpr()));
1090 TRY_TO(TraverseType(T->getElementType()));
1091})
1092
1094 { TRY_TO(TraverseType(T->getReturnType())); })
1095
1096DEF_TRAVERSE_TYPE(FunctionProtoType, {
1097 TRY_TO(TraverseType(T->getReturnType()));
1098
1099 for (const auto &A : T->param_types()) {
1100 TRY_TO(TraverseType(A));
1101 }
1102
1103 for (const auto &E : T->exceptions()) {
1104 TRY_TO(TraverseType(E));
1105 }
1106
1107 if (Expr *NE = T->getNoexceptExpr())
1108 TRY_TO(TraverseStmt(NE));
1109})
1110
1112 if (TraverseQualifier)
1113 TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
1114})
1115DEF_TRAVERSE_TYPE(UnresolvedUsingType, {
1116 if (TraverseQualifier)
1117 TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
1118})
1120 if (TraverseQualifier)
1121 TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
1122})
1123
1124DEF_TRAVERSE_TYPE(TypeOfExprType,
1125 { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
1126
1127DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnmodifiedType())); })
1128
1129DEF_TRAVERSE_TYPE(DecltypeType,
1130 { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
1131
1132DEF_TRAVERSE_TYPE(PackIndexingType, {
1133 TRY_TO(TraverseType(T->getPattern()));
1134 TRY_TO(TraverseStmt(T->getIndexExpr()));
1135})
1136
1137DEF_TRAVERSE_TYPE(UnaryTransformType, {
1138 TRY_TO(TraverseType(T->getBaseType()));
1139 TRY_TO(TraverseType(T->getUnderlyingType()));
1140})
1141
1143 TRY_TO(TraverseType(T->getDeducedType()));
1144 if (T->isConstrained()) {
1145 TRY_TO(TraverseTemplateArguments(T->getTypeConstraintArguments()));
1146 }
1147})
1148
1149DEF_TRAVERSE_TYPE(TemplateTypeParmType, {})
1150DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, {
1151 TRY_TO(TraverseType(T->getReplacementType()));
1152})
1153DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType,
1154 { TRY_TO(TraverseSubstPackTypeHelper(T)); })
1155DEF_TRAVERSE_TYPE(SubstBuiltinTemplatePackType,
1156 { TRY_TO(TraverseSubstPackTypeHelper(T)); })
1157
1158DEF_TRAVERSE_TYPE(AttributedType,
1159 { TRY_TO(TraverseType(T->getModifiedType())); })
1160
1161DEF_TRAVERSE_TYPE(CountAttributedType, {
1162 if (T->getCountExpr())
1163 TRY_TO(TraverseStmt(T->getCountExpr()));
1164 TRY_TO(TraverseType(T->desugar()));
1165})
1166
1167DEF_TRAVERSE_TYPE(BTFTagAttributedType,
1168 { TRY_TO(TraverseType(T->getWrappedType())); })
1169
1170DEF_TRAVERSE_TYPE(OverflowBehaviorType,
1171 { TRY_TO(TraverseType(T->getUnderlyingType())); })
1172
1173DEF_TRAVERSE_TYPE(HLSLAttributedResourceType,
1174 { TRY_TO(TraverseType(T->getWrappedType())); })
1175
1176DEF_TRAVERSE_TYPE(HLSLInlineSpirvType, {
1177 for (auto &Operand : T->getOperands()) {
1178 if (Operand.isConstant() || Operand.isType()) {
1179 TRY_TO(TraverseType(Operand.getResultType()));
1180 }
1181 }
1182})
1183
1184DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
1185
1187 { TRY_TO(TraverseType(T->getUnderlyingType())); })
1188
1189template <typename Derived>
1190bool RecursiveASTVisitor<Derived>::TraverseTagType(TagType *T,
1191 bool TraverseQualifier) {
1192 if (TraverseQualifier)
1193 TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
1194 return true;
1195}
1196
1197DEF_TRAVERSE_TYPE(EnumType, { TRY_TO(TraverseTagType(T, TraverseQualifier)); })
1198DEF_TRAVERSE_TYPE(RecordType,
1199 { TRY_TO(TraverseTagType(T, TraverseQualifier)); })
1200DEF_TRAVERSE_TYPE(InjectedClassNameType,
1201 { TRY_TO(TraverseTagType(T, TraverseQualifier)); })
1202
1203DEF_TRAVERSE_TYPE(DependentNameType, {
1204 if (TraverseQualifier)
1205 TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
1206})
1207
1208DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
1209 if (TraverseQualifier) {
1210 TRY_TO(TraverseTemplateName(T->getTemplateName()));
1211 } else {
1212 // FIXME: Try to preserve the rest of the template name.
1213 TRY_TO(TraverseTemplateName(TemplateName(
1214 T->getTemplateName().getAsTemplateDecl(/*IgnoreDeduced=*/true))));
1215 }
1216 TRY_TO(TraverseTemplateArguments(T->template_arguments()));
1217})
1218
1219DEF_TRAVERSE_TYPE(DeducedTemplateSpecializationType, {
1220 if (TraverseQualifier) {
1221 TRY_TO(TraverseTemplateName(T->getTemplateName()));
1222 } else {
1223 // FIXME: Try to preserve the rest of the template name.
1224 TRY_TO(TraverseTemplateName(TemplateName(
1225 T->getTemplateName().getAsTemplateDecl(/*IgnoreDeduced=*/true))));
1226 }
1227 TRY_TO(TraverseType(T->getDeducedType()));
1228})
1229
1230DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); })
1231
1232DEF_TRAVERSE_TYPE(ObjCTypeParamType, {})
1233
1235
1236DEF_TRAVERSE_TYPE(ObjCObjectType, {
1237 // We have to watch out here because an ObjCInterfaceType's base
1238 // type is itself.
1239 if (T->getBaseType().getTypePtr() != T)
1240 TRY_TO(TraverseType(T->getBaseType()));
1241 for (auto typeArg : T->getTypeArgsAsWritten()) {
1242 TRY_TO(TraverseType(typeArg));
1243 }
1244})
1245
1247 { TRY_TO(TraverseType(T->getPointeeType())); })
1248
1249DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); })
1250
1251DEF_TRAVERSE_TYPE(PipeType, { TRY_TO(TraverseType(T->getElementType())); })
1252
1255 { TRY_TO(TraverseStmt(T->getNumBitsExpr())); })
1256
1258
1259#undef DEF_TRAVERSE_TYPE
1260
1261// ----------------- TypeLoc traversal -----------------
1262
1263// This macro makes available a variable TL, the passed-in TypeLoc.
1264// If requested, it calls WalkUpFrom* for the Type in the given TypeLoc,
1265// in addition to WalkUpFrom* for the TypeLoc itself, such that existing
1266// clients that override the WalkUpFrom*Type() and/or Visit*Type() methods
1267// continue to work.
1268#define DEF_TRAVERSE_TYPELOC(TYPE, CODE) \
1269 template <typename Derived> \
1271 TYPE##Loc TL, bool TraverseQualifier) { \
1272 if (!getDerived().shouldTraversePostOrder()) { \
1273 TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
1274 if (getDerived().shouldWalkTypesOfTypeLocs()) \
1275 TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \
1276 } \
1277 { \
1278 CODE; \
1279 } \
1280 if (getDerived().shouldTraversePostOrder()) { \
1281 TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
1282 if (getDerived().shouldWalkTypesOfTypeLocs()) \
1283 TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \
1284 } \
1285 return true; \
1286 }
1287
1288template <typename Derived>
1290 QualifiedTypeLoc TL, bool TraverseQualifier) {
1291 assert(TraverseQualifier &&
1292 "Qualifiers should never occur within NestedNameSpecifiers");
1293 // Move this over to the 'main' typeloc tree. Note that this is a
1294 // move -- we pretend that we were really looking at the unqualified
1295 // typeloc all along -- rather than a recursion, so we don't follow
1296 // the normal CRTP plan of going through
1297 // getDerived().TraverseTypeLoc. If we did, we'd be traversing
1298 // twice for the same type (once as a QualifiedTypeLoc version of
1299 // the type, once as an UnqualifiedTypeLoc version of the type),
1300 // which in effect means we'd call VisitTypeLoc twice with the
1301 // 'same' type. This solves that problem, at the cost of never
1302 // seeing the qualified version of the type (unless the client
1303 // subclasses TraverseQualifiedTypeLoc themselves). It's not a
1304 // perfect solution. A perfect solution probably requires making
1305 // QualifiedTypeLoc a wrapper around TypeLoc -- like QualType is a
1306 // wrapper around Type* -- rather than being its own class in the
1307 // type hierarchy.
1308 return TraverseTypeLoc(TL.getUnqualifiedLoc());
1309}
1310
1312
1313// FIXME: ComplexTypeLoc is unfinished
1315 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1316})
1317
1319 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1320
1322 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1323
1325 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1326
1328 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1329
1330// We traverse this in the type case as well, but how is it not reached through
1331// the pointee type?
1333 if (NestedNameSpecifierLoc QL = TL.getQualifierLoc())
1335 else
1336 TRY_TO(TraverseNestedNameSpecifier(TL.getTypePtr()->getQualifier()));
1337 TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
1338})
1339
1341 { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
1342
1344 { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
1345
1346template <typename Derived>
1347bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
1348 // This isn't available for ArrayType, but is for the ArrayTypeLoc.
1349 TRY_TO(TraverseStmt(TL.getSizeExpr()));
1350 return true;
1351}
1352
1354 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1355 TRY_TO(TraverseArrayTypeLocHelper(TL));
1356})
1357
1359 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1360 TRY_TO(TraverseArrayTypeLocHelper(TL));
1361})
1362
1364 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1365 TRY_TO(TraverseArrayTypeLocHelper(TL));
1366})
1367
1369 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1370 TRY_TO(TraverseArrayTypeLocHelper(TL));
1371})
1372
1374 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1375 TRY_TO(TraverseArrayTypeLocHelper(TL));
1376})
1377
1379 TRY_TO(TraverseStmt(TL.getTypePtr()->getAddrSpaceExpr()));
1380 TRY_TO(TraverseType(TL.getTypePtr()->getPointeeType()));
1381})
1382
1383// FIXME: order? why not size expr first?
1384// FIXME: base VectorTypeLoc is unfinished
1386 if (TL.getTypePtr()->getSizeExpr())
1387 TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
1388 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1389})
1390
1391// FIXME: VectorTypeLoc is unfinished
1393 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1394})
1395
1397 if (TL.getTypePtr()->getSizeExpr())
1398 TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
1399 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1400})
1401
1402// FIXME: size and attributes
1403// FIXME: base VectorTypeLoc is unfinished
1405 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1406})
1407
1409 TRY_TO(TraverseStmt(TL.getAttrRowOperand()));
1410 TRY_TO(TraverseStmt(TL.getAttrColumnOperand()));
1411 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1412})
1413
1415 TRY_TO(TraverseStmt(TL.getAttrRowOperand()));
1416 TRY_TO(TraverseStmt(TL.getAttrColumnOperand()));
1417 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1418})
1419
1421 { TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); })
1422
1423// FIXME: location of exception specifications (attributes?)
1425 TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
1426
1427 const FunctionProtoType *T = TL.getTypePtr();
1428
1429 for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) {
1430 if (TL.getParam(I)) {
1431 TRY_TO(TraverseDecl(TL.getParam(I)));
1432 } else if (I < T->getNumParams()) {
1433 TRY_TO(TraverseType(T->getParamType(I)));
1434 }
1435 }
1436
1437 for (const auto &E : T->exceptions()) {
1438 TRY_TO(TraverseType(E));
1439 }
1440
1441 if (Expr *NE = T->getNoexceptExpr())
1442 TRY_TO(TraverseStmt(NE));
1443})
1444
1446 if (NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
1447 TraverseQualifier && QualifierLoc)
1449})
1451 if (NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
1452 TraverseQualifier && QualifierLoc)
1454})
1456 if (NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
1457 TraverseQualifier && QualifierLoc)
1459})
1460
1462 { TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); })
1463
1464DEF_TRAVERSE_TYPELOC(TypeOfType, {
1465 TRY_TO(TraverseTypeLoc(TL.getUnmodifiedTInfo()->getTypeLoc()));
1466})
1467
1468// FIXME: location of underlying expr
1469DEF_TRAVERSE_TYPELOC(DecltypeType, {
1470 TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
1471})
1472
1473DEF_TRAVERSE_TYPELOC(PackIndexingType, {
1474 TRY_TO(TraverseType(TL.getPattern()));
1475 TRY_TO(TraverseStmt(TL.getTypePtr()->getIndexExpr()));
1476})
1477
1478DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
1479 TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
1480})
1481
1482DEF_TRAVERSE_TYPELOC(AutoType, {
1483 TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
1484 if (TL.isConstrained()) {
1485 TRY_TO(TraverseConceptReference(TL.getConceptReference()));
1486 }
1487})
1488
1489DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {})
1490DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, {
1491 TRY_TO(TraverseType(TL.getTypePtr()->getReplacementType()));
1492})
1493
1494template <typename Derived>
1495bool RecursiveASTVisitor<Derived>::TraverseSubstPackTypeLocHelper(
1496 SubstPackTypeLoc TL) {
1497 TRY_TO(TraverseTemplateArgument(TL.getTypePtr()->getArgumentPack()));
1498 return true;
1499}
1500
1501template <typename Derived>
1502bool RecursiveASTVisitor<Derived>::TraverseSubstPackTypeHelper(
1503 SubstPackType *T) {
1504 TRY_TO(TraverseTemplateArgument(T->getArgumentPack()));
1505 return true;
1506}
1507
1508DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType,
1509 { TRY_TO(TraverseSubstPackTypeLocHelper(TL)); })
1510
1511DEF_TRAVERSE_TYPELOC(SubstBuiltinTemplatePackType,
1512 { TRY_TO(TraverseSubstPackTypeLocHelper(TL)); })
1513
1514DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
1515
1517 { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
1518
1519DEF_TRAVERSE_TYPELOC(AttributedType,
1520 { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
1521
1523 { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
1524
1525DEF_TRAVERSE_TYPELOC(BTFTagAttributedType,
1526 { TRY_TO(TraverseTypeLoc(TL.getWrappedLoc())); })
1527
1528DEF_TRAVERSE_TYPELOC(OverflowBehaviorType,
1529 { TRY_TO(TraverseTypeLoc(TL.getWrappedLoc())); })
1530
1531DEF_TRAVERSE_TYPELOC(HLSLAttributedResourceType,
1532 { TRY_TO(TraverseTypeLoc(TL.getWrappedLoc())); })
1533
1534DEF_TRAVERSE_TYPELOC(HLSLInlineSpirvType,
1535 { TRY_TO(TraverseType(TL.getType())); })
1536
1537template <typename Derived>
1538bool RecursiveASTVisitor<Derived>::TraverseTagTypeLoc(TagTypeLoc TL,
1539 bool TraverseQualifier) {
1540 if (NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
1541 TraverseQualifier && QualifierLoc)
1543 return true;
1544}
1545
1546DEF_TRAVERSE_TYPELOC(EnumType,
1547 { TRY_TO(TraverseTagTypeLoc(TL, TraverseQualifier)); })
1548DEF_TRAVERSE_TYPELOC(RecordType,
1549 { TRY_TO(TraverseTagTypeLoc(TL, TraverseQualifier)); })
1550DEF_TRAVERSE_TYPELOC(InjectedClassNameType,
1551 { TRY_TO(TraverseTagTypeLoc(TL, TraverseQualifier)); })
1552
1553DEF_TRAVERSE_TYPELOC(DependentNameType, {
1554 if (TraverseQualifier)
1555 TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
1556})
1557
1558DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
1559 if (TraverseQualifier)
1560 TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
1561
1562 // FIXME: Try to preserve the rest of the template name.
1563 TRY_TO(TraverseTemplateName(
1564 TemplateName(TL.getTypePtr()->getTemplateName().getAsTemplateDecl(
1565 /*IgnoreDeduced=*/true))));
1566
1567 for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
1568 TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
1569 }
1570})
1571
1572DEF_TRAVERSE_TYPELOC(DeducedTemplateSpecializationType, {
1573 if (TraverseQualifier)
1574 TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
1575
1576 const auto *T = TL.getTypePtr();
1577 // FIXME: Try to preserve the rest of the template name.
1578 TRY_TO(
1579 TraverseTemplateName(TemplateName(T->getTemplateName().getAsTemplateDecl(
1580 /*IgnoreDeduced=*/true))));
1581
1582 TRY_TO(TraverseType(T->getDeducedType()));
1583})
1584
1585DEF_TRAVERSE_TYPELOC(PackExpansionType,
1586 { TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); })
1587
1588DEF_TRAVERSE_TYPELOC(ObjCTypeParamType, {
1589 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1590 ObjCProtocolLoc ProtocolLoc(TL.getProtocol(I), TL.getProtocolLoc(I));
1591 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1592 }
1593})
1594
1596
1597DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
1598 // We have to watch out here because an ObjCInterfaceType's base
1599 // type is itself.
1600 if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
1601 TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
1602 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
1603 TRY_TO(TraverseTypeLoc(TL.getTypeArgTInfo(i)->getTypeLoc()));
1604 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1605 ObjCProtocolLoc ProtocolLoc(TL.getProtocol(I), TL.getProtocolLoc(I));
1606 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1607 }
1608})
1609
1611 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1612
1613DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
1614
1615DEF_TRAVERSE_TYPELOC(PipeType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
1616
1619 TRY_TO(TraverseStmt(TL.getTypePtr()->getNumBitsExpr()));
1620})
1621
1623
1625
1626// ----------------- Decl traversal -----------------
1627//
1628// For a Decl, we automate (in the DEF_TRAVERSE_DECL macro) traversing
1629// the children that come from the DeclContext associated with it.
1630// Therefore each Traverse* only needs to worry about children other
1631// than those.
1632
1633template <typename Derived>
1635 const Decl *Child) {
1636 // BlockDecls are traversed through BlockExprs,
1637 // CapturedDecls are traversed through CapturedStmts.
1638 if (isa<BlockDecl>(Child) || isa<CapturedDecl>(Child))
1639 return true;
1640 // Lambda classes are traversed through LambdaExprs.
1641 if (const CXXRecordDecl* Cls = dyn_cast<CXXRecordDecl>(Child))
1642 return Cls->isLambda();
1643 return false;
1644}
1645
1646template <typename Derived>
1647bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
1648 if (!DC)
1649 return true;
1650
1651 for (auto *Child : DC->decls()) {
1652 if (!canIgnoreChildDeclWhileTraversingDeclContext(Child))
1653 TRY_TO(TraverseDecl(Child));
1654 }
1655
1656 return true;
1657}
1658
1659// This macro makes available a variable D, the passed-in decl.
1660#define DEF_TRAVERSE_DECL(DECL, CODE) \
1661 template <typename Derived> \
1662 bool RecursiveASTVisitor<Derived>::Traverse##DECL(DECL *D) { \
1663 bool ShouldVisitChildren = true; \
1664 bool ReturnValue = true; \
1665 if (!getDerived().shouldTraversePostOrder()) \
1666 TRY_TO(WalkUpFrom##DECL(D)); \
1667 { CODE; } \
1668 if (ReturnValue && ShouldVisitChildren) \
1669 TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D))); \
1670 if (ReturnValue) { \
1671 /* Visit any attributes attached to this declaration. */ \
1672 for (auto *I : D->attrs()) \
1673 TRY_TO(getDerived().TraverseAttr(I)); \
1674 } \
1675 if (ReturnValue && getDerived().shouldTraversePostOrder()) \
1676 TRY_TO(WalkUpFrom##DECL(D)); \
1677 return ReturnValue; \
1678 }
1679
1681
1683 if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
1684 TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
1685 TRY_TO(TraverseStmt(D->getBody()));
1686 for (const auto &I : D->captures()) {
1687 if (I.hasCopyExpr()) {
1688 TRY_TO(TraverseStmt(I.getCopyExpr()));
1689 }
1690 }
1691 ShouldVisitChildren = false;
1692})
1693
1695 TRY_TO(TraverseStmt(D->getBody()));
1696 ShouldVisitChildren = false;
1697})
1698
1700 TRY_TO(TraverseStmt(D->getBody()));
1701 ShouldVisitChildren = false;
1702})
1703
1705
1707
1709
1711 TRY_TO(TraverseStmt(D->getTemporaryExpr()));
1712})
1713
1715 { TRY_TO(TraverseStmt(D->getAsmStringExpr())); })
1716
1717DEF_TRAVERSE_DECL(TopLevelStmtDecl, { TRY_TO(TraverseStmt(D->getStmt())); })
1718
1720
1722 // Friend is either decl or a type.
1723 if (D->getFriendType()) {
1724 TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
1725 // Traverse any CXXRecordDecl owned by this type, since
1726 // it will not be in the parent context:
1727 if (auto *TT = D->getFriendType()->getType()->getAs<TagType>();
1728 TT && TT->isTagOwned())
1729 TRY_TO(TraverseDecl(TT->getDecl()));
1730 } else {
1731 TRY_TO(TraverseDecl(D->getFriendDecl()));
1732 }
1733})
1734
1736 if (D->getFriendType())
1737 TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
1738 else
1739 TRY_TO(TraverseDecl(D->getFriendDecl()));
1740 for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
1741 TemplateParameterList *TPL = D->getTemplateParameterList(I);
1742 for (TemplateParameterList::iterator ITPL = TPL->begin(), ETPL = TPL->end();
1743 ITPL != ETPL; ++ITPL) {
1744 TRY_TO(TraverseDecl(*ITPL));
1745 }
1746 }
1747})
1748
1750
1752
1753DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {// FIXME: implement this
1754 })
1755
1757 TRY_TO(TraverseStmt(D->getAssertExpr()));
1758 TRY_TO(TraverseStmt(D->getMessage()));
1759})
1760
1762 // No double visiting: getTypeAsWritten() returns null for class
1763 // templates/nested classes where the qualifier lives inside the TSI.
1764 if (D->getQualifierLoc())
1765 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1766 if (TypeSourceInfo *TSI = D->getTypeAsWritten())
1767 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
1768 for (unsigned I = 0, E = D->getNumTemplateArgs(); I != E; ++I)
1769 TRY_TO(TraverseTemplateArgumentLoc(D->getTemplateArg(I)));
1770})
1771
1773 // Code in an unnamed namespace shows up automatically in
1774 // decls_begin()/decls_end(). Thus we don't need to recurse on
1775 // D->getAnonymousNamespace().
1776
1777 // If the traversal scope is set, then consider them to be the children of
1778 // the TUDecl, rather than traversing (and loading?) all top-level decls.
1779 auto Scope = D->getASTContext().getTraversalScope();
1780 bool HasLimitedScope =
1781 Scope.size() != 1 || !isa<TranslationUnitDecl>(Scope.front());
1782 if (HasLimitedScope) {
1783 ShouldVisitChildren = false; // we'll do that here instead
1784 for (auto *Child : Scope) {
1785 if (!canIgnoreChildDeclWhileTraversingDeclContext(Child))
1786 TRY_TO(TraverseDecl(Child));
1787 }
1788 }
1789})
1790
1792
1794
1796
1798 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1799
1800 // We shouldn't traverse an aliased namespace, since it will be
1801 // defined (and, therefore, traversed) somewhere else.
1802 ShouldVisitChildren = false;
1803})
1804
1805DEF_TRAVERSE_DECL(LabelDecl, {// There is no code in a LabelDecl.
1806 })
1807
1810 {// Code in an unnamed namespace shows up automatically in
1811 // decls_begin()/decls_end(). Thus we don't need to recurse on
1812 // D->getAnonymousNamespace().
1813 })
1814
1815DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement
1816 })
1817
1819 if (ObjCTypeParamList *typeParamList = D->getTypeParamList()) {
1820 for (auto typeParam : *typeParamList) {
1821 TRY_TO(TraverseObjCTypeParamDecl(typeParam));
1822 }
1823 }
1824 for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
1825 ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
1826 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1827 }
1828})
1829
1830DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement
1831 })
1832
1833DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement
1834 })
1835
1837 if (ObjCTypeParamList *typeParamList = D->getTypeParamListAsWritten()) {
1838 for (auto typeParam : *typeParamList) {
1839 TRY_TO(TraverseObjCTypeParamDecl(typeParam));
1840 }
1841 }
1842
1843 if (TypeSourceInfo *superTInfo = D->getSuperClassTInfo()) {
1844 TRY_TO(TraverseTypeLoc(superTInfo->getTypeLoc()));
1845 }
1846 if (D->isThisDeclarationADefinition()) {
1847 for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
1848 ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
1849 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1850 }
1851 }
1852})
1853
1855 if (D->isThisDeclarationADefinition()) {
1856 for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
1857 ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
1858 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1859 }
1860 }
1861})
1862
1864 if (D->getReturnTypeSourceInfo()) {
1865 TRY_TO(TraverseTypeLoc(D->getReturnTypeSourceInfo()->getTypeLoc()));
1866 }
1867 for (ParmVarDecl *Parameter : D->parameters()) {
1868 TRY_TO(TraverseDecl(Parameter));
1869 }
1870 if (D->isThisDeclarationADefinition()) {
1871 TRY_TO(TraverseStmt(D->getBody()));
1872 }
1873 ShouldVisitChildren = false;
1874})
1875
1877 if (D->hasExplicitBound()) {
1878 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
1879 // We shouldn't traverse D->getTypeForDecl(); it's a result of
1880 // declaring the type alias, not something that was written in the
1881 // source.
1882 }
1883})
1884
1886 if (D->getTypeSourceInfo())
1887 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
1888 else
1889 TRY_TO(TraverseType(D->getType()));
1890 ShouldVisitChildren = false;
1891})
1892
1894 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1895 TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
1896})
1897
1899 { TRY_TO(TraverseTypeLoc(D->getEnumTypeLoc())); })
1900
1902
1904 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1905})
1906
1908
1910
1912 for (auto *I : D->varlist()) {
1913 TRY_TO(TraverseStmt(I));
1914 }
1915})
1916
1918 for (auto *I : D->varlist()) {
1919 TRY_TO(TraverseStmt(I));
1920 }
1921})
1922
1924 for (auto *C : D->clauselists()) {
1925 TRY_TO(TraverseOMPClause(C));
1926 }
1927})
1928
1930 TRY_TO(TraverseStmt(D->getCombiner()));
1931 if (auto *Initializer = D->getInitializer())
1932 TRY_TO(TraverseStmt(Initializer));
1933 TRY_TO(TraverseType(D->getType()));
1934 return true;
1935})
1936
1938 for (auto *C : D->clauselists())
1939 TRY_TO(TraverseOMPClause(C));
1940 TRY_TO(TraverseType(D->getType()));
1941 return true;
1942})
1943
1944DEF_TRAVERSE_DECL(OMPCapturedExprDecl, { TRY_TO(TraverseVarHelper(D)); })
1945
1947 for (auto *I : D->varlist())
1948 TRY_TO(TraverseStmt(I));
1949 for (auto *C : D->clauselists())
1950 TRY_TO(TraverseOMPClause(C));
1951})
1952
1954 { TRY_TO(VisitOpenACCClauseList(D->clauses())); })
1955
1957 TRY_TO(TraverseStmt(D->getFunctionReference()));
1958 TRY_TO(VisitOpenACCClauseList(D->clauses()));
1959})
1960
1961// A helper method for TemplateDecl's children.
1962template <typename Derived>
1963bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
1964 TemplateParameterList *TPL) {
1965 if (TPL) {
1966 for (NamedDecl *D : *TPL) {
1967 TRY_TO(TraverseDecl(D));
1968 }
1969 if (Expr *RequiresClause = TPL->getRequiresClause()) {
1970 TRY_TO(TraverseStmt(RequiresClause));
1971 }
1972 }
1973 return true;
1974}
1975
1976template <typename Derived>
1977template <typename T>
1978bool RecursiveASTVisitor<Derived>::TraverseDeclTemplateParameterLists(T *D) {
1979 for (TemplateParameterList *TPL : D->getTemplateParameterLists())
1980 TraverseTemplateParameterListHelper(TPL);
1981 return true;
1982}
1983
1984template <typename Derived>
1986 ClassTemplateDecl *D) {
1987 for (auto *SD : D->specializations()) {
1988 for (auto *RD : SD->redecls()) {
1989 assert(!cast<CXXRecordDecl>(RD)->isInjectedClassName());
1990 switch (
1991 cast<ClassTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
1992 // Visit the implicit instantiations with the requested pattern.
1993 case TSK_Undeclared:
1995 TRY_TO(TraverseDecl(RD));
1996 break;
1997
1998 // We don't need to do anything on an explicit instantiation
1999 // or explicit specialization because there will be an explicit
2000 // node for it elsewhere.
2004 break;
2005 }
2006 }
2007 }
2008
2009 return true;
2010}
2011
2012template <typename Derived>
2014 VarTemplateDecl *D) {
2015 for (auto *SD : D->specializations()) {
2016 for (auto *RD : SD->redecls()) {
2017 switch (
2018 cast<VarTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
2019 case TSK_Undeclared:
2021 TRY_TO(TraverseDecl(RD));
2022 break;
2023
2027 break;
2028 }
2029 }
2030 }
2031
2032 return true;
2033}
2034
2035// A helper method for traversing the instantiations of a
2036// function while skipping its specializations.
2037template <typename Derived>
2040 for (auto *FD : D->specializations()) {
2041 for (auto *RD : FD->redecls()) {
2042 switch (RD->getTemplateSpecializationKind()) {
2043 case TSK_Undeclared:
2045 // We don't know what kind of FunctionDecl this is.
2046 TRY_TO(TraverseDecl(RD));
2047 break;
2048
2049 // Unlike class/variable template specializations, function template
2050 // specializations are not independent children of the DeclContext —
2051 // they are only reachable via FunctionTemplateDecl::specializations().
2052 // We must traverse them here so visitors can see the instantiated body.
2055 TRY_TO(TraverseDecl(RD));
2056 break;
2057
2059 break;
2060 }
2061 }
2062 }
2063
2064 return true;
2065}
2066
2067// This macro unifies the traversal of class, variable and function
2068// template declarations.
2069#define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND) \
2070 DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, { \
2071 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
2072 TRY_TO(TraverseDecl(D->getTemplatedDecl())); \
2073 \
2074 /* By default, we do not traverse the instantiations of \
2075 class templates since they do not appear in the user code. The \
2076 following code optionally traverses them. \
2077 \
2078 We only traverse the class instantiations when we see the canonical \
2079 declaration of the template, to ensure we only visit them once. */ \
2080 if (getDerived().shouldVisitTemplateInstantiations() && \
2081 D == D->getCanonicalDecl()) \
2082 TRY_TO(TraverseTemplateInstantiations(D)); \
2083 \
2084 /* Note that getInstantiatedFromMemberTemplate() is just a link \
2085 from a template instantiation back to the template from which \
2086 it was instantiated, and thus should not be traversed. */ \
2087 })
2088
2092
2094 // D is the "T" in something like
2095 // template <template <typename> class T> class container { };
2096 TRY_TO(TraverseDecl(D->getTemplatedDecl()));
2097 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
2098 TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
2099 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
2100})
2101
2103 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
2104})
2105
2106template <typename Derived>
2107bool RecursiveASTVisitor<Derived>::TraverseTemplateTypeParamDeclConstraints(
2108 const TemplateTypeParmDecl *D) {
2109 if (const auto *TC = D->getTypeConstraint())
2110 TRY_TO(TraverseTypeConstraint(TC));
2111 return true;
2112}
2113
2115 // D is the "T" in something like "template<typename T> class vector;"
2116 if (D->getTypeForDecl())
2117 TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
2118 TRY_TO(TraverseTemplateTypeParamDeclConstraints(D));
2119 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
2120 TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
2121})
2122
2124 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
2125 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2126 // declaring the typedef, not something that was written in the
2127 // source.
2128})
2129
2131 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
2132 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2133 // declaring the type alias, not something that was written in the
2134 // source.
2135})
2136
2138 TRY_TO(TraverseDecl(D->getTemplatedDecl()));
2139 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
2140})
2141
2143 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
2144 TRY_TO(TraverseStmt(D->getConstraintExpr()));
2145})
2146
2148 // A dependent using declaration which was marked with 'typename'.
2149 // template<class T> class A : public B<T> { using typename B<T>::foo; };
2150 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2151 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2152 // declaring the type, not something that was written in the
2153 // source.
2154})
2155
2157
2159 TRY_TO(TraverseDeclTemplateParameterLists(D));
2160
2161 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2162 if (auto *TSI = D->getIntegerTypeSourceInfo())
2163 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
2164 // The enumerators are already traversed by
2165 // decls_begin()/decls_end().
2166})
2167
2168// Helper methods for RecordDecl and its children.
2169template <typename Derived>
2170bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) {
2171 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2172 // declaring the type, not something that was written in the source.
2173
2174 TRY_TO(TraverseDeclTemplateParameterLists(D));
2175 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2176 return true;
2177}
2178
2179template <typename Derived>
2181 const CXXBaseSpecifier &Base) {
2182 TRY_TO(TraverseTypeLoc(Base.getTypeSourceInfo()->getTypeLoc()));
2183 return true;
2184}
2185
2186template <typename Derived>
2187bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(CXXRecordDecl *D) {
2188 if (!TraverseRecordHelper(D))
2189 return false;
2190 if (D->isCompleteDefinition()) {
2191 for (const auto &I : D->bases()) {
2192 TRY_TO(TraverseCXXBaseSpecifier(I));
2193 }
2194 // We don't traverse the friends or the conversions, as they are
2195 // already in decls_begin()/decls_end().
2196 }
2197 return true;
2198}
2199
2200DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); })
2201
2202DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
2203
2204template <typename Derived>
2205bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
2206 const TemplateArgumentLoc *TAL, unsigned Count) {
2207 for (unsigned I = 0; I < Count; ++I) {
2208 TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
2209 }
2210 return true;
2211}
2212
2213#define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
2214 DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, { \
2215 /* For implicit instantiations ("set<int> x;"), we don't want to \
2216 recurse at all, since the instatiated template isn't written in \
2217 the source code anywhere. (Note the instatiated *type* -- \
2218 set<int> -- is written, and will still get a callback of \
2219 TemplateSpecializationType). For explicit instantiations \
2220 ("template set<int>;"), the ExplicitInstantiationDecl node \
2221 handles traversal of template args and qualifier. \
2222 For explicit specializations ("template<> set<int> {...};"), \
2223 we traverse template args here since there is no EID. */ \
2224 if (const auto *ArgsWritten = D->getTemplateArgsAsWritten()) { \
2225 assert(D->getTemplateSpecializationKind() != TSK_ImplicitInstantiation); \
2226 if (D->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) { \
2227 TRY_TO(TraverseTemplateArgumentLocsHelper( \
2228 ArgsWritten->getTemplateArgs(), ArgsWritten->NumTemplateArgs)); \
2229 } \
2230 } \
2231 \
2232 if (getDerived().shouldVisitTemplateInstantiations() || \
2233 D->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) { \
2234 /* Traverse base definition for explicit specializations */ \
2235 TRY_TO(Traverse##DECLKIND##Helper(D)); \
2236 } else { \
2237 /* Returning from here skips traversing the \
2238 declaration context of the *TemplateSpecializationDecl \
2239 (embedded in the DEF_TRAVERSE_DECL() macro) \
2240 which contains the instantiated members of the template. */ \
2241 return true; \
2242 } \
2243 })
2244
2247
2248#define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
2249 DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, { \
2250 /* The partial specialization. */ \
2251 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
2252 /* The args that remains unspecialized. */ \
2253 TRY_TO(TraverseTemplateArgumentLocsHelper( \
2254 D->getTemplateArgsAsWritten()->getTemplateArgs(), \
2255 D->getTemplateArgsAsWritten()->NumTemplateArgs)); \
2256 \
2257 /* Don't need the *TemplatePartialSpecializationHelper, even \
2258 though that's our parent class -- we already visit all the \
2259 template args here. */ \
2260 TRY_TO(Traverse##DECLKIND##Helper(D)); \
2261 \
2262 /* Instantiations will have been visited with the primary template. */ \
2263 })
2264
2267
2268DEF_TRAVERSE_DECL(EnumConstantDecl, { TRY_TO(TraverseStmt(D->getInitExpr())); })
2269
2271 // Like UnresolvedUsingTypenameDecl, but without the 'typename':
2272 // template <class T> Class A : public Base<T> { using Base<T>::foo; };
2273 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2274 TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
2275})
2276
2278
2279template <typename Derived>
2280bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
2281 TRY_TO(TraverseDeclTemplateParameterLists(D));
2282 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2283 if (D->getTypeSourceInfo())
2284 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
2285 else
2286 TRY_TO(TraverseType(D->getType()));
2287 return true;
2288}
2289
2291 TRY_TO(TraverseVarHelper(D));
2292 for (auto *Binding : D->bindings()) {
2293 TRY_TO(TraverseDecl(Binding));
2294 }
2295})
2296
2298 if (getDerived().shouldVisitImplicitCode()) {
2299 TRY_TO(TraverseStmt(D->getBinding()));
2300 if (const auto HoldingVar = D->getHoldingVar())
2301 TRY_TO(TraverseDecl(HoldingVar));
2302 }
2303})
2304
2305DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
2306
2309
2311
2313 TRY_TO(TraverseDeclaratorHelper(D));
2314 if (D->isBitField())
2315 TRY_TO(TraverseStmt(D->getBitWidth()));
2316 if (D->hasInClassInitializer())
2317 TRY_TO(TraverseStmt(D->getInClassInitializer()));
2318})
2319
2321 TRY_TO(TraverseDeclaratorHelper(D));
2322 if (D->isBitField())
2323 TRY_TO(TraverseStmt(D->getBitWidth()));
2324 // FIXME: implement the rest.
2325})
2326
2328 TRY_TO(TraverseDeclaratorHelper(D));
2329 if (D->isBitField())
2330 TRY_TO(TraverseStmt(D->getBitWidth()));
2331 // FIXME: implement the rest.
2332})
2333
2334template <typename Derived>
2335bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
2336 TRY_TO(TraverseDeclTemplateParameterLists(D));
2337 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2338 TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
2339
2340 // If we're an explicit template specialization, iterate over the
2341 // template args that were explicitly specified. If we were doing
2342 // this in typing order, we'd do it between the return type and
2343 // the function args, but both are handled by the FunctionTypeLoc
2344 // above, so we have to choose one side. I've decided to do before.
2345 if (const FunctionTemplateSpecializationInfo *FTSI =
2346 D->getTemplateSpecializationInfo()) {
2347 if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared &&
2348 FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
2349 // A specialization might not have explicit template arguments if it has
2350 // a templated return type and concrete arguments.
2351 if (const ASTTemplateArgumentListInfo *TALI =
2352 FTSI->TemplateArgumentsAsWritten) {
2353 TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
2354 TALI->NumTemplateArgs));
2355 }
2356 }
2357 } else if (const DependentFunctionTemplateSpecializationInfo *DFSI =
2358 D->getDependentSpecializationInfo()) {
2359 if (const ASTTemplateArgumentListInfo *TALI =
2360 DFSI->TemplateArgumentsAsWritten) {
2361 TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
2362 TALI->NumTemplateArgs));
2363 }
2364 }
2365
2366 // Visit the function type itself, which can be either
2367 // FunctionNoProtoType or FunctionProtoType, or a typedef. This
2368 // also covers the return type and the function parameters,
2369 // including exception specifications.
2370 if (TypeSourceInfo *TSI = D->getTypeSourceInfo()) {
2371 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
2372 } else if (getDerived().shouldVisitImplicitCode()) {
2373 // Visit parameter variable declarations of the implicit function
2374 // if the traverser is visiting implicit code. Parameter variable
2375 // declarations do not have valid TypeSourceInfo, so to visit them
2376 // we need to traverse the declarations explicitly.
2377 for (ParmVarDecl *Parameter : D->parameters()) {
2378 TRY_TO(TraverseDecl(Parameter));
2379 }
2380 }
2381
2382 // Visit the trailing requires clause, if any.
2383 if (const AssociatedConstraint &TrailingRequiresClause =
2384 D->getTrailingRequiresClause()) {
2385 TRY_TO(TraverseStmt(
2386 const_cast<Expr *>(TrailingRequiresClause.ConstraintExpr)));
2387 }
2388
2389 if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
2390 // Constructor initializers.
2391 for (auto *I : Ctor->inits()) {
2392 if (I->isWritten() || getDerived().shouldVisitImplicitCode())
2393 TRY_TO(TraverseConstructorInitializer(I));
2394 }
2395 }
2396
2397 bool VisitBody =
2398 D->isThisDeclarationADefinition() &&
2399 // Don't visit the function body if the function definition is generated
2400 // by clang.
2401 (!D->isDefaulted() || getDerived().shouldVisitImplicitCode());
2402
2403 if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
2404 if (const CXXRecordDecl *RD = MD->getParent()) {
2405 if (RD->isLambda() &&
2406 declaresSameEntity(RD->getLambdaCallOperator(), MD)) {
2407 VisitBody = VisitBody && getDerived().shouldVisitLambdaBody();
2408 }
2409 }
2410 }
2411
2412 if (VisitBody) {
2413 TRY_TO(TraverseStmt(D->getBody()));
2414 // Body may contain using declarations whose shadows are parented to the
2415 // FunctionDecl itself.
2416 for (auto *Child : D->decls()) {
2417 if (isa<UsingShadowDecl>(Child))
2418 TRY_TO(TraverseDecl(Child));
2419 }
2420 }
2421 return true;
2422}
2423
2425 // We skip decls_begin/decls_end, which are already covered by
2426 // TraverseFunctionHelper().
2427 ShouldVisitChildren = false;
2428 ReturnValue = TraverseFunctionHelper(D);
2429})
2430
2432 // We skip decls_begin/decls_end, which are already covered by
2433 // TraverseFunctionHelper().
2434 ShouldVisitChildren = false;
2435 ReturnValue = TraverseFunctionHelper(D);
2436})
2437
2439 // We skip decls_begin/decls_end, which are already covered by
2440 // TraverseFunctionHelper().
2441 ShouldVisitChildren = false;
2442 ReturnValue = TraverseFunctionHelper(D);
2443})
2444
2446 // We skip decls_begin/decls_end, which are already covered by
2447 // TraverseFunctionHelper().
2448 ShouldVisitChildren = false;
2449 ReturnValue = TraverseFunctionHelper(D);
2450})
2451
2452// CXXConversionDecl is the declaration of a type conversion operator.
2453// It's not a cast expression.
2455 // We skip decls_begin/decls_end, which are already covered by
2456 // TraverseFunctionHelper().
2457 ShouldVisitChildren = false;
2458 ReturnValue = TraverseFunctionHelper(D);
2459})
2460
2462 // We skip decls_begin/decls_end, which are already covered by
2463 // TraverseFunctionHelper().
2464 ShouldVisitChildren = false;
2465 ReturnValue = TraverseFunctionHelper(D);
2466})
2467
2468template <typename Derived>
2469bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
2470 TRY_TO(TraverseDeclaratorHelper(D));
2471 // Default params are taken care of when we traverse the ParmVarDecl.
2472 if (!isa<ParmVarDecl>(D) &&
2473 (!D->isCXXForRangeDecl() || getDerived().shouldVisitImplicitCode()))
2474 TRY_TO(TraverseStmt(D->getInit()));
2475 return true;
2476}
2477
2478DEF_TRAVERSE_DECL(VarDecl, { TRY_TO(TraverseVarHelper(D)); })
2479
2480DEF_TRAVERSE_DECL(ImplicitParamDecl, { TRY_TO(TraverseVarHelper(D)); })
2481
2483 // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
2484 TRY_TO(TraverseDeclaratorHelper(D));
2485 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
2486 TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
2487})
2488
2490 TRY_TO(TraverseVarHelper(D));
2491
2492 if (D->hasDefaultArg() && D->hasUninstantiatedDefaultArg() &&
2493 !D->hasUnparsedDefaultArg())
2494 TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
2495
2496 if (D->hasDefaultArg() && !D->hasUninstantiatedDefaultArg() &&
2497 !D->hasUnparsedDefaultArg())
2498 TRY_TO(TraverseStmt(D->getDefaultArg()));
2499})
2500
2502
2504 TRY_TO(TraverseTemplateArguments(D->getTemplateArguments()));
2505})
2506
2507#undef DEF_TRAVERSE_DECL
2508
2509// ----------------- Stmt traversal -----------------
2510//
2511// For stmts, we automate (in the DEF_TRAVERSE_STMT macro) iterating
2512// over the children defined in children() (every stmt defines these,
2513// though sometimes the range is empty). Each individual Traverse*
2514// method only needs to worry about children other than those. To see
2515// what children() does for a given class, see, e.g.,
2516// http://clang.llvm.org/doxygen/Stmt_8cpp_source.html
2517
2518// This macro makes available a variable S, the passed-in stmt.
2519#define DEF_TRAVERSE_STMT(STMT, CODE) \
2520 template <typename Derived> \
2522 STMT *S, DataRecursionQueue *Queue) { \
2523 bool ShouldVisitChildren = true; \
2524 bool ReturnValue = true; \
2525 if (!getDerived().shouldTraversePostOrder()) \
2526 TRY_TO(WalkUpFrom##STMT(S)); \
2527 { CODE; } \
2528 if (ShouldVisitChildren) { \
2529 for (Stmt * SubStmt : getDerived().getStmtChildren(S)) { \
2530 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); \
2531 } \
2532 } \
2533 /* Call WalkUpFrom if TRY_TO_TRAVERSE_OR_ENQUEUE_STMT has traversed the \
2534 * children already. If TRY_TO_TRAVERSE_OR_ENQUEUE_STMT only enqueued the \
2535 * children, PostVisitStmt will call WalkUpFrom after we are done visiting \
2536 * children. */ \
2537 if (!Queue && ReturnValue && getDerived().shouldTraversePostOrder()) { \
2538 TRY_TO(WalkUpFrom##STMT(S)); \
2539 } \
2540 return ReturnValue; \
2541 }
2542
2544 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAsmStringExpr());
2545 for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
2546 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInputConstraintExpr(I));
2547 }
2548 for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
2549 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOutputConstraintExpr(I));
2550 }
2551 for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
2552 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getClobberExpr(I));
2553 }
2554 // children() iterates over inputExpr and outputExpr.
2555})
2556
2558 MSAsmStmt,
2559 {// FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc. Once
2560 // added this needs to be implemented.
2561 })
2562
2564 TRY_TO(TraverseDecl(S->getExceptionDecl()));
2565 // children() iterates over the handler block.
2566})
2567
2569 for (auto *I : S->decls()) {
2570 TRY_TO(TraverseDecl(I));
2571 }
2572 // Suppress the default iteration over children() by
2573 // returning. Here's why: A DeclStmt looks like 'type var [=
2574 // initializer]'. The decls above already traverse over the
2575 // initializers, so we don't have to do it again (which
2576 // children() would do).
2577 ShouldVisitChildren = false;
2578})
2579
2580// These non-expr stmts (most of them), do not need any action except
2581// iterating over the children.
2604
2606 if (!getDerived().shouldVisitImplicitCode()) {
2607 if (S->getInit())
2608 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInit());
2609 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLoopVarStmt());
2610 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRangeInit());
2611 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
2612 // Visit everything else only if shouldVisitImplicitCode().
2613 ShouldVisitChildren = false;
2614 }
2615})
2616
2618 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2619 TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
2620})
2621
2625
2627
2629 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2630 TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
2631 if (S->hasExplicitTemplateArgs()) {
2632 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2633 S->getNumTemplateArgs()));
2634 }
2635})
2636
2638 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2639 TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
2640 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2641 S->getNumTemplateArgs()));
2642})
2643
2645 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2646 TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
2647 if (S->hasExplicitTemplateArgs()) {
2648 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2649 S->getNumTemplateArgs()));
2650 }
2651})
2652
2654 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2655 TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
2656 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2657 S->getNumTemplateArgs()));
2658})
2659
2662 {// We don't traverse the cast type, as it's not written in the
2663 // source code.
2664 })
2665
2667 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2668})
2669
2671 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2672})
2673
2675 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2676})
2677
2679 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2680})
2681
2683 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2684})
2685
2687 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2688})
2689
2691 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2692})
2693
2695 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2696})
2697
2698template <typename Derived>
2700 InitListExpr *S, DataRecursionQueue *Queue) {
2701 if (S) {
2702 // Skip this if we traverse postorder. We will visit it later
2703 // in PostVisitStmt.
2704 if (!getDerived().shouldTraversePostOrder())
2705 TRY_TO(WalkUpFromInitListExpr(S));
2706
2707 // All we need are the default actions. FIXME: use a helper function.
2708 for (Stmt *SubStmt : S->children()) {
2710 }
2711
2712 if (!Queue && getDerived().shouldTraversePostOrder())
2713 TRY_TO(WalkUpFromInitListExpr(S));
2714 }
2715 return true;
2716}
2717
2718template <typename Derived>
2720 ObjCProtocolLoc ProtocolLoc) {
2721 return true;
2722}
2723
2724template <typename Derived>
2726 ConceptReference *CR) {
2727 if (!getDerived().shouldTraversePostOrder())
2728 TRY_TO(VisitConceptReference(CR));
2729 TRY_TO(TraverseNestedNameSpecifierLoc(CR->getNestedNameSpecifierLoc()));
2730 TRY_TO(TraverseDeclarationNameInfo(CR->getConceptNameInfo()));
2731 if (CR->hasExplicitTemplateArgs())
2732 TRY_TO(TraverseTemplateArgumentLocsHelper(
2733 CR->getTemplateArgsAsWritten()->getTemplateArgs(),
2734 CR->getTemplateArgsAsWritten()->NumTemplateArgs));
2735 if (getDerived().shouldTraversePostOrder())
2736 TRY_TO(VisitConceptReference(CR));
2737 return true;
2738}
2739
2740template <typename Derived>
2742 const OffsetOfNode *Node) {
2743 TRY_TO(VisitOffsetOfNode(Node));
2744 return true;
2745}
2746
2747// If shouldVisitImplicitCode() returns false, this method traverses only the
2748// syntactic form of InitListExpr.
2749// If shouldVisitImplicitCode() return true, this method is called once for
2750// each pair of syntactic and semantic InitListExpr, and it traverses the
2751// subtrees defined by the two forms. This may cause some of the children to be
2752// visited twice, if they appear both in the syntactic and the semantic form.
2753//
2754// There is no guarantee about which form \p S takes when this method is called.
2755template <typename Derived>
2757 InitListExpr *S, DataRecursionQueue *Queue) {
2758 if (S->isSemanticForm() && S->isSyntacticForm()) {
2759 // `S` does not have alternative forms, traverse only once.
2760 TRY_TO(TraverseSynOrSemInitListExpr(S, Queue));
2761 return true;
2762 }
2763 TRY_TO(TraverseSynOrSemInitListExpr(
2764 S->isSemanticForm() ? S->getSyntacticForm() : S, Queue));
2765 if (getDerived().shouldVisitImplicitCode()) {
2766 // Only visit the semantic form if the clients are interested in implicit
2767 // compiler-generated.
2768 TRY_TO(TraverseSynOrSemInitListExpr(
2769 S->isSemanticForm() ? S : S->getSemanticForm(), Queue));
2770 }
2771 return true;
2772}
2773
2774// GenericSelectionExpr is a special case because the types and expressions
2775// are interleaved. We also need to watch out for null types (default
2776// generic associations).
2778 if (S->isExprPredicate())
2779 TRY_TO(TraverseStmt(S->getControllingExpr()));
2780 else
2781 TRY_TO(TraverseTypeLoc(S->getControllingType()->getTypeLoc()));
2782
2783 for (const GenericSelectionExpr::Association Assoc : S->associations()) {
2784 if (TypeSourceInfo *TSI = Assoc.getTypeSourceInfo())
2785 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
2786 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(Assoc.getAssociationExpr());
2787 }
2788 ShouldVisitChildren = false;
2789})
2790
2791// PseudoObjectExpr is a special case because of the weirdness with
2792// syntactic expressions and opaque values.
2794 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getSyntacticForm());
2795 for (PseudoObjectExpr::semantics_iterator i = S->semantics_begin(),
2796 e = S->semantics_end();
2797 i != e; ++i) {
2798 Expr *sub = *i;
2799 if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub))
2800 sub = OVE->getSourceExpr();
2802 }
2803 ShouldVisitChildren = false;
2804})
2805
2807 // This is called for code like 'return T()' where T is a built-in
2808 // (i.e. non-class) type.
2809 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2810})
2811
2813 // The child-iterator will pick up the other arguments.
2814 TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc()));
2815})
2816
2818 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2819 // Visit each designator component (e.g. the `a`, `b`, `c` in
2820 // offsetof(Foo, a.b.c)). Array index expressions are reached through the
2821 // child-iterator, which DEF_TRAVERSE_STMT walks automatically.
2822 for (unsigned I = 0, E = S->getNumComponents(); I != E; ++I)
2823 TRY_TO(TraverseOffsetOfNode(&S->getComponent(I)));
2824})
2825
2827 // The child-iterator will pick up the arg if it's an expression,
2828 // but not if it's a type.
2829 if (S->isArgumentType())
2830 TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
2831})
2832
2834 // The child-iterator will pick up the arg if it's an expression,
2835 // but not if it's a type.
2836 if (S->isTypeOperand())
2837 TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
2838})
2839
2841 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2842})
2843
2845
2847 // The child-iterator will pick up the arg if it's an expression,
2848 // but not if it's a type.
2849 if (S->isTypeOperand())
2850 TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
2851})
2852
2854 for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
2855 TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc()));
2856})
2857
2859 TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
2860})
2861
2863 { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getQueriedExpression()); })
2864
2866 // The child-iterator will pick up the expression argument.
2867 TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
2868})
2869
2871 // This is called for code like 'return T()' where T is a class type.
2872 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2873})
2874
2875// Walk only the visible parts of lambda expressions.
2877 // Visit the capture list.
2878 for (unsigned I = 0, N = S->capture_size(); I != N; ++I) {
2879 const LambdaCapture *C = S->capture_begin() + I;
2880 if (C->isExplicit() || getDerived().shouldVisitImplicitCode()) {
2881 TRY_TO(TraverseLambdaCapture(S, C, S->capture_init_begin()[I]));
2882 }
2883 }
2884
2885 if (getDerived().shouldVisitImplicitCode()) {
2886 // The implicit model is simple: everything else is in the lambda class.
2887 TRY_TO(TraverseDecl(S->getLambdaClass()));
2888 } else {
2889 // We need to poke around to find the bits that might be explicitly written.
2890 TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2892
2893 TRY_TO(TraverseTemplateParameterListHelper(S->getTemplateParameterList()));
2894 if (S->hasExplicitParameters()) {
2895 // Visit parameters.
2896 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2897 TRY_TO(TraverseDecl(Proto.getParam(I)));
2898 }
2899
2900 auto *T = Proto.getTypePtr();
2901 for (const auto &E : T->exceptions())
2902 TRY_TO(TraverseType(E));
2903
2904 if (Expr *NE = T->getNoexceptExpr())
2906
2907 if (S->hasExplicitResultType())
2908 TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
2910 const_cast<Expr *>(S->getTrailingRequiresClause().ConstraintExpr));
2911
2912 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
2913 }
2914 ShouldVisitChildren = false;
2915})
2916
2918 // This is called for code like 'T()', where T is a template argument.
2919 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2920})
2921
2923
2924// These expressions all might take explicit template arguments.
2925// We traverse those if so. FIXME: implement these.
2929
2930// These exprs (most of them), do not need any action except iterating
2931// over the children.
2939
2941 TRY_TO(TraverseDecl(S->getBlockDecl()));
2942 return true; // no child statements to loop through.
2943})
2944
2947 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2948})
2951
2953 if (getDerived().shouldVisitImplicitCode())
2954 TRY_TO(TraverseStmt(S->getExpr()));
2955})
2956
2958 if (getDerived().shouldVisitImplicitCode())
2959 TRY_TO(TraverseStmt(S->getExpr()));
2960})
2961
2967
2969 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2970 if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
2971 TRY_TO(TraverseTypeLoc(ScopeInfo->getTypeLoc()));
2972 if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo())
2973 TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc()));
2974})
2975
2987 // FIXME: The source expression of the OVE should be listed as
2988 // a child of the ArrayInitLoopExpr.
2989 if (OpaqueValueExpr *OVE = S->getCommonExpr())
2990 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(OVE->getSourceExpr());
2991})
2994
2996 if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
2997 TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
2998})
2999
3002
3004 if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo())
3005 TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
3006})
3007
3009 if (S->isClassReceiver()) {
3010 ObjCInterfaceDecl *IDecl = S->getClassReceiver();
3011 QualType Type = IDecl->getASTContext().getObjCInterfaceType(IDecl);
3013 Data.NameLoc = S->getReceiverLocation();
3014 Data.NameEndLoc = Data.NameLoc;
3015 TRY_TO(TraverseTypeLoc(TypeLoc(Type, &Data)));
3016 }
3017})
3022
3024 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
3025})
3026
3031 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
3032})
3034 if (getDerived().shouldVisitImplicitCode()) {
3035 TRY_TO(TraverseStmt(S->getOriginalStmt()));
3036 TRY_TO(TraverseStmt(S->getKernelLaunchIdExpr()));
3037 ShouldVisitChildren = false;
3038 }
3039})
3047 for (IntegerLiteral *IL : S->underlying_data_elements()) {
3049 }
3050})
3051
3053 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
3054 if (S->hasExplicitTemplateArgs()) {
3055 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
3056 S->getNumTemplateArgs()));
3057 }
3058})
3059
3061 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
3062 if (S->hasExplicitTemplateArgs()) {
3063 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
3064 S->getNumTemplateArgs()));
3065 }
3066})
3067
3072DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
3073
3075 if (getDerived().shouldVisitImplicitCode()) {
3076 TRY_TO(TraverseStmt(S->getOriginalStmt()));
3077 TRY_TO(TraverseStmt(S->getKernelLaunchStmt()));
3078 TRY_TO(TraverseDecl(S->getOutlinedFunctionDecl()));
3079 ShouldVisitChildren = false;
3080 }
3081})
3082
3085 if (!getDerived().shouldVisitImplicitCode()) {
3087 S->getDecomposedForm();
3088 TRY_TO(TraverseStmt(const_cast<Expr*>(Decomposed.LHS)));
3089 TRY_TO(TraverseStmt(const_cast<Expr*>(Decomposed.RHS)));
3090 ShouldVisitChildren = false;
3091 }
3092})
3096
3097// These operators (all of them) do not need any action except
3098// iterating over the children.
3114
3116 if (S->getLifetimeExtendedTemporaryDecl()) {
3117 TRY_TO(TraverseLifetimeExtendedTemporaryDecl(
3118 S->getLifetimeExtendedTemporaryDecl()));
3119 ShouldVisitChildren = false;
3120 }
3121})
3122// For coroutines expressions, traverse either the operand
3123// as written or the implied calls, depending on what the
3124// derived class requests.
3126 if (!getDerived().shouldVisitImplicitCode()) {
3127 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
3128 ShouldVisitChildren = false;
3129 }
3130})
3132 if (!getDerived().shouldVisitImplicitCode()) {
3133 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
3134 ShouldVisitChildren = false;
3135 }
3136})
3138 if (!getDerived().shouldVisitImplicitCode()) {
3139 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
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})
3155
3157 TRY_TO(TraverseConceptReference(S->getConceptReference()));
3158})
3159
3161 TRY_TO(TraverseDecl(S->getBody()));
3162 for (ParmVarDecl *Parm : S->getLocalParameters())
3163 TRY_TO(TraverseDecl(Parm));
3164 for (concepts::Requirement *Req : S->getRequirements())
3165 TRY_TO(TraverseConceptRequirement(Req));
3166})
3167
3168// These literals (all of them) do not need any action.
3179
3180// Traverse OpenCL: AsType, Convert.
3182
3183// OpenMP directives.
3184template <typename Derived>
3185bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
3186 OMPExecutableDirective *S) {
3187 for (auto *C : S->clauses()) {
3188 TRY_TO(TraverseOMPClause(C));
3189 }
3190 return true;
3191}
3192
3193DEF_TRAVERSE_STMT(OMPCanonicalLoop, {
3194 if (!getDerived().shouldVisitImplicitCode()) {
3195 // Visit only the syntactical loop.
3196 TRY_TO(TraverseStmt(S->getLoopStmt()));
3197 ShouldVisitChildren = false;
3198 }
3199})
3200
3201template <typename Derived>
3202bool
3203RecursiveASTVisitor<Derived>::TraverseOMPLoopDirective(OMPLoopDirective *S) {
3204 return TraverseOMPExecutableDirective(S);
3205}
3206
3207DEF_TRAVERSE_STMT(OMPMetaDirective,
3208 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3209
3210DEF_TRAVERSE_STMT(OMPParallelDirective,
3211 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3212
3213DEF_TRAVERSE_STMT(OMPSimdDirective,
3214 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3215
3216DEF_TRAVERSE_STMT(OMPTileDirective,
3217 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3218
3219DEF_TRAVERSE_STMT(OMPStripeDirective,
3220 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3221
3222DEF_TRAVERSE_STMT(OMPUnrollDirective,
3223 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3224
3225DEF_TRAVERSE_STMT(OMPReverseDirective,
3226 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3227
3228DEF_TRAVERSE_STMT(OMPFuseDirective,
3229 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3230
3231DEF_TRAVERSE_STMT(OMPInterchangeDirective,
3232 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3233
3234DEF_TRAVERSE_STMT(OMPSplitDirective,
3235 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3236
3237DEF_TRAVERSE_STMT(OMPForDirective,
3238 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3239
3240DEF_TRAVERSE_STMT(OMPForSimdDirective,
3241 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3242
3243DEF_TRAVERSE_STMT(OMPSectionsDirective,
3244 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3245
3246DEF_TRAVERSE_STMT(OMPSectionDirective,
3247 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3248
3249DEF_TRAVERSE_STMT(OMPScopeDirective,
3250 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3251
3252DEF_TRAVERSE_STMT(OMPSingleDirective,
3253 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3254
3255DEF_TRAVERSE_STMT(OMPMasterDirective,
3256 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3257
3258DEF_TRAVERSE_STMT(OMPCriticalDirective, {
3259 TRY_TO(TraverseDeclarationNameInfo(S->getDirectiveName()));
3260 TRY_TO(TraverseOMPExecutableDirective(S));
3261})
3262
3263DEF_TRAVERSE_STMT(OMPParallelForDirective,
3264 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3265
3266DEF_TRAVERSE_STMT(OMPParallelForSimdDirective,
3267 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3268
3269DEF_TRAVERSE_STMT(OMPParallelMasterDirective,
3270 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3271
3272DEF_TRAVERSE_STMT(OMPParallelMaskedDirective,
3273 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3274
3275DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
3276 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3277
3278DEF_TRAVERSE_STMT(OMPTaskDirective,
3279 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3280
3281DEF_TRAVERSE_STMT(OMPTaskyieldDirective,
3282 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3283
3284DEF_TRAVERSE_STMT(OMPBarrierDirective,
3285 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3286
3287DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
3288 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3289
3290DEF_TRAVERSE_STMT(OMPTaskgroupDirective,
3291 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3292
3293DEF_TRAVERSE_STMT(OMPCancellationPointDirective,
3294 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3295
3296DEF_TRAVERSE_STMT(OMPCancelDirective,
3297 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3298
3299DEF_TRAVERSE_STMT(OMPFlushDirective,
3300 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3301
3302DEF_TRAVERSE_STMT(OMPDepobjDirective,
3303 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3304
3305DEF_TRAVERSE_STMT(OMPScanDirective,
3306 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3307
3308DEF_TRAVERSE_STMT(OMPOrderedDirective,
3309 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3310
3311DEF_TRAVERSE_STMT(OMPAtomicDirective,
3312 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3313
3314DEF_TRAVERSE_STMT(OMPTargetDirective,
3315 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3316
3317DEF_TRAVERSE_STMT(OMPTargetDataDirective,
3318 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3319
3320DEF_TRAVERSE_STMT(OMPTargetEnterDataDirective,
3321 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3322
3323DEF_TRAVERSE_STMT(OMPTargetExitDataDirective,
3324 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3325
3326DEF_TRAVERSE_STMT(OMPTargetParallelDirective,
3327 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3328
3329DEF_TRAVERSE_STMT(OMPTargetParallelForDirective,
3330 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3331
3332DEF_TRAVERSE_STMT(OMPTeamsDirective,
3333 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3334
3335DEF_TRAVERSE_STMT(OMPTargetUpdateDirective,
3336 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3337
3338DEF_TRAVERSE_STMT(OMPTaskLoopDirective,
3339 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3340
3341DEF_TRAVERSE_STMT(OMPTaskLoopSimdDirective,
3342 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3343
3344DEF_TRAVERSE_STMT(OMPMasterTaskLoopDirective,
3345 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3346
3347DEF_TRAVERSE_STMT(OMPMasterTaskLoopSimdDirective,
3348 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3349
3350DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopDirective,
3351 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3352
3353DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopSimdDirective,
3354 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3355
3356DEF_TRAVERSE_STMT(OMPMaskedTaskLoopDirective,
3357 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3358
3359DEF_TRAVERSE_STMT(OMPMaskedTaskLoopSimdDirective,
3360 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3361
3362DEF_TRAVERSE_STMT(OMPParallelMaskedTaskLoopDirective,
3363 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3364
3365DEF_TRAVERSE_STMT(OMPParallelMaskedTaskLoopSimdDirective,
3366 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3367
3368DEF_TRAVERSE_STMT(OMPDistributeDirective,
3369 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3370
3371DEF_TRAVERSE_STMT(OMPDistributeParallelForDirective,
3372 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3373
3374DEF_TRAVERSE_STMT(OMPDistributeParallelForSimdDirective,
3375 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3376
3377DEF_TRAVERSE_STMT(OMPDistributeSimdDirective,
3378 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3379
3380DEF_TRAVERSE_STMT(OMPTargetParallelForSimdDirective,
3381 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3382
3383DEF_TRAVERSE_STMT(OMPTargetSimdDirective,
3384 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3385
3386DEF_TRAVERSE_STMT(OMPTeamsDistributeDirective,
3387 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3388
3389DEF_TRAVERSE_STMT(OMPTeamsDistributeSimdDirective,
3390 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3391
3392DEF_TRAVERSE_STMT(OMPTeamsDistributeParallelForSimdDirective,
3393 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3394
3395DEF_TRAVERSE_STMT(OMPTeamsDistributeParallelForDirective,
3396 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3397
3398DEF_TRAVERSE_STMT(OMPTargetTeamsDirective,
3399 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3400
3401DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeDirective,
3402 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3403
3404DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForDirective,
3405 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3406
3407DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForSimdDirective,
3408 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3409
3410DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeSimdDirective,
3411 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3412
3413DEF_TRAVERSE_STMT(OMPInteropDirective,
3414 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3415
3416DEF_TRAVERSE_STMT(OMPDispatchDirective,
3417 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3418
3419DEF_TRAVERSE_STMT(OMPMaskedDirective,
3420 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3421
3422DEF_TRAVERSE_STMT(OMPGenericLoopDirective,
3423 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3424
3425DEF_TRAVERSE_STMT(OMPTeamsGenericLoopDirective,
3426 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3427
3428DEF_TRAVERSE_STMT(OMPTargetTeamsGenericLoopDirective,
3429 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3430
3431DEF_TRAVERSE_STMT(OMPParallelGenericLoopDirective,
3432 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3433
3434DEF_TRAVERSE_STMT(OMPTargetParallelGenericLoopDirective,
3435 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3436
3437DEF_TRAVERSE_STMT(OMPAssumeDirective,
3438 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3439
3440DEF_TRAVERSE_STMT(OMPErrorDirective,
3441 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3442
3443// OpenMP clauses.
3444template <typename Derived>
3445bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
3446 if (!C)
3447 return true;
3448 switch (C->getClauseKind()) {
3449#define GEN_CLANG_CLAUSE_CLASS
3450#define CLAUSE_CLASS(Enum, Str, Class) \
3451 case llvm::omp::Clause::Enum: \
3452 TRY_TO(Visit##Class(static_cast<Class *>(C))); \
3453 break;
3454#define CLAUSE_NO_CLASS(Enum, Str) \
3455 case llvm::omp::Clause::Enum: \
3456 break;
3457#include "llvm/Frontend/OpenMP/OMP.inc"
3458 }
3459 return true;
3460}
3461
3462template <typename Derived>
3463bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPreInit(
3464 OMPClauseWithPreInit *Node) {
3465 TRY_TO(TraverseStmt(Node->getPreInitStmt()));
3466 return true;
3467}
3468
3469template <typename Derived>
3470bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPostUpdate(
3472 TRY_TO(VisitOMPClauseWithPreInit(Node));
3473 TRY_TO(TraverseStmt(Node->getPostUpdateExpr()));
3474 return true;
3475}
3476
3477template <typename Derived>
3480 TRY_TO(TraverseStmt(C->getAllocator()));
3481 return true;
3482}
3483
3484template <typename Derived>
3486 TRY_TO(TraverseStmt(C->getAllocator()));
3487 TRY_TO(VisitOMPClauseList(C));
3488 return true;
3489}
3490
3491template <typename Derived>
3493 TRY_TO(VisitOMPClauseWithPreInit(C));
3494 TRY_TO(TraverseStmt(C->getCondition()));
3495 return true;
3496}
3497
3498template <typename Derived>
3500 TRY_TO(VisitOMPClauseWithPreInit(C));
3501 TRY_TO(TraverseStmt(C->getCondition()));
3502 return true;
3503}
3504
3505template <typename Derived>
3506bool
3508 TRY_TO(VisitOMPClauseWithPreInit(C));
3509 TRY_TO(TraverseStmt(C->getNumThreads()));
3510 return true;
3511}
3512
3513template <typename Derived>
3515 TRY_TO(TraverseStmt(C->getAlignment()));
3516 return true;
3517}
3518
3519template <typename Derived>
3521 TRY_TO(TraverseStmt(C->getSafelen()));
3522 return true;
3523}
3524
3525template <typename Derived>
3527 TRY_TO(TraverseStmt(C->getSimdlen()));
3528 return true;
3529}
3530
3531template <typename Derived>
3533 for (Expr *E : C->getSizesRefs())
3534 TRY_TO(TraverseStmt(E));
3535 return true;
3536}
3537
3538template <typename Derived>
3540 for (Expr *E : C->getCountsRefs())
3541 TRY_TO(TraverseStmt(E));
3542 return true;
3543}
3544
3545template <typename Derived>
3548 for (Expr *E : C->getArgsRefs())
3549 TRY_TO(TraverseStmt(E));
3550 return true;
3551}
3552
3553template <typename Derived>
3555 return true;
3556}
3557
3558template <typename Derived>
3561 TRY_TO(TraverseStmt(C->getFirst()));
3562 TRY_TO(TraverseStmt(C->getCount()));
3563 return true;
3564}
3565
3566template <typename Derived>
3568 TRY_TO(TraverseStmt(C->getFactor()));
3569 return true;
3570}
3571
3572template <typename Derived>
3573bool
3575 TRY_TO(TraverseStmt(C->getNumForLoops()));
3576 return true;
3577}
3578
3579template <typename Derived>
3581 return true;
3582}
3583
3584template <typename Derived>
3587 return true;
3588}
3589
3590template <typename Derived>
3592 OMPTransparentClause *C) {
3593 TRY_TO(TraverseStmt(C->getImpexType()));
3594 return true;
3595}
3596
3597template <typename Derived>
3599 return true;
3600}
3601
3602template <typename Derived>
3604 OMPUnifiedAddressClause *) {
3605 return true;
3606}
3607
3608template <typename Derived>
3610 OMPUnifiedSharedMemoryClause *) {
3611 return true;
3612}
3613
3614template <typename Derived>
3616 OMPReverseOffloadClause *) {
3617 return true;
3618}
3619
3620template <typename Derived>
3622 OMPDynamicAllocatorsClause *) {
3623 return true;
3624}
3625
3626template <typename Derived>
3628 OMPAtomicDefaultMemOrderClause *) {
3629 return true;
3630}
3631
3632template <typename Derived>
3634 return true;
3635}
3636
3637template <typename Derived>
3639 return true;
3640}
3641
3642template <typename Derived>
3644 return true;
3645}
3646
3647template <typename Derived>
3649 TRY_TO(TraverseStmt(C->getMessageString()));
3650 return true;
3651}
3652
3653template <typename Derived>
3654bool
3656 TRY_TO(VisitOMPClauseWithPreInit(C));
3657 TRY_TO(TraverseStmt(C->getChunkSize()));
3658 return true;
3659}
3660
3661template <typename Derived>
3663 TRY_TO(TraverseStmt(C->getNumForLoops()));
3664 return true;
3665}
3666
3667template <typename Derived>
3669 TRY_TO(TraverseStmt(C->getCondition()));
3670 return true;
3671}
3672
3673template <typename Derived>
3675 return true;
3676}
3677
3678template <typename Derived>
3679bool
3681 return true;
3682}
3683
3684template <typename Derived>
3686 return true;
3687}
3688
3689template <typename Derived>
3691 return true;
3692}
3693
3694template <typename Derived>
3696 return true;
3697}
3698
3699template <typename Derived>
3701 return true;
3702}
3703
3704template <typename Derived>
3706 return true;
3707}
3708
3709template <typename Derived>
3711 return true;
3712}
3713
3714template <typename Derived>
3716 return true;
3717}
3718
3719template <typename Derived>
3721 return true;
3722}
3723
3724template <typename Derived>
3726 return true;
3727}
3728
3729template <typename Derived>
3731 return true;
3732}
3733
3734template <typename Derived>
3736 return true;
3737}
3738
3739template <typename Derived>
3741 return true;
3742}
3743
3744template <typename Derived>
3746 OMPNoOpenMPRoutinesClause *) {
3747 return true;
3748}
3749
3750template <typename Derived>
3752 OMPNoOpenMPConstructsClause *) {
3753 return true;
3754}
3755
3756template <typename Derived>
3758 OMPNoParallelismClause *) {
3759 return true;
3760}
3761
3762template <typename Derived>
3764 return true;
3765}
3766
3767template <typename Derived>
3769 return true;
3770}
3771
3772template <typename Derived>
3774 return true;
3775}
3776
3777template <typename Derived>
3779 return true;
3780}
3781
3782template <typename Derived>
3784 return true;
3785}
3786
3787template <typename Derived>
3789 return true;
3790}
3791
3792template <typename Derived>
3794 return true;
3795}
3796
3797template <typename Derived>
3799 TRY_TO(VisitOMPClauseList(C));
3800 return true;
3801}
3802
3803template <typename Derived>
3805 TRY_TO(TraverseStmt(C->getInteropVar()));
3806 return true;
3807}
3808
3809template <typename Derived>
3811 TRY_TO(TraverseStmt(C->getInteropVar()));
3812 return true;
3813}
3814
3815template <typename Derived>
3817 OMPNovariantsClause *C) {
3818 TRY_TO(VisitOMPClauseWithPreInit(C));
3819 TRY_TO(TraverseStmt(C->getCondition()));
3820 return true;
3821}
3822
3823template <typename Derived>
3825 OMPNocontextClause *C) {
3826 TRY_TO(VisitOMPClauseWithPreInit(C));
3827 TRY_TO(TraverseStmt(C->getCondition()));
3828 return true;
3829}
3830
3831template <typename Derived>
3832template <typename T>
3833bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
3834 for (auto *E : Node->varlist()) {
3835 TRY_TO(TraverseStmt(E));
3836 }
3837 return true;
3838}
3839
3840template <typename Derived>
3842 OMPInclusiveClause *C) {
3843 TRY_TO(VisitOMPClauseList(C));
3844 return true;
3845}
3846
3847template <typename Derived>
3849 OMPExclusiveClause *C) {
3850 TRY_TO(VisitOMPClauseList(C));
3851 return true;
3852}
3853
3854template <typename Derived>
3856 TRY_TO(VisitOMPClauseList(C));
3857 for (auto *E : C->private_copies()) {
3858 TRY_TO(TraverseStmt(E));
3859 }
3860 return true;
3861}
3862
3863template <typename Derived>
3865 OMPFirstprivateClause *C) {
3866 TRY_TO(VisitOMPClauseList(C));
3867 TRY_TO(VisitOMPClauseWithPreInit(C));
3868 for (auto *E : C->private_copies()) {
3869 TRY_TO(TraverseStmt(E));
3870 }
3871 for (auto *E : C->inits()) {
3872 TRY_TO(TraverseStmt(E));
3873 }
3874 return true;
3875}
3876
3877template <typename Derived>
3879 OMPLastprivateClause *C) {
3880 TRY_TO(VisitOMPClauseList(C));
3881 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3882 for (auto *E : C->private_copies()) {
3883 TRY_TO(TraverseStmt(E));
3884 }
3885 for (auto *E : C->source_exprs()) {
3886 TRY_TO(TraverseStmt(E));
3887 }
3888 for (auto *E : C->destination_exprs()) {
3889 TRY_TO(TraverseStmt(E));
3890 }
3891 for (auto *E : C->assignment_ops()) {
3892 TRY_TO(TraverseStmt(E));
3893 }
3894 return true;
3895}
3896
3897template <typename Derived>
3899 TRY_TO(VisitOMPClauseList(C));
3900 return true;
3901}
3902
3903template <typename Derived>
3905 TRY_TO(TraverseStmt(C->getStep()));
3906 TRY_TO(TraverseStmt(C->getCalcStep()));
3907 TRY_TO(VisitOMPClauseList(C));
3908 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3909 for (auto *E : C->privates()) {
3910 TRY_TO(TraverseStmt(E));
3911 }
3912 for (auto *E : C->inits()) {
3913 TRY_TO(TraverseStmt(E));
3914 }
3915 for (auto *E : C->updates()) {
3916 TRY_TO(TraverseStmt(E));
3917 }
3918 for (auto *E : C->finals()) {
3919 TRY_TO(TraverseStmt(E));
3920 }
3921 return true;
3922}
3923
3924template <typename Derived>
3926 TRY_TO(TraverseStmt(C->getAlignment()));
3927 TRY_TO(VisitOMPClauseList(C));
3928 return true;
3929}
3930
3931template <typename Derived>
3933 TRY_TO(VisitOMPClauseList(C));
3934 for (auto *E : C->source_exprs()) {
3935 TRY_TO(TraverseStmt(E));
3936 }
3937 for (auto *E : C->destination_exprs()) {
3938 TRY_TO(TraverseStmt(E));
3939 }
3940 for (auto *E : C->assignment_ops()) {
3941 TRY_TO(TraverseStmt(E));
3942 }
3943 return true;
3944}
3945
3946template <typename Derived>
3948 OMPCopyprivateClause *C) {
3949 TRY_TO(VisitOMPClauseList(C));
3950 for (auto *E : C->source_exprs()) {
3951 TRY_TO(TraverseStmt(E));
3952 }
3953 for (auto *E : C->destination_exprs()) {
3954 TRY_TO(TraverseStmt(E));
3955 }
3956 for (auto *E : C->assignment_ops()) {
3957 TRY_TO(TraverseStmt(E));
3958 }
3959 return true;
3960}
3961
3962template <typename Derived>
3963bool
3965 TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
3966 TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
3967 TRY_TO(VisitOMPClauseList(C));
3968 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3969 for (auto *E : C->privates()) {
3970 TRY_TO(TraverseStmt(E));
3971 }
3972 for (auto *E : C->lhs_exprs()) {
3973 TRY_TO(TraverseStmt(E));
3974 }
3975 for (auto *E : C->rhs_exprs()) {
3976 TRY_TO(TraverseStmt(E));
3977 }
3978 for (auto *E : C->reduction_ops()) {
3979 TRY_TO(TraverseStmt(E));
3980 }
3981 if (C->getModifier() == OMPC_REDUCTION_inscan) {
3982 for (auto *E : C->copy_ops()) {
3983 TRY_TO(TraverseStmt(E));
3984 }
3985 for (auto *E : C->copy_array_temps()) {
3986 TRY_TO(TraverseStmt(E));
3987 }
3988 for (auto *E : C->copy_array_elems()) {
3989 TRY_TO(TraverseStmt(E));
3990 }
3991 }
3992 return true;
3993}
3994
3995template <typename Derived>
3997 OMPTaskReductionClause *C) {
3998 TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
3999 TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
4000 TRY_TO(VisitOMPClauseList(C));
4001 TRY_TO(VisitOMPClauseWithPostUpdate(C));
4002 for (auto *E : C->privates()) {
4003 TRY_TO(TraverseStmt(E));
4004 }
4005 for (auto *E : C->lhs_exprs()) {
4006 TRY_TO(TraverseStmt(E));
4007 }
4008 for (auto *E : C->rhs_exprs()) {
4009 TRY_TO(TraverseStmt(E));
4010 }
4011 for (auto *E : C->reduction_ops()) {
4012 TRY_TO(TraverseStmt(E));
4013 }
4014 return true;
4015}
4016
4017template <typename Derived>
4019 OMPInReductionClause *C) {
4020 TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
4021 TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
4022 TRY_TO(VisitOMPClauseList(C));
4023 TRY_TO(VisitOMPClauseWithPostUpdate(C));
4024 for (auto *E : C->privates()) {
4025 TRY_TO(TraverseStmt(E));
4026 }
4027 for (auto *E : C->lhs_exprs()) {
4028 TRY_TO(TraverseStmt(E));
4029 }
4030 for (auto *E : C->rhs_exprs()) {
4031 TRY_TO(TraverseStmt(E));
4032 }
4033 for (auto *E : C->reduction_ops()) {
4034 TRY_TO(TraverseStmt(E));
4035 }
4036 for (auto *E : C->taskgroup_descriptors())
4037 TRY_TO(TraverseStmt(E));
4038 return true;
4039}
4040
4041template <typename Derived>
4043 TRY_TO(VisitOMPClauseList(C));
4044 return true;
4045}
4046
4047template <typename Derived>
4049 TRY_TO(TraverseStmt(C->getDepobj()));
4050 return true;
4051}
4052
4053template <typename Derived>
4055 TRY_TO(VisitOMPClauseList(C));
4056 return true;
4057}
4058
4059template <typename Derived>
4061 TRY_TO(VisitOMPClauseWithPreInit(C));
4062 TRY_TO(TraverseStmt(C->getDevice()));
4063 return true;
4064}
4065
4066template <typename Derived>
4068 TRY_TO(VisitOMPClauseList(C));
4069 return true;
4070}
4071
4072template <typename Derived>
4074 OMPNumTeamsClause *C) {
4075 TRY_TO(VisitOMPClauseList(C));
4076 TRY_TO(VisitOMPClauseWithPreInit(C));
4077 return true;
4078}
4079
4080template <typename Derived>
4082 OMPThreadLimitClause *C) {
4083 TRY_TO(VisitOMPClauseList(C));
4084 TRY_TO(VisitOMPClauseWithPreInit(C));
4085 return true;
4086}
4087
4088template <typename Derived>
4090 OMPPriorityClause *C) {
4091 TRY_TO(VisitOMPClauseWithPreInit(C));
4092 TRY_TO(TraverseStmt(C->getPriority()));
4093 return true;
4094}
4095
4096template <typename Derived>
4098 OMPGrainsizeClause *C) {
4099 TRY_TO(VisitOMPClauseWithPreInit(C));
4100 TRY_TO(TraverseStmt(C->getGrainsize()));
4101 return true;
4102}
4103
4104template <typename Derived>
4106 OMPNumTasksClause *C) {
4107 TRY_TO(VisitOMPClauseWithPreInit(C));
4108 TRY_TO(TraverseStmt(C->getNumTasks()));
4109 return true;
4110}
4111
4112template <typename Derived>
4114 TRY_TO(TraverseStmt(C->getHint()));
4115 return true;
4116}
4117
4118template <typename Derived>
4120 OMPDistScheduleClause *C) {
4121 TRY_TO(VisitOMPClauseWithPreInit(C));
4122 TRY_TO(TraverseStmt(C->getChunkSize()));
4123 return true;
4124}
4125
4126template <typename Derived>
4127bool
4129 return true;
4130}
4131
4132template <typename Derived>
4134 TRY_TO(VisitOMPClauseList(C));
4135 return true;
4136}
4137
4138template <typename Derived>
4140 TRY_TO(VisitOMPClauseList(C));
4141 return true;
4142}
4143
4144template <typename Derived>
4146 OMPUseDevicePtrClause *C) {
4147 TRY_TO(VisitOMPClauseList(C));
4148 return true;
4149}
4150
4151template <typename Derived>
4153 OMPUseDeviceAddrClause *C) {
4154 TRY_TO(VisitOMPClauseList(C));
4155 return true;
4156}
4157
4158template <typename Derived>
4160 OMPIsDevicePtrClause *C) {
4161 TRY_TO(VisitOMPClauseList(C));
4162 return true;
4163}
4164
4165template <typename Derived>
4167 OMPHasDeviceAddrClause *C) {
4168 TRY_TO(VisitOMPClauseList(C));
4169 return true;
4170}
4171
4172template <typename Derived>
4174 OMPNontemporalClause *C) {
4175 TRY_TO(VisitOMPClauseList(C));
4176 for (auto *E : C->private_refs()) {
4177 TRY_TO(TraverseStmt(E));
4178 }
4179 return true;
4180}
4181
4182template <typename Derived>
4184 return true;
4185}
4186
4187template <typename Derived>
4189 TRY_TO(TraverseStmt(C->getEventHandler()));
4190 return true;
4191}
4192
4193template <typename Derived>
4195 OMPUsesAllocatorsClause *C) {
4196 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
4197 const OMPUsesAllocatorsClause::Data Data = C->getAllocatorData(I);
4198 TRY_TO(TraverseStmt(Data.Allocator));
4199 TRY_TO(TraverseStmt(Data.AllocatorTraits));
4200 }
4201 return true;
4202}
4203
4204template <typename Derived>
4206 OMPAffinityClause *C) {
4207 TRY_TO(TraverseStmt(C->getModifier()));
4208 for (Expr *E : C->varlist())
4209 TRY_TO(TraverseStmt(E));
4210 return true;
4211}
4212
4213template <typename Derived>
4215 TRY_TO(VisitOMPClauseWithPreInit(C));
4216 TRY_TO(TraverseStmt(C->getThreadID()));
4217 return true;
4218}
4219
4220template <typename Derived>
4222 return true;
4223}
4224
4225template <typename Derived>
4227 OMPXDynCGroupMemClause *C) {
4228 TRY_TO(VisitOMPClauseWithPreInit(C));
4229 TRY_TO(TraverseStmt(C->getSize()));
4230 return true;
4231}
4232
4233template <typename Derived>
4235 OMPDynGroupprivateClause *C) {
4236 TRY_TO(VisitOMPClauseWithPreInit(C));
4237 TRY_TO(TraverseStmt(C->getSize()));
4238 return true;
4239}
4240
4241template <typename Derived>
4243 OMPDoacrossClause *C) {
4244 TRY_TO(VisitOMPClauseList(C));
4245 return true;
4246}
4247
4248template <typename Derived>
4250 OMPXAttributeClause *C) {
4251 return true;
4252}
4253
4254template <typename Derived>
4256 return true;
4257}
4258
4259template <typename Derived>
4260bool RecursiveASTVisitor<Derived>::TraverseOpenACCConstructStmt(
4262 TRY_TO(VisitOpenACCClauseList(C->clauses()));
4263 return true;
4264}
4265
4266template <typename Derived>
4267bool RecursiveASTVisitor<Derived>::TraverseOpenACCAssociatedStmtConstruct(
4269 TRY_TO(TraverseOpenACCConstructStmt(S));
4270 TRY_TO(TraverseStmt(S->getAssociatedStmt()));
4271 return true;
4272}
4273
4274template <typename Derived>
4275bool RecursiveASTVisitor<Derived>::VisitOpenACCClause(const OpenACCClause *C) {
4276 for (const Stmt *Child : C->children())
4277 TRY_TO(TraverseStmt(const_cast<Stmt *>(Child)));
4278 return true;
4279}
4280
4281template <typename Derived>
4282bool RecursiveASTVisitor<Derived>::VisitOpenACCClauseList(
4284
4285 for (const auto *C : Clauses)
4286 TRY_TO(VisitOpenACCClause(C));
4287 return true;
4288}
4289
4291 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4292DEF_TRAVERSE_STMT(OpenACCLoopConstruct,
4293 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4294DEF_TRAVERSE_STMT(OpenACCCombinedConstruct,
4295 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4296DEF_TRAVERSE_STMT(OpenACCDataConstruct,
4297 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4298DEF_TRAVERSE_STMT(OpenACCEnterDataConstruct,
4299 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4300DEF_TRAVERSE_STMT(OpenACCExitDataConstruct,
4301 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4302DEF_TRAVERSE_STMT(OpenACCHostDataConstruct,
4303 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4304DEF_TRAVERSE_STMT(OpenACCWaitConstruct, {
4305 if (S->hasDevNumExpr())
4306 TRY_TO(TraverseStmt(S->getDevNumExpr()));
4307 for (auto *E : S->getQueueIdExprs())
4308 TRY_TO(TraverseStmt(E));
4309 TRY_TO(VisitOpenACCClauseList(S->clauses()));
4310})
4311DEF_TRAVERSE_STMT(OpenACCInitConstruct,
4312 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4313DEF_TRAVERSE_STMT(OpenACCShutdownConstruct,
4314 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4315DEF_TRAVERSE_STMT(OpenACCSetConstruct,
4316 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4317DEF_TRAVERSE_STMT(OpenACCUpdateConstruct,
4318 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4319DEF_TRAVERSE_STMT(OpenACCAtomicConstruct,
4320 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4321DEF_TRAVERSE_STMT(OpenACCCacheConstruct, {
4322 for (auto *E : S->getVarList())
4323 TRY_TO(TraverseStmt(E));
4324})
4325
4326// Traverse HLSL: Out argument expression
4328
4329// FIXME: look at the following tricky-seeming exprs to see if we
4330// need to recurse on anything. These are ones that have methods
4331// returning decls or qualtypes or nestednamespecifier -- though I'm
4332// not sure if they own them -- or just seemed very complicated, or
4333// had lots of sub-types to explore.
4334//
4335// VisitOverloadExpr and its children: recurse on template args? etc?
4336
4337// FIXME: go through all the stmts and exprs again, and see which of them
4338// create new types, and recurse on the types (TypeLocs?) of those.
4339// Candidates:
4340//
4341// http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html
4342// http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html
4343// http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html
4344// Every class that has getQualifier.
4345
4346#undef DEF_TRAVERSE_STMT
4347#undef TRAVERSE_STMT
4348#undef TRAVERSE_STMT_BASE
4349
4350#undef TRY_TO
4351
4352} // end namespace clang
4353
4354#endif // LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
This file provides AST data structures related to concepts.
#define STMT(DERIVED, BASE)
Definition ASTFwd.h:23
#define TYPE(DERIVED, BASE)
Definition ASTFwd.h:26
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc QualifierLoc)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines OpenACC nodes for declarative directives.
This file defines OpenMP nodes for declarative directives.
Defines the C++ template declaration subclasses.
#define DEF_TRAVERSE_TMPL_INST(kind)
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines Expressions and AST nodes for C++2a concepts.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the LambdaCapture class.
This file defines OpenMP AST classes for clauses.
Defines some OpenMP-specific enums and functions.
#define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND)
#define TRAVERSE_STMT_BASE(NAME, CLASS, VAR, QUEUE)
#define DEF_TRAVERSE_TYPE(TYPE, CODE)
#define DEF_TRAVERSE_TYPELOC(TYPE, CODE)
#define TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S)
#define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND, DECLKIND)
#define DEF_TRAVERSE_DECL(DECL, CODE)
#define DEF_TRAVERSE_STMT(STMT, CODE)
#define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND)
#define TRY_TO(CALL_EXPR)
Defines various enumerations that describe declaration and type specifiers.
Defines the Objective-C statement AST node classes.
This file defines OpenACC AST classes for statement-level contructs.
This file defines OpenMP AST classes for executable directives and clauses.
This file defines SYCL AST classes used to represent calls to SYCL kernels.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:227
TranslationUnitDecl * getTranslationUnitDecl() const
Represents an access specifier followed by colon ':'.
Definition DeclCXX.h:86
AddrLabelExpr - The GNU address of label extension, representing &&label.
Definition Expr.h:4553
Represents a type which was implicitly adjusted by the semantic engine for arbitrary reasons.
Definition TypeBase.h:3544
Represents the index of the current element of an array being initialized by an ArrayInitLoopExpr.
Definition Expr.h:6022
Represents a loop initializing the elements of an array.
Definition Expr.h:5969
Represents a constant array type that does not decay to a pointer when used as a function parameter.
Definition TypeBase.h:3947
This class represents BOTH the OpenMP Array Section and OpenACC 'subarray', with a boolean differenti...
Definition Expr.h:7220
ArraySubscriptExpr - [C99 6.5.2.1] Array Subscripting.
Definition Expr.h:2724
Wrapper for source info for arrays.
Definition TypeLoc.h:1777
An Embarcadero array type trait, as used in the implementation of __array_rank and __array_extent.
Definition ExprCXX.h:3000
AsTypeExpr - Clang builtin function __builtin_astype [OpenCL 6.2.4.2] This AST node provides support ...
Definition Expr.h:6734
AtomicExpr - Variadic atomic builtins: __atomic_exchange, __atomic_fetch_*, __atomic_load,...
Definition Expr.h:6929
Attr - This represents one attribute.
Definition Attr.h:46
Represents an attribute applied to a statement.
Definition Stmt.h:2209
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
Definition Expr.h:4456
A builtin binary operation expression such as "x + y" or "x <= y".
Definition Expr.h:4041
A binding in a decomposition declaration.
Definition DeclCXX.h:4190
A fixed int type of a specified bitwidth.
Definition TypeBase.h:8288
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition Decl.h:4690
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition Expr.h:6673
Pointer to a block type.
Definition TypeBase.h:3597
BreakStmt - This represents a break.
Definition Stmt.h:3141
Represents a C++2a __builtin_bit_cast(T, v) expression.
Definition ExprCXX.h:5472
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:3219
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Definition Expr.h:3972
Represents a call to a CUDA kernel function.
Definition ExprCXX.h:238
A C++ addrspace_cast expression (currently only enabled for OpenCL).
Definition ExprCXX.h:608
Represents a base class of a C++ class.
Definition DeclCXX.h:146
Represents binding an expression to a temporary.
Definition ExprCXX.h:1497
A boolean literal, per ([C++ lex.bool] Boolean literals).
Definition ExprCXX.h:727
CXXCatchStmt - This represents a C++ catch block.
Definition StmtCXX.h:28
A C++ const_cast expression (C++ [expr.const.cast]).
Definition ExprCXX.h:570
Represents a call to a C++ constructor.
Definition ExprCXX.h:1552
Represents a C++ constructor within a class.
Definition DeclCXX.h:2620
Represents a C++ conversion function within a class.
Definition DeclCXX.h:2952
Represents a C++ base or member initializer.
Definition DeclCXX.h:2385
Represents a C++ deduction guide declaration.
Definition DeclCXX.h:1983
A default argument (C++ [dcl.fct.default]).
Definition ExprCXX.h:1274
A use of a default initializer in a constructor or in aggregate initialization.
Definition ExprCXX.h:1381
Represents a delete expression for memory deallocation and destructor calls, e.g.
Definition ExprCXX.h:2630
Represents a C++ member access expression where the actual member referenced could not be resolved be...
Definition ExprCXX.h:3870
Represents a C++ destructor within a class.
Definition DeclCXX.h:2882
A C++ dynamic_cast expression (C++ [expr.dynamic.cast]).
Definition ExprCXX.h:485
Represents a folding of a pack over an operator.
Definition ExprCXX.h:5032
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
Definition StmtCXX.h:135
Represents an explicit C++ type conversion that uses "functional" notation (C++ [expr....
Definition ExprCXX.h:1835
Represents a call to an inherited base class constructor from an inheriting constructor.
Definition ExprCXX.h:1755
Represents a call to a member function that may be written either with member call syntax (e....
Definition ExprCXX.h:183
Represents a static or instance method of a struct/union/class.
Definition DeclCXX.h:2132
Represents a new-expression for memory allocation and constructor calls, e.g: "new CXXNewExpr(foo)".
Definition ExprCXX.h:2359
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
Definition ExprCXX.h:4309
The null pointer literal (C++11 [lex.nullptr])
Definition ExprCXX.h:772
A call to an overloaded operator written using operator syntax.
Definition ExprCXX.h:85
Represents a list-initialization with parenthesis.
Definition ExprCXX.h:5141
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
Definition ExprCXX.h:2749
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
Represents a C++26 reflect expression [expr.reflect].
Definition ExprCXX.h:5504
A C++ reinterpret_cast expression (C++ [expr.reinterpret.cast]).
Definition ExprCXX.h:530
A rewritten comparison expression that was originally written using operator syntax.
Definition ExprCXX.h:290
An expression "T()" which creates an rvalue of a non-class type T.
Definition ExprCXX.h:2200
A C++ static_cast expression (C++ [expr.static.cast]).
Definition ExprCXX.h:440
Implicit construction of a std::initializer_list<T> object from an array temporary within list-initia...
Definition ExprCXX.h:804
Represents a C++ functional cast expression that builds a temporary object.
Definition ExprCXX.h:1903
Represents the this expression in C++.
Definition ExprCXX.h:1158
A C++ throw-expression (C++ [except.throw]).
Definition ExprCXX.h:1212
CXXTryStmt - A C++ try block, including all handlers.
Definition StmtCXX.h:69
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
Definition ExprCXX.h:852
Describes an explicit type conversion that uses functional notion but could not be resolved because o...
Definition ExprCXX.h:3744
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
Definition ExprCXX.h:1072
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Definition Expr.h:2946
Represents the body of a CapturedStmt, and serves as its DeclContext.
Definition Decl.h:4962
This captures a statement into a function.
Definition Stmt.h:3943
CaseStmt - Represent a case statement.
Definition Stmt.h:1926
ChooseExpr - GNU builtin-in function __builtin_choose_expr.
Definition Expr.h:4851
Declaration of a class template.
Represents a 'co_await' expression.
Definition ExprCXX.h:5365
Complex values, per C99 6.2.5p11.
Definition TypeBase.h:3330
CompoundAssignOperator - For compound assignments (e.g.
Definition Expr.h:4303
CompoundLiteralExpr - [C99 6.5.2.5].
Definition Expr.h:3608
CompoundStmt - This represents a group of statements like { stmt stmt }.
Definition Stmt.h:1746
Declaration of a C++20 concept.
A reference to a concept and its template args, as it appears in the code.
Definition ASTConcept.h:130
Represents the specialization of a concept - evaluates to a prvalue of type bool.
ConditionalOperator - The ?
Definition Expr.h:4394
Represents the canonical version of C arrays with a specified constant size.
Definition TypeBase.h:3815
ConstantExpr - An expression that occurs in a constant context and optionally the result of evaluatin...
Definition Expr.h:1085
Represents a concrete matrix type with constant number of rows and columns.
Definition TypeBase.h:4442
Represents a shadow constructor declaration introduced into a class by a C++11 using-declaration that...
Definition DeclCXX.h:3682
ContinueStmt - This represents a continue.
Definition Stmt.h:3125
ConvertVectorExpr - Clang builtin function __builtin_convertvector This AST node provides support for...
Definition Expr.h:4722
Represents a 'co_return' statement in the C++ Coroutines TS.
Definition StmtCXX.h:473
Represents the body of a coroutine.
Definition StmtCXX.h:320
Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...
Definition TypeBase.h:3491
Represents a 'co_yield' expression.
Definition ExprCXX.h:5446
Represents a pointer type decayed from an array or function type.
Definition TypeBase.h:3580
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1462
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2122
A reference to a declared variable, function, enum, etc.
Definition Expr.h:1273
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
Definition Stmt.h:1637
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition DeclBase.h:601
Kind getKind() const
Definition DeclBase.h:450
TemplateDecl * getCXXDeductionGuideTemplate() const
If this name is the name of a C++ deduction guide, return the template associated with that name.
NameKind getNameKind() const
Determine what kind of name this is.
Represents a ValueDecl that came out of a declarator.
Definition Decl.h:780
A decomposition declaration.
Definition DeclCXX.h:4254
DeferStmt - This represents a deferred statement.
Definition Stmt.h:3242
Represents an extended address space qualifier where the input address space value is dependent.
Definition TypeBase.h:4116
Represents a 'co_await' expression while the type of the promise is dependent.
Definition ExprCXX.h:5397
Provides information about a dependent function-template specialization declaration.
A qualified reference to a name whose declaration cannot yet be resolved.
Definition ExprCXX.h:3510
Represents an array type in C++ whose size is a value-dependent expression.
Definition TypeBase.h:4066
Represents an extended vector type where either the type or size is dependent.
Definition TypeBase.h:4156
Represents a matrix type where the type and the number of rows and columns is dependent on a template...
Definition TypeBase.h:4528
Represents a vector type where either the type or size is dependent.
Definition TypeBase.h:4282
Represents a C99 designated initializer expression.
Definition Expr.h:5552
DoStmt - This represents a 'do/while' stmt.
Definition Stmt.h:2838
Represents a reference to emded data.
Definition Expr.h:5129
Represents an empty-declaration.
Definition Decl.h:5197
An instance of this object exists for each enum constant that is defined.
Definition Decl.h:3441
Represents an enum.
Definition Decl.h:4029
Represents an explicit instantiation of a template entity in source code.
Represents a standard C++ module export declaration.
Definition Decl.h:5150
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
Definition ExprCXX.h:3661
This represents one expression.
Definition Expr.h:112
An expression trait intrinsic.
Definition ExprCXX.h:3073
ExtVectorElementExpr - This represents access to specific elements of a vector, and may occur on the ...
Definition Expr.h:6611
ExtVectorType - Extended vector type.
Definition TypeBase.h:4322
Declaration context for names declared as extern "C" in C++.
Definition Decl.h:247
Represents a member of a struct/union/class.
Definition Decl.h:3178
ForStmt - This represents a 'for (init;cond;inc)' stmt.
Definition Stmt.h:2894
FriendDecl - Represents the declaration of a friend entity, which can be a function,...
Definition DeclFriend.h:54
Declaration of a friend template.
Represents a function declaration or definition.
Definition Decl.h:2018
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Definition TypeBase.h:4940
Represents a reference to a function parameter pack, init-capture pack, or binding pack that has been...
Definition ExprCXX.h:4841
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5362
Declaration of a template function.
Provides information about a function template specialization, which is a FunctionDecl that has been ...
This represents a GCC inline-assembly statement extension.
Definition Stmt.h:3452
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
Definition Expr.h:4926
Represents a C11 generic selection.
Definition Expr.h:6183
AssociationTy< false > Association
Definition Expr.h:6416
GotoStmt - This represents a direct goto.
Definition Stmt.h:2975
HLSLBufferDecl - Represent a cbuffer or tbuffer declaration.
Definition Decl.h:5212
This class represents temporary values used to represent inout and out arguments in HLSL.
Definition Expr.h:7398
IfStmt - This represents an if/then/else.
Definition Stmt.h:2265
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
Definition Expr.h:1734
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
Definition Expr.h:3856
Represents an implicitly-generated value initialization of an object of a given type.
Definition Expr.h:6058
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Definition Decl.h:5071
Represents a C array with an unspecified size.
Definition TypeBase.h:3964
Represents a field injected from an anonymous union/struct into the parent scope.
Definition Decl.h:3485
IndirectGotoStmt - This represents an indirect goto.
Definition Stmt.h:3014
Describes an C or C++ initializer list.
Definition Expr.h:5302
An lvalue reference type, per C++11 [dcl.ref].
Definition TypeBase.h:3672
Represents the declaration of a label.
Definition Decl.h:524
LabelStmt - Represents a label, which has a substatement.
Definition Stmt.h:2152
Describes the capture of a variable or of this, or of a C++1y init-capture.
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition ExprCXX.h:1972
Implicit declaration of a temporary that was materialized by a MaterializeTemporaryExpr and lifetime-...
Definition DeclCXX.h:3313
Represents a linkage specification.
Definition DeclCXX.h:3020
This represents a Microsoft inline-assembly statement extension.
Definition Stmt.h:3671
Representation of a Microsoft __if_exists or __if_not_exists statement with a dependent name.
Definition StmtCXX.h:253
A global _GUID constant.
Definition DeclCXX.h:4403
An instance of this class represents the declaration of a property member.
Definition DeclCXX.h:4349
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:6241
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Definition ExprCXX.h:4920
MatrixSingleSubscriptExpr - Matrix single subscript expression for the MatrixType extension when you ...
Definition Expr.h:2798
MatrixSubscriptExpr - Matrix subscript expression for the MatrixType extension.
Definition Expr.h:2868
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
Definition Expr.h:3367
A pointer to member type per C++ 8.3.3 - Pointers to members.
Definition TypeBase.h:3708
This represents a decl that may have a name.
Definition Decl.h:274
Represents a C++ namespace alias.
Definition DeclCXX.h:3206
Represent a C++ namespace.
Definition Decl.h:592
A C++ nested-name-specifier augmented with source location information.
NestedNameSpecifier getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
NamespaceAndPrefixLoc castAsNamespaceAndPrefix() const
For a nested-name-specifier that refers to a namespace, retrieve the namespace and its prefix.
TypeLoc castAsTypeLoc() const
For a nested-name-specifier that refers to a type, retrieve the type with source-location information...
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
NamespaceAndPrefix getAsNamespaceAndPrefix() const
@ MicrosoftSuper
Microsoft's '__super' specifier, stored as a CXXRecordDecl* of the class it appeared in.
@ Global
The global specifier '::'. There is no stored value.
@ Namespace
A namespace-like entity, stored as a NamespaceBaseDecl*.
Represents a place-holder for an object not to be initialized by anything.
Definition Expr.h:5878
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
NullStmt - This is the null statement ";": C99 6.8.3p3.
Definition Stmt.h:1709
This represents the 'align' clause in the 'pragma omp allocate' directive.
This represents clause 'allocate' in the 'pragma omp ...' directives.
This represents 'pragma omp allocate ...' directive.
Definition DeclOpenMP.h:536
This represents 'allocator' clause in the 'pragma omp ...' directive.
An explicit cast in C or a C-style cast in C++, which uses the syntax ([s1][s2]......
Definition ExprOpenMP.h:24
Pseudo declaration for capturing expressions.
Definition DeclOpenMP.h:445
Class that handles post-update expression for some clauses, like 'lastprivate', 'reduction' etc.
Class that handles pre-initialization statement for some clauses, like 'schedule',...
This is a basic class for representing single OpenMP clause.
This represents 'collapse' clause in the 'pragma omp ...' directive.
This represents the 'counts' clause in the 'pragma omp split' directive.
This represents 'pragma omp declare mapper ...' directive.
Definition DeclOpenMP.h:349
This represents 'pragma omp declare reduction ...' directive.
Definition DeclOpenMP.h:239
This represents 'default' clause in the 'pragma omp ...' directive.
This represents 'final' clause in the 'pragma omp ...' directive.
Representation of the 'full' clause of the 'pragma omp unroll' directive.
This represents 'pragma omp groupprivate ...' directive.
Definition DeclOpenMP.h:173
This represents 'if' clause in the 'pragma omp ...' directive.
OpenMP 5.0 [2.1.6 Iterators] Iterators are identifiers that expand to multiple values in the clause o...
Definition ExprOpenMP.h:151
This class represents the 'looprange' clause in the 'pragma omp fuse' directive.
This represents 'num_threads' clause in the 'pragma omp ...' directive.
Representation of the 'partial' clause of the 'pragma omp unroll' directive.
This class represents the 'permutation' clause in the 'pragma omp interchange' directive.
This represents 'pragma omp requires...' directive.
Definition DeclOpenMP.h:479
This represents 'safelen' clause in the 'pragma omp ...' directive.
This represents 'simdlen' clause in the 'pragma omp ...' directive.
This represents the 'sizes' clause in the 'pragma omp tile' directive.
This represents 'pragma omp threadprivate ...' directive.
Definition DeclOpenMP.h:110
This represents 'threadset' clause in the 'pragma omp task ...' directive.
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
Definition ExprObjC.h:220
Represents Objective-C's @catch statement.
Definition StmtObjC.h:77
Represents a field declaration created by an @defs(...).
Definition DeclObjC.h:2030
Represents Objective-C's @finally statement.
Definition StmtObjC.h:127
Represents Objective-C's @synchronized statement.
Definition StmtObjC.h:303
Represents Objective-C's @throw statement.
Definition StmtObjC.h:358
Represents Objective-C's @try ... @catch ... @finally statement.
Definition StmtObjC.h:167
Represents Objective-C's @autoreleasepool Statement.
Definition StmtObjC.h:394
A runtime availability query.
Definition ExprObjC.h:1734
ObjCBoolLiteralExpr - Objective-C Boolean Literal.
Definition ExprObjC.h:119
ObjCBoxedExpr - used for generalized expression boxing.
Definition ExprObjC.h:159
An Objective-C "bridged" cast expression, which casts between Objective-C pointers and C pointers,...
Definition ExprObjC.h:1674
ObjCCategoryDecl - Represents a category declaration.
Definition DeclObjC.h:2329
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
Definition DeclObjC.h:2545
ObjCCompatibleAliasDecl - Represents alias of a class.
Definition DeclObjC.h:2775
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
Definition ExprObjC.h:342
ObjCEncodeExpr, used for @encode in Objective-C.
Definition ExprObjC.h:441
Represents Objective-C's collection statement.
Definition StmtObjC.h:23
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Definition DeclObjC.h:2597
ObjCIndirectCopyRestoreExpr - Represents the passing of a function argument by indirect copy-restore ...
Definition ExprObjC.h:1613
Represents an ObjC class declaration.
Definition DeclObjC.h:1154
Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...
Definition TypeBase.h:7998
ObjCIsaExpr - Represent X->isa and X.isa when X is an ObjC 'id' type.
Definition ExprObjC.h:1529
ObjCIvarDecl - Represents an ObjC instance variable.
Definition DeclObjC.h:1952
ObjCIvarRefExpr - A reference to an ObjC instance variable.
Definition ExprObjC.h:580
An expression that sends a message to the given Objective-C object or class.
Definition ExprObjC.h:971
ObjCMethodDecl - Represents an instance or class method declaration.
Definition DeclObjC.h:140
Represents a pointer to an Objective C object.
Definition TypeBase.h:8054
Represents one property declaration in an Objective-C interface.
Definition DeclObjC.h:731
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
Definition DeclObjC.h:2805
ObjCPropertyRefExpr - A dot-syntax expression to access an ObjC property.
Definition ExprObjC.h:648
Represents an Objective-C protocol declaration.
Definition DeclObjC.h:2084
ObjCProtocolExpr used for protocol expression in Objective-C.
Definition ExprObjC.h:536
ObjCSelectorExpr used for @selector in Objective-C.
Definition ExprObjC.h:486
ObjCStringLiteral, used for Objective-C string literals i.e.
Definition ExprObjC.h:84
ObjCSubscriptRefExpr - used for array and dictionary subscripting.
Definition ExprObjC.h:870
Represents the declaration of an Objective-C type parameter.
Definition DeclObjC.h:578
Stores a list of Objective-C type parameters for a parameterized class or a category/extension thereo...
Definition DeclObjC.h:662
OffsetOfExpr - [C99 7.17] - This represents an expression of the form offsetof(record-type,...
Definition Expr.h:2530
Helper class for OffsetOfExpr.
Definition Expr.h:2424
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
Definition Expr.h:1181
This is a base class for any OpenACC statement-level constructs that have an associated statement.
Definition StmtOpenACC.h:81
This expression type represents an asterisk in an OpenACC Size-Expr, used in the 'tile' and 'gang' cl...
Definition Expr.h:2093
This is the base type for all OpenACC Clauses.
This is the base class for an OpenACC statement-level construct, other construct types are expected t...
Definition StmtOpenACC.h:26
Represents a partial function definition.
Definition Decl.h:4897
Represents a C++11 pack expansion that produces a sequence of expressions.
Definition ExprCXX.h:4363
ParenExpr - This represents a parenthesized expression, e.g.
Definition Expr.h:2185
Sugar for parentheses used when specifying types.
Definition TypeBase.h:3357
Represents a parameter to a function.
Definition Decl.h:1808
PipeType - OpenCL20.
Definition TypeBase.h:8254
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition TypeBase.h:3383
Represents a #pragma comment line.
Definition Decl.h:167
Represents a #pragma detect_mismatch line.
Definition Decl.h:201
[C99 6.4.2.2] - A predefined identifier such as func.
Definition Expr.h:2008
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
Definition Expr.h:6805
Expr *const * semantics_iterator
Definition Expr.h:6864
A (possibly-)qualified type.
Definition TypeBase.h:937
Represents a template name as written in source code.
Wrapper of type source information for a type with non-trivial direct qualifiers.
Definition TypeLoc.h:300
UnqualTypeLoc getUnqualifiedLoc() const
Definition TypeLoc.h:304
An rvalue reference type, per C++11 [dcl.ref].
Definition TypeBase.h:3690
Represents a struct/union/class.
Definition Decl.h:4343
Frontend produces RecoveryExprs on semantic errors that prevent creating other well-formed expression...
Definition Expr.h:7504
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue=nullptr)
Recursively visit a statement or expression, by dispatching to Traverse*() based on the argument's dy...
bool TraverseTemplateArgument(const TemplateArgument &Arg)
Recursively visit a template argument and dispatch to the appropriate method for the argument type.
bool TraverseConceptRequirement(concepts::Requirement *R)
bool dataTraverseStmtPre(Stmt *S)
Invoked before visiting a statement or expression via data recursion.
bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLoc)
Recursively visit an Objective-C protocol reference with location information.
bool TraverseOffsetOfNode(const OffsetOfNode *Node)
Recursively visit a single component of an __builtin_offsetof designator (a field,...
bool VisitUnqualTypeLoc(UnqualTypeLoc TL)
bool TraverseConceptExprRequirement(concepts::ExprRequirement *R)
bool TraverseNestedNameSpecifier(NestedNameSpecifier NNS)
Recursively visit a C++ nested-name-specifier.
bool TraverseAST(ASTContext &AST)
Recursively visits an entire AST, starting from the TranslationUnitDecl.
bool shouldVisitTemplateInstantiations() const
Return whether this visitor should recurse into template instantiations.
bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc)
Recursively visit a template argument location and dispatch to the appropriate method for the argumen...
bool canIgnoreChildDeclWhileTraversingDeclContext(const Decl *Child)
bool dataTraverseStmtPost(Stmt *S)
Invoked after visiting a statement or expression via data recursion.
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS)
Recursively visit a C++ nested-name-specifier with location information.
bool TraverseTemplateName(TemplateName Template)
Recursively visit a template name and dispatch to the appropriate method.
Stmt::child_range getStmtChildren(Stmt *S)
bool shouldVisitImplicitCode() const
Return whether this visitor should recurse into implicit code, e.g., implicit constructors and destru...
bool TraverseConceptReference(ConceptReference *CR)
Recursively visit concept reference with location information.
bool TraverseTemplateArguments(ArrayRef< TemplateArgument > Args)
Recursively visit a set of template arguments.
bool TraverseTypeLoc(TypeLoc TL, bool TraverseQualifier=true)
Recursively visit a type with location, by dispatching to Traverse*TypeLoc() based on the argument ty...
bool WalkUpFromUnqualTypeLoc(UnqualTypeLoc TL)
bool dataTraverseNode(Stmt *S, DataRecursionQueue *Queue)
bool TraverseDecl(Decl *D)
Recursively visit a declaration, by dispatching to Traverse*Decl() based on the argument's dynamic ty...
bool TraverseTypeConstraint(const TypeConstraint *C)
bool WalkUpFromQualifiedTypeLoc(QualifiedTypeLoc TL)
bool VisitOffsetOfNode(const OffsetOfNode *Node)
Visit a single component of an __builtin_offsetof designator.
bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C, Expr *Init)
Recursively visit a lambda capture.
bool VisitConceptReference(ConceptReference *CR)
bool shouldTraversePostOrder() const
Return whether this visitor should traverse post-order.
SmallVectorImpl< llvm::PointerIntPair< Stmt *, 1, bool > > DataRecursionQueue
A queue used for performing data recursion over statements.
bool shouldVisitLambdaBody() const
Return whether this visitor should recurse into lambda body.
bool TraverseSynOrSemInitListExpr(InitListExpr *S, DataRecursionQueue *Queue=nullptr)
Recursively visit the syntactic or semantic form of an initialization list.
bool TraverseAttr(Attr *At)
Recursively visit an attribute, by dispatching to Traverse*Attr() based on the argument's dynamic typ...
bool TraverseType(QualType T, bool TraverseQualifier=true)
Recursively visit a type, by dispatching to Traverse*Type() based on the argument's getTypeClass() pr...
bool TraverseConceptNestedRequirement(concepts::NestedRequirement *R)
bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL)
bool shouldWalkTypesOfTypeLocs() const
Return whether this visitor should recurse into the types of TypeLocs.
bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo)
Recursively visit a name with its location information.
bool TraverseCXXBaseSpecifier(const CXXBaseSpecifier &Base)
Recursively visit a base specifier.
Derived & getDerived()
Return a reference to the derived class.
bool TraverseConceptTypeRequirement(concepts::TypeRequirement *R)
bool TraverseConstructorInitializer(CXXCtorInitializer *Init)
Recursively visit a constructor initializer.
Represents the body of a requires-expression.
Definition DeclCXX.h:2101
C++2a [expr.prim.req]: A requires-expression provides a concise way to express requirements on templa...
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
Definition Stmt.h:3166
Represents a __leave statement.
Definition Stmt.h:3904
SYCLKernelCallStmt represents the transformation that is applied to the body of a function declared w...
Definition StmtSYCL.h:36
Scope - A scope is a transient data structure that is used while parsing the program.
Definition Scope.h:41
ShuffleVectorExpr - clang-specific builtin-in function __builtin_shufflevector.
Definition Expr.h:4646
Represents an expression that computes the length of a parameter pack.
Definition ExprCXX.h:4441
Represents a function call to one of __builtin_LINE(), __builtin_COLUMN(), __builtin_FUNCTION(),...
Definition Expr.h:5020
Represents a C++11 static_assert declaration.
Definition DeclCXX.h:4141
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
Definition Expr.h:4598
Stmt - This represents one statement.
Definition Stmt.h:86
@ NoStmtClass
Definition Stmt.h:89
child_range children()
Definition Stmt.cpp:304
StmtClass getStmtClass() const
Definition Stmt.h:1499
llvm::iterator_range< child_iterator > child_range
Definition Stmt.h:1588
StringLiteral - This represents a string literal expression, e.g.
Definition Expr.h:1802
Represents a reference to a non-type template parameter that has been substituted with a template arg...
Definition ExprCXX.h:4664
Represents a reference to a non-type template parameter pack that has been substituted with a non-tem...
Definition ExprCXX.h:4754
Abstract type representing delayed type pack expansions.
Definition TypeLoc.h:986
SwitchStmt - This represents a 'switch' stmt.
Definition Stmt.h:2515
Location wrapper for a TemplateArgument.
const TemplateArgument & getArgument() const
TypeSourceInfo * getTypeSourceInfo() const
Expr * getSourceExpression() const
NestedNameSpecifierLoc getTemplateQualifierLoc() const
Represents a template argument.
Expr * getAsExpr() const
Retrieve the template argument as an expression.
QualType getAsType() const
Retrieve the type for a type template argument.
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Template
The template argument is a template name that was provided for a template template parameter.
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
@ Pack
The template argument is actually a parameter pack.
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
@ Type
The template argument is a type.
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
ArgKind getKind() const
Return the kind of stored template argument.
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion,...
Represents a C++ template name within the type system.
A template parameter object.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl ** iterator
Iterates through the template parameters in this list.
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
Declaration of a template type parameter.
A declaration that models statements at global scope.
Definition Decl.h:4653
The top declaration context.
Definition Decl.h:105
Represents the declaration of a typedef-name via a C++11 alias-declaration.
Definition Decl.h:3706
Declaration of an alias template.
Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...
Definition ASTConcept.h:227
Base wrapper for a particular "section" of type source info.
Definition TypeLoc.h:59
UnqualTypeLoc getUnqualifiedLoc() const
Skips past any qualifiers, if this is qualified.
Definition TypeLoc.h:349
NestedNameSpecifierLoc getPrefix() const
If this type represents a qualified-id, this returns it's nested name specifier.
Definition TypeLoc.cpp:473
TypeLocClass getTypeLocClass() const
Definition TypeLoc.h:116
bool isNull() const
Definition TypeLoc.h:121
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
Definition TypeLoc.h:2735
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
Definition TypeBase.h:6273
A container of type source information.
Definition TypeBase.h:8407
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:1871
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Definition Decl.h:3685
UnaryExprOrTypeTraitExpr - expression with either a type or (unevaluated) expression operand.
Definition Expr.h:2628
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Definition Expr.h:2247
An artificial decl, representing a global anonymous constant value which is uniquified by value withi...
Definition DeclCXX.h:4460
Wrapper of type source information for a type with no direct qualifiers.
Definition TypeLoc.h:274
A reference to a name which we were able to look up during parsing but could not resolve to a specifi...
Definition ExprCXX.h:3390
Represents a C++ member access expression for which lookup produced a set of overloaded functions.
Definition ExprCXX.h:4126
This node is generated when a using-declaration that was annotated with attribute((using_if_exists)) ...
Definition DeclCXX.h:4123
Represents the dependent type named by a dependently-scoped typename using declaration,...
Definition TypeBase.h:6078
Represents a dependent using declaration which was marked with typename.
Definition DeclCXX.h:4042
Represents a dependent using declaration which was not marked with typename.
Definition DeclCXX.h:3945
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:3596
Represents C++ using-directive.
Definition DeclCXX.h:3101
Represents a C++ using-enum-declaration.
Definition DeclCXX.h:3797
Represents a pack of using declarations that a single using-declarator pack-expanded into.
Definition DeclCXX.h:3878
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Definition DeclCXX.h:3404
Represents a call to the builtin function __builtin_va_arg.
Definition Expr.h:4960
Represents a variable declaration or definition.
Definition Decl.h:924
Declaration of a variable template.
Represents a C array with a specified size that is not an integer-constant-expression.
Definition TypeBase.h:4021
Represents a GCC generic vector type.
Definition TypeBase.h:4230
WhileStmt - This represents a 'while' stmt.
Definition Stmt.h:2703
A requires-expression requirement which queries the validity and properties of an expression ('simple...
A requires-expression requirement which is satisfied when a general constraint expression is satisfie...
A static requirement that can be used in a requires-expression to check properties of types and expre...
A requires-expression requirement which queries the existence of a type name or type template special...
LLVM_ATTRIBUTE_ALWAYS_INLINE LLVM_ATTRIBUTE_NODEBUG auto isSameMethod(FirstMethodPtrTy FirstMethodPtr, SecondMethodPtrTy SecondMethodPtr) -> bool
Returns true if and only if FirstMethodPtr and SecondMethodPtr are pointers to the same non-static me...
The JSON file list parser is used to communicate input to InstallAPI.
bool isa(CodeGen::Address addr)
Definition Address.h:330
TRY_TO(TraverseNestedNameSpecifier(Qualifier))
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
Definition Parser.h:61
OpenACCComputeConstruct(OpenACCDirectiveKind K, SourceLocation Start, SourceLocation DirectiveLoc, SourceLocation End, ArrayRef< const OpenACCClause * > Clauses, Stmt *StructuredBlock)
@ Parameter
The parameter type of a method or function.
Definition TypeBase.h:908
@ Template
We are parsing a template declaration.
Definition Parser.h:81
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
Definition DeclBase.h:1301
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
Definition Specifiers.h:207
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
Definition Specifiers.h:203
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition Specifiers.h:199
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
Definition Specifiers.h:195
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition Specifiers.h:192
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Class
The "class" keyword introduces the elaborated-type-specifier.
Definition TypeBase.h:5972
DEF_TRAVERSE_TYPE(ComplexType, { TRY_TO(TraverseType(T->getElementType()));}) DEF_TRAVERSE_TYPE(PointerType
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
DeclarationName getName() const
getName - Returns the embedded declaration name.
TypeSourceInfo * getNamedTypeInfo() const
getNamedTypeInfo - Returns the source type info associated to the name.