clang 20.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"
26#include "clang/AST/Expr.h"
27#include "clang/AST/ExprCXX.h"
29#include "clang/AST/ExprObjC.h"
35#include "clang/AST/Stmt.h"
36#include "clang/AST/StmtCXX.h"
37#include "clang/AST/StmtObjC.h"
42#include "clang/AST/Type.h"
43#include "clang/AST/TypeLoc.h"
44#include "clang/Basic/LLVM.h"
47#include "llvm/ADT/PointerIntPair.h"
48#include "llvm/ADT/SmallVector.h"
49#include "llvm/Support/Casting.h"
50#include <algorithm>
51#include <cstddef>
52#include <type_traits>
53
54namespace clang {
55
56// A helper macro to implement short-circuiting when recursing. It
57// invokes CALL_EXPR, which must be a method call, on the derived
58// object (s.t. a user of RecursiveASTVisitor can override the method
59// in CALL_EXPR).
60#define TRY_TO(CALL_EXPR) \
61 do { \
62 if (!getDerived().CALL_EXPR) \
63 return false; \
64 } while (false)
65
66namespace detail {
67
68template <typename T, typename U>
69struct has_same_member_pointer_type : std::false_type {};
70template <typename T, typename U, typename R, typename... P>
71struct has_same_member_pointer_type<R (T::*)(P...), R (U::*)(P...)>
72 : std::true_type {};
73
74/// Returns true if and only if \p FirstMethodPtr and \p SecondMethodPtr
75/// are pointers to the same non-static member function.
76template <typename FirstMethodPtrTy, typename SecondMethodPtrTy>
77LLVM_ATTRIBUTE_ALWAYS_INLINE LLVM_ATTRIBUTE_NODEBUG auto
78isSameMethod([[maybe_unused]] FirstMethodPtrTy FirstMethodPtr,
79 [[maybe_unused]] SecondMethodPtrTy SecondMethodPtr)
80 -> bool {
81 if constexpr (has_same_member_pointer_type<FirstMethodPtrTy,
82 SecondMethodPtrTy>::value)
83 return FirstMethodPtr == SecondMethodPtr;
84 return false;
85}
86
87} // end namespace detail
88
89/// A class that does preorder or postorder
90/// depth-first traversal on the entire Clang AST and visits each node.
91///
92/// This class performs three distinct tasks:
93/// 1. traverse the AST (i.e. go to each node);
94/// 2. at a given node, walk up the class hierarchy, starting from
95/// the node's dynamic type, until the top-most class (e.g. Stmt,
96/// Decl, or Type) is reached.
97/// 3. given a (node, class) combination, where 'class' is some base
98/// class of the dynamic type of 'node', call a user-overridable
99/// function to actually visit the node.
100///
101/// These tasks are done by three groups of methods, respectively:
102/// 1. TraverseDecl(Decl *x) does task #1. It is the entry point
103/// for traversing an AST rooted at x. This method simply
104/// dispatches (i.e. forwards) to TraverseFoo(Foo *x) where Foo
105/// is the dynamic type of *x, which calls WalkUpFromFoo(x) and
106/// then recursively visits the child nodes of x.
107/// TraverseStmt(Stmt *x) and TraverseType(QualType x) work
108/// similarly.
109/// 2. WalkUpFromFoo(Foo *x) does task #2. It does not try to visit
110/// any child node of x. Instead, it first calls WalkUpFromBar(x)
111/// where Bar is the direct parent class of Foo (unless Foo has
112/// no parent), and then calls VisitFoo(x) (see the next list item).
113/// 3. VisitFoo(Foo *x) does task #3.
114///
115/// These three method groups are tiered (Traverse* > WalkUpFrom* >
116/// Visit*). A method (e.g. Traverse*) may call methods from the same
117/// tier (e.g. other Traverse*) or one tier lower (e.g. WalkUpFrom*).
118/// It may not call methods from a higher tier.
119///
120/// Note that since WalkUpFromFoo() calls WalkUpFromBar() (where Bar
121/// is Foo's super class) before calling VisitFoo(), the result is
122/// that the Visit*() methods for a given node are called in the
123/// top-down order (e.g. for a node of type NamespaceDecl, the order will
124/// be VisitDecl(), VisitNamedDecl(), and then VisitNamespaceDecl()).
125///
126/// This scheme guarantees that all Visit*() calls for the same AST
127/// node are grouped together. In other words, Visit*() methods for
128/// different nodes are never interleaved.
129///
130/// Clients of this visitor should subclass the visitor (providing
131/// themselves as the template argument, using the curiously recurring
132/// template pattern) and override any of the Traverse*, WalkUpFrom*,
133/// and Visit* methods for declarations, types, statements,
134/// expressions, or other AST nodes where the visitor should customize
135/// behavior. Most users only need to override Visit*. Advanced
136/// users may override Traverse* and WalkUpFrom* to implement custom
137/// traversal strategies. Returning false from one of these overridden
138/// functions will abort the entire traversal.
139///
140/// By default, this visitor tries to visit every part of the explicit
141/// source code exactly once. The default policy towards templates
142/// is to descend into the 'pattern' class or function body, not any
143/// explicit or implicit instantiations. Explicit specializations
144/// are still visited, and the patterns of partial specializations
145/// are visited separately. This behavior can be changed by
146/// overriding shouldVisitTemplateInstantiations() in the derived class
147/// to return true, in which case all known implicit and explicit
148/// instantiations will be visited at the same time as the pattern
149/// from which they were produced.
150///
151/// By default, this visitor preorder traverses the AST. If postorder traversal
152/// is needed, the \c shouldTraversePostOrder method needs to be overridden
153/// to return \c true.
154template <typename Derived> class RecursiveASTVisitor {
155public:
156 /// A queue used for performing data recursion over statements.
157 /// Parameters involving this type are used to implement data
158 /// recursion over Stmts and Exprs within this class, and should
159 /// typically not be explicitly specified by derived classes.
160 /// The bool bit indicates whether the statement has been traversed or not.
163
164 /// Return a reference to the derived class.
165 Derived &getDerived() { return *static_cast<Derived *>(this); }
166
167 /// Return whether this visitor should recurse into
168 /// template instantiations.
169 bool shouldVisitTemplateInstantiations() const { return false; }
170
171 /// Return whether this visitor should recurse into the types of
172 /// TypeLocs.
173 bool shouldWalkTypesOfTypeLocs() const { return true; }
174
175 /// Return whether this visitor should recurse into implicit
176 /// code, e.g., implicit constructors and destructors.
177 bool shouldVisitImplicitCode() const { return false; }
178
179 /// Return whether this visitor should recurse into lambda body
180 bool shouldVisitLambdaBody() const { return true; }
181
182 /// Return whether this visitor should traverse post-order.
183 bool shouldTraversePostOrder() const { return false; }
184
185 /// Recursively visits an entire AST, starting from the TranslationUnitDecl.
186 /// \returns false if visitation was terminated early.
188 // Currently just an alias for TraverseDecl(TUDecl), but kept in case
189 // we change the implementation again.
190 return getDerived().TraverseDecl(AST.getTranslationUnitDecl());
191 }
192
193 /// Recursively visit a statement or expression, by
194 /// dispatching to Traverse*() based on the argument's dynamic type.
195 ///
196 /// \returns false if the visitation was terminated early, true
197 /// otherwise (including when the argument is nullptr).
198 bool TraverseStmt(Stmt *S, DataRecursionQueue *Queue = nullptr);
199
200 /// Invoked before visiting a statement or expression via data recursion.
201 ///
202 /// \returns false to skip visiting the node, true otherwise.
203 bool dataTraverseStmtPre(Stmt *S) { return true; }
204
205 /// Invoked after visiting a statement or expression via data recursion.
206 /// This is not invoked if the previously invoked \c dataTraverseStmtPre
207 /// returned false.
208 ///
209 /// \returns false if the visitation was terminated early, true otherwise.
210 bool dataTraverseStmtPost(Stmt *S) { return true; }
211
212 /// Recursively visit a type, by dispatching to
213 /// Traverse*Type() based on the argument's getTypeClass() property.
214 ///
215 /// \returns false if the visitation was terminated early, true
216 /// otherwise (including when the argument is a Null type).
218
219 /// Recursively visit a type with location, by dispatching to
220 /// Traverse*TypeLoc() based on the argument type's getTypeClass() property.
221 ///
222 /// \returns false if the visitation was terminated early, true
223 /// otherwise (including when the argument is a Null type location).
225
226 /// Recursively visit an attribute, by dispatching to
227 /// Traverse*Attr() based on the argument's dynamic type.
228 ///
229 /// \returns false if the visitation was terminated early, true
230 /// otherwise (including when the argument is a Null type location).
232
233 /// Recursively visit a declaration, by dispatching to
234 /// Traverse*Decl() based on the argument's dynamic type.
235 ///
236 /// \returns false if the visitation was terminated early, true
237 /// otherwise (including when the argument is NULL).
239
240 /// Recursively visit a C++ nested-name-specifier.
241 ///
242 /// \returns false if the visitation was terminated early, true otherwise.
244
245 /// Recursively visit a C++ nested-name-specifier with location
246 /// information.
247 ///
248 /// \returns false if the visitation was terminated early, true otherwise.
250
251 /// Recursively visit a name with its location information.
252 ///
253 /// \returns false if the visitation was terminated early, true otherwise.
255
256 /// Recursively visit a template name and dispatch to the
257 /// appropriate method.
258 ///
259 /// \returns false if the visitation was terminated early, true otherwise.
261
262 /// Recursively visit a template argument and dispatch to the
263 /// appropriate method for the argument type.
264 ///
265 /// \returns false if the visitation was terminated early, true otherwise.
266 // FIXME: migrate callers to TemplateArgumentLoc instead.
268
269 /// Recursively visit a template argument location and dispatch to the
270 /// appropriate method for the argument type.
271 ///
272 /// \returns false if the visitation was terminated early, true otherwise.
274
275 /// Recursively visit a set of template arguments.
276 /// This can be overridden by a subclass, but it's not expected that
277 /// will be needed -- this visitor always dispatches to another.
278 ///
279 /// \returns false if the visitation was terminated early, true otherwise.
280 // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead.
282
283 /// Recursively visit a base specifier. This can be overridden by a
284 /// subclass.
285 ///
286 /// \returns false if the visitation was terminated early, true otherwise.
288
289 /// Recursively visit a constructor initializer. This
290 /// automatically dispatches to another visitor for the initializer
291 /// expression, but not for the name of the initializer, so may
292 /// be overridden for clients that need access to the name.
293 ///
294 /// \returns false if the visitation was terminated early, true otherwise.
296
297 /// Recursively visit a lambda capture. \c Init is the expression that
298 /// will be used to initialize the capture.
299 ///
300 /// \returns false if the visitation was terminated early, true otherwise.
302 Expr *Init);
303
304 /// Recursively visit the syntactic or semantic form of an
305 /// initialization list.
306 ///
307 /// \returns false if the visitation was terminated early, true otherwise.
309 DataRecursionQueue *Queue = nullptr);
310
311 /// Recursively visit an Objective-C protocol reference with location
312 /// information.
313 ///
314 /// \returns false if the visitation was terminated early, true otherwise.
316
317 /// Recursively visit concept reference with location information.
318 ///
319 /// \returns false if the visitation was terminated early, true otherwise.
321
322 // Visit concept reference.
323 bool VisitConceptReference(ConceptReference *CR) { return true; }
324 // ---- Methods on Attrs ----
325
326 // Visit an attribute.
327 bool VisitAttr(Attr *A) { return true; }
328
329// Declare Traverse* and empty Visit* for all Attr classes.
330#define ATTR_VISITOR_DECLS_ONLY
331#include "clang/AST/AttrVisitor.inc"
332#undef ATTR_VISITOR_DECLS_ONLY
333
334// ---- Methods on Stmts ----
335
336 Stmt::child_range getStmtChildren(Stmt *S) { return S->children(); }
337
338private:
339 // Traverse the given statement. If the most-derived traverse function takes a
340 // data recursion queue, pass it on; otherwise, discard it. Note that the
341 // first branch of this conditional must compile whether or not the derived
342 // class can take a queue, so if we're taking the second arm, make the first
343 // arm call our function rather than the derived class version.
344#define TRAVERSE_STMT_BASE(NAME, CLASS, VAR, QUEUE) \
345 (::clang::detail::has_same_member_pointer_type< \
346 decltype(&RecursiveASTVisitor::Traverse##NAME), \
347 decltype(&Derived::Traverse##NAME)>::value \
348 ? static_cast<std::conditional_t< \
349 ::clang::detail::has_same_member_pointer_type< \
350 decltype(&RecursiveASTVisitor::Traverse##NAME), \
351 decltype(&Derived::Traverse##NAME)>::value, \
352 Derived &, RecursiveASTVisitor &>>(*this) \
353 .Traverse##NAME(static_cast<CLASS *>(VAR), QUEUE) \
354 : getDerived().Traverse##NAME(static_cast<CLASS *>(VAR)))
355
356// Try to traverse the given statement, or enqueue it if we're performing data
357// recursion in the middle of traversing another statement. Can only be called
358// from within a DEF_TRAVERSE_STMT body or similar context.
359#define TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S) \
360 do { \
361 if (!TRAVERSE_STMT_BASE(Stmt, Stmt, S, Queue)) \
362 return false; \
363 } while (false)
364
365public:
366// Declare Traverse*() for all concrete Stmt classes.
367#define ABSTRACT_STMT(STMT)
368#define STMT(CLASS, PARENT) \
369 bool Traverse##CLASS(CLASS *S, DataRecursionQueue *Queue = nullptr);
370#include "clang/AST/StmtNodes.inc"
371 // The above header #undefs ABSTRACT_STMT and STMT upon exit.
372
373 // Define WalkUpFrom*() and empty Visit*() for all Stmt classes.
374 bool WalkUpFromStmt(Stmt *S) { return getDerived().VisitStmt(S); }
375 bool VisitStmt(Stmt *S) { return true; }
376#define STMT(CLASS, PARENT) \
377 bool WalkUpFrom##CLASS(CLASS *S) { \
378 TRY_TO(WalkUpFrom##PARENT(S)); \
379 TRY_TO(Visit##CLASS(S)); \
380 return true; \
381 } \
382 bool Visit##CLASS(CLASS *S) { return true; }
383#include "clang/AST/StmtNodes.inc"
384
385// ---- Methods on Types ----
386// FIXME: revamp to take TypeLoc's rather than Types.
387
388// Declare Traverse*() for all concrete Type classes.
389#define ABSTRACT_TYPE(CLASS, BASE)
390#define TYPE(CLASS, BASE) bool Traverse##CLASS##Type(CLASS##Type *T);
391#include "clang/AST/TypeNodes.inc"
392 // The above header #undefs ABSTRACT_TYPE and TYPE upon exit.
393
394 // Define WalkUpFrom*() and empty Visit*() for all Type classes.
395 bool WalkUpFromType(Type *T) { return getDerived().VisitType(T); }
396 bool VisitType(Type *T) { return true; }
397#define TYPE(CLASS, BASE) \
398 bool WalkUpFrom##CLASS##Type(CLASS##Type *T) { \
399 TRY_TO(WalkUpFrom##BASE(T)); \
400 TRY_TO(Visit##CLASS##Type(T)); \
401 return true; \
402 } \
403 bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
404#include "clang/AST/TypeNodes.inc"
405
406// ---- Methods on TypeLocs ----
407// FIXME: this currently just calls the matching Type methods
408
409// Declare Traverse*() for all concrete TypeLoc classes.
410#define ABSTRACT_TYPELOC(CLASS, BASE)
411#define TYPELOC(CLASS, BASE) bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
412#include "clang/AST/TypeLocNodes.def"
413 // The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit.
414
415 // Define WalkUpFrom*() and empty Visit*() for all TypeLoc classes.
416 bool WalkUpFromTypeLoc(TypeLoc TL) { return getDerived().VisitTypeLoc(TL); }
417 bool VisitTypeLoc(TypeLoc TL) { return true; }
418
419 // QualifiedTypeLoc and UnqualTypeLoc are not declared in
420 // TypeNodes.inc and thus need to be handled specially.
422 return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
423 }
424 bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { return true; }
426 return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
427 }
428 bool VisitUnqualTypeLoc(UnqualTypeLoc TL) { return true; }
429
430// Note that BASE includes trailing 'Type' which CLASS doesn't.
431#define TYPE(CLASS, BASE) \
432 bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
433 TRY_TO(WalkUpFrom##BASE##Loc(TL)); \
434 TRY_TO(Visit##CLASS##TypeLoc(TL)); \
435 return true; \
436 } \
437 bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
438#include "clang/AST/TypeNodes.inc"
439
440// ---- Methods on Decls ----
441
442// Declare Traverse*() for all concrete Decl classes.
443#define ABSTRACT_DECL(DECL)
444#define DECL(CLASS, BASE) bool Traverse##CLASS##Decl(CLASS##Decl *D);
445#include "clang/AST/DeclNodes.inc"
446 // The above header #undefs ABSTRACT_DECL and DECL upon exit.
447
448 // Define WalkUpFrom*() and empty Visit*() for all Decl classes.
449 bool WalkUpFromDecl(Decl *D) { return getDerived().VisitDecl(D); }
450 bool VisitDecl(Decl *D) { return true; }
451#define DECL(CLASS, BASE) \
452 bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) { \
453 TRY_TO(WalkUpFrom##BASE(D)); \
454 TRY_TO(Visit##CLASS##Decl(D)); \
455 return true; \
456 } \
457 bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
458#include "clang/AST/DeclNodes.inc"
459
461
462#define DEF_TRAVERSE_TMPL_INST(TMPLDECLKIND) \
463 bool TraverseTemplateInstantiations(TMPLDECLKIND##TemplateDecl *D);
467#undef DEF_TRAVERSE_TMPL_INST
468
470
475
477
478private:
479 // These are helper methods used by more than one Traverse* method.
480 bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
481
482 // Traverses template parameter lists of either a DeclaratorDecl or TagDecl.
483 template <typename T>
484 bool TraverseDeclTemplateParameterLists(T *D);
485
486 bool TraverseTemplateTypeParamDeclConstraints(const TemplateTypeParmDecl *D);
487
488 bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL,
489 unsigned Count);
490 bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL);
491 bool TraverseRecordHelper(RecordDecl *D);
492 bool TraverseCXXRecordHelper(CXXRecordDecl *D);
493 bool TraverseDeclaratorHelper(DeclaratorDecl *D);
494 bool TraverseDeclContextHelper(DeclContext *DC);
495 bool TraverseFunctionHelper(FunctionDecl *D);
496 bool TraverseVarHelper(VarDecl *D);
497 bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
498 bool TraverseOMPLoopDirective(OMPLoopDirective *S);
499 bool TraverseOMPClause(OMPClause *C);
500#define GEN_CLANG_CLAUSE_CLASS
501#define CLAUSE_CLASS(Enum, Str, Class) bool Visit##Class(Class *C);
502#include "llvm/Frontend/OpenMP/OMP.inc"
503 /// Process clauses with list of variables.
504 template <typename T> bool VisitOMPClauseList(T *Node);
505 /// Process clauses with pre-initis.
506 bool VisitOMPClauseWithPreInit(OMPClauseWithPreInit *Node);
507 bool VisitOMPClauseWithPostUpdate(OMPClauseWithPostUpdate *Node);
508
509 bool PostVisitStmt(Stmt *S);
510 bool TraverseOpenACCConstructStmt(OpenACCConstructStmt *S);
511 bool
512 TraverseOpenACCAssociatedStmtConstruct(OpenACCAssociatedStmtConstruct *S);
513 bool VisitOpenACCClauseList(ArrayRef<const OpenACCClause *>);
514 bool VisitOpenACCClause(const OpenACCClause *);
515};
516
517template <typename Derived>
519 const TypeConstraint *C) {
520 if (!getDerived().shouldVisitImplicitCode()) {
521 TRY_TO(TraverseConceptReference(C->getConceptReference()));
522 return true;
523 }
524 if (Expr *IDC = C->getImmediatelyDeclaredConstraint()) {
525 TRY_TO(TraverseStmt(IDC));
526 } else {
527 // Avoid traversing the ConceptReference in the TypeConstraint
528 // if we have an immediately-declared-constraint, otherwise
529 // we'll end up visiting the concept and the arguments in
530 // the TC twice.
531 TRY_TO(TraverseConceptReference(C->getConceptReference()));
532 }
533 return true;
534}
535
536template <typename Derived>
539 switch (R->getKind()) {
541 return getDerived().TraverseConceptTypeRequirement(
542 cast<concepts::TypeRequirement>(R));
545 return getDerived().TraverseConceptExprRequirement(
546 cast<concepts::ExprRequirement>(R));
548 return getDerived().TraverseConceptNestedRequirement(
549 cast<concepts::NestedRequirement>(R));
550 }
551 llvm_unreachable("unexpected case");
552}
553
554template <typename Derived>
556 DataRecursionQueue *Queue) {
557 // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
558 switch (S->getStmtClass()) {
560 break;
561#define ABSTRACT_STMT(STMT)
562#define STMT(CLASS, PARENT) \
563 case Stmt::CLASS##Class: \
564 return TRAVERSE_STMT_BASE(CLASS, CLASS, S, Queue);
565#include "clang/AST/StmtNodes.inc"
566 }
567
568 return true;
569}
570
571#undef DISPATCH_STMT
572
573template <typename Derived>
576 if (R->isSubstitutionFailure())
577 return true;
578 return getDerived().TraverseTypeLoc(R->getType()->getTypeLoc());
579}
580
581template <typename Derived>
585 TRY_TO(TraverseStmt(R->getExpr()));
586 auto &RetReq = R->getReturnTypeRequirement();
587 if (RetReq.isTypeConstraint()) {
588 if (getDerived().shouldVisitImplicitCode()) {
589 TRY_TO(TraverseTemplateParameterListHelper(
590 RetReq.getTypeConstraintTemplateParameterList()));
591 } else {
592 // Template parameter list is implicit, visit constraint directly.
593 TRY_TO(TraverseTypeConstraint(RetReq.getTypeConstraint()));
594 }
595 }
596 return true;
597}
598
599template <typename Derived>
602 if (!R->hasInvalidConstraint())
603 return getDerived().TraverseStmt(R->getConstraintExpr());
604 return true;
605}
606
607template <typename Derived>
609 // In pre-order traversal mode, each Traverse##STMT method is responsible for
610 // calling WalkUpFrom. Therefore, if the user overrides Traverse##STMT and
611 // does not call the default implementation, the WalkUpFrom callback is not
612 // called. Post-order traversal mode should provide the same behavior
613 // regarding method overrides.
614 //
615 // In post-order traversal mode the Traverse##STMT method, when it receives a
616 // DataRecursionQueue, can't call WalkUpFrom after traversing children because
617 // it only enqueues the children and does not traverse them. TraverseStmt
618 // traverses the enqueued children, and we call WalkUpFrom here.
619 //
620 // However, to make pre-order and post-order modes identical with regards to
621 // whether they call WalkUpFrom at all, we call WalkUpFrom if and only if the
622 // user did not override the Traverse##STMT method. We implement the override
623 // check with isSameMethod calls below.
624
625 switch (S->getStmtClass()) {
627 break;
628#define ABSTRACT_STMT(STMT)
629#define STMT(CLASS, PARENT) \
630 case Stmt::CLASS##Class: \
631 if (::clang::detail::isSameMethod(&RecursiveASTVisitor::Traverse##CLASS, \
632 &Derived::Traverse##CLASS)) { \
633 TRY_TO(WalkUpFrom##CLASS(static_cast<CLASS *>(S))); \
634 } \
635 break;
636#define INITLISTEXPR(CLASS, PARENT) \
637 case Stmt::CLASS##Class: \
638 if (::clang::detail::isSameMethod(&RecursiveASTVisitor::Traverse##CLASS, \
639 &Derived::Traverse##CLASS)) { \
640 auto ILE = static_cast<CLASS *>(S); \
641 if (auto Syn = ILE->isSemanticForm() ? ILE->getSyntacticForm() : ILE) \
642 TRY_TO(WalkUpFrom##CLASS(Syn)); \
643 if (auto Sem = ILE->isSemanticForm() ? ILE : ILE->getSemanticForm()) \
644 TRY_TO(WalkUpFrom##CLASS(Sem)); \
645 } \
646 break;
647#include "clang/AST/StmtNodes.inc"
648 }
649
650 return true;
651}
652
653#undef DISPATCH_STMT
654
655// Inlining this method can lead to large code size and compile-time increases
656// without any benefit to runtime performance.
657template <typename Derived>
658LLVM_ATTRIBUTE_NOINLINE bool
660 if (!S)
661 return true;
662
663 if (Queue) {
664 Queue->push_back({S, false});
665 return true;
666 }
667
669 LocalQueue.push_back({S, false});
670
671 while (!LocalQueue.empty()) {
672 auto &CurrSAndVisited = LocalQueue.back();
673 Stmt *CurrS = CurrSAndVisited.getPointer();
674 bool Visited = CurrSAndVisited.getInt();
675 if (Visited) {
676 LocalQueue.pop_back();
677 TRY_TO(dataTraverseStmtPost(CurrS));
678 if (getDerived().shouldTraversePostOrder()) {
679 TRY_TO(PostVisitStmt(CurrS));
680 }
681 continue;
682 }
683
684 if (getDerived().dataTraverseStmtPre(CurrS)) {
685 CurrSAndVisited.setInt(true);
686 size_t N = LocalQueue.size();
687 TRY_TO(dataTraverseNode(CurrS, &LocalQueue));
688 // Process new children in the order they were added.
689 std::reverse(LocalQueue.begin() + N, LocalQueue.end());
690 } else {
691 LocalQueue.pop_back();
692 }
693 }
694
695 return true;
696}
697
698template <typename Derived>
700 if (T.isNull())
701 return true;
702
703 switch (T->getTypeClass()) {
704#define ABSTRACT_TYPE(CLASS, BASE)
705#define TYPE(CLASS, BASE) \
706 case Type::CLASS: \
707 return getDerived().Traverse##CLASS##Type( \
708 static_cast<CLASS##Type *>(const_cast<Type *>(T.getTypePtr())));
709#include "clang/AST/TypeNodes.inc"
710 }
711
712 return true;
713}
714
715template <typename Derived>
717 if (TL.isNull())
718 return true;
719
720 switch (TL.getTypeLocClass()) {
721#define ABSTRACT_TYPELOC(CLASS, BASE)
722#define TYPELOC(CLASS, BASE) \
723 case TypeLoc::CLASS: \
724 return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>());
725#include "clang/AST/TypeLocNodes.def"
726 }
727
728 return true;
729}
730
731// Define the Traverse*Attr(Attr* A) methods
732#define VISITORCLASS RecursiveASTVisitor
733#include "clang/AST/AttrVisitor.inc"
734#undef VISITORCLASS
735
736template <typename Derived>
738 if (!D)
739 return true;
740
741 // As a syntax visitor, by default we want to ignore declarations for
742 // implicit declarations (ones not typed explicitly by the user).
743 if (!getDerived().shouldVisitImplicitCode()) {
744 if (D->isImplicit()) {
745 // For an implicit template type parameter, its type constraints are not
746 // implicit and are not represented anywhere else. We still need to visit
747 // them.
748 if (auto *TTPD = dyn_cast<TemplateTypeParmDecl>(D))
749 return TraverseTemplateTypeParamDeclConstraints(TTPD);
750 return true;
751 }
752
753 // Deduction guides for alias templates are always synthesized, so they
754 // should not be traversed unless shouldVisitImplicitCode() returns true.
755 //
756 // It's important to note that checking the implicit bit is not efficient
757 // for the alias case. For deduction guides synthesized from explicit
758 // user-defined deduction guides, we must maintain the explicit bit to
759 // ensure correct overload resolution.
760 if (auto *FTD = dyn_cast<FunctionTemplateDecl>(D))
761 if (llvm::isa_and_present<TypeAliasTemplateDecl>(
762 FTD->getDeclName().getCXXDeductionGuideTemplate()))
763 return true;
764 }
765
766 switch (D->getKind()) {
767#define ABSTRACT_DECL(DECL)
768#define DECL(CLASS, BASE) \
769 case Decl::CLASS: \
770 if (!getDerived().Traverse##CLASS##Decl(static_cast<CLASS##Decl *>(D))) \
771 return false; \
772 break;
773#include "clang/AST/DeclNodes.inc"
774 }
775 return true;
776}
777
778template <typename Derived>
780 NestedNameSpecifier *NNS) {
781 if (!NNS)
782 return true;
783
784 if (NNS->getPrefix())
785 TRY_TO(TraverseNestedNameSpecifier(NNS->getPrefix()));
786
787 switch (NNS->getKind()) {
793 return true;
794
797 TRY_TO(TraverseType(QualType(NNS->getAsType(), 0)));
798 }
799
800 return true;
801}
802
803template <typename Derived>
806 if (!NNS)
807 return true;
808
809 if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
810 TRY_TO(TraverseNestedNameSpecifierLoc(Prefix));
811
812 switch (NNS.getNestedNameSpecifier()->getKind()) {
818 return true;
819
822 TRY_TO(TraverseTypeLoc(NNS.getTypeLoc()));
823 break;
824 }
825
826 return true;
827}
828
829template <typename Derived>
831 DeclarationNameInfo NameInfo) {
832 switch (NameInfo.getName().getNameKind()) {
836 if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
837 TRY_TO(TraverseTypeLoc(TSInfo->getTypeLoc()));
838 break;
839
841 TRY_TO(TraverseTemplateName(
843 break;
844
852 break;
853 }
854
855 return true;
856}
857
858template <typename Derived>
861 TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier()));
862 } else if (QualifiedTemplateName *QTN =
863 Template.getAsQualifiedTemplateName()) {
864 if (QTN->getQualifier()) {
865 TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier()));
866 }
867 }
868
869 return true;
870}
871
872template <typename Derived>
874 const TemplateArgument &Arg) {
875 switch (Arg.getKind()) {
881 return true;
882
884 return getDerived().TraverseType(Arg.getAsType());
885
888 return getDerived().TraverseTemplateName(
890
892 return getDerived().TraverseStmt(Arg.getAsExpr());
893
895 return getDerived().TraverseTemplateArguments(Arg.pack_elements());
896 }
897
898 return true;
899}
900
901// FIXME: no template name location?
902// FIXME: no source locations for a template argument pack?
903template <typename Derived>
905 const TemplateArgumentLoc &ArgLoc) {
906 const TemplateArgument &Arg = ArgLoc.getArgument();
907
908 switch (Arg.getKind()) {
914 return true;
915
917 // FIXME: how can TSI ever be NULL?
918 if (TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo())
919 return getDerived().TraverseTypeLoc(TSI->getTypeLoc());
920 else
921 return getDerived().TraverseType(Arg.getAsType());
922 }
923
926 if (ArgLoc.getTemplateQualifierLoc())
927 TRY_TO(getDerived().TraverseNestedNameSpecifierLoc(
928 ArgLoc.getTemplateQualifierLoc()));
929 return getDerived().TraverseTemplateName(
931
933 return getDerived().TraverseStmt(ArgLoc.getSourceExpression());
934
936 return getDerived().TraverseTemplateArguments(Arg.pack_elements());
937 }
938
939 return true;
940}
941
942template <typename Derived>
945 for (const TemplateArgument &Arg : Args)
946 TRY_TO(TraverseTemplateArgument(Arg));
947
948 return true;
949}
950
951template <typename Derived>
954 if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo())
955 TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
956
957 if (Init->isWritten() || getDerived().shouldVisitImplicitCode())
958 TRY_TO(TraverseStmt(Init->getInit()));
959
960 return true;
961}
962
963template <typename Derived>
964bool
966 const LambdaCapture *C,
967 Expr *Init) {
968 if (LE->isInitCapture(C))
969 TRY_TO(TraverseDecl(C->getCapturedVar()));
970 else
971 TRY_TO(TraverseStmt(Init));
972 return true;
973}
974
975// ----------------- Type traversal -----------------
976
977// This macro makes available a variable T, the passed-in type.
978#define DEF_TRAVERSE_TYPE(TYPE, CODE) \
979 template <typename Derived> \
980 bool RecursiveASTVisitor<Derived>::Traverse##TYPE(TYPE *T) { \
981 if (!getDerived().shouldTraversePostOrder()) \
982 TRY_TO(WalkUpFrom##TYPE(T)); \
983 { CODE; } \
984 if (getDerived().shouldTraversePostOrder()) \
985 TRY_TO(WalkUpFrom##TYPE(T)); \
986 return true; \
987 }
988
989DEF_TRAVERSE_TYPE(BuiltinType, {})
990
991DEF_TRAVERSE_TYPE(ComplexType, { TRY_TO(TraverseType(T->getElementType())); })
992
993DEF_TRAVERSE_TYPE(PointerType, { TRY_TO(TraverseType(T->getPointeeType())); })
994
996 { TRY_TO(TraverseType(T->getPointeeType())); })
997
998DEF_TRAVERSE_TYPE(LValueReferenceType,
999 { TRY_TO(TraverseType(T->getPointeeType())); })
1000
1002 { TRY_TO(TraverseType(T->getPointeeType())); })
1003
1004DEF_TRAVERSE_TYPE(MemberPointerType, {
1005 TRY_TO(TraverseType(QualType(T->getClass(), 0)));
1006 TRY_TO(TraverseType(T->getPointeeType()));
1007})
1008
1009DEF_TRAVERSE_TYPE(AdjustedType, { TRY_TO(TraverseType(T->getOriginalType())); })
1010
1011DEF_TRAVERSE_TYPE(DecayedType, { TRY_TO(TraverseType(T->getOriginalType())); })
1012
1014 TRY_TO(TraverseType(T->getElementType()));
1015 if (T->getSizeExpr())
1016 TRY_TO(TraverseStmt(const_cast<Expr*>(T->getSizeExpr())));
1017})
1018
1019DEF_TRAVERSE_TYPE(ArrayParameterType, {
1020 TRY_TO(TraverseType(T->getElementType()));
1021 if (T->getSizeExpr())
1022 TRY_TO(TraverseStmt(const_cast<Expr *>(T->getSizeExpr())));
1023})
1024
1026 { TRY_TO(TraverseType(T->getElementType())); })
1027
1028DEF_TRAVERSE_TYPE(VariableArrayType, {
1029 TRY_TO(TraverseType(T->getElementType()));
1030 TRY_TO(TraverseStmt(T->getSizeExpr()));
1031})
1032
1034 TRY_TO(TraverseType(T->getElementType()));
1035 if (T->getSizeExpr())
1036 TRY_TO(TraverseStmt(T->getSizeExpr()));
1037})
1038
1039DEF_TRAVERSE_TYPE(DependentAddressSpaceType, {
1040 TRY_TO(TraverseStmt(T->getAddrSpaceExpr()));
1041 TRY_TO(TraverseType(T->getPointeeType()));
1042})
1043
1045 if (T->getSizeExpr())
1046 TRY_TO(TraverseStmt(T->getSizeExpr()));
1047 TRY_TO(TraverseType(T->getElementType()));
1048})
1049
1050DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
1051 if (T->getSizeExpr())
1052 TRY_TO(TraverseStmt(T->getSizeExpr()));
1053 TRY_TO(TraverseType(T->getElementType()));
1054})
1055
1056DEF_TRAVERSE_TYPE(VectorType, { TRY_TO(TraverseType(T->getElementType())); })
1057
1058DEF_TRAVERSE_TYPE(ExtVectorType, { TRY_TO(TraverseType(T->getElementType())); })
1059
1061 { TRY_TO(TraverseType(T->getElementType())); })
1062
1063DEF_TRAVERSE_TYPE(DependentSizedMatrixType, {
1064 if (T->getRowExpr())
1065 TRY_TO(TraverseStmt(T->getRowExpr()));
1066 if (T->getColumnExpr())
1067 TRY_TO(TraverseStmt(T->getColumnExpr()));
1068 TRY_TO(TraverseType(T->getElementType()));
1069})
1070
1072 { TRY_TO(TraverseType(T->getReturnType())); })
1073
1074DEF_TRAVERSE_TYPE(FunctionProtoType, {
1075 TRY_TO(TraverseType(T->getReturnType()));
1076
1077 for (const auto &A : T->param_types()) {
1078 TRY_TO(TraverseType(A));
1079 }
1080
1081 for (const auto &E : T->exceptions()) {
1082 TRY_TO(TraverseType(E));
1083 }
1084
1085 if (Expr *NE = T->getNoexceptExpr())
1086 TRY_TO(TraverseStmt(NE));
1087})
1088
1089DEF_TRAVERSE_TYPE(UsingType, {})
1090DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
1091DEF_TRAVERSE_TYPE(TypedefType, {})
1092
1094 { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
1095
1096DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnmodifiedType())); })
1097
1099 { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
1100
1101DEF_TRAVERSE_TYPE(PackIndexingType, {
1102 TRY_TO(TraverseType(T->getPattern()));
1103 TRY_TO(TraverseStmt(T->getIndexExpr()));
1104})
1105
1107 TRY_TO(TraverseType(T->getBaseType()));
1108 TRY_TO(TraverseType(T->getUnderlyingType()));
1109})
1110
1111DEF_TRAVERSE_TYPE(AutoType, {
1112 TRY_TO(TraverseType(T->getDeducedType()));
1113 if (T->isConstrained()) {
1114 TRY_TO(TraverseTemplateArguments(T->getTypeConstraintArguments()));
1115 }
1116})
1118 TRY_TO(TraverseTemplateName(T->getTemplateName()));
1119 TRY_TO(TraverseType(T->getDeducedType()));
1120})
1121
1122DEF_TRAVERSE_TYPE(RecordType, {})
1123DEF_TRAVERSE_TYPE(EnumType, {})
1124DEF_TRAVERSE_TYPE(TemplateTypeParmType, {})
1125DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, {
1126 TRY_TO(TraverseType(T->getReplacementType()));
1127})
1129 TRY_TO(TraverseTemplateArgument(T->getArgumentPack()));
1130})
1131
1132DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
1133 TRY_TO(TraverseTemplateName(T->getTemplateName()));
1134 TRY_TO(TraverseTemplateArguments(T->template_arguments()));
1135})
1136
1137DEF_TRAVERSE_TYPE(InjectedClassNameType, {})
1138
1140 { TRY_TO(TraverseType(T->getModifiedType())); })
1141
1142DEF_TRAVERSE_TYPE(CountAttributedType, {
1143 if (T->getCountExpr())
1144 TRY_TO(TraverseStmt(T->getCountExpr()));
1145 TRY_TO(TraverseType(T->desugar()));
1146})
1147
1149 { TRY_TO(TraverseType(T->getWrappedType())); })
1150
1151DEF_TRAVERSE_TYPE(HLSLAttributedResourceType,
1152 { TRY_TO(TraverseType(T->getWrappedType())); })
1153
1154DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
1155
1156DEF_TRAVERSE_TYPE(MacroQualifiedType,
1157 { TRY_TO(TraverseType(T->getUnderlyingType())); })
1158
1160 if (T->getQualifier()) {
1161 TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
1162 }
1163 TRY_TO(TraverseType(T->getNamedType()));
1164})
1165
1166DEF_TRAVERSE_TYPE(DependentNameType,
1167 { TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); })
1168
1170 TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
1171 TRY_TO(TraverseTemplateArguments(T->template_arguments()));
1172})
1173
1174DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); })
1175
1176DEF_TRAVERSE_TYPE(ObjCTypeParamType, {})
1177
1178DEF_TRAVERSE_TYPE(ObjCInterfaceType, {})
1179
1181 // We have to watch out here because an ObjCInterfaceType's base
1182 // type is itself.
1183 if (T->getBaseType().getTypePtr() != T)
1184 TRY_TO(TraverseType(T->getBaseType()));
1185 for (auto typeArg : T->getTypeArgsAsWritten()) {
1186 TRY_TO(TraverseType(typeArg));
1187 }
1188})
1189
1190DEF_TRAVERSE_TYPE(ObjCObjectPointerType,
1191 { TRY_TO(TraverseType(T->getPointeeType())); })
1192
1193DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); })
1194
1195DEF_TRAVERSE_TYPE(PipeType, { TRY_TO(TraverseType(T->getElementType())); })
1196
1197DEF_TRAVERSE_TYPE(BitIntType, {})
1199 { TRY_TO(TraverseStmt(T->getNumBitsExpr())); })
1200
1201#undef DEF_TRAVERSE_TYPE
1202
1203// ----------------- TypeLoc traversal -----------------
1204
1205// This macro makes available a variable TL, the passed-in TypeLoc.
1206// If requested, it calls WalkUpFrom* for the Type in the given TypeLoc,
1207// in addition to WalkUpFrom* for the TypeLoc itself, such that existing
1208// clients that override the WalkUpFrom*Type() and/or Visit*Type() methods
1209// continue to work.
1210#define DEF_TRAVERSE_TYPELOC(TYPE, CODE) \
1211 template <typename Derived> \
1212 bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) { \
1213 if (!getDerived().shouldTraversePostOrder()) { \
1214 TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
1215 if (getDerived().shouldWalkTypesOfTypeLocs()) \
1216 TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \
1217 } \
1218 { CODE; } \
1219 if (getDerived().shouldTraversePostOrder()) { \
1220 TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
1221 if (getDerived().shouldWalkTypesOfTypeLocs()) \
1222 TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \
1223 } \
1224 return true; \
1225 }
1226
1227template <typename Derived>
1228bool
1229RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(QualifiedTypeLoc TL) {
1230 // Move this over to the 'main' typeloc tree. Note that this is a
1231 // move -- we pretend that we were really looking at the unqualified
1232 // typeloc all along -- rather than a recursion, so we don't follow
1233 // the normal CRTP plan of going through
1234 // getDerived().TraverseTypeLoc. If we did, we'd be traversing
1235 // twice for the same type (once as a QualifiedTypeLoc version of
1236 // the type, once as an UnqualifiedTypeLoc version of the type),
1237 // which in effect means we'd call VisitTypeLoc twice with the
1238 // 'same' type. This solves that problem, at the cost of never
1239 // seeing the qualified version of the type (unless the client
1240 // subclasses TraverseQualifiedTypeLoc themselves). It's not a
1241 // perfect solution. A perfect solution probably requires making
1242 // QualifiedTypeLoc a wrapper around TypeLoc -- like QualType is a
1243 // wrapper around Type* -- rather than being its own class in the
1244 // type hierarchy.
1245 return TraverseTypeLoc(TL.getUnqualifiedLoc());
1246}
1247
1248DEF_TRAVERSE_TYPELOC(BuiltinType, {})
1249
1250// FIXME: ComplexTypeLoc is unfinished
1252 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1253})
1254
1255DEF_TRAVERSE_TYPELOC(PointerType,
1256 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1257
1259 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1260
1261DEF_TRAVERSE_TYPELOC(LValueReferenceType,
1262 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1263
1265 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1266
1267// We traverse this in the type case as well, but how is it not reached through
1268// the pointee type?
1269DEF_TRAVERSE_TYPELOC(MemberPointerType, {
1270 if (auto *TSI = TL.getClassTInfo())
1271 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
1272 else
1273 TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
1274 TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
1275})
1276
1278 { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
1279
1280DEF_TRAVERSE_TYPELOC(DecayedType,
1281 { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
1282
1283template <typename Derived>
1284bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
1285 // This isn't available for ArrayType, but is for the ArrayTypeLoc.
1286 TRY_TO(TraverseStmt(TL.getSizeExpr()));
1287 return true;
1288}
1289
1291 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1292 TRY_TO(TraverseArrayTypeLocHelper(TL));
1293})
1294
1295DEF_TRAVERSE_TYPELOC(ArrayParameterType, {
1296 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1297 TRY_TO(TraverseArrayTypeLocHelper(TL));
1298})
1299
1301 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1302 TRY_TO(TraverseArrayTypeLocHelper(TL));
1303})
1304
1305DEF_TRAVERSE_TYPELOC(VariableArrayType, {
1306 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1307 TRY_TO(TraverseArrayTypeLocHelper(TL));
1308})
1309
1311 TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1312 TRY_TO(TraverseArrayTypeLocHelper(TL));
1313})
1314
1315DEF_TRAVERSE_TYPELOC(DependentAddressSpaceType, {
1316 TRY_TO(TraverseStmt(TL.getTypePtr()->getAddrSpaceExpr()));
1317 TRY_TO(TraverseType(TL.getTypePtr()->getPointeeType()));
1318})
1319
1320// FIXME: order? why not size expr first?
1321// FIXME: base VectorTypeLoc is unfinished
1323 if (TL.getTypePtr()->getSizeExpr())
1324 TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
1325 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1326})
1327
1328// FIXME: VectorTypeLoc is unfinished
1329DEF_TRAVERSE_TYPELOC(VectorType, {
1330 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1331})
1332
1334 if (TL.getTypePtr()->getSizeExpr())
1335 TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
1336 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1337})
1338
1339// FIXME: size and attributes
1340// FIXME: base VectorTypeLoc is unfinished
1341DEF_TRAVERSE_TYPELOC(ExtVectorType, {
1342 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1343})
1344
1346 TRY_TO(TraverseStmt(TL.getAttrRowOperand()));
1347 TRY_TO(TraverseStmt(TL.getAttrColumnOperand()));
1348 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1349})
1350
1351DEF_TRAVERSE_TYPELOC(DependentSizedMatrixType, {
1352 TRY_TO(TraverseStmt(TL.getAttrRowOperand()));
1353 TRY_TO(TraverseStmt(TL.getAttrColumnOperand()));
1354 TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1355})
1356
1358 { TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); })
1359
1360// FIXME: location of exception specifications (attributes?)
1361DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
1362 TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
1363
1364 const FunctionProtoType *T = TL.getTypePtr();
1365
1366 for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) {
1367 if (TL.getParam(I)) {
1368 TRY_TO(TraverseDecl(TL.getParam(I)));
1369 } else if (I < T->getNumParams()) {
1370 TRY_TO(TraverseType(T->getParamType(I)));
1371 }
1372 }
1373
1374 for (const auto &E : T->exceptions()) {
1375 TRY_TO(TraverseType(E));
1376 }
1377
1378 if (Expr *NE = T->getNoexceptExpr())
1379 TRY_TO(TraverseStmt(NE));
1380})
1381
1382DEF_TRAVERSE_TYPELOC(UsingType, {})
1383DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
1384DEF_TRAVERSE_TYPELOC(TypedefType, {})
1385
1387 { TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); })
1388
1389DEF_TRAVERSE_TYPELOC(TypeOfType, {
1390 TRY_TO(TraverseTypeLoc(TL.getUnmodifiedTInfo()->getTypeLoc()));
1391})
1392
1393// FIXME: location of underlying expr
1395 TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
1396})
1397
1398DEF_TRAVERSE_TYPELOC(PackIndexingType, {
1399 TRY_TO(TraverseType(TL.getPattern()));
1400 TRY_TO(TraverseStmt(TL.getTypePtr()->getIndexExpr()));
1401})
1402
1404 TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
1405})
1406
1407DEF_TRAVERSE_TYPELOC(AutoType, {
1408 TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
1409 if (TL.isConstrained()) {
1410 TRY_TO(TraverseConceptReference(TL.getConceptReference()));
1411 }
1412})
1413
1415 TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
1416 TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
1417})
1418
1419DEF_TRAVERSE_TYPELOC(RecordType, {})
1420DEF_TRAVERSE_TYPELOC(EnumType, {})
1421DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {})
1422DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, {
1423 TRY_TO(TraverseType(TL.getTypePtr()->getReplacementType()));
1424})
1426 TRY_TO(TraverseTemplateArgument(TL.getTypePtr()->getArgumentPack()));
1427})
1428
1429// FIXME: use the loc for the template name?
1430DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
1431 TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
1432 for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
1433 TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
1434 }
1435})
1436
1437DEF_TRAVERSE_TYPELOC(InjectedClassNameType, {})
1438
1439DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
1440
1441DEF_TRAVERSE_TYPELOC(MacroQualifiedType,
1442 { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
1443
1445 { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
1446
1447DEF_TRAVERSE_TYPELOC(CountAttributedType,
1448 { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
1449
1451 { TRY_TO(TraverseTypeLoc(TL.getWrappedLoc())); })
1452
1453DEF_TRAVERSE_TYPELOC(HLSLAttributedResourceType,
1454 { TRY_TO(TraverseTypeLoc(TL.getWrappedLoc())); })
1455
1457 if (TL.getQualifierLoc()) {
1458 TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
1459 }
1460 TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
1461})
1462
1463DEF_TRAVERSE_TYPELOC(DependentNameType, {
1464 TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
1465})
1466
1468 if (TL.getQualifierLoc()) {
1469 TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
1470 }
1471
1472 for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
1473 TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
1474 }
1475})
1476
1477DEF_TRAVERSE_TYPELOC(PackExpansionType,
1478 { TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); })
1479
1481 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1482 ObjCProtocolLoc ProtocolLoc(TL.getProtocol(I), TL.getProtocolLoc(I));
1483 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1484 }
1485})
1486
1487DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, {})
1488
1489DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
1490 // We have to watch out here because an ObjCInterfaceType's base
1491 // type is itself.
1492 if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
1493 TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
1494 for (unsigned i = 0, n = TL.getNumTypeArgs(); i != n; ++i)
1495 TRY_TO(TraverseTypeLoc(TL.getTypeArgTInfo(i)->getTypeLoc()));
1496 for (unsigned I = 0, N = TL.getNumProtocols(); I != N; ++I) {
1497 ObjCProtocolLoc ProtocolLoc(TL.getProtocol(I), TL.getProtocolLoc(I));
1498 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1499 }
1500})
1501
1503 { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1504
1505DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
1506
1507DEF_TRAVERSE_TYPELOC(PipeType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
1508
1509DEF_TRAVERSE_TYPELOC(BitIntType, {})
1510DEF_TRAVERSE_TYPELOC(DependentBitIntType, {
1511 TRY_TO(TraverseStmt(TL.getTypePtr()->getNumBitsExpr()));
1512})
1513
1515
1516// ----------------- Decl traversal -----------------
1517//
1518// For a Decl, we automate (in the DEF_TRAVERSE_DECL macro) traversing
1519// the children that come from the DeclContext associated with it.
1520// Therefore each Traverse* only needs to worry about children other
1521// than those.
1522
1523template <typename Derived>
1525 const Decl *Child) {
1526 // BlockDecls are traversed through BlockExprs,
1527 // CapturedDecls are traversed through CapturedStmts.
1528 if (isa<BlockDecl>(Child) || isa<CapturedDecl>(Child))
1529 return true;
1530 // Lambda classes are traversed through LambdaExprs.
1531 if (const CXXRecordDecl* Cls = dyn_cast<CXXRecordDecl>(Child))
1532 return Cls->isLambda();
1533 return false;
1534}
1535
1536template <typename Derived>
1538 if (!DC)
1539 return true;
1540
1541 for (auto *Child : DC->decls()) {
1542 if (!canIgnoreChildDeclWhileTraversingDeclContext(Child))
1543 TRY_TO(TraverseDecl(Child));
1544 }
1545
1546 return true;
1547}
1548
1549// This macro makes available a variable D, the passed-in decl.
1550#define DEF_TRAVERSE_DECL(DECL, CODE) \
1551 template <typename Derived> \
1552 bool RecursiveASTVisitor<Derived>::Traverse##DECL(DECL *D) { \
1553 bool ShouldVisitChildren = true; \
1554 bool ReturnValue = true; \
1555 if (!getDerived().shouldTraversePostOrder()) \
1556 TRY_TO(WalkUpFrom##DECL(D)); \
1557 { CODE; } \
1558 if (ReturnValue && ShouldVisitChildren) \
1559 TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D))); \
1560 if (ReturnValue) { \
1561 /* Visit any attributes attached to this declaration. */ \
1562 for (auto *I : D->attrs()) \
1563 TRY_TO(getDerived().TraverseAttr(I)); \
1564 } \
1565 if (ReturnValue && getDerived().shouldTraversePostOrder()) \
1566 TRY_TO(WalkUpFrom##DECL(D)); \
1567 return ReturnValue; \
1568 }
1569
1570DEF_TRAVERSE_DECL(AccessSpecDecl, {})
1571
1573 if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
1574 TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
1575 TRY_TO(TraverseStmt(D->getBody()));
1576 for (const auto &I : D->captures()) {
1577 if (I.hasCopyExpr()) {
1578 TRY_TO(TraverseStmt(I.getCopyExpr()));
1579 }
1580 }
1581 ShouldVisitChildren = false;
1582})
1583
1584DEF_TRAVERSE_DECL(CapturedDecl, {
1585 TRY_TO(TraverseStmt(D->getBody()));
1587})
1588
1589DEF_TRAVERSE_DECL(EmptyDecl, {})
1590
1591DEF_TRAVERSE_DECL(HLSLBufferDecl, {})
1592
1594 TRY_TO(TraverseStmt(D->getTemporaryExpr()));
1595})
1596
1597DEF_TRAVERSE_DECL(FileScopeAsmDecl,
1598 { TRY_TO(TraverseStmt(D->getAsmString())); })
1599
1600DEF_TRAVERSE_DECL(TopLevelStmtDecl, { TRY_TO(TraverseStmt(D->getStmt())); })
1601
1602DEF_TRAVERSE_DECL(ImportDecl, {})
1603
1604DEF_TRAVERSE_DECL(FriendDecl, {
1605 // Friend is either decl or a type.
1606 if (D->getFriendType()) {
1607 TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
1608 // Traverse any CXXRecordDecl owned by this type, since
1609 // it will not be in the parent context:
1610 if (auto *ET = D->getFriendType()->getType()->getAs<ElaboratedType>())
1611 TRY_TO(TraverseDecl(ET->getOwnedTagDecl()));
1612 } else {
1613 TRY_TO(TraverseDecl(D->getFriendDecl()));
1614 }
1615})
1616
1617DEF_TRAVERSE_DECL(FriendTemplateDecl, {
1618 if (D->getFriendType())
1619 TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
1620 else
1621 TRY_TO(TraverseDecl(D->getFriendDecl()));
1622 for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
1623 TemplateParameterList *TPL = D->getTemplateParameterList(I);
1624 for (TemplateParameterList::iterator ITPL = TPL->begin(), ETPL = TPL->end();
1625 ITPL != ETPL; ++ITPL) {
1626 TRY_TO(TraverseDecl(*ITPL));
1627 }
1628 }
1629})
1630
1631DEF_TRAVERSE_DECL(LinkageSpecDecl, {})
1632
1633DEF_TRAVERSE_DECL(ExportDecl, {})
1634
1635DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {// FIXME: implement this
1636 })
1637
1638DEF_TRAVERSE_DECL(StaticAssertDecl, {
1639 TRY_TO(TraverseStmt(D->getAssertExpr()));
1640 TRY_TO(TraverseStmt(D->getMessage()));
1641})
1642
1643DEF_TRAVERSE_DECL(TranslationUnitDecl, {
1644 // Code in an unnamed namespace shows up automatically in
1645 // decls_begin()/decls_end(). Thus we don't need to recurse on
1646 // D->getAnonymousNamespace().
1647
1648 // If the traversal scope is set, then consider them to be the children of
1649 // the TUDecl, rather than traversing (and loading?) all top-level decls.
1650 auto Scope = D->getASTContext().getTraversalScope();
1651 bool HasLimitedScope =
1652 Scope.size() != 1 || !isa<TranslationUnitDecl>(Scope.front());
1653 if (HasLimitedScope) {
1654 ShouldVisitChildren = false; // we'll do that here instead
1655 for (auto *Child : Scope) {
1656 if (!canIgnoreChildDeclWhileTraversingDeclContext(Child))
1657 TRY_TO(TraverseDecl(Child));
1658 }
1659 }
1660})
1661
1662DEF_TRAVERSE_DECL(PragmaCommentDecl, {})
1663
1664DEF_TRAVERSE_DECL(PragmaDetectMismatchDecl, {})
1665
1666DEF_TRAVERSE_DECL(ExternCContextDecl, {})
1667
1668DEF_TRAVERSE_DECL(NamespaceAliasDecl, {
1669 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1670
1671 // We shouldn't traverse an aliased namespace, since it will be
1672 // defined (and, therefore, traversed) somewhere else.
1673 ShouldVisitChildren = false;
1674})
1675
1676DEF_TRAVERSE_DECL(LabelDecl, {// There is no code in a LabelDecl.
1677 })
1678
1680 NamespaceDecl,
1681 {// Code in an unnamed namespace shows up automatically in
1682 // decls_begin()/decls_end(). Thus we don't need to recurse on
1683 // D->getAnonymousNamespace().
1684 })
1685
1686DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement
1687 })
1688
1689DEF_TRAVERSE_DECL(ObjCCategoryDecl, {
1690 if (ObjCTypeParamList *typeParamList = D->getTypeParamList()) {
1691 for (auto typeParam : *typeParamList) {
1692 TRY_TO(TraverseObjCTypeParamDecl(typeParam));
1693 }
1694 }
1695 for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
1696 ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
1697 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1698 }
1699})
1700
1701DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement
1702 })
1703
1704DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement
1705 })
1706
1707DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {
1708 if (ObjCTypeParamList *typeParamList = D->getTypeParamListAsWritten()) {
1709 for (auto typeParam : *typeParamList) {
1710 TRY_TO(TraverseObjCTypeParamDecl(typeParam));
1711 }
1712 }
1713
1714 if (TypeSourceInfo *superTInfo = D->getSuperClassTInfo()) {
1715 TRY_TO(TraverseTypeLoc(superTInfo->getTypeLoc()));
1716 }
1717 if (D->isThisDeclarationADefinition()) {
1718 for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
1719 ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
1720 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1721 }
1722 }
1723})
1724
1725DEF_TRAVERSE_DECL(ObjCProtocolDecl, {
1726 if (D->isThisDeclarationADefinition()) {
1727 for (auto It : llvm::zip(D->protocols(), D->protocol_locs())) {
1728 ObjCProtocolLoc ProtocolLoc(std::get<0>(It), std::get<1>(It));
1729 TRY_TO(TraverseObjCProtocolLoc(ProtocolLoc));
1730 }
1731 }
1732})
1733
1734DEF_TRAVERSE_DECL(ObjCMethodDecl, {
1735 if (D->getReturnTypeSourceInfo()) {
1736 TRY_TO(TraverseTypeLoc(D->getReturnTypeSourceInfo()->getTypeLoc()));
1737 }
1738 for (ParmVarDecl *Parameter : D->parameters()) {
1739 TRY_TO(TraverseDecl(Parameter));
1740 }
1741 if (D->isThisDeclarationADefinition()) {
1742 TRY_TO(TraverseStmt(D->getBody()));
1743 }
1744 ShouldVisitChildren = false;
1745})
1746
1747DEF_TRAVERSE_DECL(ObjCTypeParamDecl, {
1748 if (D->hasExplicitBound()) {
1749 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
1750 // We shouldn't traverse D->getTypeForDecl(); it's a result of
1751 // declaring the type alias, not something that was written in the
1752 // source.
1753 }
1754})
1755
1756DEF_TRAVERSE_DECL(ObjCPropertyDecl, {
1757 if (D->getTypeSourceInfo())
1758 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
1759 else
1760 TRY_TO(TraverseType(D->getType()));
1761 ShouldVisitChildren = false;
1762})
1763
1764DEF_TRAVERSE_DECL(UsingDecl, {
1765 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1766 TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
1767})
1768
1769DEF_TRAVERSE_DECL(UsingEnumDecl,
1770 { TRY_TO(TraverseTypeLoc(D->getEnumTypeLoc())); })
1771
1772DEF_TRAVERSE_DECL(UsingPackDecl, {})
1773
1774DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
1775 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1776})
1777
1778DEF_TRAVERSE_DECL(UsingShadowDecl, {})
1779
1780DEF_TRAVERSE_DECL(ConstructorUsingShadowDecl, {})
1781
1782DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
1783 for (auto *I : D->varlist()) {
1784 TRY_TO(TraverseStmt(I));
1785 }
1786})
1787
1788DEF_TRAVERSE_DECL(OMPRequiresDecl, {
1789 for (auto *C : D->clauselists()) {
1790 TRY_TO(TraverseOMPClause(C));
1791 }
1792})
1793
1794DEF_TRAVERSE_DECL(OMPDeclareReductionDecl, {
1795 TRY_TO(TraverseStmt(D->getCombiner()));
1796 if (auto *Initializer = D->getInitializer())
1797 TRY_TO(TraverseStmt(Initializer));
1798 TRY_TO(TraverseType(D->getType()));
1799 return true;
1800})
1801
1802DEF_TRAVERSE_DECL(OMPDeclareMapperDecl, {
1803 for (auto *C : D->clauselists())
1804 TRY_TO(TraverseOMPClause(C));
1805 TRY_TO(TraverseType(D->getType()));
1806 return true;
1807})
1808
1809DEF_TRAVERSE_DECL(OMPCapturedExprDecl, { TRY_TO(TraverseVarHelper(D)); })
1810
1811DEF_TRAVERSE_DECL(OMPAllocateDecl, {
1812 for (auto *I : D->varlist())
1813 TRY_TO(TraverseStmt(I));
1814 for (auto *C : D->clauselists())
1815 TRY_TO(TraverseOMPClause(C));
1816})
1817
1818// A helper method for TemplateDecl's children.
1819template <typename Derived>
1820bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
1821 TemplateParameterList *TPL) {
1822 if (TPL) {
1823 for (NamedDecl *D : *TPL) {
1824 TRY_TO(TraverseDecl(D));
1825 }
1826 if (Expr *RequiresClause = TPL->getRequiresClause()) {
1827 TRY_TO(TraverseStmt(RequiresClause));
1828 }
1829 }
1830 return true;
1831}
1832
1833template <typename Derived>
1834template <typename T>
1835bool RecursiveASTVisitor<Derived>::TraverseDeclTemplateParameterLists(T *D) {
1836 for (unsigned i = 0; i < D->getNumTemplateParameterLists(); i++) {
1837 TemplateParameterList *TPL = D->getTemplateParameterList(i);
1838 TraverseTemplateParameterListHelper(TPL);
1839 }
1840 return true;
1841}
1842
1843template <typename Derived>
1844bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
1845 ClassTemplateDecl *D) {
1846 for (auto *SD : D->specializations()) {
1847 for (auto *RD : SD->redecls()) {
1848 assert(!cast<CXXRecordDecl>(RD)->isInjectedClassName());
1849 switch (
1850 cast<ClassTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
1851 // Visit the implicit instantiations with the requested pattern.
1852 case TSK_Undeclared:
1854 TRY_TO(TraverseDecl(RD));
1855 break;
1856
1857 // We don't need to do anything on an explicit instantiation
1858 // or explicit specialization because there will be an explicit
1859 // node for it elsewhere.
1863 break;
1864 }
1865 }
1866 }
1867
1868 return true;
1869}
1870
1871template <typename Derived>
1872bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
1873 VarTemplateDecl *D) {
1874 for (auto *SD : D->specializations()) {
1875 for (auto *RD : SD->redecls()) {
1876 switch (
1877 cast<VarTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
1878 case TSK_Undeclared:
1880 TRY_TO(TraverseDecl(RD));
1881 break;
1882
1886 break;
1887 }
1888 }
1889 }
1890
1891 return true;
1892}
1893
1894// A helper method for traversing the instantiations of a
1895// function while skipping its specializations.
1896template <typename Derived>
1897bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
1898 FunctionTemplateDecl *D) {
1899 for (auto *FD : D->specializations()) {
1900 for (auto *RD : FD->redecls()) {
1901 switch (RD->getTemplateSpecializationKind()) {
1902 case TSK_Undeclared:
1904 // We don't know what kind of FunctionDecl this is.
1905 TRY_TO(TraverseDecl(RD));
1906 break;
1907
1908 // FIXME: For now traverse explicit instantiations here. Change that
1909 // once they are represented as dedicated nodes in the AST.
1912 TRY_TO(TraverseDecl(RD));
1913 break;
1914
1916 break;
1917 }
1918 }
1919 }
1920
1921 return true;
1922}
1923
1924// This macro unifies the traversal of class, variable and function
1925// template declarations.
1926#define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND) \
1927 DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, { \
1928 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
1929 TRY_TO(TraverseDecl(D->getTemplatedDecl())); \
1930 \
1931 /* By default, we do not traverse the instantiations of \
1932 class templates since they do not appear in the user code. The \
1933 following code optionally traverses them. \
1934 \
1935 We only traverse the class instantiations when we see the canonical \
1936 declaration of the template, to ensure we only visit them once. */ \
1937 if (getDerived().shouldVisitTemplateInstantiations() && \
1938 D == D->getCanonicalDecl()) \
1939 TRY_TO(TraverseTemplateInstantiations(D)); \
1940 \
1941 /* Note that getInstantiatedFromMemberTemplate() is just a link \
1942 from a template instantiation back to the template from which \
1943 it was instantiated, and thus should not be traversed. */ \
1944 })
1945
1948DEF_TRAVERSE_TMPL_DECL(Function)
1949
1950DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, {
1951 // D is the "T" in something like
1952 // template <template <typename> class T> class container { };
1953 TRY_TO(TraverseDecl(D->getTemplatedDecl()));
1954 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
1955 TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
1956 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
1957})
1958
1959DEF_TRAVERSE_DECL(BuiltinTemplateDecl, {
1960 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
1961})
1962
1963template <typename Derived>
1964bool RecursiveASTVisitor<Derived>::TraverseTemplateTypeParamDeclConstraints(
1965 const TemplateTypeParmDecl *D) {
1966 if (const auto *TC = D->getTypeConstraint())
1967 TRY_TO(TraverseTypeConstraint(TC));
1968 return true;
1969}
1970
1971DEF_TRAVERSE_DECL(TemplateTypeParmDecl, {
1972 // D is the "T" in something like "template<typename T> class vector;"
1973 if (D->getTypeForDecl())
1974 TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
1975 TRY_TO(TraverseTemplateTypeParamDeclConstraints(D));
1976 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
1977 TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
1978})
1979
1980DEF_TRAVERSE_DECL(TypedefDecl, {
1981 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
1982 // We shouldn't traverse D->getTypeForDecl(); it's a result of
1983 // declaring the typedef, not something that was written in the
1984 // source.
1985})
1986
1987DEF_TRAVERSE_DECL(TypeAliasDecl, {
1988 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
1989 // We shouldn't traverse D->getTypeForDecl(); it's a result of
1990 // declaring the type alias, not something that was written in the
1991 // source.
1992})
1993
1994DEF_TRAVERSE_DECL(TypeAliasTemplateDecl, {
1995 TRY_TO(TraverseDecl(D->getTemplatedDecl()));
1996 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
1997})
1998
1999DEF_TRAVERSE_DECL(ConceptDecl, {
2000 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
2001 TRY_TO(TraverseStmt(D->getConstraintExpr()));
2002})
2003
2004DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, {
2005 // A dependent using declaration which was marked with 'typename'.
2006 // template<class T> class A : public B<T> { using typename B<T>::foo; };
2007 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2008 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2009 // declaring the type, not something that was written in the
2010 // source.
2011})
2012
2013DEF_TRAVERSE_DECL(UnresolvedUsingIfExistsDecl, {})
2014
2015DEF_TRAVERSE_DECL(EnumDecl, {
2016 TRY_TO(TraverseDeclTemplateParameterLists(D));
2017
2018 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2019 if (auto *TSI = D->getIntegerTypeSourceInfo())
2020 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
2021 // The enumerators are already traversed by
2022 // decls_begin()/decls_end().
2023})
2024
2025// Helper methods for RecordDecl and its children.
2026template <typename Derived>
2027bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) {
2028 // We shouldn't traverse D->getTypeForDecl(); it's a result of
2029 // declaring the type, not something that was written in the source.
2030
2031 TRY_TO(TraverseDeclTemplateParameterLists(D));
2032 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2033 return true;
2034}
2035
2036template <typename Derived>
2037bool RecursiveASTVisitor<Derived>::TraverseCXXBaseSpecifier(
2038 const CXXBaseSpecifier &Base) {
2039 TRY_TO(TraverseTypeLoc(Base.getTypeSourceInfo()->getTypeLoc()));
2040 return true;
2041}
2042
2043template <typename Derived>
2044bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(CXXRecordDecl *D) {
2045 if (!TraverseRecordHelper(D))
2046 return false;
2047 if (D->isCompleteDefinition()) {
2048 for (const auto &I : D->bases()) {
2049 TRY_TO(TraverseCXXBaseSpecifier(I));
2050 }
2051 // We don't traverse the friends or the conversions, as they are
2052 // already in decls_begin()/decls_end().
2053 }
2054 return true;
2055}
2056
2057DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); })
2058
2059DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
2060
2061template <typename Derived>
2062bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
2063 const TemplateArgumentLoc *TAL, unsigned Count) {
2064 for (unsigned I = 0; I < Count; ++I) {
2065 TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
2066 }
2067 return true;
2068}
2069
2070#define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
2071 DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, { \
2072 /* For implicit instantiations ("set<int> x;"), we don't want to \
2073 recurse at all, since the instatiated template isn't written in \
2074 the source code anywhere. (Note the instatiated *type* -- \
2075 set<int> -- is written, and will still get a callback of \
2076 TemplateSpecializationType). For explicit instantiations \
2077 ("template set<int>;"), we do need a callback, since this \
2078 is the only callback that's made for this instantiation. \
2079 We use getTemplateArgsAsWritten() to distinguish. */ \
2080 if (const auto *ArgsWritten = D->getTemplateArgsAsWritten()) { \
2081 /* The args that remains unspecialized. */ \
2082 TRY_TO(TraverseTemplateArgumentLocsHelper( \
2083 ArgsWritten->getTemplateArgs(), ArgsWritten->NumTemplateArgs)); \
2084 } \
2085 \
2086 if (getDerived().shouldVisitTemplateInstantiations() || \
2087 D->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) { \
2088 /* Traverse base definition for explicit specializations */ \
2089 TRY_TO(Traverse##DECLKIND##Helper(D)); \
2090 } else { \
2091 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc())); \
2092 \
2093 /* Returning from here skips traversing the \
2094 declaration context of the *TemplateSpecializationDecl \
2095 (embedded in the DEF_TRAVERSE_DECL() macro) \
2096 which contains the instantiated members of the template. */ \
2097 return true; \
2098 } \
2099 })
2100
2101DEF_TRAVERSE_TMPL_SPEC_DECL(Class, CXXRecord)
2103
2104#define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
2105 DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, { \
2106 /* The partial specialization. */ \
2107 TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters())); \
2108 /* The args that remains unspecialized. */ \
2109 TRY_TO(TraverseTemplateArgumentLocsHelper( \
2110 D->getTemplateArgsAsWritten()->getTemplateArgs(), \
2111 D->getTemplateArgsAsWritten()->NumTemplateArgs)); \
2112 \
2113 /* Don't need the *TemplatePartialSpecializationHelper, even \
2114 though that's our parent class -- we already visit all the \
2115 template args here. */ \
2116 TRY_TO(Traverse##DECLKIND##Helper(D)); \
2117 \
2118 /* Instantiations will have been visited with the primary template. */ \
2119 })
2120
2121DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Class, CXXRecord)
2123
2124DEF_TRAVERSE_DECL(EnumConstantDecl, { TRY_TO(TraverseStmt(D->getInitExpr())); })
2125
2126DEF_TRAVERSE_DECL(UnresolvedUsingValueDecl, {
2127 // Like UnresolvedUsingTypenameDecl, but without the 'typename':
2128 // template <class T> Class A : public Base<T> { using Base<T>::foo; };
2129 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2130 TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
2131})
2132
2133DEF_TRAVERSE_DECL(IndirectFieldDecl, {})
2134
2135template <typename Derived>
2136bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
2137 TRY_TO(TraverseDeclTemplateParameterLists(D));
2138 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2139 if (D->getTypeSourceInfo())
2140 TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
2141 else
2142 TRY_TO(TraverseType(D->getType()));
2143 return true;
2144}
2145
2146DEF_TRAVERSE_DECL(DecompositionDecl, {
2147 TRY_TO(TraverseVarHelper(D));
2148 for (auto *Binding : D->bindings()) {
2149 TRY_TO(TraverseDecl(Binding));
2150 }
2151})
2152
2153DEF_TRAVERSE_DECL(BindingDecl, {
2154 if (getDerived().shouldVisitImplicitCode()) {
2155 TRY_TO(TraverseStmt(D->getBinding()));
2156 if (const auto HoldingVar = D->getHoldingVar())
2157 TRY_TO(TraverseDecl(HoldingVar));
2158 }
2159})
2160
2161DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
2162
2163DEF_TRAVERSE_DECL(MSGuidDecl, {})
2164DEF_TRAVERSE_DECL(UnnamedGlobalConstantDecl, {})
2165
2166DEF_TRAVERSE_DECL(TemplateParamObjectDecl, {})
2167
2168DEF_TRAVERSE_DECL(FieldDecl, {
2169 TRY_TO(TraverseDeclaratorHelper(D));
2170 if (D->isBitField())
2171 TRY_TO(TraverseStmt(D->getBitWidth()));
2172 if (D->hasInClassInitializer())
2173 TRY_TO(TraverseStmt(D->getInClassInitializer()));
2174})
2175
2176DEF_TRAVERSE_DECL(ObjCAtDefsFieldDecl, {
2177 TRY_TO(TraverseDeclaratorHelper(D));
2178 if (D->isBitField())
2179 TRY_TO(TraverseStmt(D->getBitWidth()));
2180 // FIXME: implement the rest.
2181})
2182
2183DEF_TRAVERSE_DECL(ObjCIvarDecl, {
2184 TRY_TO(TraverseDeclaratorHelper(D));
2185 if (D->isBitField())
2186 TRY_TO(TraverseStmt(D->getBitWidth()));
2187 // FIXME: implement the rest.
2188})
2189
2190template <typename Derived>
2191bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
2192 TRY_TO(TraverseDeclTemplateParameterLists(D));
2193 TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
2194 TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
2195
2196 // If we're an explicit template specialization, iterate over the
2197 // template args that were explicitly specified. If we were doing
2198 // this in typing order, we'd do it between the return type and
2199 // the function args, but both are handled by the FunctionTypeLoc
2200 // above, so we have to choose one side. I've decided to do before.
2201 if (const FunctionTemplateSpecializationInfo *FTSI =
2202 D->getTemplateSpecializationInfo()) {
2203 if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared &&
2204 FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
2205 // A specialization might not have explicit template arguments if it has
2206 // a templated return type and concrete arguments.
2207 if (const ASTTemplateArgumentListInfo *TALI =
2208 FTSI->TemplateArgumentsAsWritten) {
2209 TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
2210 TALI->NumTemplateArgs));
2211 }
2212 }
2213 } else if (const DependentFunctionTemplateSpecializationInfo *DFSI =
2214 D->getDependentSpecializationInfo()) {
2215 if (const ASTTemplateArgumentListInfo *TALI =
2216 DFSI->TemplateArgumentsAsWritten) {
2217 TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
2218 TALI->NumTemplateArgs));
2219 }
2220 }
2221
2222 // Visit the function type itself, which can be either
2223 // FunctionNoProtoType or FunctionProtoType, or a typedef. This
2224 // also covers the return type and the function parameters,
2225 // including exception specifications.
2226 if (TypeSourceInfo *TSI = D->getTypeSourceInfo()) {
2227 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
2228 } else if (getDerived().shouldVisitImplicitCode()) {
2229 // Visit parameter variable declarations of the implicit function
2230 // if the traverser is visiting implicit code. Parameter variable
2231 // declarations do not have valid TypeSourceInfo, so to visit them
2232 // we need to traverse the declarations explicitly.
2233 for (ParmVarDecl *Parameter : D->parameters()) {
2234 TRY_TO(TraverseDecl(Parameter));
2235 }
2236 }
2237
2238 // Visit the trailing requires clause, if any.
2239 if (Expr *TrailingRequiresClause = D->getTrailingRequiresClause()) {
2240 TRY_TO(TraverseStmt(TrailingRequiresClause));
2241 }
2242
2243 if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
2244 // Constructor initializers.
2245 for (auto *I : Ctor->inits()) {
2246 if (I->isWritten() || getDerived().shouldVisitImplicitCode())
2247 TRY_TO(TraverseConstructorInitializer(I));
2248 }
2249 }
2250
2251 bool VisitBody =
2252 D->isThisDeclarationADefinition() &&
2253 // Don't visit the function body if the function definition is generated
2254 // by clang.
2255 (!D->isDefaulted() || getDerived().shouldVisitImplicitCode());
2256
2257 if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) {
2258 if (const CXXRecordDecl *RD = MD->getParent()) {
2259 if (RD->isLambda() &&
2260 declaresSameEntity(RD->getLambdaCallOperator(), MD)) {
2261 VisitBody = VisitBody && getDerived().shouldVisitLambdaBody();
2262 }
2263 }
2264 }
2265
2266 if (VisitBody) {
2267 TRY_TO(TraverseStmt(D->getBody()));
2268 // Body may contain using declarations whose shadows are parented to the
2269 // FunctionDecl itself.
2270 for (auto *Child : D->decls()) {
2271 if (isa<UsingShadowDecl>(Child))
2272 TRY_TO(TraverseDecl(Child));
2273 }
2274 }
2275 return true;
2276}
2277
2278DEF_TRAVERSE_DECL(FunctionDecl, {
2279 // We skip decls_begin/decls_end, which are already covered by
2280 // TraverseFunctionHelper().
2281 ShouldVisitChildren = false;
2282 ReturnValue = TraverseFunctionHelper(D);
2283})
2284
2285DEF_TRAVERSE_DECL(CXXDeductionGuideDecl, {
2286 // We skip decls_begin/decls_end, which are already covered by
2287 // TraverseFunctionHelper().
2288 ShouldVisitChildren = false;
2289 ReturnValue = TraverseFunctionHelper(D);
2290})
2291
2292DEF_TRAVERSE_DECL(CXXMethodDecl, {
2293 // We skip decls_begin/decls_end, which are already covered by
2294 // TraverseFunctionHelper().
2295 ShouldVisitChildren = false;
2296 ReturnValue = TraverseFunctionHelper(D);
2297})
2298
2299DEF_TRAVERSE_DECL(CXXConstructorDecl, {
2300 // We skip decls_begin/decls_end, which are already covered by
2301 // TraverseFunctionHelper().
2302 ShouldVisitChildren = false;
2303 ReturnValue = TraverseFunctionHelper(D);
2304})
2305
2306// CXXConversionDecl is the declaration of a type conversion operator.
2307// It's not a cast expression.
2308DEF_TRAVERSE_DECL(CXXConversionDecl, {
2309 // We skip decls_begin/decls_end, which are already covered by
2310 // TraverseFunctionHelper().
2311 ShouldVisitChildren = false;
2312 ReturnValue = TraverseFunctionHelper(D);
2313})
2314
2315DEF_TRAVERSE_DECL(CXXDestructorDecl, {
2316 // We skip decls_begin/decls_end, which are already covered by
2317 // TraverseFunctionHelper().
2318 ShouldVisitChildren = false;
2319 ReturnValue = TraverseFunctionHelper(D);
2320})
2321
2322template <typename Derived>
2323bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
2324 TRY_TO(TraverseDeclaratorHelper(D));
2325 // Default params are taken care of when we traverse the ParmVarDecl.
2326 if (!isa<ParmVarDecl>(D) &&
2327 (!D->isCXXForRangeDecl() || getDerived().shouldVisitImplicitCode()))
2328 TRY_TO(TraverseStmt(D->getInit()));
2329 return true;
2330}
2331
2332DEF_TRAVERSE_DECL(VarDecl, { TRY_TO(TraverseVarHelper(D)); })
2333
2334DEF_TRAVERSE_DECL(ImplicitParamDecl, { TRY_TO(TraverseVarHelper(D)); })
2335
2336DEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, {
2337 // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
2338 TRY_TO(TraverseDeclaratorHelper(D));
2339 if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
2340 TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
2341})
2342
2343DEF_TRAVERSE_DECL(ParmVarDecl, {
2344 TRY_TO(TraverseVarHelper(D));
2345
2346 if (D->hasDefaultArg() && D->hasUninstantiatedDefaultArg() &&
2347 !D->hasUnparsedDefaultArg())
2348 TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
2349
2350 if (D->hasDefaultArg() && !D->hasUninstantiatedDefaultArg() &&
2351 !D->hasUnparsedDefaultArg())
2352 TRY_TO(TraverseStmt(D->getDefaultArg()));
2353})
2354
2355DEF_TRAVERSE_DECL(RequiresExprBodyDecl, {})
2356
2357DEF_TRAVERSE_DECL(ImplicitConceptSpecializationDecl, {
2358 TRY_TO(TraverseTemplateArguments(D->getTemplateArguments()));
2359})
2360
2361#undef DEF_TRAVERSE_DECL
2362
2363// ----------------- Stmt traversal -----------------
2364//
2365// For stmts, we automate (in the DEF_TRAVERSE_STMT macro) iterating
2366// over the children defined in children() (every stmt defines these,
2367// though sometimes the range is empty). Each individual Traverse*
2368// method only needs to worry about children other than those. To see
2369// what children() does for a given class, see, e.g.,
2370// http://clang.llvm.org/doxygen/Stmt_8cpp_source.html
2371
2372// This macro makes available a variable S, the passed-in stmt.
2373#define DEF_TRAVERSE_STMT(STMT, CODE) \
2374 template <typename Derived> \
2375 bool RecursiveASTVisitor<Derived>::Traverse##STMT( \
2376 STMT *S, DataRecursionQueue *Queue) { \
2377 bool ShouldVisitChildren = true; \
2378 bool ReturnValue = true; \
2379 if (!getDerived().shouldTraversePostOrder()) \
2380 TRY_TO(WalkUpFrom##STMT(S)); \
2381 { CODE; } \
2382 if (ShouldVisitChildren) { \
2383 for (Stmt * SubStmt : getDerived().getStmtChildren(S)) { \
2384 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(SubStmt); \
2385 } \
2386 } \
2387 /* Call WalkUpFrom if TRY_TO_TRAVERSE_OR_ENQUEUE_STMT has traversed the \
2388 * children already. If TRY_TO_TRAVERSE_OR_ENQUEUE_STMT only enqueued the \
2389 * children, PostVisitStmt will call WalkUpFrom after we are done visiting \
2390 * children. */ \
2391 if (!Queue && ReturnValue && getDerived().shouldTraversePostOrder()) { \
2392 TRY_TO(WalkUpFrom##STMT(S)); \
2393 } \
2394 return ReturnValue; \
2395 }
2396
2397DEF_TRAVERSE_STMT(GCCAsmStmt, {
2398 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getAsmString());
2399 for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
2400 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInputConstraintLiteral(I));
2401 }
2402 for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
2403 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOutputConstraintLiteral(I));
2404 }
2405 for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
2406 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getClobberStringLiteral(I));
2407 }
2408 // children() iterates over inputExpr and outputExpr.
2409})
2410
2412 MSAsmStmt,
2413 {// FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc. Once
2414 // added this needs to be implemented.
2415 })
2416
2417DEF_TRAVERSE_STMT(CXXCatchStmt, {
2418 TRY_TO(TraverseDecl(S->getExceptionDecl()));
2419 // children() iterates over the handler block.
2420})
2421
2422DEF_TRAVERSE_STMT(DeclStmt, {
2423 for (auto *I : S->decls()) {
2424 TRY_TO(TraverseDecl(I));
2425 }
2426 // Suppress the default iteration over children() by
2427 // returning. Here's why: A DeclStmt looks like 'type var [=
2428 // initializer]'. The decls above already traverse over the
2429 // initializers, so we don't have to do it again (which
2430 // children() would do).
2431 ShouldVisitChildren = false;
2432})
2433
2434// These non-expr stmts (most of them), do not need any action except
2435// iterating over the children.
2436DEF_TRAVERSE_STMT(BreakStmt, {})
2437DEF_TRAVERSE_STMT(CXXTryStmt, {})
2438DEF_TRAVERSE_STMT(CaseStmt, {})
2439DEF_TRAVERSE_STMT(CompoundStmt, {})
2440DEF_TRAVERSE_STMT(ContinueStmt, {})
2441DEF_TRAVERSE_STMT(DefaultStmt, {})
2442DEF_TRAVERSE_STMT(DoStmt, {})
2443DEF_TRAVERSE_STMT(ForStmt, {})
2444DEF_TRAVERSE_STMT(GotoStmt, {})
2445DEF_TRAVERSE_STMT(IfStmt, {})
2446DEF_TRAVERSE_STMT(IndirectGotoStmt, {})
2447DEF_TRAVERSE_STMT(LabelStmt, {})
2448DEF_TRAVERSE_STMT(AttributedStmt, {})
2449DEF_TRAVERSE_STMT(NullStmt, {})
2450DEF_TRAVERSE_STMT(ObjCAtCatchStmt, {})
2451DEF_TRAVERSE_STMT(ObjCAtFinallyStmt, {})
2452DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, {})
2453DEF_TRAVERSE_STMT(ObjCAtThrowStmt, {})
2454DEF_TRAVERSE_STMT(ObjCAtTryStmt, {})
2455DEF_TRAVERSE_STMT(ObjCForCollectionStmt, {})
2456DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, {})
2457
2458DEF_TRAVERSE_STMT(CXXForRangeStmt, {
2459 if (!getDerived().shouldVisitImplicitCode()) {
2460 if (S->getInit())
2461 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getInit());
2462 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getLoopVarStmt());
2463 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getRangeInit());
2464 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
2465 // Visit everything else only if shouldVisitImplicitCode().
2466 ShouldVisitChildren = false;
2467 }
2468})
2469
2470DEF_TRAVERSE_STMT(MSDependentExistsStmt, {
2471 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2472 TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
2473})
2474
2475DEF_TRAVERSE_STMT(ReturnStmt, {})
2476DEF_TRAVERSE_STMT(SwitchStmt, {})
2477DEF_TRAVERSE_STMT(WhileStmt, {})
2478
2479DEF_TRAVERSE_STMT(ConstantExpr, {})
2480
2481DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
2482 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2483 TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
2484 if (S->hasExplicitTemplateArgs()) {
2485 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2486 S->getNumTemplateArgs()));
2487 }
2488})
2489
2490DEF_TRAVERSE_STMT(DeclRefExpr, {
2491 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2492 TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
2493 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2494 S->getNumTemplateArgs()));
2495})
2496
2497DEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, {
2498 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2499 TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
2500 if (S->hasExplicitTemplateArgs()) {
2501 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2502 S->getNumTemplateArgs()));
2503 }
2504})
2505
2506DEF_TRAVERSE_STMT(MemberExpr, {
2507 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2508 TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
2509 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2510 S->getNumTemplateArgs()));
2511})
2512
2514 ImplicitCastExpr,
2515 {// We don't traverse the cast type, as it's not written in the
2516 // source code.
2517 })
2518
2519DEF_TRAVERSE_STMT(CStyleCastExpr, {
2520 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2521})
2522
2523DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, {
2524 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2525})
2526
2527DEF_TRAVERSE_STMT(CXXAddrspaceCastExpr, {
2528 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2529})
2530
2531DEF_TRAVERSE_STMT(CXXConstCastExpr, {
2532 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2533})
2534
2535DEF_TRAVERSE_STMT(CXXDynamicCastExpr, {
2536 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2537})
2538
2539DEF_TRAVERSE_STMT(CXXReinterpretCastExpr, {
2540 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2541})
2542
2543DEF_TRAVERSE_STMT(CXXStaticCastExpr, {
2544 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2545})
2546
2547DEF_TRAVERSE_STMT(BuiltinBitCastExpr, {
2548 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2549})
2550
2551template <typename Derived>
2552bool RecursiveASTVisitor<Derived>::TraverseSynOrSemInitListExpr(
2553 InitListExpr *S, DataRecursionQueue *Queue) {
2554 if (S) {
2555 // Skip this if we traverse postorder. We will visit it later
2556 // in PostVisitStmt.
2557 if (!getDerived().shouldTraversePostOrder())
2558 TRY_TO(WalkUpFromInitListExpr(S));
2559
2560 // All we need are the default actions. FIXME: use a helper function.
2561 for (Stmt *SubStmt : S->children()) {
2563 }
2564
2565 if (!Queue && getDerived().shouldTraversePostOrder())
2566 TRY_TO(WalkUpFromInitListExpr(S));
2567 }
2568 return true;
2569}
2570
2571template <typename Derived>
2572bool RecursiveASTVisitor<Derived>::TraverseObjCProtocolLoc(
2573 ObjCProtocolLoc ProtocolLoc) {
2574 return true;
2575}
2576
2577template <typename Derived>
2578bool RecursiveASTVisitor<Derived>::TraverseConceptReference(
2579 ConceptReference *CR) {
2580 if (!getDerived().shouldTraversePostOrder())
2581 TRY_TO(VisitConceptReference(CR));
2582 TRY_TO(TraverseNestedNameSpecifierLoc(CR->getNestedNameSpecifierLoc()));
2583 TRY_TO(TraverseDeclarationNameInfo(CR->getConceptNameInfo()));
2584 if (CR->hasExplicitTemplateArgs())
2585 TRY_TO(TraverseTemplateArgumentLocsHelper(
2586 CR->getTemplateArgsAsWritten()->getTemplateArgs(),
2587 CR->getTemplateArgsAsWritten()->NumTemplateArgs));
2588 if (getDerived().shouldTraversePostOrder())
2589 TRY_TO(VisitConceptReference(CR));
2590 return true;
2591}
2592
2593// If shouldVisitImplicitCode() returns false, this method traverses only the
2594// syntactic form of InitListExpr.
2595// If shouldVisitImplicitCode() return true, this method is called once for
2596// each pair of syntactic and semantic InitListExpr, and it traverses the
2597// subtrees defined by the two forms. This may cause some of the children to be
2598// visited twice, if they appear both in the syntactic and the semantic form.
2599//
2600// There is no guarantee about which form \p S takes when this method is called.
2601template <typename Derived>
2602bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(
2603 InitListExpr *S, DataRecursionQueue *Queue) {
2604 if (S->isSemanticForm() && S->isSyntacticForm()) {
2605 // `S` does not have alternative forms, traverse only once.
2606 TRY_TO(TraverseSynOrSemInitListExpr(S, Queue));
2607 return true;
2608 }
2609 TRY_TO(TraverseSynOrSemInitListExpr(
2610 S->isSemanticForm() ? S->getSyntacticForm() : S, Queue));
2611 if (getDerived().shouldVisitImplicitCode()) {
2612 // Only visit the semantic form if the clients are interested in implicit
2613 // compiler-generated.
2614 TRY_TO(TraverseSynOrSemInitListExpr(
2615 S->isSemanticForm() ? S : S->getSemanticForm(), Queue));
2616 }
2617 return true;
2618}
2619
2620// GenericSelectionExpr is a special case because the types and expressions
2621// are interleaved. We also need to watch out for null types (default
2622// generic associations).
2623DEF_TRAVERSE_STMT(GenericSelectionExpr, {
2624 if (S->isExprPredicate())
2625 TRY_TO(TraverseStmt(S->getControllingExpr()));
2626 else
2627 TRY_TO(TraverseTypeLoc(S->getControllingType()->getTypeLoc()));
2628
2629 for (const GenericSelectionExpr::Association Assoc : S->associations()) {
2630 if (TypeSourceInfo *TSI = Assoc.getTypeSourceInfo())
2631 TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
2632 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(Assoc.getAssociationExpr());
2633 }
2634 ShouldVisitChildren = false;
2635})
2636
2637// PseudoObjectExpr is a special case because of the weirdness with
2638// syntactic expressions and opaque values.
2639DEF_TRAVERSE_STMT(PseudoObjectExpr, {
2640 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getSyntacticForm());
2641 for (PseudoObjectExpr::semantics_iterator i = S->semantics_begin(),
2642 e = S->semantics_end();
2643 i != e; ++i) {
2644 Expr *sub = *i;
2645 if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub))
2646 sub = OVE->getSourceExpr();
2648 }
2649 ShouldVisitChildren = false;
2650})
2651
2652DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, {
2653 // This is called for code like 'return T()' where T is a built-in
2654 // (i.e. non-class) type.
2655 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2656})
2657
2658DEF_TRAVERSE_STMT(CXXNewExpr, {
2659 // The child-iterator will pick up the other arguments.
2660 TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc()));
2661})
2662
2663DEF_TRAVERSE_STMT(OffsetOfExpr, {
2664 // The child-iterator will pick up the expression representing
2665 // the field.
2666 // FIMXE: for code like offsetof(Foo, a.b.c), should we get
2667 // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c?
2668 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2669})
2670
2671DEF_TRAVERSE_STMT(UnaryExprOrTypeTraitExpr, {
2672 // The child-iterator will pick up the arg if it's an expression,
2673 // but not if it's a type.
2674 if (S->isArgumentType())
2675 TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
2676})
2677
2678DEF_TRAVERSE_STMT(CXXTypeidExpr, {
2679 // The child-iterator will pick up the arg if it's an expression,
2680 // but not if it's a type.
2681 if (S->isTypeOperand())
2682 TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
2683})
2684
2685DEF_TRAVERSE_STMT(MSPropertyRefExpr, {
2686 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2687})
2688
2689DEF_TRAVERSE_STMT(MSPropertySubscriptExpr, {})
2690
2691DEF_TRAVERSE_STMT(CXXUuidofExpr, {
2692 // The child-iterator will pick up the arg if it's an expression,
2693 // but not if it's a type.
2694 if (S->isTypeOperand())
2695 TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
2696})
2697
2698DEF_TRAVERSE_STMT(TypeTraitExpr, {
2699 for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
2700 TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc()));
2701})
2702
2703DEF_TRAVERSE_STMT(ArrayTypeTraitExpr, {
2704 TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
2705})
2706
2707DEF_TRAVERSE_STMT(ExpressionTraitExpr,
2708 { TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getQueriedExpression()); })
2709
2710DEF_TRAVERSE_STMT(VAArgExpr, {
2711 // The child-iterator will pick up the expression argument.
2712 TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
2713})
2714
2715DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
2716 // This is called for code like 'return T()' where T is a class type.
2717 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2718})
2719
2720// Walk only the visible parts of lambda expressions.
2721DEF_TRAVERSE_STMT(LambdaExpr, {
2722 // Visit the capture list.
2723 for (unsigned I = 0, N = S->capture_size(); I != N; ++I) {
2724 const LambdaCapture *C = S->capture_begin() + I;
2725 if (C->isExplicit() || getDerived().shouldVisitImplicitCode()) {
2726 TRY_TO(TraverseLambdaCapture(S, C, S->capture_init_begin()[I]));
2727 }
2728 }
2729
2730 if (getDerived().shouldVisitImplicitCode()) {
2731 // The implicit model is simple: everything else is in the lambda class.
2732 TRY_TO(TraverseDecl(S->getLambdaClass()));
2733 } else {
2734 // We need to poke around to find the bits that might be explicitly written.
2735 TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2736 FunctionProtoTypeLoc Proto = TL.getAsAdjusted<FunctionProtoTypeLoc>();
2737
2738 TRY_TO(TraverseTemplateParameterListHelper(S->getTemplateParameterList()));
2739 if (S->hasExplicitParameters()) {
2740 // Visit parameters.
2741 for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I)
2742 TRY_TO(TraverseDecl(Proto.getParam(I)));
2743 }
2744
2745 auto *T = Proto.getTypePtr();
2746 for (const auto &E : T->exceptions())
2747 TRY_TO(TraverseType(E));
2748
2749 if (Expr *NE = T->getNoexceptExpr())
2751
2752 if (S->hasExplicitResultType())
2753 TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
2754 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getTrailingRequiresClause());
2755
2756 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
2757 }
2758 ShouldVisitChildren = false;
2759})
2760
2761DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, {
2762 // This is called for code like 'T()', where T is a template argument.
2763 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2764})
2765
2766// These expressions all might take explicit template arguments.
2767// We traverse those if so. FIXME: implement these.
2768DEF_TRAVERSE_STMT(CXXConstructExpr, {})
2769DEF_TRAVERSE_STMT(CallExpr, {})
2770DEF_TRAVERSE_STMT(CXXMemberCallExpr, {})
2771
2772// These exprs (most of them), do not need any action except iterating
2773// over the children.
2774DEF_TRAVERSE_STMT(AddrLabelExpr, {})
2775DEF_TRAVERSE_STMT(ArraySubscriptExpr, {})
2776DEF_TRAVERSE_STMT(MatrixSubscriptExpr, {})
2777DEF_TRAVERSE_STMT(ArraySectionExpr, {})
2778DEF_TRAVERSE_STMT(OMPArrayShapingExpr, {})
2779DEF_TRAVERSE_STMT(OMPIteratorExpr, {})
2780
2781DEF_TRAVERSE_STMT(BlockExpr, {
2782 TRY_TO(TraverseDecl(S->getBlockDecl()));
2783 return true; // no child statements to loop through.
2784})
2785
2786DEF_TRAVERSE_STMT(ChooseExpr, {})
2787DEF_TRAVERSE_STMT(CompoundLiteralExpr, {
2788 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2789})
2790DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, {})
2791DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, {})
2792
2793DEF_TRAVERSE_STMT(CXXDefaultArgExpr, {
2794 if (getDerived().shouldVisitImplicitCode())
2795 TRY_TO(TraverseStmt(S->getExpr()));
2796})
2797
2798DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {
2799 if (getDerived().shouldVisitImplicitCode())
2800 TRY_TO(TraverseStmt(S->getExpr()));
2801})
2802
2803DEF_TRAVERSE_STMT(CXXDeleteExpr, {})
2804DEF_TRAVERSE_STMT(ExprWithCleanups, {})
2805DEF_TRAVERSE_STMT(CXXInheritedCtorInitExpr, {})
2806DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, {})
2807DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, {})
2808
2809DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {
2810 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2811 if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
2812 TRY_TO(TraverseTypeLoc(ScopeInfo->getTypeLoc()));
2813 if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo())
2814 TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc()));
2815})
2816
2817DEF_TRAVERSE_STMT(CXXThisExpr, {})
2818DEF_TRAVERSE_STMT(CXXThrowExpr, {})
2819DEF_TRAVERSE_STMT(UserDefinedLiteral, {})
2820DEF_TRAVERSE_STMT(DesignatedInitExpr, {})
2821DEF_TRAVERSE_STMT(DesignatedInitUpdateExpr, {})
2822DEF_TRAVERSE_STMT(ExtVectorElementExpr, {})
2823DEF_TRAVERSE_STMT(GNUNullExpr, {})
2824DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {})
2825DEF_TRAVERSE_STMT(NoInitExpr, {})
2826DEF_TRAVERSE_STMT(ArrayInitLoopExpr, {
2827 // FIXME: The source expression of the OVE should be listed as
2828 // a child of the ArrayInitLoopExpr.
2829 if (OpaqueValueExpr *OVE = S->getCommonExpr())
2830 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(OVE->getSourceExpr());
2831})
2832DEF_TRAVERSE_STMT(ArrayInitIndexExpr, {})
2833DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, {})
2834
2835DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
2836 if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
2837 TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
2838})
2839
2840DEF_TRAVERSE_STMT(ObjCIsaExpr, {})
2841DEF_TRAVERSE_STMT(ObjCIvarRefExpr, {})
2842
2843DEF_TRAVERSE_STMT(ObjCMessageExpr, {
2844 if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo())
2845 TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
2846})
2847
2848DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, {
2849 if (S->isClassReceiver()) {
2850 ObjCInterfaceDecl *IDecl = S->getClassReceiver();
2851 QualType Type = IDecl->getASTContext().getObjCInterfaceType(IDecl);
2852 ObjCInterfaceLocInfo Data;
2853 Data.NameLoc = S->getReceiverLocation();
2854 Data.NameEndLoc = Data.NameLoc;
2855 TRY_TO(TraverseTypeLoc(TypeLoc(Type, &Data)));
2856 }
2857})
2858DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, {})
2859DEF_TRAVERSE_STMT(ObjCProtocolExpr, {})
2860DEF_TRAVERSE_STMT(ObjCSelectorExpr, {})
2861DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, {})
2862
2863DEF_TRAVERSE_STMT(ObjCBridgedCastExpr, {
2864 TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2865})
2866
2867DEF_TRAVERSE_STMT(ObjCAvailabilityCheckExpr, {})
2868DEF_TRAVERSE_STMT(ParenExpr, {})
2869DEF_TRAVERSE_STMT(ParenListExpr, {})
2870DEF_TRAVERSE_STMT(SYCLUniqueStableNameExpr, {
2871 TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2872})
2873DEF_TRAVERSE_STMT(OpenACCAsteriskSizeExpr, {})
2874DEF_TRAVERSE_STMT(PredefinedExpr, {})
2875DEF_TRAVERSE_STMT(ShuffleVectorExpr, {})
2876DEF_TRAVERSE_STMT(ConvertVectorExpr, {})
2877DEF_TRAVERSE_STMT(StmtExpr, {})
2878DEF_TRAVERSE_STMT(SourceLocExpr, {})
2879DEF_TRAVERSE_STMT(EmbedExpr, {
2880 for (IntegerLiteral *IL : S->underlying_data_elements()) {
2882 }
2883})
2884
2885DEF_TRAVERSE_STMT(UnresolvedLookupExpr, {
2886 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2887 if (S->hasExplicitTemplateArgs()) {
2888 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2889 S->getNumTemplateArgs()));
2890 }
2891})
2892
2893DEF_TRAVERSE_STMT(UnresolvedMemberExpr, {
2894 TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2895 if (S->hasExplicitTemplateArgs()) {
2896 TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2897 S->getNumTemplateArgs()));
2898 }
2899})
2900
2901DEF_TRAVERSE_STMT(SEHTryStmt, {})
2902DEF_TRAVERSE_STMT(SEHExceptStmt, {})
2903DEF_TRAVERSE_STMT(SEHFinallyStmt, {})
2904DEF_TRAVERSE_STMT(SEHLeaveStmt, {})
2905DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
2906
2907DEF_TRAVERSE_STMT(CXXOperatorCallExpr, {})
2908DEF_TRAVERSE_STMT(CXXRewrittenBinaryOperator, {
2909 if (!getDerived().shouldVisitImplicitCode()) {
2910 CXXRewrittenBinaryOperator::DecomposedForm Decomposed =
2911 S->getDecomposedForm();
2912 TRY_TO(TraverseStmt(const_cast<Expr*>(Decomposed.LHS)));
2913 TRY_TO(TraverseStmt(const_cast<Expr*>(Decomposed.RHS)));
2914 ShouldVisitChildren = false;
2915 }
2916})
2917DEF_TRAVERSE_STMT(OpaqueValueExpr, {})
2918DEF_TRAVERSE_STMT(TypoExpr, {})
2919DEF_TRAVERSE_STMT(RecoveryExpr, {})
2920DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {})
2921
2922// These operators (all of them) do not need any action except
2923// iterating over the children.
2924DEF_TRAVERSE_STMT(BinaryConditionalOperator, {})
2925DEF_TRAVERSE_STMT(ConditionalOperator, {})
2926DEF_TRAVERSE_STMT(UnaryOperator, {})
2927DEF_TRAVERSE_STMT(BinaryOperator, {})
2928DEF_TRAVERSE_STMT(CompoundAssignOperator, {})
2929DEF_TRAVERSE_STMT(CXXNoexceptExpr, {})
2930DEF_TRAVERSE_STMT(PackExpansionExpr, {})
2931DEF_TRAVERSE_STMT(SizeOfPackExpr, {})
2932DEF_TRAVERSE_STMT(PackIndexingExpr, {})
2933DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, {})
2934DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {})
2935DEF_TRAVERSE_STMT(FunctionParmPackExpr, {})
2936DEF_TRAVERSE_STMT(CXXFoldExpr, {})
2937DEF_TRAVERSE_STMT(AtomicExpr, {})
2938DEF_TRAVERSE_STMT(CXXParenListInitExpr, {})
2939
2940DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {
2941 if (S->getLifetimeExtendedTemporaryDecl()) {
2942 TRY_TO(TraverseLifetimeExtendedTemporaryDecl(
2943 S->getLifetimeExtendedTemporaryDecl()));
2944 ShouldVisitChildren = false;
2945 }
2946})
2947// For coroutines expressions, traverse either the operand
2948// as written or the implied calls, depending on what the
2949// derived class requests.
2950DEF_TRAVERSE_STMT(CoroutineBodyStmt, {
2951 if (!getDerived().shouldVisitImplicitCode()) {
2952 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getBody());
2953 ShouldVisitChildren = false;
2954 }
2955})
2956DEF_TRAVERSE_STMT(CoreturnStmt, {
2957 if (!getDerived().shouldVisitImplicitCode()) {
2958 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
2959 ShouldVisitChildren = false;
2960 }
2961})
2962DEF_TRAVERSE_STMT(CoawaitExpr, {
2963 if (!getDerived().shouldVisitImplicitCode()) {
2964 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
2965 ShouldVisitChildren = false;
2966 }
2967})
2968DEF_TRAVERSE_STMT(DependentCoawaitExpr, {
2969 if (!getDerived().shouldVisitImplicitCode()) {
2970 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
2971 ShouldVisitChildren = false;
2972 }
2973})
2974DEF_TRAVERSE_STMT(CoyieldExpr, {
2975 if (!getDerived().shouldVisitImplicitCode()) {
2976 TRY_TO_TRAVERSE_OR_ENQUEUE_STMT(S->getOperand());
2977 ShouldVisitChildren = false;
2978 }
2979})
2980
2981DEF_TRAVERSE_STMT(ConceptSpecializationExpr, {
2982 TRY_TO(TraverseConceptReference(S->getConceptReference()));
2983})
2984
2985DEF_TRAVERSE_STMT(RequiresExpr, {
2986 TRY_TO(TraverseDecl(S->getBody()));
2987 for (ParmVarDecl *Parm : S->getLocalParameters())
2988 TRY_TO(TraverseDecl(Parm));
2989 for (concepts::Requirement *Req : S->getRequirements())
2990 TRY_TO(TraverseConceptRequirement(Req));
2991})
2992
2993// These literals (all of them) do not need any action.
2994DEF_TRAVERSE_STMT(IntegerLiteral, {})
2995DEF_TRAVERSE_STMT(FixedPointLiteral, {})
2996DEF_TRAVERSE_STMT(CharacterLiteral, {})
2997DEF_TRAVERSE_STMT(FloatingLiteral, {})
2998DEF_TRAVERSE_STMT(ImaginaryLiteral, {})
2999DEF_TRAVERSE_STMT(StringLiteral, {})
3000DEF_TRAVERSE_STMT(ObjCStringLiteral, {})
3001DEF_TRAVERSE_STMT(ObjCBoxedExpr, {})
3002DEF_TRAVERSE_STMT(ObjCArrayLiteral, {})
3003DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, {})
3004
3005// Traverse OpenCL: AsType, Convert.
3006DEF_TRAVERSE_STMT(AsTypeExpr, {})
3007
3008// OpenMP directives.
3009template <typename Derived>
3010bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
3011 OMPExecutableDirective *S) {
3012 for (auto *C : S->clauses()) {
3013 TRY_TO(TraverseOMPClause(C));
3014 }
3015 return true;
3016}
3017
3018DEF_TRAVERSE_STMT(OMPCanonicalLoop, {
3019 if (!getDerived().shouldVisitImplicitCode()) {
3020 // Visit only the syntactical loop.
3021 TRY_TO(TraverseStmt(S->getLoopStmt()));
3022 ShouldVisitChildren = false;
3023 }
3024})
3025
3026template <typename Derived>
3027bool
3028RecursiveASTVisitor<Derived>::TraverseOMPLoopDirective(OMPLoopDirective *S) {
3029 return TraverseOMPExecutableDirective(S);
3030}
3031
3032DEF_TRAVERSE_STMT(OMPMetaDirective,
3033 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3034
3035DEF_TRAVERSE_STMT(OMPParallelDirective,
3036 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3037
3038DEF_TRAVERSE_STMT(OMPSimdDirective,
3039 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3040
3041DEF_TRAVERSE_STMT(OMPTileDirective,
3042 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3043
3044DEF_TRAVERSE_STMT(OMPUnrollDirective,
3045 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3046
3047DEF_TRAVERSE_STMT(OMPReverseDirective,
3048 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3049
3050DEF_TRAVERSE_STMT(OMPInterchangeDirective,
3051 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3052
3053DEF_TRAVERSE_STMT(OMPForDirective,
3054 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3055
3056DEF_TRAVERSE_STMT(OMPForSimdDirective,
3057 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3058
3059DEF_TRAVERSE_STMT(OMPSectionsDirective,
3060 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3061
3062DEF_TRAVERSE_STMT(OMPSectionDirective,
3063 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3064
3065DEF_TRAVERSE_STMT(OMPScopeDirective,
3066 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3067
3068DEF_TRAVERSE_STMT(OMPSingleDirective,
3069 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3070
3071DEF_TRAVERSE_STMT(OMPMasterDirective,
3072 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3073
3074DEF_TRAVERSE_STMT(OMPCriticalDirective, {
3075 TRY_TO(TraverseDeclarationNameInfo(S->getDirectiveName()));
3076 TRY_TO(TraverseOMPExecutableDirective(S));
3077})
3078
3079DEF_TRAVERSE_STMT(OMPParallelForDirective,
3080 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3081
3082DEF_TRAVERSE_STMT(OMPParallelForSimdDirective,
3083 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3084
3085DEF_TRAVERSE_STMT(OMPParallelMasterDirective,
3086 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3087
3088DEF_TRAVERSE_STMT(OMPParallelMaskedDirective,
3089 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3090
3091DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
3092 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3093
3094DEF_TRAVERSE_STMT(OMPTaskDirective,
3095 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3096
3097DEF_TRAVERSE_STMT(OMPTaskyieldDirective,
3098 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3099
3100DEF_TRAVERSE_STMT(OMPBarrierDirective,
3101 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3102
3103DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
3104 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3105
3106DEF_TRAVERSE_STMT(OMPTaskgroupDirective,
3107 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3108
3109DEF_TRAVERSE_STMT(OMPCancellationPointDirective,
3110 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3111
3112DEF_TRAVERSE_STMT(OMPCancelDirective,
3113 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3114
3115DEF_TRAVERSE_STMT(OMPFlushDirective,
3116 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3117
3118DEF_TRAVERSE_STMT(OMPDepobjDirective,
3119 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3120
3121DEF_TRAVERSE_STMT(OMPScanDirective,
3122 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3123
3124DEF_TRAVERSE_STMT(OMPOrderedDirective,
3125 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3126
3127DEF_TRAVERSE_STMT(OMPAtomicDirective,
3128 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3129
3130DEF_TRAVERSE_STMT(OMPTargetDirective,
3131 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3132
3133DEF_TRAVERSE_STMT(OMPTargetDataDirective,
3134 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3135
3136DEF_TRAVERSE_STMT(OMPTargetEnterDataDirective,
3137 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3138
3139DEF_TRAVERSE_STMT(OMPTargetExitDataDirective,
3140 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3141
3142DEF_TRAVERSE_STMT(OMPTargetParallelDirective,
3143 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3144
3145DEF_TRAVERSE_STMT(OMPTargetParallelForDirective,
3146 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3147
3148DEF_TRAVERSE_STMT(OMPTeamsDirective,
3149 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3150
3151DEF_TRAVERSE_STMT(OMPTargetUpdateDirective,
3152 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3153
3154DEF_TRAVERSE_STMT(OMPTaskLoopDirective,
3155 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3156
3157DEF_TRAVERSE_STMT(OMPTaskLoopSimdDirective,
3158 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3159
3160DEF_TRAVERSE_STMT(OMPMasterTaskLoopDirective,
3161 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3162
3163DEF_TRAVERSE_STMT(OMPMasterTaskLoopSimdDirective,
3164 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3165
3166DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopDirective,
3167 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3168
3169DEF_TRAVERSE_STMT(OMPParallelMasterTaskLoopSimdDirective,
3170 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3171
3172DEF_TRAVERSE_STMT(OMPMaskedTaskLoopDirective,
3173 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3174
3175DEF_TRAVERSE_STMT(OMPMaskedTaskLoopSimdDirective,
3176 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3177
3178DEF_TRAVERSE_STMT(OMPParallelMaskedTaskLoopDirective,
3179 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3180
3181DEF_TRAVERSE_STMT(OMPParallelMaskedTaskLoopSimdDirective,
3182 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3183
3184DEF_TRAVERSE_STMT(OMPDistributeDirective,
3185 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3186
3187DEF_TRAVERSE_STMT(OMPDistributeParallelForDirective,
3188 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3189
3190DEF_TRAVERSE_STMT(OMPDistributeParallelForSimdDirective,
3191 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3192
3193DEF_TRAVERSE_STMT(OMPDistributeSimdDirective,
3194 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3195
3196DEF_TRAVERSE_STMT(OMPTargetParallelForSimdDirective,
3197 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3198
3199DEF_TRAVERSE_STMT(OMPTargetSimdDirective,
3200 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3201
3202DEF_TRAVERSE_STMT(OMPTeamsDistributeDirective,
3203 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3204
3205DEF_TRAVERSE_STMT(OMPTeamsDistributeSimdDirective,
3206 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3207
3208DEF_TRAVERSE_STMT(OMPTeamsDistributeParallelForSimdDirective,
3209 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3210
3211DEF_TRAVERSE_STMT(OMPTeamsDistributeParallelForDirective,
3212 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3213
3214DEF_TRAVERSE_STMT(OMPTargetTeamsDirective,
3215 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3216
3217DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeDirective,
3218 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3219
3220DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForDirective,
3221 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3222
3223DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeParallelForSimdDirective,
3224 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3225
3226DEF_TRAVERSE_STMT(OMPTargetTeamsDistributeSimdDirective,
3227 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3228
3229DEF_TRAVERSE_STMT(OMPInteropDirective,
3230 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3231
3232DEF_TRAVERSE_STMT(OMPDispatchDirective,
3233 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3234
3235DEF_TRAVERSE_STMT(OMPMaskedDirective,
3236 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3237
3238DEF_TRAVERSE_STMT(OMPGenericLoopDirective,
3239 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3240
3241DEF_TRAVERSE_STMT(OMPTeamsGenericLoopDirective,
3242 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3243
3244DEF_TRAVERSE_STMT(OMPTargetTeamsGenericLoopDirective,
3245 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3246
3247DEF_TRAVERSE_STMT(OMPParallelGenericLoopDirective,
3248 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3249
3250DEF_TRAVERSE_STMT(OMPTargetParallelGenericLoopDirective,
3251 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3252
3253DEF_TRAVERSE_STMT(OMPAssumeDirective,
3254 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3255
3256DEF_TRAVERSE_STMT(OMPErrorDirective,
3257 { TRY_TO(TraverseOMPExecutableDirective(S)); })
3258
3259// OpenMP clauses.
3260template <typename Derived>
3261bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
3262 if (!C)
3263 return true;
3264 switch (C->getClauseKind()) {
3265#define GEN_CLANG_CLAUSE_CLASS
3266#define CLAUSE_CLASS(Enum, Str, Class) \
3267 case llvm::omp::Clause::Enum: \
3268 TRY_TO(Visit##Class(static_cast<Class *>(C))); \
3269 break;
3270#define CLAUSE_NO_CLASS(Enum, Str) \
3271 case llvm::omp::Clause::Enum: \
3272 break;
3273#include "llvm/Frontend/OpenMP/OMP.inc"
3274 }
3275 return true;
3276}
3277
3278template <typename Derived>
3279bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPreInit(
3280 OMPClauseWithPreInit *Node) {
3281 TRY_TO(TraverseStmt(Node->getPreInitStmt()));
3282 return true;
3283}
3284
3285template <typename Derived>
3286bool RecursiveASTVisitor<Derived>::VisitOMPClauseWithPostUpdate(
3287 OMPClauseWithPostUpdate *Node) {
3288 TRY_TO(VisitOMPClauseWithPreInit(Node));
3289 TRY_TO(TraverseStmt(Node->getPostUpdateExpr()));
3290 return true;
3291}
3292
3293template <typename Derived>
3294bool RecursiveASTVisitor<Derived>::VisitOMPAllocatorClause(
3295 OMPAllocatorClause *C) {
3296 TRY_TO(TraverseStmt(C->getAllocator()));
3297 return true;
3298}
3299
3300template <typename Derived>
3301bool RecursiveASTVisitor<Derived>::VisitOMPAllocateClause(OMPAllocateClause *C) {
3302 TRY_TO(TraverseStmt(C->getAllocator()));
3303 TRY_TO(VisitOMPClauseList(C));
3304 return true;
3305}
3306
3307template <typename Derived>
3308bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
3309 TRY_TO(VisitOMPClauseWithPreInit(C));
3310 TRY_TO(TraverseStmt(C->getCondition()));
3311 return true;
3312}
3313
3314template <typename Derived>
3315bool RecursiveASTVisitor<Derived>::VisitOMPFinalClause(OMPFinalClause *C) {
3316 TRY_TO(VisitOMPClauseWithPreInit(C));
3317 TRY_TO(TraverseStmt(C->getCondition()));
3318 return true;
3319}
3320
3321template <typename Derived>
3322bool
3323RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
3324 TRY_TO(VisitOMPClauseWithPreInit(C));
3325 TRY_TO(TraverseStmt(C->getNumThreads()));
3326 return true;
3327}
3328
3329template <typename Derived>
3330bool RecursiveASTVisitor<Derived>::VisitOMPAlignClause(OMPAlignClause *C) {
3331 TRY_TO(TraverseStmt(C->getAlignment()));
3332 return true;
3333}
3334
3335template <typename Derived>
3336bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) {
3337 TRY_TO(TraverseStmt(C->getSafelen()));
3338 return true;
3339}
3340
3341template <typename Derived>
3342bool RecursiveASTVisitor<Derived>::VisitOMPSimdlenClause(OMPSimdlenClause *C) {
3343 TRY_TO(TraverseStmt(C->getSimdlen()));
3344 return true;
3345}
3346
3347template <typename Derived>
3348bool RecursiveASTVisitor<Derived>::VisitOMPSizesClause(OMPSizesClause *C) {
3349 for (Expr *E : C->getSizesRefs())
3350 TRY_TO(TraverseStmt(E));
3351 return true;
3352}
3353
3354template <typename Derived>
3355bool RecursiveASTVisitor<Derived>::VisitOMPPermutationClause(
3356 OMPPermutationClause *C) {
3357 for (Expr *E : C->getArgsRefs())
3358 TRY_TO(TraverseStmt(E));
3359 return true;
3360}
3361
3362template <typename Derived>
3363bool RecursiveASTVisitor<Derived>::VisitOMPFullClause(OMPFullClause *C) {
3364 return true;
3365}
3366
3367template <typename Derived>
3368bool RecursiveASTVisitor<Derived>::VisitOMPPartialClause(OMPPartialClause *C) {
3369 TRY_TO(TraverseStmt(C->getFactor()));
3370 return true;
3371}
3372
3373template <typename Derived>
3374bool
3375RecursiveASTVisitor<Derived>::VisitOMPCollapseClause(OMPCollapseClause *C) {
3376 TRY_TO(TraverseStmt(C->getNumForLoops()));
3377 return true;
3378}
3379
3380template <typename Derived>
3381bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *) {
3382 return true;
3383}
3384
3385template <typename Derived>
3386bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *) {
3387 return true;
3388}
3389
3390template <typename Derived>
3391bool RecursiveASTVisitor<Derived>::VisitOMPUnifiedAddressClause(
3392 OMPUnifiedAddressClause *) {
3393 return true;
3394}
3395
3396template <typename Derived>
3397bool RecursiveASTVisitor<Derived>::VisitOMPUnifiedSharedMemoryClause(
3398 OMPUnifiedSharedMemoryClause *) {
3399 return true;
3400}
3401
3402template <typename Derived>
3403bool RecursiveASTVisitor<Derived>::VisitOMPReverseOffloadClause(
3404 OMPReverseOffloadClause *) {
3405 return true;
3406}
3407
3408template <typename Derived>
3409bool RecursiveASTVisitor<Derived>::VisitOMPDynamicAllocatorsClause(
3410 OMPDynamicAllocatorsClause *) {
3411 return true;
3412}
3413
3414template <typename Derived>
3415bool RecursiveASTVisitor<Derived>::VisitOMPAtomicDefaultMemOrderClause(
3416 OMPAtomicDefaultMemOrderClause *) {
3417 return true;
3418}
3419
3420template <typename Derived>
3421bool RecursiveASTVisitor<Derived>::VisitOMPAtClause(OMPAtClause *) {
3422 return true;
3423}
3424
3425template <typename Derived>
3426bool RecursiveASTVisitor<Derived>::VisitOMPSeverityClause(OMPSeverityClause *) {
3427 return true;
3428}
3429
3430template <typename Derived>
3431bool RecursiveASTVisitor<Derived>::VisitOMPMessageClause(OMPMessageClause *C) {
3432 TRY_TO(TraverseStmt(C->getMessageString()));
3433 return true;
3434}
3435
3436template <typename Derived>
3437bool
3438RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {
3439 TRY_TO(VisitOMPClauseWithPreInit(C));
3440 TRY_TO(TraverseStmt(C->getChunkSize()));
3441 return true;
3442}
3443
3444template <typename Derived>
3445bool RecursiveASTVisitor<Derived>::VisitOMPOrderedClause(OMPOrderedClause *C) {
3446 TRY_TO(TraverseStmt(C->getNumForLoops()));
3447 return true;
3448}
3449
3450template <typename Derived>
3451bool RecursiveASTVisitor<Derived>::VisitOMPNowaitClause(OMPNowaitClause *) {
3452 return true;
3453}
3454
3455template <typename Derived>
3456bool RecursiveASTVisitor<Derived>::VisitOMPUntiedClause(OMPUntiedClause *) {
3457 return true;
3458}
3459
3460template <typename Derived>
3461bool
3462RecursiveASTVisitor<Derived>::VisitOMPMergeableClause(OMPMergeableClause *) {
3463 return true;
3464}
3465
3466template <typename Derived>
3467bool RecursiveASTVisitor<Derived>::VisitOMPReadClause(OMPReadClause *) {
3468 return true;
3469}
3470
3471template <typename Derived>
3472bool RecursiveASTVisitor<Derived>::VisitOMPWriteClause(OMPWriteClause *) {
3473 return true;
3474}
3475
3476template <typename Derived>
3477bool RecursiveASTVisitor<Derived>::VisitOMPUpdateClause(OMPUpdateClause *) {
3478 return true;
3479}
3480
3481template <typename Derived>
3482bool RecursiveASTVisitor<Derived>::VisitOMPCaptureClause(OMPCaptureClause *) {
3483 return true;
3484}
3485
3486template <typename Derived>
3487bool RecursiveASTVisitor<Derived>::VisitOMPCompareClause(OMPCompareClause *) {
3488 return true;
3489}
3490
3491template <typename Derived>
3492bool RecursiveASTVisitor<Derived>::VisitOMPFailClause(OMPFailClause *) {
3493 return true;
3494}
3495
3496template <typename Derived>
3497bool RecursiveASTVisitor<Derived>::VisitOMPSeqCstClause(OMPSeqCstClause *) {
3498 return true;
3499}
3500
3501template <typename Derived>
3502bool RecursiveASTVisitor<Derived>::VisitOMPAcqRelClause(OMPAcqRelClause *) {
3503 return true;
3504}
3505
3506template <typename Derived>
3507bool RecursiveASTVisitor<Derived>::VisitOMPAbsentClause(OMPAbsentClause *) {
3508 return true;
3509}
3510
3511template <typename Derived>
3512bool RecursiveASTVisitor<Derived>::VisitOMPHoldsClause(OMPHoldsClause *) {
3513 return true;
3514}
3515
3516template <typename Derived>
3517bool RecursiveASTVisitor<Derived>::VisitOMPContainsClause(OMPContainsClause *) {
3518 return true;
3519}
3520
3521template <typename Derived>
3522bool RecursiveASTVisitor<Derived>::VisitOMPNoOpenMPClause(OMPNoOpenMPClause *) {
3523 return true;
3524}
3525
3526template <typename Derived>
3527bool RecursiveASTVisitor<Derived>::VisitOMPNoOpenMPRoutinesClause(
3528 OMPNoOpenMPRoutinesClause *) {
3529 return true;
3530}
3531
3532template <typename Derived>
3533bool RecursiveASTVisitor<Derived>::VisitOMPNoParallelismClause(
3534 OMPNoParallelismClause *) {
3535 return true;
3536}
3537
3538template <typename Derived>
3539bool RecursiveASTVisitor<Derived>::VisitOMPAcquireClause(OMPAcquireClause *) {
3540 return true;
3541}
3542
3543template <typename Derived>
3544bool RecursiveASTVisitor<Derived>::VisitOMPReleaseClause(OMPReleaseClause *) {
3545 return true;
3546}
3547
3548template <typename Derived>
3549bool RecursiveASTVisitor<Derived>::VisitOMPRelaxedClause(OMPRelaxedClause *) {
3550 return true;
3551}
3552
3553template <typename Derived>
3554bool RecursiveASTVisitor<Derived>::VisitOMPWeakClause(OMPWeakClause *) {
3555 return true;
3556}
3557
3558template <typename Derived>
3559bool RecursiveASTVisitor<Derived>::VisitOMPThreadsClause(OMPThreadsClause *) {
3560 return true;
3561}
3562
3563template <typename Derived>
3564bool RecursiveASTVisitor<Derived>::VisitOMPSIMDClause(OMPSIMDClause *) {
3565 return true;
3566}
3567
3568template <typename Derived>
3569bool RecursiveASTVisitor<Derived>::VisitOMPNogroupClause(OMPNogroupClause *) {
3570 return true;
3571}
3572
3573template <typename Derived>
3574bool RecursiveASTVisitor<Derived>::VisitOMPInitClause(OMPInitClause *C) {
3575 TRY_TO(VisitOMPClauseList(C));
3576 return true;
3577}
3578
3579template <typename Derived>
3580bool RecursiveASTVisitor<Derived>::VisitOMPUseClause(OMPUseClause *C) {
3581 TRY_TO(TraverseStmt(C->getInteropVar()));
3582 return true;
3583}
3584
3585template <typename Derived>
3586bool RecursiveASTVisitor<Derived>::VisitOMPDestroyClause(OMPDestroyClause *C) {
3587 TRY_TO(TraverseStmt(C->getInteropVar()));
3588 return true;
3589}
3590
3591template <typename Derived>
3592bool RecursiveASTVisitor<Derived>::VisitOMPNovariantsClause(
3593 OMPNovariantsClause *C) {
3594 TRY_TO(VisitOMPClauseWithPreInit(C));
3595 TRY_TO(TraverseStmt(C->getCondition()));
3596 return true;
3597}
3598
3599template <typename Derived>
3600bool RecursiveASTVisitor<Derived>::VisitOMPNocontextClause(
3601 OMPNocontextClause *C) {
3602 TRY_TO(VisitOMPClauseWithPreInit(C));
3603 TRY_TO(TraverseStmt(C->getCondition()));
3604 return true;
3605}
3606
3607template <typename Derived>
3608template <typename T>
3609bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
3610 for (auto *E : Node->varlist()) {
3611 TRY_TO(TraverseStmt(E));
3612 }
3613 return true;
3614}
3615
3616template <typename Derived>
3617bool RecursiveASTVisitor<Derived>::VisitOMPInclusiveClause(
3618 OMPInclusiveClause *C) {
3619 TRY_TO(VisitOMPClauseList(C));
3620 return true;
3621}
3622
3623template <typename Derived>
3624bool RecursiveASTVisitor<Derived>::VisitOMPExclusiveClause(
3625 OMPExclusiveClause *C) {
3626 TRY_TO(VisitOMPClauseList(C));
3627 return true;
3628}
3629
3630template <typename Derived>
3631bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
3632 TRY_TO(VisitOMPClauseList(C));
3633 for (auto *E : C->private_copies()) {
3634 TRY_TO(TraverseStmt(E));
3635 }
3636 return true;
3637}
3638
3639template <typename Derived>
3640bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
3641 OMPFirstprivateClause *C) {
3642 TRY_TO(VisitOMPClauseList(C));
3643 TRY_TO(VisitOMPClauseWithPreInit(C));
3644 for (auto *E : C->private_copies()) {
3645 TRY_TO(TraverseStmt(E));
3646 }
3647 for (auto *E : C->inits()) {
3648 TRY_TO(TraverseStmt(E));
3649 }
3650 return true;
3651}
3652
3653template <typename Derived>
3654bool RecursiveASTVisitor<Derived>::VisitOMPLastprivateClause(
3655 OMPLastprivateClause *C) {
3656 TRY_TO(VisitOMPClauseList(C));
3657 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3658 for (auto *E : C->private_copies()) {
3659 TRY_TO(TraverseStmt(E));
3660 }
3661 for (auto *E : C->source_exprs()) {
3662 TRY_TO(TraverseStmt(E));
3663 }
3664 for (auto *E : C->destination_exprs()) {
3665 TRY_TO(TraverseStmt(E));
3666 }
3667 for (auto *E : C->assignment_ops()) {
3668 TRY_TO(TraverseStmt(E));
3669 }
3670 return true;
3671}
3672
3673template <typename Derived>
3674bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
3675 TRY_TO(VisitOMPClauseList(C));
3676 return true;
3677}
3678
3679template <typename Derived>
3680bool RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) {
3681 TRY_TO(TraverseStmt(C->getStep()));
3682 TRY_TO(TraverseStmt(C->getCalcStep()));
3683 TRY_TO(VisitOMPClauseList(C));
3684 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3685 for (auto *E : C->privates()) {
3686 TRY_TO(TraverseStmt(E));
3687 }
3688 for (auto *E : C->inits()) {
3689 TRY_TO(TraverseStmt(E));
3690 }
3691 for (auto *E : C->updates()) {
3692 TRY_TO(TraverseStmt(E));
3693 }
3694 for (auto *E : C->finals()) {
3695 TRY_TO(TraverseStmt(E));
3696 }
3697 return true;
3698}
3699
3700template <typename Derived>
3701bool RecursiveASTVisitor<Derived>::VisitOMPAlignedClause(OMPAlignedClause *C) {
3702 TRY_TO(TraverseStmt(C->getAlignment()));
3703 TRY_TO(VisitOMPClauseList(C));
3704 return true;
3705}
3706
3707template <typename Derived>
3708bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
3709 TRY_TO(VisitOMPClauseList(C));
3710 for (auto *E : C->source_exprs()) {
3711 TRY_TO(TraverseStmt(E));
3712 }
3713 for (auto *E : C->destination_exprs()) {
3714 TRY_TO(TraverseStmt(E));
3715 }
3716 for (auto *E : C->assignment_ops()) {
3717 TRY_TO(TraverseStmt(E));
3718 }
3719 return true;
3720}
3721
3722template <typename Derived>
3723bool RecursiveASTVisitor<Derived>::VisitOMPCopyprivateClause(
3724 OMPCopyprivateClause *C) {
3725 TRY_TO(VisitOMPClauseList(C));
3726 for (auto *E : C->source_exprs()) {
3727 TRY_TO(TraverseStmt(E));
3728 }
3729 for (auto *E : C->destination_exprs()) {
3730 TRY_TO(TraverseStmt(E));
3731 }
3732 for (auto *E : C->assignment_ops()) {
3733 TRY_TO(TraverseStmt(E));
3734 }
3735 return true;
3736}
3737
3738template <typename Derived>
3739bool
3740RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) {
3741 TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
3742 TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
3743 TRY_TO(VisitOMPClauseList(C));
3744 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3745 for (auto *E : C->privates()) {
3746 TRY_TO(TraverseStmt(E));
3747 }
3748 for (auto *E : C->lhs_exprs()) {
3749 TRY_TO(TraverseStmt(E));
3750 }
3751 for (auto *E : C->rhs_exprs()) {
3752 TRY_TO(TraverseStmt(E));
3753 }
3754 for (auto *E : C->reduction_ops()) {
3755 TRY_TO(TraverseStmt(E));
3756 }
3757 if (C->getModifier() == OMPC_REDUCTION_inscan) {
3758 for (auto *E : C->copy_ops()) {
3759 TRY_TO(TraverseStmt(E));
3760 }
3761 for (auto *E : C->copy_array_temps()) {
3762 TRY_TO(TraverseStmt(E));
3763 }
3764 for (auto *E : C->copy_array_elems()) {
3765 TRY_TO(TraverseStmt(E));
3766 }
3767 }
3768 return true;
3769}
3770
3771template <typename Derived>
3772bool RecursiveASTVisitor<Derived>::VisitOMPTaskReductionClause(
3773 OMPTaskReductionClause *C) {
3774 TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
3775 TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
3776 TRY_TO(VisitOMPClauseList(C));
3777 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3778 for (auto *E : C->privates()) {
3779 TRY_TO(TraverseStmt(E));
3780 }
3781 for (auto *E : C->lhs_exprs()) {
3782 TRY_TO(TraverseStmt(E));
3783 }
3784 for (auto *E : C->rhs_exprs()) {
3785 TRY_TO(TraverseStmt(E));
3786 }
3787 for (auto *E : C->reduction_ops()) {
3788 TRY_TO(TraverseStmt(E));
3789 }
3790 return true;
3791}
3792
3793template <typename Derived>
3794bool RecursiveASTVisitor<Derived>::VisitOMPInReductionClause(
3795 OMPInReductionClause *C) {
3796 TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
3797 TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
3798 TRY_TO(VisitOMPClauseList(C));
3799 TRY_TO(VisitOMPClauseWithPostUpdate(C));
3800 for (auto *E : C->privates()) {
3801 TRY_TO(TraverseStmt(E));
3802 }
3803 for (auto *E : C->lhs_exprs()) {
3804 TRY_TO(TraverseStmt(E));
3805 }
3806 for (auto *E : C->rhs_exprs()) {
3807 TRY_TO(TraverseStmt(E));
3808 }
3809 for (auto *E : C->reduction_ops()) {
3810 TRY_TO(TraverseStmt(E));
3811 }
3812 for (auto *E : C->taskgroup_descriptors())
3813 TRY_TO(TraverseStmt(E));
3814 return true;
3815}
3816
3817template <typename Derived>
3818bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
3819 TRY_TO(VisitOMPClauseList(C));
3820 return true;
3821}
3822
3823template <typename Derived>
3824bool RecursiveASTVisitor<Derived>::VisitOMPDepobjClause(OMPDepobjClause *C) {
3825 TRY_TO(TraverseStmt(C->getDepobj()));
3826 return true;
3827}
3828
3829template <typename Derived>
3830bool RecursiveASTVisitor<Derived>::VisitOMPDependClause(OMPDependClause *C) {
3831 TRY_TO(VisitOMPClauseList(C));
3832 return true;
3833}
3834
3835template <typename Derived>
3836bool RecursiveASTVisitor<Derived>::VisitOMPDeviceClause(OMPDeviceClause *C) {
3837 TRY_TO(VisitOMPClauseWithPreInit(C));
3838 TRY_TO(TraverseStmt(C->getDevice()));
3839 return true;
3840}
3841
3842template <typename Derived>
3843bool RecursiveASTVisitor<Derived>::VisitOMPMapClause(OMPMapClause *C) {
3844 TRY_TO(VisitOMPClauseList(C));
3845 return true;
3846}
3847
3848template <typename Derived>
3849bool RecursiveASTVisitor<Derived>::VisitOMPNumTeamsClause(
3850 OMPNumTeamsClause *C) {
3851 TRY_TO(VisitOMPClauseList(C));
3852 TRY_TO(VisitOMPClauseWithPreInit(C));
3853 return true;
3854}
3855
3856template <typename Derived>
3857bool RecursiveASTVisitor<Derived>::VisitOMPThreadLimitClause(
3858 OMPThreadLimitClause *C) {
3859 TRY_TO(VisitOMPClauseList(C));
3860 TRY_TO(VisitOMPClauseWithPreInit(C));
3861 return true;
3862}
3863
3864template <typename Derived>
3865bool RecursiveASTVisitor<Derived>::VisitOMPPriorityClause(
3866 OMPPriorityClause *C) {
3867 TRY_TO(VisitOMPClauseWithPreInit(C));
3868 TRY_TO(TraverseStmt(C->getPriority()));
3869 return true;
3870}
3871
3872template <typename Derived>
3873bool RecursiveASTVisitor<Derived>::VisitOMPGrainsizeClause(
3874 OMPGrainsizeClause *C) {
3875 TRY_TO(VisitOMPClauseWithPreInit(C));
3876 TRY_TO(TraverseStmt(C->getGrainsize()));
3877 return true;
3878}
3879
3880template <typename Derived>
3881bool RecursiveASTVisitor<Derived>::VisitOMPNumTasksClause(
3882 OMPNumTasksClause *C) {
3883 TRY_TO(VisitOMPClauseWithPreInit(C));
3884 TRY_TO(TraverseStmt(C->getNumTasks()));
3885 return true;
3886}
3887
3888template <typename Derived>
3889bool RecursiveASTVisitor<Derived>::VisitOMPHintClause(OMPHintClause *C) {
3890 TRY_TO(TraverseStmt(C->getHint()));
3891 return true;
3892}
3893
3894template <typename Derived>
3895bool RecursiveASTVisitor<Derived>::VisitOMPDistScheduleClause(
3896 OMPDistScheduleClause *C) {
3897 TRY_TO(VisitOMPClauseWithPreInit(C));
3898 TRY_TO(TraverseStmt(C->getChunkSize()));
3899 return true;
3900}
3901
3902template <typename Derived>
3903bool
3904RecursiveASTVisitor<Derived>::VisitOMPDefaultmapClause(OMPDefaultmapClause *C) {
3905 return true;
3906}
3907
3908template <typename Derived>
3909bool RecursiveASTVisitor<Derived>::VisitOMPToClause(OMPToClause *C) {
3910 TRY_TO(VisitOMPClauseList(C));
3911 return true;
3912}
3913
3914template <typename Derived>
3915bool RecursiveASTVisitor<Derived>::VisitOMPFromClause(OMPFromClause *C) {
3916 TRY_TO(VisitOMPClauseList(C));
3917 return true;
3918}
3919
3920template <typename Derived>
3921bool RecursiveASTVisitor<Derived>::VisitOMPUseDevicePtrClause(
3922 OMPUseDevicePtrClause *C) {
3923 TRY_TO(VisitOMPClauseList(C));
3924 return true;
3925}
3926
3927template <typename Derived>
3928bool RecursiveASTVisitor<Derived>::VisitOMPUseDeviceAddrClause(
3929 OMPUseDeviceAddrClause *C) {
3930 TRY_TO(VisitOMPClauseList(C));
3931 return true;
3932}
3933
3934template <typename Derived>
3935bool RecursiveASTVisitor<Derived>::VisitOMPIsDevicePtrClause(
3936 OMPIsDevicePtrClause *C) {
3937 TRY_TO(VisitOMPClauseList(C));
3938 return true;
3939}
3940
3941template <typename Derived>
3942bool RecursiveASTVisitor<Derived>::VisitOMPHasDeviceAddrClause(
3943 OMPHasDeviceAddrClause *C) {
3944 TRY_TO(VisitOMPClauseList(C));
3945 return true;
3946}
3947
3948template <typename Derived>
3949bool RecursiveASTVisitor<Derived>::VisitOMPNontemporalClause(
3950 OMPNontemporalClause *C) {
3951 TRY_TO(VisitOMPClauseList(C));
3952 for (auto *E : C->private_refs()) {
3953 TRY_TO(TraverseStmt(E));
3954 }
3955 return true;
3956}
3957
3958template <typename Derived>
3959bool RecursiveASTVisitor<Derived>::VisitOMPOrderClause(OMPOrderClause *) {
3960 return true;
3961}
3962
3963template <typename Derived>
3964bool RecursiveASTVisitor<Derived>::VisitOMPDetachClause(OMPDetachClause *C) {
3965 TRY_TO(TraverseStmt(C->getEventHandler()));
3966 return true;
3967}
3968
3969template <typename Derived>
3970bool RecursiveASTVisitor<Derived>::VisitOMPUsesAllocatorsClause(
3971 OMPUsesAllocatorsClause *C) {
3972 for (unsigned I = 0, E = C->getNumberOfAllocators(); I < E; ++I) {
3973 const OMPUsesAllocatorsClause::Data Data = C->getAllocatorData(I);
3974 TRY_TO(TraverseStmt(Data.Allocator));
3975 TRY_TO(TraverseStmt(Data.AllocatorTraits));
3976 }
3977 return true;
3978}
3979
3980template <typename Derived>
3981bool RecursiveASTVisitor<Derived>::VisitOMPAffinityClause(
3982 OMPAffinityClause *C) {
3983 TRY_TO(TraverseStmt(C->getModifier()));
3984 for (Expr *E : C->varlist())
3985 TRY_TO(TraverseStmt(E));
3986 return true;
3987}
3988
3989template <typename Derived>
3990bool RecursiveASTVisitor<Derived>::VisitOMPFilterClause(OMPFilterClause *C) {
3991 TRY_TO(VisitOMPClauseWithPreInit(C));
3992 TRY_TO(TraverseStmt(C->getThreadID()));
3993 return true;
3994}
3995
3996template <typename Derived>
3997bool RecursiveASTVisitor<Derived>::VisitOMPBindClause(OMPBindClause *C) {
3998 return true;
3999}
4000
4001template <typename Derived>
4002bool RecursiveASTVisitor<Derived>::VisitOMPXDynCGroupMemClause(
4003 OMPXDynCGroupMemClause *C) {
4004 TRY_TO(VisitOMPClauseWithPreInit(C));
4005 TRY_TO(TraverseStmt(C->getSize()));
4006 return true;
4007}
4008
4009template <typename Derived>
4010bool RecursiveASTVisitor<Derived>::VisitOMPDoacrossClause(
4011 OMPDoacrossClause *C) {
4012 TRY_TO(VisitOMPClauseList(C));
4013 return true;
4014}
4015
4016template <typename Derived>
4017bool RecursiveASTVisitor<Derived>::VisitOMPXAttributeClause(
4018 OMPXAttributeClause *C) {
4019 return true;
4020}
4021
4022template <typename Derived>
4023bool RecursiveASTVisitor<Derived>::VisitOMPXBareClause(OMPXBareClause *C) {
4024 return true;
4025}
4026
4027template <typename Derived>
4028bool RecursiveASTVisitor<Derived>::TraverseOpenACCConstructStmt(
4029 OpenACCConstructStmt *C) {
4030 TRY_TO(VisitOpenACCClauseList(C->clauses()));
4031 return true;
4032}
4033
4034template <typename Derived>
4035bool RecursiveASTVisitor<Derived>::TraverseOpenACCAssociatedStmtConstruct(
4036 OpenACCAssociatedStmtConstruct *S) {
4037 TRY_TO(TraverseOpenACCConstructStmt(S));
4038 TRY_TO(TraverseStmt(S->getAssociatedStmt()));
4039 return true;
4040}
4041
4042template <typename Derived>
4043bool RecursiveASTVisitor<Derived>::VisitOpenACCClause(const OpenACCClause *C) {
4044 for (const Stmt *Child : C->children())
4045 TRY_TO(TraverseStmt(const_cast<Stmt *>(Child)));
4046 return true;
4047}
4048
4049template <typename Derived>
4050bool RecursiveASTVisitor<Derived>::VisitOpenACCClauseList(
4051 ArrayRef<const OpenACCClause *> Clauses) {
4052
4053 for (const auto *C : Clauses)
4054 TRY_TO(VisitOpenACCClause(C));
4055 return true;
4056}
4057
4058DEF_TRAVERSE_STMT(OpenACCComputeConstruct,
4059 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4060DEF_TRAVERSE_STMT(OpenACCLoopConstruct,
4061 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4062DEF_TRAVERSE_STMT(OpenACCCombinedConstruct,
4063 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4064DEF_TRAVERSE_STMT(OpenACCDataConstruct,
4065 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4066DEF_TRAVERSE_STMT(OpenACCEnterDataConstruct,
4067 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4068DEF_TRAVERSE_STMT(OpenACCExitDataConstruct,
4069 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4070DEF_TRAVERSE_STMT(OpenACCHostDataConstruct,
4071 { TRY_TO(TraverseOpenACCAssociatedStmtConstruct(S)); })
4072DEF_TRAVERSE_STMT(OpenACCWaitConstruct, {
4073 if (S->hasDevNumExpr())
4074 TRY_TO(TraverseStmt(S->getDevNumExpr()));
4075 for (auto *E : S->getQueueIdExprs())
4076 TRY_TO(TraverseStmt(E));
4077 TRY_TO(VisitOpenACCClauseList(S->clauses()));
4078})
4079DEF_TRAVERSE_STMT(OpenACCInitConstruct,
4080 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4081DEF_TRAVERSE_STMT(OpenACCShutdownConstruct,
4082 { TRY_TO(VisitOpenACCClauseList(S->clauses())); })
4083
4084// Traverse HLSL: Out argument expression
4085DEF_TRAVERSE_STMT(HLSLOutArgExpr, {})
4086
4087// FIXME: look at the following tricky-seeming exprs to see if we
4088// need to recurse on anything. These are ones that have methods
4089// returning decls or qualtypes or nestednamespecifier -- though I'm
4090// not sure if they own them -- or just seemed very complicated, or
4091// had lots of sub-types to explore.
4092//
4093// VisitOverloadExpr and its children: recurse on template args? etc?
4094
4095// FIXME: go through all the stmts and exprs again, and see which of them
4096// create new types, and recurse on the types (TypeLocs?) of those.
4097// Candidates:
4098//
4099// http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html
4100// http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html
4101// http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html
4102// Every class that has getQualifier.
4103
4104#undef DEF_TRAVERSE_STMT
4105#undef TRAVERSE_STMT
4106#undef TRAVERSE_STMT_BASE
4107
4108#undef TRY_TO
4109
4110} // end namespace clang
4111
4112#endif // LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
This file provides AST data structures related to concepts.
#define TYPE(DERIVED, BASE)
Definition: ASTFwd.h:26
MatchType Type
DynTypedNode Node
StringRef P
const Decl * D
Expr * E
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
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.
llvm::DenseSet< const void * > Visited
Definition: HTMLLogger.cpp:145
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 STMT(CLASS, PARENT)
#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)
SourceLocation Loc
Definition: SemaObjC.cpp:759
Defines various enumerations that describe declaration and type specifiers.
const char * Data
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.
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:188
TranslationUnitDecl * getTranslationUnitDecl() const
Definition: ASTContext.h:1141
Represents a type which was implicitly adjusted by the semantic engine for arbitrary reasons.
Definition: Type.h:3357
Wrapper for source info for arrays.
Definition: TypeLoc.h:1592
Attr - This represents one attribute.
Definition: Attr.h:43
An attributed type is a type to which a type attribute has been applied.
Definition: Type.h:6127
Represents a block literal declaration, which is like an unnamed FunctionDecl.
Definition: Decl.h:4474
Pointer to a block type.
Definition: Type.h:3408
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
Represents a C++ base or member initializer.
Definition: DeclCXX.h:2318
Represents a C++ struct/union/class.
Definition: DeclCXX.h:258
Complex values, per C99 6.2.5p11.
Definition: Type.h:3145
A reference to a concept and its template args, as it appears in the code.
Definition: ASTConcept.h:124
Represents the canonical version of C arrays with a specified constant size.
Definition: Type.h:3615
Represents a concrete matrix type with constant number of rows and columns.
Definition: Type.h:4232
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1435
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition: DeclBase.h:2349
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:596
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
Definition: DeclBase.h:1076
Kind getKind() const
Definition: DeclBase.h:445
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:735
Represents the type decltype(expr) (C++11).
Definition: Type.h:5874
Represents a C++17 deduced template specialization type.
Definition: Type.h:6604
Represents an array type in C++ whose size is a value-dependent expression.
Definition: Type.h:3862
Represents an extended vector type where either the type or size is dependent.
Definition: Type.h:3960
Represents a dependent template name that cannot be resolved prior to template instantiation.
Definition: TemplateName.h:548
Represents a template specialization type whose template cannot be resolved, e.g.
Definition: Type.h:7076
Represents a vector type where either the type or size is dependent.
Definition: Type.h:4086
Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...
Definition: Type.h:6943
This represents one expression.
Definition: Expr.h:110
Represents a function declaration or definition.
Definition: Decl.h:1935
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Definition: Type.h:4681
Represents a prototype with parameter type info, e.g.
Definition: Type.h:5102
QualType desugar() const
Definition: Type.h:5646
QualType getParamType(unsigned i) const
Definition: Type.h:5357
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
Definition: Type.h:5440
ArrayRef< QualType > exceptions() const
Definition: Type.h:5525
ArrayRef< QualType > param_types() const
Definition: Type.h:5511
QualType getReturnType() const
Definition: Type.h:4643
Represents a C array with an unspecified size.
Definition: Type.h:3764
Describes an C or C++ initializer list.
Definition: Expr.h:5088
Describes the capture of a variable or of this, or of a C++1y init-capture.
Definition: LambdaCapture.h:25
A C++ lambda expression, which produces a function object (of unspecified type) that can be invoked l...
Definition: ExprCXX.h:1954
Implicit declaration of a temporary that was materialized by a MaterializeTemporaryExpr and lifetime-...
Definition: DeclCXX.h:3247
A C++ nested-name-specifier augmented with source location information.
TypeLoc getTypeLoc() const
For a nested-name-specifier that refers to a type, retrieve the type with source-location information...
NestedNameSpecifierLoc getPrefix() const
Return the prefix of this nested-name-specifier.
NestedNameSpecifier * getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
SpecifierKind getKind() const
Determine what kind of nested name specifier is stored.
NestedNameSpecifier * getPrefix() const
Return the prefix of this nested name specifier.
@ NamespaceAlias
A namespace alias, stored as a NamespaceAliasDecl*.
@ TypeSpec
A type, stored as a Type*.
@ TypeSpecWithTemplate
A type that was preceded by the 'template' keyword, stored as a Type*.
@ Super
Microsoft's '__super' specifier, stored as a CXXRecordDecl* of the class it appeared in.
@ Identifier
An identifier, stored as an IdentifierInfo*.
@ Global
The global specifier '::'. There is no stored value.
@ Namespace
A namespace, stored as a NamespaceDecl*.
const Type * getAsType() const
Retrieve the type stored in this nested name specifier.
This is a basic class for representing single OpenMP clause.
Definition: OpenMPClause.h:55
This is a basic class for representing single OpenMP executable directive.
Definition: StmtOpenMP.h:266
This is a common base class for loop directives ('omp simd', 'omp for', 'omp for simd' etc....
Definition: StmtOpenMP.h:1004
Represents a pointer to an Objective C object.
Definition: Type.h:7580
Represents a class type in Objective C.
Definition: Type.h:7326
Represents a type parameter type in Objective C.
Definition: Type.h:7252
Sugar for parentheses used when specifying types.
Definition: Type.h:3172
PipeType - OpenCL20.
Definition: Type.h:7780
A (possibly-)qualified type.
Definition: Type.h:929
Represents a template name as written in source code.
Definition: TemplateName.h:491
Wrapper of type source information for a type with non-trivial direct qualifiers.
Definition: TypeLoc.h:289
UnqualTypeLoc getUnqualifiedLoc() const
Definition: TypeLoc.h:293
An rvalue reference type, per C++11 [dcl.ref].
Definition: Type.h:3501
Represents a struct/union/class.
Definition: Decl.h:4148
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 TraverseType(QualType T)
Recursively visit a type, by dispatching to Traverse*Type() based on the argument's getTypeClass() pr...
bool dataTraverseStmtPre(Stmt *S)
Invoked before visiting a statement or expression via data recursion.
bool TraverseObjCProtocolLoc(ObjCProtocolLoc ProtocolLoc)
Recursively visit an Objective-C protocol reference with location information.
bool VisitUnqualTypeLoc(UnqualTypeLoc TL)
bool TraverseConceptExprRequirement(concepts::ExprRequirement *R)
bool 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 TraverseNestedNameSpecifier(NestedNameSpecifier *NNS)
Recursively visit a C++ nested-name-specifier.
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 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 TraverseTypeLoc(TypeLoc TL)
Recursively visit a type with location, by dispatching to Traverse*TypeLoc() based on the argument ty...
bool TraverseTypeConstraint(const TypeConstraint *C)
bool WalkUpFromQualifiedTypeLoc(QualifiedTypeLoc TL)
bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C, Expr *Init)
Recursively visit a lambda capture.
bool VisitConceptReference(ConceptReference *CR)
bool shouldTraversePostOrder() const
Return whether this visitor should traverse post-order.
SmallVectorImpl< llvm::PointerIntPair< Stmt *, 1, bool > > DataRecursionQueue
A queue used for performing data recursion over statements.
bool shouldVisitLambdaBody() const
Return whether this visitor should recurse into lambda body.
bool TraverseSynOrSemInitListExpr(InitListExpr *S, DataRecursionQueue *Queue=nullptr)
Recursively visit the syntactic or semantic form of an initialization list.
bool TraverseAttr(Attr *At)
Recursively visit an attribute, by dispatching to Traverse*Attr() based on the argument's dynamic typ...
bool 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.
Stmt - This represents one statement.
Definition: Stmt.h:84
@ NoStmtClass
Definition: Stmt.h:87
llvm::iterator_range< child_iterator > child_range
Definition: Stmt.h:1479
Represents the result of substituting a set of types for a template type parameter pack.
Definition: Type.h:6464
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:524
const TemplateArgument & getArgument() const
Definition: TemplateBase.h:574
TypeSourceInfo * getTypeSourceInfo() const
Definition: TemplateBase.h:578
NestedNameSpecifierLoc getTemplateQualifierLoc() const
Definition: TemplateBase.h:609
Expr * getSourceExpression() const
Definition: TemplateBase.h:584
Represents a template argument.
Definition: TemplateBase.h:61
Expr * getAsExpr() const
Retrieve the template argument as an expression.
Definition: TemplateBase.h:408
QualType getAsType() const
Retrieve the type for a type template argument.
Definition: TemplateBase.h:319
ArrayRef< TemplateArgument > pack_elements() const
Iterator range referencing all of the elements of a template argument pack.
Definition: TemplateBase.h:432
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
Definition: TemplateBase.h:74
@ Template
The template argument is a template name that was provided for a template template parameter.
Definition: TemplateBase.h:93
@ StructuralValue
The template argument is a non-type template argument that can't be represented by the special-case D...
Definition: TemplateBase.h:89
@ Pack
The template argument is actually a parameter pack.
Definition: TemplateBase.h:107
@ TemplateExpansion
The template argument is a pack expansion of a template name that was provided for a template templat...
Definition: TemplateBase.h:97
@ NullPtr
The template argument is a null pointer or null pointer to member that was provided for a non-type te...
Definition: TemplateBase.h:78
@ Type
The template argument is a type.
Definition: TemplateBase.h:70
@ Null
Represents an empty template argument, e.g., one that has not been deduced.
Definition: TemplateBase.h:67
@ Integral
The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...
Definition: TemplateBase.h:82
@ Expression
The template argument is an expression, and we've not resolved it to one of the other forms yet,...
Definition: TemplateBase.h:103
ArgKind getKind() const
Return the kind of stored template argument.
Definition: TemplateBase.h:295
TemplateName getAsTemplateOrTemplatePattern() const
Retrieve the template argument as a template name; if the argument is a pack expansion,...
Definition: TemplateBase.h:350
Represents a C++ template name within the type system.
Definition: TemplateName.h:220
DependentTemplateName * getAsDependentTemplateName() const
Retrieve the underlying dependent template name structure, if any.
QualifiedTemplateName * getAsQualifiedTemplateName() const
Retrieve the underlying qualified template name structure, if any.
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:73
Declaration of a template type parameter.
A declaration that models statements at global scope.
Definition: Decl.h:4437
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:338
TypeLocClass getTypeLocClass() const
Definition: TypeLoc.h:116
bool isNull() const
Definition: TypeLoc.h:121
Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...
Definition: Type.h:5797
A container of type source information.
Definition: Type.h:7902
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
Definition: TypeLoc.h:256
The base class of the type hierarchy.
Definition: Type.h:1828
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:738
TypeClass getTypeClass() const
Definition: Type.h:2341
A unary type transform, which is a type constructed from another.
Definition: Type.h:5989
Wrapper of type source information for a type with no direct qualifiers.
Definition: TypeLoc.h:263
Represents a variable declaration or definition.
Definition: Decl.h:882
Represents a GCC generic vector type.
Definition: Type.h:4034
A requires-expression requirement which queries the validity and properties of an expression ('simple...
Definition: ExprConcepts.h:280
const ReturnTypeRequirement & getReturnTypeRequirement() const
Definition: ExprConcepts.h:398
A requires-expression requirement which is satisfied when a general constraint expression is satisfie...
Definition: ExprConcepts.h:429
A static requirement that can be used in a requires-expression to check properties of types and expre...
Definition: ExprConcepts.h:168
RequirementKind getKind() const
Definition: ExprConcepts.h:198
A requires-expression requirement which queries the existence of a type name or type template special...
Definition: ExprConcepts.h:225
TypeSourceInfo * getType() const
Definition: ExprConcepts.h:267
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.
for(const auto &A :T->param_types())
const FunctionProtoType * T
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
Definition: DeclBase.h:1274
@ TSK_ExplicitInstantiationDefinition
This template specialization was instantiated from a template due to an explicit instantiation defini...
Definition: Specifiers.h:206
@ TSK_ExplicitInstantiationDeclaration
This template specialization was instantiated from a template due to an explicit instantiation declar...
Definition: Specifiers.h:202
@ TSK_ExplicitSpecialization
This template specialization was declared or defined by an explicit specialization (C++ [temp....
Definition: Specifiers.h:198
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
Definition: Specifiers.h:194
@ TSK_Undeclared
This template specialization was formed from a template-id but has not yet been declared,...
Definition: Specifiers.h:191
@ Class
The "class" keyword introduces the elaborated-type-specifier.
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.