xref: /minix3/external/bsd/llvm/dist/clang/include/clang/AST/RecursiveASTVisitor.h (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===--- RecursiveASTVisitor.h - Recursive AST Visitor ----------*- C++ -*-===//
2f4a2713aSLionel Sambuc //
3f4a2713aSLionel Sambuc //                     The LLVM Compiler Infrastructure
4f4a2713aSLionel Sambuc //
5f4a2713aSLionel Sambuc // This file is distributed under the University of Illinois Open Source
6f4a2713aSLionel Sambuc // License. See LICENSE.TXT for details.
7f4a2713aSLionel Sambuc //
8f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
9f4a2713aSLionel Sambuc //
10f4a2713aSLionel Sambuc //  This file defines the RecursiveASTVisitor interface, which recursively
11f4a2713aSLionel Sambuc //  traverses the entire AST.
12f4a2713aSLionel Sambuc //
13f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
14f4a2713aSLionel Sambuc #ifndef LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
15f4a2713aSLionel Sambuc #define LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
16f4a2713aSLionel Sambuc 
17*0a6a1f1dSLionel Sambuc #include "clang/AST/Attr.h"
18f4a2713aSLionel Sambuc #include "clang/AST/Decl.h"
19f4a2713aSLionel Sambuc #include "clang/AST/DeclCXX.h"
20f4a2713aSLionel Sambuc #include "clang/AST/DeclFriend.h"
21f4a2713aSLionel Sambuc #include "clang/AST/DeclObjC.h"
22f4a2713aSLionel Sambuc #include "clang/AST/DeclOpenMP.h"
23f4a2713aSLionel Sambuc #include "clang/AST/DeclTemplate.h"
24f4a2713aSLionel Sambuc #include "clang/AST/Expr.h"
25f4a2713aSLionel Sambuc #include "clang/AST/ExprCXX.h"
26f4a2713aSLionel Sambuc #include "clang/AST/ExprObjC.h"
27f4a2713aSLionel Sambuc #include "clang/AST/NestedNameSpecifier.h"
28f4a2713aSLionel Sambuc #include "clang/AST/Stmt.h"
29f4a2713aSLionel Sambuc #include "clang/AST/StmtCXX.h"
30f4a2713aSLionel Sambuc #include "clang/AST/StmtObjC.h"
31f4a2713aSLionel Sambuc #include "clang/AST/StmtOpenMP.h"
32f4a2713aSLionel Sambuc #include "clang/AST/TemplateBase.h"
33f4a2713aSLionel Sambuc #include "clang/AST/TemplateName.h"
34f4a2713aSLionel Sambuc #include "clang/AST/Type.h"
35f4a2713aSLionel Sambuc #include "clang/AST/TypeLoc.h"
36f4a2713aSLionel Sambuc 
37f4a2713aSLionel Sambuc // The following three macros are used for meta programming.  The code
38f4a2713aSLionel Sambuc // using them is responsible for defining macro OPERATOR().
39f4a2713aSLionel Sambuc 
40f4a2713aSLionel Sambuc // All unary operators.
41f4a2713aSLionel Sambuc #define UNARYOP_LIST()                                                         \
42*0a6a1f1dSLionel Sambuc   OPERATOR(PostInc) OPERATOR(PostDec) OPERATOR(PreInc) OPERATOR(PreDec)        \
43*0a6a1f1dSLionel Sambuc       OPERATOR(AddrOf) OPERATOR(Deref) OPERATOR(Plus) OPERATOR(Minus)          \
44*0a6a1f1dSLionel Sambuc       OPERATOR(Not) OPERATOR(LNot) OPERATOR(Real) OPERATOR(Imag)               \
45f4a2713aSLionel Sambuc       OPERATOR(Extension)
46f4a2713aSLionel Sambuc 
47f4a2713aSLionel Sambuc // All binary operators (excluding compound assign operators).
48f4a2713aSLionel Sambuc #define BINOP_LIST()                                                           \
49*0a6a1f1dSLionel Sambuc   OPERATOR(PtrMemD) OPERATOR(PtrMemI) OPERATOR(Mul) OPERATOR(Div)              \
50*0a6a1f1dSLionel Sambuc       OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub) OPERATOR(Shl) OPERATOR(Shr)    \
51*0a6a1f1dSLionel Sambuc       OPERATOR(LT) OPERATOR(GT) OPERATOR(LE) OPERATOR(GE) OPERATOR(EQ)         \
52*0a6a1f1dSLionel Sambuc       OPERATOR(NE) OPERATOR(And) OPERATOR(Xor) OPERATOR(Or) OPERATOR(LAnd)     \
53*0a6a1f1dSLionel Sambuc       OPERATOR(LOr) OPERATOR(Assign) OPERATOR(Comma)
54f4a2713aSLionel Sambuc 
55f4a2713aSLionel Sambuc // All compound assign operators.
56f4a2713aSLionel Sambuc #define CAO_LIST()                                                             \
57f4a2713aSLionel Sambuc   OPERATOR(Mul) OPERATOR(Div) OPERATOR(Rem) OPERATOR(Add) OPERATOR(Sub)        \
58f4a2713aSLionel Sambuc       OPERATOR(Shl) OPERATOR(Shr) OPERATOR(And) OPERATOR(Or) OPERATOR(Xor)
59f4a2713aSLionel Sambuc 
60f4a2713aSLionel Sambuc namespace clang {
61f4a2713aSLionel Sambuc 
62f4a2713aSLionel Sambuc // A helper macro to implement short-circuiting when recursing.  It
63f4a2713aSLionel Sambuc // invokes CALL_EXPR, which must be a method call, on the derived
64f4a2713aSLionel Sambuc // object (s.t. a user of RecursiveASTVisitor can override the method
65f4a2713aSLionel Sambuc // in CALL_EXPR).
66f4a2713aSLionel Sambuc #define TRY_TO(CALL_EXPR)                                                      \
67*0a6a1f1dSLionel Sambuc   do {                                                                         \
68*0a6a1f1dSLionel Sambuc     if (!getDerived().CALL_EXPR)                                               \
69*0a6a1f1dSLionel Sambuc       return false;                                                            \
70*0a6a1f1dSLionel Sambuc   } while (0)
71f4a2713aSLionel Sambuc 
72f4a2713aSLionel Sambuc /// \brief A class that does preorder depth-first traversal on the
73f4a2713aSLionel Sambuc /// entire Clang AST and visits each node.
74f4a2713aSLionel Sambuc ///
75f4a2713aSLionel Sambuc /// This class performs three distinct tasks:
76f4a2713aSLionel Sambuc ///   1. traverse the AST (i.e. go to each node);
77f4a2713aSLionel Sambuc ///   2. at a given node, walk up the class hierarchy, starting from
78f4a2713aSLionel Sambuc ///      the node's dynamic type, until the top-most class (e.g. Stmt,
79f4a2713aSLionel Sambuc ///      Decl, or Type) is reached.
80f4a2713aSLionel Sambuc ///   3. given a (node, class) combination, where 'class' is some base
81f4a2713aSLionel Sambuc ///      class of the dynamic type of 'node', call a user-overridable
82f4a2713aSLionel Sambuc ///      function to actually visit the node.
83f4a2713aSLionel Sambuc ///
84f4a2713aSLionel Sambuc /// These tasks are done by three groups of methods, respectively:
85f4a2713aSLionel Sambuc ///   1. TraverseDecl(Decl *x) does task #1.  It is the entry point
86f4a2713aSLionel Sambuc ///      for traversing an AST rooted at x.  This method simply
87f4a2713aSLionel Sambuc ///      dispatches (i.e. forwards) to TraverseFoo(Foo *x) where Foo
88f4a2713aSLionel Sambuc ///      is the dynamic type of *x, which calls WalkUpFromFoo(x) and
89f4a2713aSLionel Sambuc ///      then recursively visits the child nodes of x.
90f4a2713aSLionel Sambuc ///      TraverseStmt(Stmt *x) and TraverseType(QualType x) work
91f4a2713aSLionel Sambuc ///      similarly.
92f4a2713aSLionel Sambuc ///   2. WalkUpFromFoo(Foo *x) does task #2.  It does not try to visit
93f4a2713aSLionel Sambuc ///      any child node of x.  Instead, it first calls WalkUpFromBar(x)
94f4a2713aSLionel Sambuc ///      where Bar is the direct parent class of Foo (unless Foo has
95f4a2713aSLionel Sambuc ///      no parent), and then calls VisitFoo(x) (see the next list item).
96f4a2713aSLionel Sambuc ///   3. VisitFoo(Foo *x) does task #3.
97f4a2713aSLionel Sambuc ///
98f4a2713aSLionel Sambuc /// These three method groups are tiered (Traverse* > WalkUpFrom* >
99f4a2713aSLionel Sambuc /// Visit*).  A method (e.g. Traverse*) may call methods from the same
100f4a2713aSLionel Sambuc /// tier (e.g. other Traverse*) or one tier lower (e.g. WalkUpFrom*).
101f4a2713aSLionel Sambuc /// It may not call methods from a higher tier.
102f4a2713aSLionel Sambuc ///
103f4a2713aSLionel Sambuc /// Note that since WalkUpFromFoo() calls WalkUpFromBar() (where Bar
104f4a2713aSLionel Sambuc /// is Foo's super class) before calling VisitFoo(), the result is
105f4a2713aSLionel Sambuc /// that the Visit*() methods for a given node are called in the
106f4a2713aSLionel Sambuc /// top-down order (e.g. for a node of type NamespaceDecl, the order will
107f4a2713aSLionel Sambuc /// be VisitDecl(), VisitNamedDecl(), and then VisitNamespaceDecl()).
108f4a2713aSLionel Sambuc ///
109f4a2713aSLionel Sambuc /// This scheme guarantees that all Visit*() calls for the same AST
110f4a2713aSLionel Sambuc /// node are grouped together.  In other words, Visit*() methods for
111f4a2713aSLionel Sambuc /// different nodes are never interleaved.
112f4a2713aSLionel Sambuc ///
113f4a2713aSLionel Sambuc /// Clients of this visitor should subclass the visitor (providing
114f4a2713aSLionel Sambuc /// themselves as the template argument, using the curiously recurring
115f4a2713aSLionel Sambuc /// template pattern) and override any of the Traverse*, WalkUpFrom*,
116f4a2713aSLionel Sambuc /// and Visit* methods for declarations, types, statements,
117f4a2713aSLionel Sambuc /// expressions, or other AST nodes where the visitor should customize
118f4a2713aSLionel Sambuc /// behavior.  Most users only need to override Visit*.  Advanced
119f4a2713aSLionel Sambuc /// users may override Traverse* and WalkUpFrom* to implement custom
120f4a2713aSLionel Sambuc /// traversal strategies.  Returning false from one of these overridden
121f4a2713aSLionel Sambuc /// functions will abort the entire traversal.
122f4a2713aSLionel Sambuc ///
123f4a2713aSLionel Sambuc /// By default, this visitor tries to visit every part of the explicit
124f4a2713aSLionel Sambuc /// source code exactly once.  The default policy towards templates
125f4a2713aSLionel Sambuc /// is to descend into the 'pattern' class or function body, not any
126f4a2713aSLionel Sambuc /// explicit or implicit instantiations.  Explicit specializations
127f4a2713aSLionel Sambuc /// are still visited, and the patterns of partial specializations
128f4a2713aSLionel Sambuc /// are visited separately.  This behavior can be changed by
129f4a2713aSLionel Sambuc /// overriding shouldVisitTemplateInstantiations() in the derived class
130f4a2713aSLionel Sambuc /// to return true, in which case all known implicit and explicit
131f4a2713aSLionel Sambuc /// instantiations will be visited at the same time as the pattern
132f4a2713aSLionel Sambuc /// from which they were produced.
133*0a6a1f1dSLionel Sambuc template <typename Derived> class RecursiveASTVisitor {
134f4a2713aSLionel Sambuc public:
135f4a2713aSLionel Sambuc   /// \brief Return a reference to the derived class.
getDerived()136f4a2713aSLionel Sambuc   Derived &getDerived() { return *static_cast<Derived *>(this); }
137f4a2713aSLionel Sambuc 
138f4a2713aSLionel Sambuc   /// \brief Return whether this visitor should recurse into
139f4a2713aSLionel Sambuc   /// template instantiations.
shouldVisitTemplateInstantiations()140f4a2713aSLionel Sambuc   bool shouldVisitTemplateInstantiations() const { return false; }
141f4a2713aSLionel Sambuc 
142f4a2713aSLionel Sambuc   /// \brief Return whether this visitor should recurse into the types of
143f4a2713aSLionel Sambuc   /// TypeLocs.
shouldWalkTypesOfTypeLocs()144f4a2713aSLionel Sambuc   bool shouldWalkTypesOfTypeLocs() const { return true; }
145f4a2713aSLionel Sambuc 
146f4a2713aSLionel Sambuc   /// \brief Return whether this visitor should recurse into implicit
147f4a2713aSLionel Sambuc   /// code, e.g., implicit constructors and destructors.
shouldVisitImplicitCode()148f4a2713aSLionel Sambuc   bool shouldVisitImplicitCode() const { return false; }
149f4a2713aSLionel Sambuc 
150f4a2713aSLionel Sambuc   /// \brief Return whether \param S should be traversed using data recursion
151f4a2713aSLionel Sambuc   /// to avoid a stack overflow with extreme cases.
shouldUseDataRecursionFor(Stmt * S)152f4a2713aSLionel Sambuc   bool shouldUseDataRecursionFor(Stmt *S) const {
153f4a2713aSLionel Sambuc     return isa<BinaryOperator>(S) || isa<UnaryOperator>(S) ||
154f4a2713aSLionel Sambuc            isa<CaseStmt>(S) || isa<CXXOperatorCallExpr>(S);
155f4a2713aSLionel Sambuc   }
156f4a2713aSLionel Sambuc 
157f4a2713aSLionel Sambuc   /// \brief Recursively visit a statement or expression, by
158f4a2713aSLionel Sambuc   /// dispatching to Traverse*() based on the argument's dynamic type.
159f4a2713aSLionel Sambuc   ///
160f4a2713aSLionel Sambuc   /// \returns false if the visitation was terminated early, true
161f4a2713aSLionel Sambuc   /// otherwise (including when the argument is NULL).
162f4a2713aSLionel Sambuc   bool TraverseStmt(Stmt *S);
163f4a2713aSLionel Sambuc 
164f4a2713aSLionel Sambuc   /// \brief Recursively visit a type, by dispatching to
165f4a2713aSLionel Sambuc   /// Traverse*Type() based on the argument's getTypeClass() property.
166f4a2713aSLionel Sambuc   ///
167f4a2713aSLionel Sambuc   /// \returns false if the visitation was terminated early, true
168f4a2713aSLionel Sambuc   /// otherwise (including when the argument is a Null type).
169f4a2713aSLionel Sambuc   bool TraverseType(QualType T);
170f4a2713aSLionel Sambuc 
171f4a2713aSLionel Sambuc   /// \brief Recursively visit a type with location, by dispatching to
172f4a2713aSLionel Sambuc   /// Traverse*TypeLoc() based on the argument type's getTypeClass() property.
173f4a2713aSLionel Sambuc   ///
174f4a2713aSLionel Sambuc   /// \returns false if the visitation was terminated early, true
175f4a2713aSLionel Sambuc   /// otherwise (including when the argument is a Null type location).
176f4a2713aSLionel Sambuc   bool TraverseTypeLoc(TypeLoc TL);
177f4a2713aSLionel Sambuc 
178*0a6a1f1dSLionel Sambuc   /// \brief Recursively visit an attribute, by dispatching to
179*0a6a1f1dSLionel Sambuc   /// Traverse*Attr() based on the argument's dynamic type.
180*0a6a1f1dSLionel Sambuc   ///
181*0a6a1f1dSLionel Sambuc   /// \returns false if the visitation was terminated early, true
182*0a6a1f1dSLionel Sambuc   /// otherwise (including when the argument is a Null type location).
183*0a6a1f1dSLionel Sambuc   bool TraverseAttr(Attr *At);
184*0a6a1f1dSLionel Sambuc 
185f4a2713aSLionel Sambuc   /// \brief Recursively visit a declaration, by dispatching to
186f4a2713aSLionel Sambuc   /// Traverse*Decl() based on the argument's dynamic type.
187f4a2713aSLionel Sambuc   ///
188f4a2713aSLionel Sambuc   /// \returns false if the visitation was terminated early, true
189f4a2713aSLionel Sambuc   /// otherwise (including when the argument is NULL).
190f4a2713aSLionel Sambuc   bool TraverseDecl(Decl *D);
191f4a2713aSLionel Sambuc 
192f4a2713aSLionel Sambuc   /// \brief Recursively visit a C++ nested-name-specifier.
193f4a2713aSLionel Sambuc   ///
194f4a2713aSLionel Sambuc   /// \returns false if the visitation was terminated early, true otherwise.
195f4a2713aSLionel Sambuc   bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
196f4a2713aSLionel Sambuc 
197f4a2713aSLionel Sambuc   /// \brief Recursively visit a C++ nested-name-specifier with location
198f4a2713aSLionel Sambuc   /// information.
199f4a2713aSLionel Sambuc   ///
200f4a2713aSLionel Sambuc   /// \returns false if the visitation was terminated early, true otherwise.
201f4a2713aSLionel Sambuc   bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
202f4a2713aSLionel Sambuc 
203f4a2713aSLionel Sambuc   /// \brief Recursively visit a name with its location information.
204f4a2713aSLionel Sambuc   ///
205f4a2713aSLionel Sambuc   /// \returns false if the visitation was terminated early, true otherwise.
206f4a2713aSLionel Sambuc   bool TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo);
207f4a2713aSLionel Sambuc 
208f4a2713aSLionel Sambuc   /// \brief Recursively visit a template name and dispatch to the
209f4a2713aSLionel Sambuc   /// appropriate method.
210f4a2713aSLionel Sambuc   ///
211f4a2713aSLionel Sambuc   /// \returns false if the visitation was terminated early, true otherwise.
212f4a2713aSLionel Sambuc   bool TraverseTemplateName(TemplateName Template);
213f4a2713aSLionel Sambuc 
214f4a2713aSLionel Sambuc   /// \brief Recursively visit a template argument and dispatch to the
215f4a2713aSLionel Sambuc   /// appropriate method for the argument type.
216f4a2713aSLionel Sambuc   ///
217f4a2713aSLionel Sambuc   /// \returns false if the visitation was terminated early, true otherwise.
218f4a2713aSLionel Sambuc   // FIXME: migrate callers to TemplateArgumentLoc instead.
219f4a2713aSLionel Sambuc   bool TraverseTemplateArgument(const TemplateArgument &Arg);
220f4a2713aSLionel Sambuc 
221f4a2713aSLionel Sambuc   /// \brief Recursively visit a template argument location and dispatch to the
222f4a2713aSLionel Sambuc   /// appropriate method for the argument type.
223f4a2713aSLionel Sambuc   ///
224f4a2713aSLionel Sambuc   /// \returns false if the visitation was terminated early, true otherwise.
225f4a2713aSLionel Sambuc   bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &ArgLoc);
226f4a2713aSLionel Sambuc 
227f4a2713aSLionel Sambuc   /// \brief Recursively visit a set of template arguments.
228f4a2713aSLionel Sambuc   /// This can be overridden by a subclass, but it's not expected that
229f4a2713aSLionel Sambuc   /// will be needed -- this visitor always dispatches to another.
230f4a2713aSLionel Sambuc   ///
231f4a2713aSLionel Sambuc   /// \returns false if the visitation was terminated early, true otherwise.
232f4a2713aSLionel Sambuc   // FIXME: take a TemplateArgumentLoc* (or TemplateArgumentListInfo) instead.
233f4a2713aSLionel Sambuc   bool TraverseTemplateArguments(const TemplateArgument *Args,
234f4a2713aSLionel Sambuc                                  unsigned NumArgs);
235f4a2713aSLionel Sambuc 
236f4a2713aSLionel Sambuc   /// \brief Recursively visit a constructor initializer.  This
237f4a2713aSLionel Sambuc   /// automatically dispatches to another visitor for the initializer
238f4a2713aSLionel Sambuc   /// expression, but not for the name of the initializer, so may
239f4a2713aSLionel Sambuc   /// be overridden for clients that need access to the name.
240f4a2713aSLionel Sambuc   ///
241f4a2713aSLionel Sambuc   /// \returns false if the visitation was terminated early, true otherwise.
242f4a2713aSLionel Sambuc   bool TraverseConstructorInitializer(CXXCtorInitializer *Init);
243f4a2713aSLionel Sambuc 
244f4a2713aSLionel Sambuc   /// \brief Recursively visit a lambda capture.
245f4a2713aSLionel Sambuc   ///
246f4a2713aSLionel Sambuc   /// \returns false if the visitation was terminated early, true otherwise.
247*0a6a1f1dSLionel Sambuc   bool TraverseLambdaCapture(LambdaExpr *LE, const LambdaCapture *C);
248f4a2713aSLionel Sambuc 
249f4a2713aSLionel Sambuc   /// \brief Recursively visit the body of a lambda expression.
250f4a2713aSLionel Sambuc   ///
251f4a2713aSLionel Sambuc   /// This provides a hook for visitors that need more context when visiting
252f4a2713aSLionel Sambuc   /// \c LE->getBody().
253f4a2713aSLionel Sambuc   ///
254f4a2713aSLionel Sambuc   /// \returns false if the visitation was terminated early, true otherwise.
255f4a2713aSLionel Sambuc   bool TraverseLambdaBody(LambdaExpr *LE);
256f4a2713aSLionel Sambuc 
257*0a6a1f1dSLionel Sambuc   // ---- Methods on Attrs ----
258*0a6a1f1dSLionel Sambuc 
259*0a6a1f1dSLionel Sambuc   // \brief Visit an attribute.
VisitAttr(Attr * A)260*0a6a1f1dSLionel Sambuc   bool VisitAttr(Attr *A) { return true; }
261*0a6a1f1dSLionel Sambuc 
262*0a6a1f1dSLionel Sambuc // Declare Traverse* and empty Visit* for all Attr classes.
263*0a6a1f1dSLionel Sambuc #define ATTR_VISITOR_DECLS_ONLY
264*0a6a1f1dSLionel Sambuc #include "clang/AST/AttrVisitor.inc"
265*0a6a1f1dSLionel Sambuc #undef ATTR_VISITOR_DECLS_ONLY
266*0a6a1f1dSLionel Sambuc 
267f4a2713aSLionel Sambuc // ---- Methods on Stmts ----
268f4a2713aSLionel Sambuc 
269f4a2713aSLionel Sambuc // Declare Traverse*() for all concrete Stmt classes.
270f4a2713aSLionel Sambuc #define ABSTRACT_STMT(STMT)
271*0a6a1f1dSLionel Sambuc #define STMT(CLASS, PARENT) bool Traverse##CLASS(CLASS *S);
272f4a2713aSLionel Sambuc #include "clang/AST/StmtNodes.inc"
273f4a2713aSLionel Sambuc   // The above header #undefs ABSTRACT_STMT and STMT upon exit.
274f4a2713aSLionel Sambuc 
275f4a2713aSLionel Sambuc   // Define WalkUpFrom*() and empty Visit*() for all Stmt classes.
WalkUpFromStmt(Stmt * S)276f4a2713aSLionel Sambuc   bool WalkUpFromStmt(Stmt *S) { return getDerived().VisitStmt(S); }
VisitStmt(Stmt * S)277f4a2713aSLionel Sambuc   bool VisitStmt(Stmt *S) { return true; }
278f4a2713aSLionel Sambuc #define STMT(CLASS, PARENT)                                                    \
279f4a2713aSLionel Sambuc   bool WalkUpFrom##CLASS(CLASS *S) {                                           \
280f4a2713aSLionel Sambuc     TRY_TO(WalkUpFrom##PARENT(S));                                             \
281f4a2713aSLionel Sambuc     TRY_TO(Visit##CLASS(S));                                                   \
282f4a2713aSLionel Sambuc     return true;                                                               \
283f4a2713aSLionel Sambuc   }                                                                            \
284f4a2713aSLionel Sambuc   bool Visit##CLASS(CLASS *S) { return true; }
285f4a2713aSLionel Sambuc #include "clang/AST/StmtNodes.inc"
286f4a2713aSLionel Sambuc 
287f4a2713aSLionel Sambuc // Define Traverse*(), WalkUpFrom*(), and Visit*() for unary
288f4a2713aSLionel Sambuc // operator methods.  Unary operators are not classes in themselves
289f4a2713aSLionel Sambuc // (they're all opcodes in UnaryOperator) but do have visitors.
290f4a2713aSLionel Sambuc #define OPERATOR(NAME)                                                         \
291f4a2713aSLionel Sambuc   bool TraverseUnary##NAME(UnaryOperator *S) {                                 \
292f4a2713aSLionel Sambuc     TRY_TO(WalkUpFromUnary##NAME(S));                                          \
293f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(S->getSubExpr()));                                     \
294f4a2713aSLionel Sambuc     return true;                                                               \
295f4a2713aSLionel Sambuc   }                                                                            \
296f4a2713aSLionel Sambuc   bool WalkUpFromUnary##NAME(UnaryOperator *S) {                               \
297f4a2713aSLionel Sambuc     TRY_TO(WalkUpFromUnaryOperator(S));                                        \
298f4a2713aSLionel Sambuc     TRY_TO(VisitUnary##NAME(S));                                               \
299f4a2713aSLionel Sambuc     return true;                                                               \
300f4a2713aSLionel Sambuc   }                                                                            \
301f4a2713aSLionel Sambuc   bool VisitUnary##NAME(UnaryOperator *S) { return true; }
302f4a2713aSLionel Sambuc 
303f4a2713aSLionel Sambuc   UNARYOP_LIST()
304f4a2713aSLionel Sambuc #undef OPERATOR
305f4a2713aSLionel Sambuc 
306f4a2713aSLionel Sambuc // Define Traverse*(), WalkUpFrom*(), and Visit*() for binary
307f4a2713aSLionel Sambuc // operator methods.  Binary operators are not classes in themselves
308f4a2713aSLionel Sambuc // (they're all opcodes in BinaryOperator) but do have visitors.
309f4a2713aSLionel Sambuc #define GENERAL_BINOP_FALLBACK(NAME, BINOP_TYPE)                               \
310f4a2713aSLionel Sambuc   bool TraverseBin##NAME(BINOP_TYPE *S) {                                      \
311f4a2713aSLionel Sambuc     TRY_TO(WalkUpFromBin##NAME(S));                                            \
312f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(S->getLHS()));                                         \
313f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(S->getRHS()));                                         \
314f4a2713aSLionel Sambuc     return true;                                                               \
315f4a2713aSLionel Sambuc   }                                                                            \
316f4a2713aSLionel Sambuc   bool WalkUpFromBin##NAME(BINOP_TYPE *S) {                                    \
317f4a2713aSLionel Sambuc     TRY_TO(WalkUpFrom##BINOP_TYPE(S));                                         \
318f4a2713aSLionel Sambuc     TRY_TO(VisitBin##NAME(S));                                                 \
319f4a2713aSLionel Sambuc     return true;                                                               \
320f4a2713aSLionel Sambuc   }                                                                            \
321f4a2713aSLionel Sambuc   bool VisitBin##NAME(BINOP_TYPE *S) { return true; }
322f4a2713aSLionel Sambuc 
323f4a2713aSLionel Sambuc #define OPERATOR(NAME) GENERAL_BINOP_FALLBACK(NAME, BinaryOperator)
BINOP_LIST()324f4a2713aSLionel Sambuc   BINOP_LIST()
325f4a2713aSLionel Sambuc #undef OPERATOR
326f4a2713aSLionel Sambuc 
327f4a2713aSLionel Sambuc // Define Traverse*(), WalkUpFrom*(), and Visit*() for compound
328f4a2713aSLionel Sambuc // assignment methods.  Compound assignment operators are not
329f4a2713aSLionel Sambuc // classes in themselves (they're all opcodes in
330f4a2713aSLionel Sambuc // CompoundAssignOperator) but do have visitors.
331f4a2713aSLionel Sambuc #define OPERATOR(NAME)                                                         \
332f4a2713aSLionel Sambuc   GENERAL_BINOP_FALLBACK(NAME##Assign, CompoundAssignOperator)
333f4a2713aSLionel Sambuc 
334f4a2713aSLionel Sambuc   CAO_LIST()
335f4a2713aSLionel Sambuc #undef OPERATOR
336f4a2713aSLionel Sambuc #undef GENERAL_BINOP_FALLBACK
337f4a2713aSLionel Sambuc 
338f4a2713aSLionel Sambuc // ---- Methods on Types ----
339f4a2713aSLionel Sambuc // FIXME: revamp to take TypeLoc's rather than Types.
340f4a2713aSLionel Sambuc 
341f4a2713aSLionel Sambuc // Declare Traverse*() for all concrete Type classes.
342f4a2713aSLionel Sambuc #define ABSTRACT_TYPE(CLASS, BASE)
343*0a6a1f1dSLionel Sambuc #define TYPE(CLASS, BASE) bool Traverse##CLASS##Type(CLASS##Type *T);
344f4a2713aSLionel Sambuc #include "clang/AST/TypeNodes.def"
345f4a2713aSLionel Sambuc   // The above header #undefs ABSTRACT_TYPE and TYPE upon exit.
346f4a2713aSLionel Sambuc 
347f4a2713aSLionel Sambuc   // Define WalkUpFrom*() and empty Visit*() for all Type classes.
348f4a2713aSLionel Sambuc   bool WalkUpFromType(Type *T) { return getDerived().VisitType(T); }
VisitType(Type * T)349f4a2713aSLionel Sambuc   bool VisitType(Type *T) { return true; }
350f4a2713aSLionel Sambuc #define TYPE(CLASS, BASE)                                                      \
351f4a2713aSLionel Sambuc   bool WalkUpFrom##CLASS##Type(CLASS##Type *T) {                               \
352f4a2713aSLionel Sambuc     TRY_TO(WalkUpFrom##BASE(T));                                               \
353f4a2713aSLionel Sambuc     TRY_TO(Visit##CLASS##Type(T));                                             \
354f4a2713aSLionel Sambuc     return true;                                                               \
355f4a2713aSLionel Sambuc   }                                                                            \
356f4a2713aSLionel Sambuc   bool Visit##CLASS##Type(CLASS##Type *T) { return true; }
357f4a2713aSLionel Sambuc #include "clang/AST/TypeNodes.def"
358f4a2713aSLionel Sambuc 
359f4a2713aSLionel Sambuc // ---- Methods on TypeLocs ----
360f4a2713aSLionel Sambuc // FIXME: this currently just calls the matching Type methods
361f4a2713aSLionel Sambuc 
362f4a2713aSLionel Sambuc // Declare Traverse*() for all concrete TypeLoc classes.
363f4a2713aSLionel Sambuc #define ABSTRACT_TYPELOC(CLASS, BASE)
364*0a6a1f1dSLionel Sambuc #define TYPELOC(CLASS, BASE) bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
365f4a2713aSLionel Sambuc #include "clang/AST/TypeLocNodes.def"
366f4a2713aSLionel Sambuc   // The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit.
367f4a2713aSLionel Sambuc 
368f4a2713aSLionel Sambuc   // Define WalkUpFrom*() and empty Visit*() for all TypeLoc classes.
WalkUpFromTypeLoc(TypeLoc TL)369f4a2713aSLionel Sambuc   bool WalkUpFromTypeLoc(TypeLoc TL) { return getDerived().VisitTypeLoc(TL); }
VisitTypeLoc(TypeLoc TL)370f4a2713aSLionel Sambuc   bool VisitTypeLoc(TypeLoc TL) { return true; }
371f4a2713aSLionel Sambuc 
372f4a2713aSLionel Sambuc   // QualifiedTypeLoc and UnqualTypeLoc are not declared in
373f4a2713aSLionel Sambuc   // TypeNodes.def and thus need to be handled specially.
WalkUpFromQualifiedTypeLoc(QualifiedTypeLoc TL)374f4a2713aSLionel Sambuc   bool WalkUpFromQualifiedTypeLoc(QualifiedTypeLoc TL) {
375f4a2713aSLionel Sambuc     return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
376f4a2713aSLionel Sambuc   }
VisitQualifiedTypeLoc(QualifiedTypeLoc TL)377f4a2713aSLionel Sambuc   bool VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { return true; }
WalkUpFromUnqualTypeLoc(UnqualTypeLoc TL)378f4a2713aSLionel Sambuc   bool WalkUpFromUnqualTypeLoc(UnqualTypeLoc TL) {
379f4a2713aSLionel Sambuc     return getDerived().VisitUnqualTypeLoc(TL.getUnqualifiedLoc());
380f4a2713aSLionel Sambuc   }
VisitUnqualTypeLoc(UnqualTypeLoc TL)381f4a2713aSLionel Sambuc   bool VisitUnqualTypeLoc(UnqualTypeLoc TL) { return true; }
382f4a2713aSLionel Sambuc 
383f4a2713aSLionel Sambuc // Note that BASE includes trailing 'Type' which CLASS doesn't.
384f4a2713aSLionel Sambuc #define TYPE(CLASS, BASE)                                                      \
385f4a2713aSLionel Sambuc   bool WalkUpFrom##CLASS##TypeLoc(CLASS##TypeLoc TL) {                         \
386f4a2713aSLionel Sambuc     TRY_TO(WalkUpFrom##BASE##Loc(TL));                                         \
387f4a2713aSLionel Sambuc     TRY_TO(Visit##CLASS##TypeLoc(TL));                                         \
388f4a2713aSLionel Sambuc     return true;                                                               \
389f4a2713aSLionel Sambuc   }                                                                            \
390f4a2713aSLionel Sambuc   bool Visit##CLASS##TypeLoc(CLASS##TypeLoc TL) { return true; }
391f4a2713aSLionel Sambuc #include "clang/AST/TypeNodes.def"
392f4a2713aSLionel Sambuc 
393f4a2713aSLionel Sambuc // ---- Methods on Decls ----
394f4a2713aSLionel Sambuc 
395f4a2713aSLionel Sambuc // Declare Traverse*() for all concrete Decl classes.
396f4a2713aSLionel Sambuc #define ABSTRACT_DECL(DECL)
397*0a6a1f1dSLionel Sambuc #define DECL(CLASS, BASE) bool Traverse##CLASS##Decl(CLASS##Decl *D);
398f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc"
399f4a2713aSLionel Sambuc   // The above header #undefs ABSTRACT_DECL and DECL upon exit.
400f4a2713aSLionel Sambuc 
401f4a2713aSLionel Sambuc   // Define WalkUpFrom*() and empty Visit*() for all Decl classes.
WalkUpFromDecl(Decl * D)402f4a2713aSLionel Sambuc   bool WalkUpFromDecl(Decl *D) { return getDerived().VisitDecl(D); }
VisitDecl(Decl * D)403f4a2713aSLionel Sambuc   bool VisitDecl(Decl *D) { return true; }
404f4a2713aSLionel Sambuc #define DECL(CLASS, BASE)                                                      \
405f4a2713aSLionel Sambuc   bool WalkUpFrom##CLASS##Decl(CLASS##Decl *D) {                               \
406f4a2713aSLionel Sambuc     TRY_TO(WalkUpFrom##BASE(D));                                               \
407f4a2713aSLionel Sambuc     TRY_TO(Visit##CLASS##Decl(D));                                             \
408f4a2713aSLionel Sambuc     return true;                                                               \
409f4a2713aSLionel Sambuc   }                                                                            \
410f4a2713aSLionel Sambuc   bool Visit##CLASS##Decl(CLASS##Decl *D) { return true; }
411f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc"
412f4a2713aSLionel Sambuc 
413f4a2713aSLionel Sambuc private:
414f4a2713aSLionel Sambuc   // These are helper methods used by more than one Traverse* method.
415f4a2713aSLionel Sambuc   bool TraverseTemplateParameterListHelper(TemplateParameterList *TPL);
416f4a2713aSLionel Sambuc #define DEF_TRAVERSE_TMPL_INST(TMPLDECLKIND)                                   \
417f4a2713aSLionel Sambuc   bool TraverseTemplateInstantiations(TMPLDECLKIND##TemplateDecl *D);
418f4a2713aSLionel Sambuc   DEF_TRAVERSE_TMPL_INST(Class)
419f4a2713aSLionel Sambuc   DEF_TRAVERSE_TMPL_INST(Var)
420f4a2713aSLionel Sambuc   DEF_TRAVERSE_TMPL_INST(Function)
421f4a2713aSLionel Sambuc #undef DEF_TRAVERSE_TMPL_INST
422f4a2713aSLionel Sambuc   bool TraverseTemplateArgumentLocsHelper(const TemplateArgumentLoc *TAL,
423f4a2713aSLionel Sambuc                                           unsigned Count);
424f4a2713aSLionel Sambuc   bool TraverseArrayTypeLocHelper(ArrayTypeLoc TL);
425f4a2713aSLionel Sambuc   bool TraverseRecordHelper(RecordDecl *D);
426f4a2713aSLionel Sambuc   bool TraverseCXXRecordHelper(CXXRecordDecl *D);
427f4a2713aSLionel Sambuc   bool TraverseDeclaratorHelper(DeclaratorDecl *D);
428f4a2713aSLionel Sambuc   bool TraverseDeclContextHelper(DeclContext *DC);
429f4a2713aSLionel Sambuc   bool TraverseFunctionHelper(FunctionDecl *D);
430f4a2713aSLionel Sambuc   bool TraverseVarHelper(VarDecl *D);
431*0a6a1f1dSLionel Sambuc   bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
432*0a6a1f1dSLionel Sambuc   bool TraverseOMPLoopDirective(OMPLoopDirective *S);
433f4a2713aSLionel Sambuc   bool TraverseOMPClause(OMPClause *C);
434*0a6a1f1dSLionel Sambuc #define OPENMP_CLAUSE(Name, Class) bool Visit##Class(Class *C);
435f4a2713aSLionel Sambuc #include "clang/Basic/OpenMPKinds.def"
436f4a2713aSLionel Sambuc   /// \brief Process clauses with list of variables.
437*0a6a1f1dSLionel Sambuc   template <typename T> bool VisitOMPClauseList(T *Node);
438f4a2713aSLionel Sambuc 
439f4a2713aSLionel Sambuc   struct EnqueueJob {
440f4a2713aSLionel Sambuc     Stmt *S;
441f4a2713aSLionel Sambuc     Stmt::child_iterator StmtIt;
442f4a2713aSLionel Sambuc 
EnqueueJobEnqueueJob443f4a2713aSLionel Sambuc     EnqueueJob(Stmt *S) : S(S), StmtIt() {}
444f4a2713aSLionel Sambuc   };
445f4a2713aSLionel Sambuc   bool dataTraverse(Stmt *S);
446f4a2713aSLionel Sambuc   bool dataTraverseNode(Stmt *S, bool &EnqueueChildren);
447f4a2713aSLionel Sambuc };
448f4a2713aSLionel Sambuc 
449f4a2713aSLionel Sambuc template <typename Derived>
dataTraverse(Stmt * S)450f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::dataTraverse(Stmt *S) {
451f4a2713aSLionel Sambuc 
452f4a2713aSLionel Sambuc   SmallVector<EnqueueJob, 16> Queue;
453f4a2713aSLionel Sambuc   Queue.push_back(S);
454f4a2713aSLionel Sambuc 
455f4a2713aSLionel Sambuc   while (!Queue.empty()) {
456f4a2713aSLionel Sambuc     EnqueueJob &job = Queue.back();
457f4a2713aSLionel Sambuc     Stmt *CurrS = job.S;
458f4a2713aSLionel Sambuc     if (!CurrS) {
459f4a2713aSLionel Sambuc       Queue.pop_back();
460f4a2713aSLionel Sambuc       continue;
461f4a2713aSLionel Sambuc     }
462f4a2713aSLionel Sambuc 
463f4a2713aSLionel Sambuc     if (getDerived().shouldUseDataRecursionFor(CurrS)) {
464f4a2713aSLionel Sambuc       if (job.StmtIt == Stmt::child_iterator()) {
465f4a2713aSLionel Sambuc         bool EnqueueChildren = true;
466*0a6a1f1dSLionel Sambuc         if (!dataTraverseNode(CurrS, EnqueueChildren))
467*0a6a1f1dSLionel Sambuc           return false;
468f4a2713aSLionel Sambuc         if (!EnqueueChildren) {
469f4a2713aSLionel Sambuc           Queue.pop_back();
470f4a2713aSLionel Sambuc           continue;
471f4a2713aSLionel Sambuc         }
472f4a2713aSLionel Sambuc         job.StmtIt = CurrS->child_begin();
473f4a2713aSLionel Sambuc       } else {
474f4a2713aSLionel Sambuc         ++job.StmtIt;
475f4a2713aSLionel Sambuc       }
476f4a2713aSLionel Sambuc 
477f4a2713aSLionel Sambuc       if (job.StmtIt != CurrS->child_end())
478f4a2713aSLionel Sambuc         Queue.push_back(*job.StmtIt);
479f4a2713aSLionel Sambuc       else
480f4a2713aSLionel Sambuc         Queue.pop_back();
481f4a2713aSLionel Sambuc       continue;
482f4a2713aSLionel Sambuc     }
483f4a2713aSLionel Sambuc 
484f4a2713aSLionel Sambuc     Queue.pop_back();
485f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(CurrS));
486f4a2713aSLionel Sambuc   }
487f4a2713aSLionel Sambuc 
488f4a2713aSLionel Sambuc   return true;
489f4a2713aSLionel Sambuc }
490f4a2713aSLionel Sambuc 
491f4a2713aSLionel Sambuc template <typename Derived>
dataTraverseNode(Stmt * S,bool & EnqueueChildren)492f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::dataTraverseNode(Stmt *S,
493f4a2713aSLionel Sambuc                                                     bool &EnqueueChildren) {
494f4a2713aSLionel Sambuc 
495f4a2713aSLionel Sambuc // Dispatch to the corresponding WalkUpFrom* function only if the derived
496f4a2713aSLionel Sambuc // class didn't override Traverse* (and thus the traversal is trivial).
497f4a2713aSLionel Sambuc #define DISPATCH_WALK(NAME, CLASS, VAR)                                        \
498f4a2713aSLionel Sambuc   {                                                                            \
499f4a2713aSLionel Sambuc     bool (Derived::*DerivedFn)(CLASS *) = &Derived::Traverse##NAME;            \
500f4a2713aSLionel Sambuc     bool (Derived::*BaseFn)(CLASS *) = &RecursiveASTVisitor::Traverse##NAME;   \
501f4a2713aSLionel Sambuc     if (DerivedFn == BaseFn)                                                   \
502f4a2713aSLionel Sambuc       return getDerived().WalkUpFrom##NAME(static_cast<CLASS *>(VAR));         \
503f4a2713aSLionel Sambuc   }                                                                            \
504f4a2713aSLionel Sambuc   EnqueueChildren = false;                                                     \
505f4a2713aSLionel Sambuc   return getDerived().Traverse##NAME(static_cast<CLASS *>(VAR));
506f4a2713aSLionel Sambuc 
507f4a2713aSLionel Sambuc   if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
508f4a2713aSLionel Sambuc     switch (BinOp->getOpcode()) {
509f4a2713aSLionel Sambuc #define OPERATOR(NAME)                                                         \
510*0a6a1f1dSLionel Sambuc   case BO_##NAME:                                                              \
511*0a6a1f1dSLionel Sambuc     DISPATCH_WALK(Bin##NAME, BinaryOperator, S);
512f4a2713aSLionel Sambuc 
513f4a2713aSLionel Sambuc       BINOP_LIST()
514f4a2713aSLionel Sambuc #undef OPERATOR
515f4a2713aSLionel Sambuc 
516f4a2713aSLionel Sambuc #define OPERATOR(NAME)                                                         \
517f4a2713aSLionel Sambuc   case BO_##NAME##Assign:                                                      \
518f4a2713aSLionel Sambuc     DISPATCH_WALK(Bin##NAME##Assign, CompoundAssignOperator, S);
519f4a2713aSLionel Sambuc 
520f4a2713aSLionel Sambuc       CAO_LIST()
521f4a2713aSLionel Sambuc #undef OPERATOR
522f4a2713aSLionel Sambuc     }
523f4a2713aSLionel Sambuc   } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
524f4a2713aSLionel Sambuc     switch (UnOp->getOpcode()) {
525f4a2713aSLionel Sambuc #define OPERATOR(NAME)                                                         \
526*0a6a1f1dSLionel Sambuc   case UO_##NAME:                                                              \
527*0a6a1f1dSLionel Sambuc     DISPATCH_WALK(Unary##NAME, UnaryOperator, S);
528f4a2713aSLionel Sambuc 
529f4a2713aSLionel Sambuc       UNARYOP_LIST()
530f4a2713aSLionel Sambuc #undef OPERATOR
531f4a2713aSLionel Sambuc     }
532f4a2713aSLionel Sambuc   }
533f4a2713aSLionel Sambuc 
534f4a2713aSLionel Sambuc   // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
535f4a2713aSLionel Sambuc   switch (S->getStmtClass()) {
536*0a6a1f1dSLionel Sambuc   case Stmt::NoStmtClass:
537*0a6a1f1dSLionel Sambuc     break;
538f4a2713aSLionel Sambuc #define ABSTRACT_STMT(STMT)
539f4a2713aSLionel Sambuc #define STMT(CLASS, PARENT)                                                    \
540*0a6a1f1dSLionel Sambuc   case Stmt::CLASS##Class:                                                     \
541*0a6a1f1dSLionel Sambuc     DISPATCH_WALK(CLASS, CLASS, S);
542f4a2713aSLionel Sambuc #include "clang/AST/StmtNodes.inc"
543f4a2713aSLionel Sambuc   }
544f4a2713aSLionel Sambuc 
545f4a2713aSLionel Sambuc #undef DISPATCH_WALK
546f4a2713aSLionel Sambuc 
547f4a2713aSLionel Sambuc   return true;
548f4a2713aSLionel Sambuc }
549f4a2713aSLionel Sambuc 
550f4a2713aSLionel Sambuc #define DISPATCH(NAME, CLASS, VAR)                                             \
551f4a2713aSLionel Sambuc   return getDerived().Traverse##NAME(static_cast<CLASS *>(VAR))
552f4a2713aSLionel Sambuc 
553f4a2713aSLionel Sambuc template <typename Derived>
TraverseStmt(Stmt * S)554f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S) {
555f4a2713aSLionel Sambuc   if (!S)
556f4a2713aSLionel Sambuc     return true;
557f4a2713aSLionel Sambuc 
558*0a6a1f1dSLionel Sambuc #define DISPATCH_STMT(NAME, CLASS, VAR) DISPATCH(NAME, CLASS, VAR)
559*0a6a1f1dSLionel Sambuc 
560f4a2713aSLionel Sambuc   if (getDerived().shouldUseDataRecursionFor(S))
561f4a2713aSLionel Sambuc     return dataTraverse(S);
562f4a2713aSLionel Sambuc 
563f4a2713aSLionel Sambuc   // If we have a binary expr, dispatch to the subcode of the binop.  A smart
564f4a2713aSLionel Sambuc   // optimizer (e.g. LLVM) will fold this comparison into the switch stmt
565f4a2713aSLionel Sambuc   // below.
566f4a2713aSLionel Sambuc   if (BinaryOperator *BinOp = dyn_cast<BinaryOperator>(S)) {
567f4a2713aSLionel Sambuc     switch (BinOp->getOpcode()) {
568f4a2713aSLionel Sambuc #define OPERATOR(NAME)                                                         \
569*0a6a1f1dSLionel Sambuc   case BO_##NAME:                                                              \
570*0a6a1f1dSLionel Sambuc     DISPATCH_STMT(Bin##NAME, BinaryOperator, S);
571f4a2713aSLionel Sambuc 
572f4a2713aSLionel Sambuc       BINOP_LIST()
573f4a2713aSLionel Sambuc #undef OPERATOR
574f4a2713aSLionel Sambuc #undef BINOP_LIST
575f4a2713aSLionel Sambuc 
576f4a2713aSLionel Sambuc #define OPERATOR(NAME)                                                         \
577f4a2713aSLionel Sambuc   case BO_##NAME##Assign:                                                      \
578*0a6a1f1dSLionel Sambuc     DISPATCH_STMT(Bin##NAME##Assign, CompoundAssignOperator, S);
579f4a2713aSLionel Sambuc 
580f4a2713aSLionel Sambuc       CAO_LIST()
581f4a2713aSLionel Sambuc #undef OPERATOR
582f4a2713aSLionel Sambuc #undef CAO_LIST
583f4a2713aSLionel Sambuc     }
584f4a2713aSLionel Sambuc   } else if (UnaryOperator *UnOp = dyn_cast<UnaryOperator>(S)) {
585f4a2713aSLionel Sambuc     switch (UnOp->getOpcode()) {
586f4a2713aSLionel Sambuc #define OPERATOR(NAME)                                                         \
587*0a6a1f1dSLionel Sambuc   case UO_##NAME:                                                              \
588*0a6a1f1dSLionel Sambuc     DISPATCH_STMT(Unary##NAME, UnaryOperator, S);
589f4a2713aSLionel Sambuc 
590f4a2713aSLionel Sambuc       UNARYOP_LIST()
591f4a2713aSLionel Sambuc #undef OPERATOR
592f4a2713aSLionel Sambuc #undef UNARYOP_LIST
593f4a2713aSLionel Sambuc     }
594f4a2713aSLionel Sambuc   }
595f4a2713aSLionel Sambuc 
596f4a2713aSLionel Sambuc   // Top switch stmt: dispatch to TraverseFooStmt for each concrete FooStmt.
597f4a2713aSLionel Sambuc   switch (S->getStmtClass()) {
598*0a6a1f1dSLionel Sambuc   case Stmt::NoStmtClass:
599*0a6a1f1dSLionel Sambuc     break;
600f4a2713aSLionel Sambuc #define ABSTRACT_STMT(STMT)
601f4a2713aSLionel Sambuc #define STMT(CLASS, PARENT)                                                    \
602*0a6a1f1dSLionel Sambuc   case Stmt::CLASS##Class:                                                     \
603*0a6a1f1dSLionel Sambuc     DISPATCH_STMT(CLASS, CLASS, S);
604f4a2713aSLionel Sambuc #include "clang/AST/StmtNodes.inc"
605f4a2713aSLionel Sambuc   }
606f4a2713aSLionel Sambuc 
607f4a2713aSLionel Sambuc   return true;
608f4a2713aSLionel Sambuc }
609f4a2713aSLionel Sambuc 
610*0a6a1f1dSLionel Sambuc #undef DISPATCH_STMT
611*0a6a1f1dSLionel Sambuc 
612f4a2713aSLionel Sambuc template <typename Derived>
TraverseType(QualType T)613f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) {
614f4a2713aSLionel Sambuc   if (T.isNull())
615f4a2713aSLionel Sambuc     return true;
616f4a2713aSLionel Sambuc 
617f4a2713aSLionel Sambuc   switch (T->getTypeClass()) {
618f4a2713aSLionel Sambuc #define ABSTRACT_TYPE(CLASS, BASE)
619f4a2713aSLionel Sambuc #define TYPE(CLASS, BASE)                                                      \
620*0a6a1f1dSLionel Sambuc   case Type::CLASS:                                                            \
621*0a6a1f1dSLionel Sambuc     DISPATCH(CLASS##Type, CLASS##Type, const_cast<Type *>(T.getTypePtr()));
622f4a2713aSLionel Sambuc #include "clang/AST/TypeNodes.def"
623f4a2713aSLionel Sambuc   }
624f4a2713aSLionel Sambuc 
625f4a2713aSLionel Sambuc   return true;
626f4a2713aSLionel Sambuc }
627f4a2713aSLionel Sambuc 
628f4a2713aSLionel Sambuc template <typename Derived>
TraverseTypeLoc(TypeLoc TL)629f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
630f4a2713aSLionel Sambuc   if (TL.isNull())
631f4a2713aSLionel Sambuc     return true;
632f4a2713aSLionel Sambuc 
633f4a2713aSLionel Sambuc   switch (TL.getTypeLocClass()) {
634f4a2713aSLionel Sambuc #define ABSTRACT_TYPELOC(CLASS, BASE)
635f4a2713aSLionel Sambuc #define TYPELOC(CLASS, BASE)                                                   \
636f4a2713aSLionel Sambuc   case TypeLoc::CLASS:                                                         \
637f4a2713aSLionel Sambuc     return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>());
638f4a2713aSLionel Sambuc #include "clang/AST/TypeLocNodes.def"
639f4a2713aSLionel Sambuc   }
640f4a2713aSLionel Sambuc 
641f4a2713aSLionel Sambuc   return true;
642f4a2713aSLionel Sambuc }
643f4a2713aSLionel Sambuc 
644*0a6a1f1dSLionel Sambuc // Define the Traverse*Attr(Attr* A) methods
645*0a6a1f1dSLionel Sambuc #define VISITORCLASS RecursiveASTVisitor
646*0a6a1f1dSLionel Sambuc #include "clang/AST/AttrVisitor.inc"
647*0a6a1f1dSLionel Sambuc #undef VISITORCLASS
648f4a2713aSLionel Sambuc 
649f4a2713aSLionel Sambuc template <typename Derived>
TraverseDecl(Decl * D)650f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
651f4a2713aSLionel Sambuc   if (!D)
652f4a2713aSLionel Sambuc     return true;
653f4a2713aSLionel Sambuc 
654f4a2713aSLionel Sambuc   // As a syntax visitor, by default we want to ignore declarations for
655f4a2713aSLionel Sambuc   // implicit declarations (ones not typed explicitly by the user).
656f4a2713aSLionel Sambuc   if (!getDerived().shouldVisitImplicitCode() && D->isImplicit())
657f4a2713aSLionel Sambuc     return true;
658f4a2713aSLionel Sambuc 
659f4a2713aSLionel Sambuc   switch (D->getKind()) {
660f4a2713aSLionel Sambuc #define ABSTRACT_DECL(DECL)
661f4a2713aSLionel Sambuc #define DECL(CLASS, BASE)                                                      \
662*0a6a1f1dSLionel Sambuc   case Decl::CLASS:                                                            \
663*0a6a1f1dSLionel Sambuc     if (!getDerived().Traverse##CLASS##Decl(static_cast<CLASS##Decl *>(D)))    \
664*0a6a1f1dSLionel Sambuc       return false;                                                            \
665*0a6a1f1dSLionel Sambuc     break;
666f4a2713aSLionel Sambuc #include "clang/AST/DeclNodes.inc"
667f4a2713aSLionel Sambuc   }
668f4a2713aSLionel Sambuc 
669*0a6a1f1dSLionel Sambuc   // Visit any attributes attached to this declaration.
670*0a6a1f1dSLionel Sambuc   for (auto *I : D->attrs()) {
671*0a6a1f1dSLionel Sambuc     if (!getDerived().TraverseAttr(I))
672*0a6a1f1dSLionel Sambuc       return false;
673*0a6a1f1dSLionel Sambuc   }
674f4a2713aSLionel Sambuc   return true;
675f4a2713aSLionel Sambuc }
676f4a2713aSLionel Sambuc 
677f4a2713aSLionel Sambuc #undef DISPATCH
678f4a2713aSLionel Sambuc 
679f4a2713aSLionel Sambuc template <typename Derived>
TraverseNestedNameSpecifier(NestedNameSpecifier * NNS)680f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
681f4a2713aSLionel Sambuc     NestedNameSpecifier *NNS) {
682f4a2713aSLionel Sambuc   if (!NNS)
683f4a2713aSLionel Sambuc     return true;
684f4a2713aSLionel Sambuc 
685f4a2713aSLionel Sambuc   if (NNS->getPrefix())
686f4a2713aSLionel Sambuc     TRY_TO(TraverseNestedNameSpecifier(NNS->getPrefix()));
687f4a2713aSLionel Sambuc 
688f4a2713aSLionel Sambuc   switch (NNS->getKind()) {
689f4a2713aSLionel Sambuc   case NestedNameSpecifier::Identifier:
690f4a2713aSLionel Sambuc   case NestedNameSpecifier::Namespace:
691f4a2713aSLionel Sambuc   case NestedNameSpecifier::NamespaceAlias:
692f4a2713aSLionel Sambuc   case NestedNameSpecifier::Global:
693*0a6a1f1dSLionel Sambuc   case NestedNameSpecifier::Super:
694f4a2713aSLionel Sambuc     return true;
695f4a2713aSLionel Sambuc 
696f4a2713aSLionel Sambuc   case NestedNameSpecifier::TypeSpec:
697f4a2713aSLionel Sambuc   case NestedNameSpecifier::TypeSpecWithTemplate:
698f4a2713aSLionel Sambuc     TRY_TO(TraverseType(QualType(NNS->getAsType(), 0)));
699f4a2713aSLionel Sambuc   }
700f4a2713aSLionel Sambuc 
701f4a2713aSLionel Sambuc   return true;
702f4a2713aSLionel Sambuc }
703f4a2713aSLionel Sambuc 
704f4a2713aSLionel Sambuc template <typename Derived>
TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS)705f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
706f4a2713aSLionel Sambuc     NestedNameSpecifierLoc NNS) {
707f4a2713aSLionel Sambuc   if (!NNS)
708f4a2713aSLionel Sambuc     return true;
709f4a2713aSLionel Sambuc 
710f4a2713aSLionel Sambuc   if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
711f4a2713aSLionel Sambuc     TRY_TO(TraverseNestedNameSpecifierLoc(Prefix));
712f4a2713aSLionel Sambuc 
713f4a2713aSLionel Sambuc   switch (NNS.getNestedNameSpecifier()->getKind()) {
714f4a2713aSLionel Sambuc   case NestedNameSpecifier::Identifier:
715f4a2713aSLionel Sambuc   case NestedNameSpecifier::Namespace:
716f4a2713aSLionel Sambuc   case NestedNameSpecifier::NamespaceAlias:
717f4a2713aSLionel Sambuc   case NestedNameSpecifier::Global:
718*0a6a1f1dSLionel Sambuc   case NestedNameSpecifier::Super:
719f4a2713aSLionel Sambuc     return true;
720f4a2713aSLionel Sambuc 
721f4a2713aSLionel Sambuc   case NestedNameSpecifier::TypeSpec:
722f4a2713aSLionel Sambuc   case NestedNameSpecifier::TypeSpecWithTemplate:
723f4a2713aSLionel Sambuc     TRY_TO(TraverseTypeLoc(NNS.getTypeLoc()));
724f4a2713aSLionel Sambuc     break;
725f4a2713aSLionel Sambuc   }
726f4a2713aSLionel Sambuc 
727f4a2713aSLionel Sambuc   return true;
728f4a2713aSLionel Sambuc }
729f4a2713aSLionel Sambuc 
730f4a2713aSLionel Sambuc template <typename Derived>
TraverseDeclarationNameInfo(DeclarationNameInfo NameInfo)731f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseDeclarationNameInfo(
732f4a2713aSLionel Sambuc     DeclarationNameInfo NameInfo) {
733f4a2713aSLionel Sambuc   switch (NameInfo.getName().getNameKind()) {
734f4a2713aSLionel Sambuc   case DeclarationName::CXXConstructorName:
735f4a2713aSLionel Sambuc   case DeclarationName::CXXDestructorName:
736f4a2713aSLionel Sambuc   case DeclarationName::CXXConversionFunctionName:
737f4a2713aSLionel Sambuc     if (TypeSourceInfo *TSInfo = NameInfo.getNamedTypeInfo())
738f4a2713aSLionel Sambuc       TRY_TO(TraverseTypeLoc(TSInfo->getTypeLoc()));
739f4a2713aSLionel Sambuc 
740f4a2713aSLionel Sambuc     break;
741f4a2713aSLionel Sambuc 
742f4a2713aSLionel Sambuc   case DeclarationName::Identifier:
743f4a2713aSLionel Sambuc   case DeclarationName::ObjCZeroArgSelector:
744f4a2713aSLionel Sambuc   case DeclarationName::ObjCOneArgSelector:
745f4a2713aSLionel Sambuc   case DeclarationName::ObjCMultiArgSelector:
746f4a2713aSLionel Sambuc   case DeclarationName::CXXOperatorName:
747f4a2713aSLionel Sambuc   case DeclarationName::CXXLiteralOperatorName:
748f4a2713aSLionel Sambuc   case DeclarationName::CXXUsingDirective:
749f4a2713aSLionel Sambuc     break;
750f4a2713aSLionel Sambuc   }
751f4a2713aSLionel Sambuc 
752f4a2713aSLionel Sambuc   return true;
753f4a2713aSLionel Sambuc }
754f4a2713aSLionel Sambuc 
755f4a2713aSLionel Sambuc template <typename Derived>
TraverseTemplateName(TemplateName Template)756f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseTemplateName(TemplateName Template) {
757f4a2713aSLionel Sambuc   if (DependentTemplateName *DTN = Template.getAsDependentTemplateName())
758f4a2713aSLionel Sambuc     TRY_TO(TraverseNestedNameSpecifier(DTN->getQualifier()));
759f4a2713aSLionel Sambuc   else if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName())
760f4a2713aSLionel Sambuc     TRY_TO(TraverseNestedNameSpecifier(QTN->getQualifier()));
761f4a2713aSLionel Sambuc 
762f4a2713aSLionel Sambuc   return true;
763f4a2713aSLionel Sambuc }
764f4a2713aSLionel Sambuc 
765f4a2713aSLionel Sambuc template <typename Derived>
TraverseTemplateArgument(const TemplateArgument & Arg)766f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseTemplateArgument(
767f4a2713aSLionel Sambuc     const TemplateArgument &Arg) {
768f4a2713aSLionel Sambuc   switch (Arg.getKind()) {
769f4a2713aSLionel Sambuc   case TemplateArgument::Null:
770f4a2713aSLionel Sambuc   case TemplateArgument::Declaration:
771f4a2713aSLionel Sambuc   case TemplateArgument::Integral:
772f4a2713aSLionel Sambuc   case TemplateArgument::NullPtr:
773f4a2713aSLionel Sambuc     return true;
774f4a2713aSLionel Sambuc 
775f4a2713aSLionel Sambuc   case TemplateArgument::Type:
776f4a2713aSLionel Sambuc     return getDerived().TraverseType(Arg.getAsType());
777f4a2713aSLionel Sambuc 
778f4a2713aSLionel Sambuc   case TemplateArgument::Template:
779f4a2713aSLionel Sambuc   case TemplateArgument::TemplateExpansion:
780f4a2713aSLionel Sambuc     return getDerived().TraverseTemplateName(
781f4a2713aSLionel Sambuc         Arg.getAsTemplateOrTemplatePattern());
782f4a2713aSLionel Sambuc 
783f4a2713aSLionel Sambuc   case TemplateArgument::Expression:
784f4a2713aSLionel Sambuc     return getDerived().TraverseStmt(Arg.getAsExpr());
785f4a2713aSLionel Sambuc 
786f4a2713aSLionel Sambuc   case TemplateArgument::Pack:
787f4a2713aSLionel Sambuc     return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
788f4a2713aSLionel Sambuc                                                   Arg.pack_size());
789f4a2713aSLionel Sambuc   }
790f4a2713aSLionel Sambuc 
791f4a2713aSLionel Sambuc   return true;
792f4a2713aSLionel Sambuc }
793f4a2713aSLionel Sambuc 
794f4a2713aSLionel Sambuc // FIXME: no template name location?
795f4a2713aSLionel Sambuc // FIXME: no source locations for a template argument pack?
796f4a2713aSLionel Sambuc template <typename Derived>
TraverseTemplateArgumentLoc(const TemplateArgumentLoc & ArgLoc)797f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLoc(
798f4a2713aSLionel Sambuc     const TemplateArgumentLoc &ArgLoc) {
799f4a2713aSLionel Sambuc   const TemplateArgument &Arg = ArgLoc.getArgument();
800f4a2713aSLionel Sambuc 
801f4a2713aSLionel Sambuc   switch (Arg.getKind()) {
802f4a2713aSLionel Sambuc   case TemplateArgument::Null:
803f4a2713aSLionel Sambuc   case TemplateArgument::Declaration:
804f4a2713aSLionel Sambuc   case TemplateArgument::Integral:
805f4a2713aSLionel Sambuc   case TemplateArgument::NullPtr:
806f4a2713aSLionel Sambuc     return true;
807f4a2713aSLionel Sambuc 
808f4a2713aSLionel Sambuc   case TemplateArgument::Type: {
809f4a2713aSLionel Sambuc     // FIXME: how can TSI ever be NULL?
810f4a2713aSLionel Sambuc     if (TypeSourceInfo *TSI = ArgLoc.getTypeSourceInfo())
811f4a2713aSLionel Sambuc       return getDerived().TraverseTypeLoc(TSI->getTypeLoc());
812f4a2713aSLionel Sambuc     else
813f4a2713aSLionel Sambuc       return getDerived().TraverseType(Arg.getAsType());
814f4a2713aSLionel Sambuc   }
815f4a2713aSLionel Sambuc 
816f4a2713aSLionel Sambuc   case TemplateArgument::Template:
817f4a2713aSLionel Sambuc   case TemplateArgument::TemplateExpansion:
818f4a2713aSLionel Sambuc     if (ArgLoc.getTemplateQualifierLoc())
819f4a2713aSLionel Sambuc       TRY_TO(getDerived().TraverseNestedNameSpecifierLoc(
820f4a2713aSLionel Sambuc           ArgLoc.getTemplateQualifierLoc()));
821f4a2713aSLionel Sambuc     return getDerived().TraverseTemplateName(
822f4a2713aSLionel Sambuc         Arg.getAsTemplateOrTemplatePattern());
823f4a2713aSLionel Sambuc 
824f4a2713aSLionel Sambuc   case TemplateArgument::Expression:
825f4a2713aSLionel Sambuc     return getDerived().TraverseStmt(ArgLoc.getSourceExpression());
826f4a2713aSLionel Sambuc 
827f4a2713aSLionel Sambuc   case TemplateArgument::Pack:
828f4a2713aSLionel Sambuc     return getDerived().TraverseTemplateArguments(Arg.pack_begin(),
829f4a2713aSLionel Sambuc                                                   Arg.pack_size());
830f4a2713aSLionel Sambuc   }
831f4a2713aSLionel Sambuc 
832f4a2713aSLionel Sambuc   return true;
833f4a2713aSLionel Sambuc }
834f4a2713aSLionel Sambuc 
835f4a2713aSLionel Sambuc template <typename Derived>
TraverseTemplateArguments(const TemplateArgument * Args,unsigned NumArgs)836f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseTemplateArguments(
837*0a6a1f1dSLionel Sambuc     const TemplateArgument *Args, unsigned NumArgs) {
838f4a2713aSLionel Sambuc   for (unsigned I = 0; I != NumArgs; ++I) {
839f4a2713aSLionel Sambuc     TRY_TO(TraverseTemplateArgument(Args[I]));
840f4a2713aSLionel Sambuc   }
841f4a2713aSLionel Sambuc 
842f4a2713aSLionel Sambuc   return true;
843f4a2713aSLionel Sambuc }
844f4a2713aSLionel Sambuc 
845f4a2713aSLionel Sambuc template <typename Derived>
TraverseConstructorInitializer(CXXCtorInitializer * Init)846f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseConstructorInitializer(
847f4a2713aSLionel Sambuc     CXXCtorInitializer *Init) {
848f4a2713aSLionel Sambuc   if (TypeSourceInfo *TInfo = Init->getTypeSourceInfo())
849f4a2713aSLionel Sambuc     TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
850f4a2713aSLionel Sambuc 
851f4a2713aSLionel Sambuc   if (Init->isWritten() || getDerived().shouldVisitImplicitCode())
852f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(Init->getInit()));
853f4a2713aSLionel Sambuc   return true;
854f4a2713aSLionel Sambuc }
855f4a2713aSLionel Sambuc 
856f4a2713aSLionel Sambuc template <typename Derived>
857*0a6a1f1dSLionel Sambuc bool
TraverseLambdaCapture(LambdaExpr * LE,const LambdaCapture * C)858*0a6a1f1dSLionel Sambuc RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
859*0a6a1f1dSLionel Sambuc                                                     const LambdaCapture *C) {
860f4a2713aSLionel Sambuc   if (C->isInitCapture())
861f4a2713aSLionel Sambuc     TRY_TO(TraverseDecl(C->getCapturedVar()));
862f4a2713aSLionel Sambuc   return true;
863f4a2713aSLionel Sambuc }
864f4a2713aSLionel Sambuc 
865f4a2713aSLionel Sambuc template <typename Derived>
TraverseLambdaBody(LambdaExpr * LE)866f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseLambdaBody(LambdaExpr *LE) {
867f4a2713aSLionel Sambuc   TRY_TO(TraverseStmt(LE->getBody()));
868f4a2713aSLionel Sambuc   return true;
869f4a2713aSLionel Sambuc }
870f4a2713aSLionel Sambuc 
871f4a2713aSLionel Sambuc // ----------------- Type traversal -----------------
872f4a2713aSLionel Sambuc 
873f4a2713aSLionel Sambuc // This macro makes available a variable T, the passed-in type.
874f4a2713aSLionel Sambuc #define DEF_TRAVERSE_TYPE(TYPE, CODE)                                          \
875f4a2713aSLionel Sambuc   template <typename Derived>                                                  \
876f4a2713aSLionel Sambuc   bool RecursiveASTVisitor<Derived>::Traverse##TYPE(TYPE *T) {                 \
877f4a2713aSLionel Sambuc     TRY_TO(WalkUpFrom##TYPE(T));                                               \
878f4a2713aSLionel Sambuc     { CODE; }                                                                  \
879f4a2713aSLionel Sambuc     return true;                                                               \
880f4a2713aSLionel Sambuc   }
881f4a2713aSLionel Sambuc 
882f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPE(BuiltinType, {})
883f4a2713aSLionel Sambuc 
884*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPE(ComplexType, { TRY_TO(TraverseType(T->getElementType())); })
885f4a2713aSLionel Sambuc 
886*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPE(PointerType, { TRY_TO(TraverseType(T->getPointeeType())); })
887f4a2713aSLionel Sambuc 
888*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPE(BlockPointerType,
889*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseType(T->getPointeeType())); })
890f4a2713aSLionel Sambuc 
891*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPE(LValueReferenceType,
892*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseType(T->getPointeeType())); })
893f4a2713aSLionel Sambuc 
894*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPE(RValueReferenceType,
895*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseType(T->getPointeeType())); })
896f4a2713aSLionel Sambuc 
897f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPE(MemberPointerType, {
898f4a2713aSLionel Sambuc   TRY_TO(TraverseType(QualType(T->getClass(), 0)));
899f4a2713aSLionel Sambuc   TRY_TO(TraverseType(T->getPointeeType()));
900f4a2713aSLionel Sambuc })
901f4a2713aSLionel Sambuc 
902*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPE(AdjustedType, { TRY_TO(TraverseType(T->getOriginalType())); })
903f4a2713aSLionel Sambuc 
904*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPE(DecayedType, { TRY_TO(TraverseType(T->getOriginalType())); })
905f4a2713aSLionel Sambuc 
906*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPE(ConstantArrayType,
907*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseType(T->getElementType())); })
908*0a6a1f1dSLionel Sambuc 
909*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPE(IncompleteArrayType,
910*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseType(T->getElementType())); })
911f4a2713aSLionel Sambuc 
912f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPE(VariableArrayType, {
913f4a2713aSLionel Sambuc   TRY_TO(TraverseType(T->getElementType()));
914f4a2713aSLionel Sambuc   TRY_TO(TraverseStmt(T->getSizeExpr()));
915f4a2713aSLionel Sambuc })
916f4a2713aSLionel Sambuc 
917f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPE(DependentSizedArrayType, {
918f4a2713aSLionel Sambuc   TRY_TO(TraverseType(T->getElementType()));
919f4a2713aSLionel Sambuc   if (T->getSizeExpr())
920f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(T->getSizeExpr()));
921f4a2713aSLionel Sambuc })
922f4a2713aSLionel Sambuc 
923f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPE(DependentSizedExtVectorType, {
924f4a2713aSLionel Sambuc   if (T->getSizeExpr())
925f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(T->getSizeExpr()));
926f4a2713aSLionel Sambuc   TRY_TO(TraverseType(T->getElementType()));
927f4a2713aSLionel Sambuc })
928f4a2713aSLionel Sambuc 
929*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPE(VectorType, { TRY_TO(TraverseType(T->getElementType())); })
930f4a2713aSLionel Sambuc 
931*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPE(ExtVectorType, { TRY_TO(TraverseType(T->getElementType())); })
932f4a2713aSLionel Sambuc 
933*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPE(FunctionNoProtoType,
934*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseType(T->getReturnType())); })
935f4a2713aSLionel Sambuc 
936f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPE(FunctionProtoType, {
937*0a6a1f1dSLionel Sambuc   TRY_TO(TraverseType(T->getReturnType()));
938f4a2713aSLionel Sambuc 
939*0a6a1f1dSLionel Sambuc   for (const auto &A : T->param_types()) {
940*0a6a1f1dSLionel Sambuc     TRY_TO(TraverseType(A));
941f4a2713aSLionel Sambuc   }
942f4a2713aSLionel Sambuc 
943*0a6a1f1dSLionel Sambuc   for (const auto &E : T->exceptions()) {
944*0a6a1f1dSLionel Sambuc     TRY_TO(TraverseType(E));
945f4a2713aSLionel Sambuc   }
946*0a6a1f1dSLionel Sambuc 
947*0a6a1f1dSLionel Sambuc   if (Expr *NE = T->getNoexceptExpr())
948*0a6a1f1dSLionel Sambuc     TRY_TO(TraverseStmt(NE));
949f4a2713aSLionel Sambuc })
950f4a2713aSLionel Sambuc 
951f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
952f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPE(TypedefType, {})
953f4a2713aSLionel Sambuc 
954*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPE(TypeOfExprType,
955*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
956f4a2713aSLionel Sambuc 
957*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPE(TypeOfType, { TRY_TO(TraverseType(T->getUnderlyingType())); })
958f4a2713aSLionel Sambuc 
959*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPE(DecltypeType,
960*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
961f4a2713aSLionel Sambuc 
962f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPE(UnaryTransformType, {
963f4a2713aSLionel Sambuc   TRY_TO(TraverseType(T->getBaseType()));
964f4a2713aSLionel Sambuc   TRY_TO(TraverseType(T->getUnderlyingType()));
965f4a2713aSLionel Sambuc })
966f4a2713aSLionel Sambuc 
967*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPE(AutoType, { TRY_TO(TraverseType(T->getDeducedType())); })
968f4a2713aSLionel Sambuc 
969f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPE(RecordType, {})
970f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPE(EnumType, {})
971f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPE(TemplateTypeParmType, {})
972f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, {})
973f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, {})
974f4a2713aSLionel Sambuc 
975f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
976f4a2713aSLionel Sambuc   TRY_TO(TraverseTemplateName(T->getTemplateName()));
977f4a2713aSLionel Sambuc   TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
978f4a2713aSLionel Sambuc })
979f4a2713aSLionel Sambuc 
980f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPE(InjectedClassNameType, {})
981f4a2713aSLionel Sambuc 
982*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPE(AttributedType,
983*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseType(T->getModifiedType())); })
984f4a2713aSLionel Sambuc 
985*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
986f4a2713aSLionel Sambuc 
987f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPE(ElaboratedType, {
988f4a2713aSLionel Sambuc   if (T->getQualifier()) {
989f4a2713aSLionel Sambuc     TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
990f4a2713aSLionel Sambuc   }
991f4a2713aSLionel Sambuc   TRY_TO(TraverseType(T->getNamedType()));
992f4a2713aSLionel Sambuc })
993f4a2713aSLionel Sambuc 
994*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPE(DependentNameType,
995*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); })
996f4a2713aSLionel Sambuc 
997f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
998f4a2713aSLionel Sambuc   TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
999f4a2713aSLionel Sambuc   TRY_TO(TraverseTemplateArguments(T->getArgs(), T->getNumArgs()));
1000f4a2713aSLionel Sambuc })
1001f4a2713aSLionel Sambuc 
1002*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); })
1003f4a2713aSLionel Sambuc 
1004f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPE(ObjCInterfaceType, {})
1005f4a2713aSLionel Sambuc 
1006f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPE(ObjCObjectType, {
1007f4a2713aSLionel Sambuc   // We have to watch out here because an ObjCInterfaceType's base
1008f4a2713aSLionel Sambuc   // type is itself.
1009f4a2713aSLionel Sambuc   if (T->getBaseType().getTypePtr() != T)
1010f4a2713aSLionel Sambuc     TRY_TO(TraverseType(T->getBaseType()));
1011f4a2713aSLionel Sambuc })
1012f4a2713aSLionel Sambuc 
1013*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPE(ObjCObjectPointerType,
1014*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseType(T->getPointeeType())); })
1015f4a2713aSLionel Sambuc 
1016*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPE(AtomicType, { TRY_TO(TraverseType(T->getValueType())); })
1017f4a2713aSLionel Sambuc 
1018f4a2713aSLionel Sambuc #undef DEF_TRAVERSE_TYPE
1019f4a2713aSLionel Sambuc 
1020f4a2713aSLionel Sambuc // ----------------- TypeLoc traversal -----------------
1021f4a2713aSLionel Sambuc 
1022f4a2713aSLionel Sambuc // This macro makes available a variable TL, the passed-in TypeLoc.
1023f4a2713aSLionel Sambuc // If requested, it calls WalkUpFrom* for the Type in the given TypeLoc,
1024f4a2713aSLionel Sambuc // in addition to WalkUpFrom* for the TypeLoc itself, such that existing
1025f4a2713aSLionel Sambuc // clients that override the WalkUpFrom*Type() and/or Visit*Type() methods
1026f4a2713aSLionel Sambuc // continue to work.
1027f4a2713aSLionel Sambuc #define DEF_TRAVERSE_TYPELOC(TYPE, CODE)                                       \
1028f4a2713aSLionel Sambuc   template <typename Derived>                                                  \
1029f4a2713aSLionel Sambuc   bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) {       \
1030f4a2713aSLionel Sambuc     if (getDerived().shouldWalkTypesOfTypeLocs())                              \
1031f4a2713aSLionel Sambuc       TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr())));           \
1032f4a2713aSLionel Sambuc     TRY_TO(WalkUpFrom##TYPE##Loc(TL));                                         \
1033f4a2713aSLionel Sambuc     { CODE; }                                                                  \
1034f4a2713aSLionel Sambuc     return true;                                                               \
1035f4a2713aSLionel Sambuc   }
1036f4a2713aSLionel Sambuc 
1037f4a2713aSLionel Sambuc template <typename Derived>
1038*0a6a1f1dSLionel Sambuc bool
TraverseQualifiedTypeLoc(QualifiedTypeLoc TL)1039*0a6a1f1dSLionel Sambuc RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(QualifiedTypeLoc TL) {
1040f4a2713aSLionel Sambuc   // Move this over to the 'main' typeloc tree.  Note that this is a
1041f4a2713aSLionel Sambuc   // move -- we pretend that we were really looking at the unqualified
1042f4a2713aSLionel Sambuc   // typeloc all along -- rather than a recursion, so we don't follow
1043f4a2713aSLionel Sambuc   // the normal CRTP plan of going through
1044f4a2713aSLionel Sambuc   // getDerived().TraverseTypeLoc.  If we did, we'd be traversing
1045f4a2713aSLionel Sambuc   // twice for the same type (once as a QualifiedTypeLoc version of
1046f4a2713aSLionel Sambuc   // the type, once as an UnqualifiedTypeLoc version of the type),
1047f4a2713aSLionel Sambuc   // which in effect means we'd call VisitTypeLoc twice with the
1048f4a2713aSLionel Sambuc   // 'same' type.  This solves that problem, at the cost of never
1049f4a2713aSLionel Sambuc   // seeing the qualified version of the type (unless the client
1050f4a2713aSLionel Sambuc   // subclasses TraverseQualifiedTypeLoc themselves).  It's not a
1051f4a2713aSLionel Sambuc   // perfect solution.  A perfect solution probably requires making
1052f4a2713aSLionel Sambuc   // QualifiedTypeLoc a wrapper around TypeLoc -- like QualType is a
1053f4a2713aSLionel Sambuc   // wrapper around Type* -- rather than being its own class in the
1054f4a2713aSLionel Sambuc   // type hierarchy.
1055f4a2713aSLionel Sambuc   return TraverseTypeLoc(TL.getUnqualifiedLoc());
1056f4a2713aSLionel Sambuc }
1057f4a2713aSLionel Sambuc 
1058f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(BuiltinType, {})
1059f4a2713aSLionel Sambuc 
1060f4a2713aSLionel Sambuc // FIXME: ComplexTypeLoc is unfinished
1061f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(ComplexType, {
1062f4a2713aSLionel Sambuc   TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1063f4a2713aSLionel Sambuc })
1064f4a2713aSLionel Sambuc 
1065*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPELOC(PointerType,
1066*0a6a1f1dSLionel Sambuc                      { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1067f4a2713aSLionel Sambuc 
1068*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPELOC(BlockPointerType,
1069*0a6a1f1dSLionel Sambuc                      { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1070f4a2713aSLionel Sambuc 
1071*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPELOC(LValueReferenceType,
1072*0a6a1f1dSLionel Sambuc                      { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1073f4a2713aSLionel Sambuc 
1074*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPELOC(RValueReferenceType,
1075*0a6a1f1dSLionel Sambuc                      { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1076f4a2713aSLionel Sambuc 
1077f4a2713aSLionel Sambuc // FIXME: location of base class?
1078f4a2713aSLionel Sambuc // We traverse this in the type case as well, but how is it not reached through
1079f4a2713aSLionel Sambuc // the pointee type?
1080f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(MemberPointerType, {
1081f4a2713aSLionel Sambuc   TRY_TO(TraverseType(QualType(TL.getTypePtr()->getClass(), 0)));
1082f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(TL.getPointeeLoc()));
1083f4a2713aSLionel Sambuc })
1084f4a2713aSLionel Sambuc 
1085*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPELOC(AdjustedType,
1086*0a6a1f1dSLionel Sambuc                      { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
1087*0a6a1f1dSLionel Sambuc 
1088*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPELOC(DecayedType,
1089*0a6a1f1dSLionel Sambuc                      { TRY_TO(TraverseTypeLoc(TL.getOriginalLoc())); })
1090f4a2713aSLionel Sambuc 
1091f4a2713aSLionel Sambuc template <typename Derived>
TraverseArrayTypeLocHelper(ArrayTypeLoc TL)1092f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseArrayTypeLocHelper(ArrayTypeLoc TL) {
1093f4a2713aSLionel Sambuc   // This isn't available for ArrayType, but is for the ArrayTypeLoc.
1094f4a2713aSLionel Sambuc   TRY_TO(TraverseStmt(TL.getSizeExpr()));
1095f4a2713aSLionel Sambuc   return true;
1096f4a2713aSLionel Sambuc }
1097f4a2713aSLionel Sambuc 
1098f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(ConstantArrayType, {
1099f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1100f4a2713aSLionel Sambuc   return TraverseArrayTypeLocHelper(TL);
1101f4a2713aSLionel Sambuc })
1102f4a2713aSLionel Sambuc 
1103f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(IncompleteArrayType, {
1104f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1105f4a2713aSLionel Sambuc   return TraverseArrayTypeLocHelper(TL);
1106f4a2713aSLionel Sambuc })
1107f4a2713aSLionel Sambuc 
1108f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(VariableArrayType, {
1109f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1110f4a2713aSLionel Sambuc   return TraverseArrayTypeLocHelper(TL);
1111f4a2713aSLionel Sambuc })
1112f4a2713aSLionel Sambuc 
1113f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(DependentSizedArrayType, {
1114f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(TL.getElementLoc()));
1115f4a2713aSLionel Sambuc   return TraverseArrayTypeLocHelper(TL);
1116f4a2713aSLionel Sambuc })
1117f4a2713aSLionel Sambuc 
1118f4a2713aSLionel Sambuc // FIXME: order? why not size expr first?
1119f4a2713aSLionel Sambuc // FIXME: base VectorTypeLoc is unfinished
1120f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(DependentSizedExtVectorType, {
1121f4a2713aSLionel Sambuc   if (TL.getTypePtr()->getSizeExpr())
1122f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(TL.getTypePtr()->getSizeExpr()));
1123f4a2713aSLionel Sambuc   TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1124f4a2713aSLionel Sambuc })
1125f4a2713aSLionel Sambuc 
1126f4a2713aSLionel Sambuc // FIXME: VectorTypeLoc is unfinished
1127f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(VectorType, {
1128f4a2713aSLionel Sambuc   TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1129f4a2713aSLionel Sambuc })
1130f4a2713aSLionel Sambuc 
1131f4a2713aSLionel Sambuc // FIXME: size and attributes
1132f4a2713aSLionel Sambuc // FIXME: base VectorTypeLoc is unfinished
1133f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(ExtVectorType, {
1134f4a2713aSLionel Sambuc   TRY_TO(TraverseType(TL.getTypePtr()->getElementType()));
1135f4a2713aSLionel Sambuc })
1136f4a2713aSLionel Sambuc 
1137*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPELOC(FunctionNoProtoType,
1138*0a6a1f1dSLionel Sambuc                      { TRY_TO(TraverseTypeLoc(TL.getReturnLoc())); })
1139f4a2713aSLionel Sambuc 
1140f4a2713aSLionel Sambuc // FIXME: location of exception specifications (attributes?)
1141f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
1142*0a6a1f1dSLionel Sambuc   TRY_TO(TraverseTypeLoc(TL.getReturnLoc()));
1143f4a2713aSLionel Sambuc 
1144f4a2713aSLionel Sambuc   const FunctionProtoType *T = TL.getTypePtr();
1145f4a2713aSLionel Sambuc 
1146*0a6a1f1dSLionel Sambuc   for (unsigned I = 0, E = TL.getNumParams(); I != E; ++I) {
1147*0a6a1f1dSLionel Sambuc     if (TL.getParam(I)) {
1148*0a6a1f1dSLionel Sambuc       TRY_TO(TraverseDecl(TL.getParam(I)));
1149*0a6a1f1dSLionel Sambuc     } else if (I < T->getNumParams()) {
1150*0a6a1f1dSLionel Sambuc       TRY_TO(TraverseType(T->getParamType(I)));
1151f4a2713aSLionel Sambuc     }
1152f4a2713aSLionel Sambuc   }
1153f4a2713aSLionel Sambuc 
1154*0a6a1f1dSLionel Sambuc   for (const auto &E : T->exceptions()) {
1155*0a6a1f1dSLionel Sambuc     TRY_TO(TraverseType(E));
1156f4a2713aSLionel Sambuc   }
1157*0a6a1f1dSLionel Sambuc 
1158*0a6a1f1dSLionel Sambuc   if (Expr *NE = T->getNoexceptExpr())
1159*0a6a1f1dSLionel Sambuc     TRY_TO(TraverseStmt(NE));
1160f4a2713aSLionel Sambuc })
1161f4a2713aSLionel Sambuc 
1162f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
1163f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(TypedefType, {})
1164f4a2713aSLionel Sambuc 
1165*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPELOC(TypeOfExprType,
1166*0a6a1f1dSLionel Sambuc                      { TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); })
1167f4a2713aSLionel Sambuc 
1168f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(TypeOfType, {
1169f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
1170f4a2713aSLionel Sambuc })
1171f4a2713aSLionel Sambuc 
1172f4a2713aSLionel Sambuc // FIXME: location of underlying expr
1173f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(DecltypeType, {
1174f4a2713aSLionel Sambuc   TRY_TO(TraverseStmt(TL.getTypePtr()->getUnderlyingExpr()));
1175f4a2713aSLionel Sambuc })
1176f4a2713aSLionel Sambuc 
1177f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(UnaryTransformType, {
1178f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(TL.getUnderlyingTInfo()->getTypeLoc()));
1179f4a2713aSLionel Sambuc })
1180f4a2713aSLionel Sambuc 
1181f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(AutoType, {
1182f4a2713aSLionel Sambuc   TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
1183f4a2713aSLionel Sambuc })
1184f4a2713aSLionel Sambuc 
1185f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(RecordType, {})
1186f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(EnumType, {})
1187f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {})
1188f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, {})
1189f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, {})
1190f4a2713aSLionel Sambuc 
1191f4a2713aSLionel Sambuc // FIXME: use the loc for the template name?
1192f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
1193f4a2713aSLionel Sambuc   TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
1194f4a2713aSLionel Sambuc   for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
1195f4a2713aSLionel Sambuc     TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
1196f4a2713aSLionel Sambuc   }
1197f4a2713aSLionel Sambuc })
1198f4a2713aSLionel Sambuc 
1199f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(InjectedClassNameType, {})
1200f4a2713aSLionel Sambuc 
1201*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
1202f4a2713aSLionel Sambuc 
1203*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPELOC(AttributedType,
1204*0a6a1f1dSLionel Sambuc                      { TRY_TO(TraverseTypeLoc(TL.getModifiedLoc())); })
1205f4a2713aSLionel Sambuc 
1206f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(ElaboratedType, {
1207f4a2713aSLionel Sambuc   if (TL.getQualifierLoc()) {
1208f4a2713aSLionel Sambuc     TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
1209f4a2713aSLionel Sambuc   }
1210f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
1211f4a2713aSLionel Sambuc })
1212f4a2713aSLionel Sambuc 
1213f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(DependentNameType, {
1214f4a2713aSLionel Sambuc   TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
1215f4a2713aSLionel Sambuc })
1216f4a2713aSLionel Sambuc 
1217f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
1218f4a2713aSLionel Sambuc   if (TL.getQualifierLoc()) {
1219f4a2713aSLionel Sambuc     TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
1220f4a2713aSLionel Sambuc   }
1221f4a2713aSLionel Sambuc 
1222f4a2713aSLionel Sambuc   for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
1223f4a2713aSLionel Sambuc     TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
1224f4a2713aSLionel Sambuc   }
1225f4a2713aSLionel Sambuc })
1226f4a2713aSLionel Sambuc 
1227*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPELOC(PackExpansionType,
1228*0a6a1f1dSLionel Sambuc                      { TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); })
1229f4a2713aSLionel Sambuc 
1230f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(ObjCInterfaceType, {})
1231f4a2713aSLionel Sambuc 
1232f4a2713aSLionel Sambuc DEF_TRAVERSE_TYPELOC(ObjCObjectType, {
1233f4a2713aSLionel Sambuc   // We have to watch out here because an ObjCInterfaceType's base
1234f4a2713aSLionel Sambuc   // type is itself.
1235f4a2713aSLionel Sambuc   if (TL.getTypePtr()->getBaseType().getTypePtr() != TL.getTypePtr())
1236f4a2713aSLionel Sambuc     TRY_TO(TraverseTypeLoc(TL.getBaseLoc()));
1237f4a2713aSLionel Sambuc })
1238f4a2713aSLionel Sambuc 
1239*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPELOC(ObjCObjectPointerType,
1240*0a6a1f1dSLionel Sambuc                      { TRY_TO(TraverseTypeLoc(TL.getPointeeLoc())); })
1241f4a2713aSLionel Sambuc 
1242*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_TYPELOC(AtomicType, { TRY_TO(TraverseTypeLoc(TL.getValueLoc())); })
1243f4a2713aSLionel Sambuc 
1244f4a2713aSLionel Sambuc #undef DEF_TRAVERSE_TYPELOC
1245f4a2713aSLionel Sambuc 
1246f4a2713aSLionel Sambuc // ----------------- Decl traversal -----------------
1247f4a2713aSLionel Sambuc //
1248f4a2713aSLionel Sambuc // For a Decl, we automate (in the DEF_TRAVERSE_DECL macro) traversing
1249f4a2713aSLionel Sambuc // the children that come from the DeclContext associated with it.
1250f4a2713aSLionel Sambuc // Therefore each Traverse* only needs to worry about children other
1251f4a2713aSLionel Sambuc // than those.
1252f4a2713aSLionel Sambuc 
1253f4a2713aSLionel Sambuc template <typename Derived>
TraverseDeclContextHelper(DeclContext * DC)1254f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseDeclContextHelper(DeclContext *DC) {
1255f4a2713aSLionel Sambuc   if (!DC)
1256f4a2713aSLionel Sambuc     return true;
1257f4a2713aSLionel Sambuc 
1258*0a6a1f1dSLionel Sambuc   for (auto *Child : DC->decls()) {
1259f4a2713aSLionel Sambuc     // BlockDecls and CapturedDecls are traversed through BlockExprs and
1260f4a2713aSLionel Sambuc     // CapturedStmts respectively.
1261*0a6a1f1dSLionel Sambuc     if (!isa<BlockDecl>(Child) && !isa<CapturedDecl>(Child))
1262*0a6a1f1dSLionel Sambuc       TRY_TO(TraverseDecl(Child));
1263f4a2713aSLionel Sambuc   }
1264f4a2713aSLionel Sambuc 
1265f4a2713aSLionel Sambuc   return true;
1266f4a2713aSLionel Sambuc }
1267f4a2713aSLionel Sambuc 
1268f4a2713aSLionel Sambuc // This macro makes available a variable D, the passed-in decl.
1269f4a2713aSLionel Sambuc #define DEF_TRAVERSE_DECL(DECL, CODE)                                          \
1270f4a2713aSLionel Sambuc   template <typename Derived>                                                  \
1271f4a2713aSLionel Sambuc   bool RecursiveASTVisitor<Derived>::Traverse##DECL(DECL *D) {                 \
1272f4a2713aSLionel Sambuc     TRY_TO(WalkUpFrom##DECL(D));                                               \
1273f4a2713aSLionel Sambuc     { CODE; }                                                                  \
1274f4a2713aSLionel Sambuc     TRY_TO(TraverseDeclContextHelper(dyn_cast<DeclContext>(D)));               \
1275f4a2713aSLionel Sambuc     return true;                                                               \
1276f4a2713aSLionel Sambuc   }
1277f4a2713aSLionel Sambuc 
1278f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(AccessSpecDecl, {})
1279f4a2713aSLionel Sambuc 
1280f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(BlockDecl, {
1281f4a2713aSLionel Sambuc   if (TypeSourceInfo *TInfo = D->getSignatureAsWritten())
1282f4a2713aSLionel Sambuc     TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
1283f4a2713aSLionel Sambuc   TRY_TO(TraverseStmt(D->getBody()));
1284*0a6a1f1dSLionel Sambuc   for (const auto &I : D->captures()) {
1285*0a6a1f1dSLionel Sambuc     if (I.hasCopyExpr()) {
1286*0a6a1f1dSLionel Sambuc       TRY_TO(TraverseStmt(I.getCopyExpr()));
1287*0a6a1f1dSLionel Sambuc     }
1288*0a6a1f1dSLionel Sambuc   }
1289f4a2713aSLionel Sambuc   // This return statement makes sure the traversal of nodes in
1290f4a2713aSLionel Sambuc   // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
1291f4a2713aSLionel Sambuc   // is skipped - don't remove it.
1292f4a2713aSLionel Sambuc   return true;
1293f4a2713aSLionel Sambuc })
1294f4a2713aSLionel Sambuc 
1295f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(CapturedDecl, {
1296f4a2713aSLionel Sambuc   TRY_TO(TraverseStmt(D->getBody()));
1297f4a2713aSLionel Sambuc   // This return statement makes sure the traversal of nodes in
1298f4a2713aSLionel Sambuc   // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
1299f4a2713aSLionel Sambuc   // is skipped - don't remove it.
1300f4a2713aSLionel Sambuc   return true;
1301f4a2713aSLionel Sambuc })
1302f4a2713aSLionel Sambuc 
1303f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(EmptyDecl, {})
1304f4a2713aSLionel Sambuc 
1305*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_DECL(FileScopeAsmDecl,
1306*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseStmt(D->getAsmString())); })
1307f4a2713aSLionel Sambuc 
1308f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(ImportDecl, {})
1309f4a2713aSLionel Sambuc 
1310f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(FriendDecl, {
1311f4a2713aSLionel Sambuc   // Friend is either decl or a type.
1312f4a2713aSLionel Sambuc   if (D->getFriendType())
1313f4a2713aSLionel Sambuc     TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
1314f4a2713aSLionel Sambuc   else
1315f4a2713aSLionel Sambuc     TRY_TO(TraverseDecl(D->getFriendDecl()));
1316f4a2713aSLionel Sambuc })
1317f4a2713aSLionel Sambuc 
1318f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(FriendTemplateDecl, {
1319f4a2713aSLionel Sambuc   if (D->getFriendType())
1320f4a2713aSLionel Sambuc     TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
1321f4a2713aSLionel Sambuc   else
1322f4a2713aSLionel Sambuc     TRY_TO(TraverseDecl(D->getFriendDecl()));
1323f4a2713aSLionel Sambuc   for (unsigned I = 0, E = D->getNumTemplateParameters(); I < E; ++I) {
1324f4a2713aSLionel Sambuc     TemplateParameterList *TPL = D->getTemplateParameterList(I);
1325*0a6a1f1dSLionel Sambuc     for (TemplateParameterList::iterator ITPL = TPL->begin(), ETPL = TPL->end();
1326f4a2713aSLionel Sambuc          ITPL != ETPL; ++ITPL) {
1327f4a2713aSLionel Sambuc       TRY_TO(TraverseDecl(*ITPL));
1328f4a2713aSLionel Sambuc     }
1329f4a2713aSLionel Sambuc   }
1330f4a2713aSLionel Sambuc })
1331f4a2713aSLionel Sambuc 
1332f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(ClassScopeFunctionSpecializationDecl, {
1333f4a2713aSLionel Sambuc   TRY_TO(TraverseDecl(D->getSpecialization()));
1334f4a2713aSLionel Sambuc 
1335f4a2713aSLionel Sambuc   if (D->hasExplicitTemplateArgs()) {
1336f4a2713aSLionel Sambuc     const TemplateArgumentListInfo &args = D->templateArgs();
1337*0a6a1f1dSLionel Sambuc     TRY_TO(TraverseTemplateArgumentLocsHelper(args.getArgumentArray(),
1338*0a6a1f1dSLionel Sambuc                                               args.size()));
1339f4a2713aSLionel Sambuc   }
1340f4a2713aSLionel Sambuc })
1341f4a2713aSLionel Sambuc 
1342f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(LinkageSpecDecl, {})
1343f4a2713aSLionel Sambuc 
1344*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_DECL(ObjCPropertyImplDecl, {// FIXME: implement this
1345f4a2713aSLionel Sambuc                                         })
1346f4a2713aSLionel Sambuc 
1347f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(StaticAssertDecl, {
1348f4a2713aSLionel Sambuc   TRY_TO(TraverseStmt(D->getAssertExpr()));
1349f4a2713aSLionel Sambuc   TRY_TO(TraverseStmt(D->getMessage()));
1350f4a2713aSLionel Sambuc })
1351f4a2713aSLionel Sambuc 
1352*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_DECL(
1353*0a6a1f1dSLionel Sambuc     TranslationUnitDecl,
1354*0a6a1f1dSLionel Sambuc     {// Code in an unnamed namespace shows up automatically in
1355f4a2713aSLionel Sambuc      // decls_begin()/decls_end().  Thus we don't need to recurse on
1356f4a2713aSLionel Sambuc      // D->getAnonymousNamespace().
1357f4a2713aSLionel Sambuc     })
1358f4a2713aSLionel Sambuc 
1359f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(NamespaceAliasDecl, {
1360f4a2713aSLionel Sambuc   // We shouldn't traverse an aliased namespace, since it will be
1361f4a2713aSLionel Sambuc   // defined (and, therefore, traversed) somewhere else.
1362f4a2713aSLionel Sambuc   //
1363f4a2713aSLionel Sambuc   // This return statement makes sure the traversal of nodes in
1364f4a2713aSLionel Sambuc   // decls_begin()/decls_end() (done in the DEF_TRAVERSE_DECL macro)
1365f4a2713aSLionel Sambuc   // is skipped - don't remove it.
1366f4a2713aSLionel Sambuc   return true;
1367f4a2713aSLionel Sambuc })
1368f4a2713aSLionel Sambuc 
1369*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_DECL(LabelDecl, {// There is no code in a LabelDecl.
1370f4a2713aSLionel Sambuc                              })
1371f4a2713aSLionel Sambuc 
1372*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_DECL(
1373*0a6a1f1dSLionel Sambuc     NamespaceDecl,
1374*0a6a1f1dSLionel Sambuc     {// Code in an unnamed namespace shows up automatically in
1375f4a2713aSLionel Sambuc      // decls_begin()/decls_end().  Thus we don't need to recurse on
1376f4a2713aSLionel Sambuc      // D->getAnonymousNamespace().
1377f4a2713aSLionel Sambuc     })
1378f4a2713aSLionel Sambuc 
1379*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_DECL(ObjCCompatibleAliasDecl, {// FIXME: implement
1380f4a2713aSLionel Sambuc                                            })
1381f4a2713aSLionel Sambuc 
1382*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_DECL(ObjCCategoryDecl, {// FIXME: implement
1383f4a2713aSLionel Sambuc                                     })
1384f4a2713aSLionel Sambuc 
1385*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_DECL(ObjCCategoryImplDecl, {// FIXME: implement
1386f4a2713aSLionel Sambuc                                         })
1387f4a2713aSLionel Sambuc 
1388*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_DECL(ObjCImplementationDecl, {// FIXME: implement
1389f4a2713aSLionel Sambuc                                           })
1390f4a2713aSLionel Sambuc 
1391*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_DECL(ObjCInterfaceDecl, {// FIXME: implement
1392f4a2713aSLionel Sambuc                                      })
1393f4a2713aSLionel Sambuc 
1394*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_DECL(ObjCProtocolDecl, {// FIXME: implement
1395f4a2713aSLionel Sambuc                                     })
1396f4a2713aSLionel Sambuc 
1397f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(ObjCMethodDecl, {
1398*0a6a1f1dSLionel Sambuc   if (D->getReturnTypeSourceInfo()) {
1399*0a6a1f1dSLionel Sambuc     TRY_TO(TraverseTypeLoc(D->getReturnTypeSourceInfo()->getTypeLoc()));
1400f4a2713aSLionel Sambuc   }
1401*0a6a1f1dSLionel Sambuc   for (ObjCMethodDecl::param_iterator I = D->param_begin(), E = D->param_end();
1402*0a6a1f1dSLionel Sambuc        I != E; ++I) {
1403f4a2713aSLionel Sambuc     TRY_TO(TraverseDecl(*I));
1404f4a2713aSLionel Sambuc   }
1405f4a2713aSLionel Sambuc   if (D->isThisDeclarationADefinition()) {
1406f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(D->getBody()));
1407f4a2713aSLionel Sambuc   }
1408f4a2713aSLionel Sambuc   return true;
1409f4a2713aSLionel Sambuc })
1410f4a2713aSLionel Sambuc 
1411f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(ObjCPropertyDecl, {
1412*0a6a1f1dSLionel Sambuc   if (D->getTypeSourceInfo())
1413*0a6a1f1dSLionel Sambuc     TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
1414*0a6a1f1dSLionel Sambuc   else
1415*0a6a1f1dSLionel Sambuc     TRY_TO(TraverseType(D->getType()));
1416*0a6a1f1dSLionel Sambuc   return true;
1417f4a2713aSLionel Sambuc })
1418f4a2713aSLionel Sambuc 
1419f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(UsingDecl, {
1420f4a2713aSLionel Sambuc   TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1421f4a2713aSLionel Sambuc   TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
1422f4a2713aSLionel Sambuc })
1423f4a2713aSLionel Sambuc 
1424f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(UsingDirectiveDecl, {
1425f4a2713aSLionel Sambuc   TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1426f4a2713aSLionel Sambuc })
1427f4a2713aSLionel Sambuc 
1428f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(UsingShadowDecl, {})
1429f4a2713aSLionel Sambuc 
1430f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(OMPThreadPrivateDecl, {
1431*0a6a1f1dSLionel Sambuc   for (auto *I : D->varlists()) {
1432*0a6a1f1dSLionel Sambuc     TRY_TO(TraverseStmt(I));
1433f4a2713aSLionel Sambuc   }
1434f4a2713aSLionel Sambuc })
1435f4a2713aSLionel Sambuc 
1436f4a2713aSLionel Sambuc // A helper method for TemplateDecl's children.
1437f4a2713aSLionel Sambuc template <typename Derived>
TraverseTemplateParameterListHelper(TemplateParameterList * TPL)1438f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseTemplateParameterListHelper(
1439f4a2713aSLionel Sambuc     TemplateParameterList *TPL) {
1440f4a2713aSLionel Sambuc   if (TPL) {
1441f4a2713aSLionel Sambuc     for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();
1442f4a2713aSLionel Sambuc          I != E; ++I) {
1443f4a2713aSLionel Sambuc       TRY_TO(TraverseDecl(*I));
1444f4a2713aSLionel Sambuc     }
1445f4a2713aSLionel Sambuc   }
1446f4a2713aSLionel Sambuc   return true;
1447f4a2713aSLionel Sambuc }
1448f4a2713aSLionel Sambuc 
1449*0a6a1f1dSLionel Sambuc template <typename Derived>
TraverseTemplateInstantiations(ClassTemplateDecl * D)1450*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
1451*0a6a1f1dSLionel Sambuc     ClassTemplateDecl *D) {
1452*0a6a1f1dSLionel Sambuc   for (auto *SD : D->specializations()) {
1453*0a6a1f1dSLionel Sambuc     for (auto *RD : SD->redecls()) {
1454*0a6a1f1dSLionel Sambuc       // We don't want to visit injected-class-names in this traversal.
1455*0a6a1f1dSLionel Sambuc       if (cast<CXXRecordDecl>(RD)->isInjectedClassName())
1456*0a6a1f1dSLionel Sambuc         continue;
1457*0a6a1f1dSLionel Sambuc 
1458*0a6a1f1dSLionel Sambuc       switch (
1459*0a6a1f1dSLionel Sambuc           cast<ClassTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
1460*0a6a1f1dSLionel Sambuc       // Visit the implicit instantiations with the requested pattern.
1461*0a6a1f1dSLionel Sambuc       case TSK_Undeclared:
1462*0a6a1f1dSLionel Sambuc       case TSK_ImplicitInstantiation:
1463*0a6a1f1dSLionel Sambuc         TRY_TO(TraverseDecl(RD));
1464*0a6a1f1dSLionel Sambuc         break;
1465*0a6a1f1dSLionel Sambuc 
1466*0a6a1f1dSLionel Sambuc       // We don't need to do anything on an explicit instantiation
1467*0a6a1f1dSLionel Sambuc       // or explicit specialization because there will be an explicit
1468*0a6a1f1dSLionel Sambuc       // node for it elsewhere.
1469*0a6a1f1dSLionel Sambuc       case TSK_ExplicitInstantiationDeclaration:
1470*0a6a1f1dSLionel Sambuc       case TSK_ExplicitInstantiationDefinition:
1471*0a6a1f1dSLionel Sambuc       case TSK_ExplicitSpecialization:
1472*0a6a1f1dSLionel Sambuc         break;
1473*0a6a1f1dSLionel Sambuc       }
1474*0a6a1f1dSLionel Sambuc     }
1475f4a2713aSLionel Sambuc   }
1476f4a2713aSLionel Sambuc 
1477*0a6a1f1dSLionel Sambuc   return true;
1478*0a6a1f1dSLionel Sambuc }
1479*0a6a1f1dSLionel Sambuc 
1480*0a6a1f1dSLionel Sambuc template <typename Derived>
TraverseTemplateInstantiations(VarTemplateDecl * D)1481*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
1482*0a6a1f1dSLionel Sambuc     VarTemplateDecl *D) {
1483*0a6a1f1dSLionel Sambuc   for (auto *SD : D->specializations()) {
1484*0a6a1f1dSLionel Sambuc     for (auto *RD : SD->redecls()) {
1485*0a6a1f1dSLionel Sambuc       switch (
1486*0a6a1f1dSLionel Sambuc           cast<VarTemplateSpecializationDecl>(RD)->getSpecializationKind()) {
1487*0a6a1f1dSLionel Sambuc       case TSK_Undeclared:
1488*0a6a1f1dSLionel Sambuc       case TSK_ImplicitInstantiation:
1489*0a6a1f1dSLionel Sambuc         TRY_TO(TraverseDecl(RD));
1490*0a6a1f1dSLionel Sambuc         break;
1491*0a6a1f1dSLionel Sambuc 
1492*0a6a1f1dSLionel Sambuc       case TSK_ExplicitInstantiationDeclaration:
1493*0a6a1f1dSLionel Sambuc       case TSK_ExplicitInstantiationDefinition:
1494*0a6a1f1dSLionel Sambuc       case TSK_ExplicitSpecialization:
1495*0a6a1f1dSLionel Sambuc         break;
1496*0a6a1f1dSLionel Sambuc       }
1497*0a6a1f1dSLionel Sambuc     }
1498*0a6a1f1dSLionel Sambuc   }
1499*0a6a1f1dSLionel Sambuc 
1500*0a6a1f1dSLionel Sambuc   return true;
1501*0a6a1f1dSLionel Sambuc }
1502f4a2713aSLionel Sambuc 
1503f4a2713aSLionel Sambuc // A helper method for traversing the instantiations of a
1504f4a2713aSLionel Sambuc // function while skipping its specializations.
1505f4a2713aSLionel Sambuc template <typename Derived>
TraverseTemplateInstantiations(FunctionTemplateDecl * D)1506f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseTemplateInstantiations(
1507f4a2713aSLionel Sambuc     FunctionTemplateDecl *D) {
1508*0a6a1f1dSLionel Sambuc   for (auto *FD : D->specializations()) {
1509*0a6a1f1dSLionel Sambuc     for (auto *RD : FD->redecls()) {
1510*0a6a1f1dSLionel Sambuc       switch (RD->getTemplateSpecializationKind()) {
1511f4a2713aSLionel Sambuc       case TSK_Undeclared:
1512f4a2713aSLionel Sambuc       case TSK_ImplicitInstantiation:
1513f4a2713aSLionel Sambuc         // We don't know what kind of FunctionDecl this is.
1514*0a6a1f1dSLionel Sambuc         TRY_TO(TraverseDecl(RD));
1515f4a2713aSLionel Sambuc         break;
1516f4a2713aSLionel Sambuc 
1517f4a2713aSLionel Sambuc       // FIXME: For now traverse explicit instantiations here. Change that
1518f4a2713aSLionel Sambuc       // once they are represented as dedicated nodes in the AST.
1519f4a2713aSLionel Sambuc       case TSK_ExplicitInstantiationDeclaration:
1520f4a2713aSLionel Sambuc       case TSK_ExplicitInstantiationDefinition:
1521*0a6a1f1dSLionel Sambuc         TRY_TO(TraverseDecl(RD));
1522f4a2713aSLionel Sambuc         break;
1523f4a2713aSLionel Sambuc 
1524f4a2713aSLionel Sambuc       case TSK_ExplicitSpecialization:
1525f4a2713aSLionel Sambuc         break;
1526f4a2713aSLionel Sambuc       }
1527f4a2713aSLionel Sambuc     }
1528*0a6a1f1dSLionel Sambuc   }
1529f4a2713aSLionel Sambuc 
1530f4a2713aSLionel Sambuc   return true;
1531f4a2713aSLionel Sambuc }
1532f4a2713aSLionel Sambuc 
1533f4a2713aSLionel Sambuc // This macro unifies the traversal of class, variable and function
1534f4a2713aSLionel Sambuc // template declarations.
1535f4a2713aSLionel Sambuc #define DEF_TRAVERSE_TMPL_DECL(TMPLDECLKIND)                                   \
1536f4a2713aSLionel Sambuc   DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateDecl, {                              \
1537f4a2713aSLionel Sambuc     TRY_TO(TraverseDecl(D->getTemplatedDecl()));                               \
1538f4a2713aSLionel Sambuc     TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));   \
1539f4a2713aSLionel Sambuc                                                                                \
1540*0a6a1f1dSLionel Sambuc     /* By default, we do not traverse the instantiations of                    \
1541*0a6a1f1dSLionel Sambuc        class templates since they do not appear in the user code. The          \
1542*0a6a1f1dSLionel Sambuc        following code optionally traverses them.                               \
1543*0a6a1f1dSLionel Sambuc                                                                                \
1544*0a6a1f1dSLionel Sambuc        We only traverse the class instantiations when we see the canonical     \
1545f4a2713aSLionel Sambuc        declaration of the template, to ensure we only visit them once. */      \
1546f4a2713aSLionel Sambuc     if (getDerived().shouldVisitTemplateInstantiations() &&                    \
1547f4a2713aSLionel Sambuc         D == D->getCanonicalDecl())                                            \
1548f4a2713aSLionel Sambuc       TRY_TO(TraverseTemplateInstantiations(D));                               \
1549f4a2713aSLionel Sambuc                                                                                \
1550*0a6a1f1dSLionel Sambuc     /* Note that getInstantiatedFromMemberTemplate() is just a link            \
1551*0a6a1f1dSLionel Sambuc        from a template instantiation back to the template from which           \
1552f4a2713aSLionel Sambuc        it was instantiated, and thus should not be traversed. */               \
1553f4a2713aSLionel Sambuc   })
1554f4a2713aSLionel Sambuc 
1555f4a2713aSLionel Sambuc DEF_TRAVERSE_TMPL_DECL(Class)
DEF_TRAVERSE_TMPL_DECL(Var)1556f4a2713aSLionel Sambuc DEF_TRAVERSE_TMPL_DECL(Var)
1557f4a2713aSLionel Sambuc DEF_TRAVERSE_TMPL_DECL(Function)
1558f4a2713aSLionel Sambuc 
1559f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(TemplateTemplateParmDecl, {
1560f4a2713aSLionel Sambuc   // D is the "T" in something like
1561f4a2713aSLionel Sambuc   //   template <template <typename> class T> class container { };
1562f4a2713aSLionel Sambuc   TRY_TO(TraverseDecl(D->getTemplatedDecl()));
1563f4a2713aSLionel Sambuc   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) {
1564f4a2713aSLionel Sambuc     TRY_TO(TraverseTemplateArgumentLoc(D->getDefaultArgument()));
1565f4a2713aSLionel Sambuc   }
1566f4a2713aSLionel Sambuc   TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
1567f4a2713aSLionel Sambuc })
1568f4a2713aSLionel Sambuc 
1569f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(TemplateTypeParmDecl, {
1570f4a2713aSLionel Sambuc   // D is the "T" in something like "template<typename T> class vector;"
1571f4a2713aSLionel Sambuc   if (D->getTypeForDecl())
1572f4a2713aSLionel Sambuc     TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
1573f4a2713aSLionel Sambuc   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
1574f4a2713aSLionel Sambuc     TRY_TO(TraverseTypeLoc(D->getDefaultArgumentInfo()->getTypeLoc()));
1575f4a2713aSLionel Sambuc })
1576f4a2713aSLionel Sambuc 
1577f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(TypedefDecl, {
1578f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
1579f4a2713aSLionel Sambuc   // We shouldn't traverse D->getTypeForDecl(); it's a result of
1580f4a2713aSLionel Sambuc   // declaring the typedef, not something that was written in the
1581f4a2713aSLionel Sambuc   // source.
1582f4a2713aSLionel Sambuc })
1583f4a2713aSLionel Sambuc 
1584f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(TypeAliasDecl, {
1585f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
1586f4a2713aSLionel Sambuc   // We shouldn't traverse D->getTypeForDecl(); it's a result of
1587f4a2713aSLionel Sambuc   // declaring the type alias, not something that was written in the
1588f4a2713aSLionel Sambuc   // source.
1589f4a2713aSLionel Sambuc })
1590f4a2713aSLionel Sambuc 
1591f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(TypeAliasTemplateDecl, {
1592f4a2713aSLionel Sambuc   TRY_TO(TraverseDecl(D->getTemplatedDecl()));
1593f4a2713aSLionel Sambuc   TRY_TO(TraverseTemplateParameterListHelper(D->getTemplateParameters()));
1594f4a2713aSLionel Sambuc })
1595f4a2713aSLionel Sambuc 
1596f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(UnresolvedUsingTypenameDecl, {
1597f4a2713aSLionel Sambuc   // A dependent using declaration which was marked with 'typename'.
1598f4a2713aSLionel Sambuc   //   template<class T> class A : public B<T> { using typename B<T>::foo; };
1599f4a2713aSLionel Sambuc   TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1600f4a2713aSLionel Sambuc   // We shouldn't traverse D->getTypeForDecl(); it's a result of
1601f4a2713aSLionel Sambuc   // declaring the type, not something that was written in the
1602f4a2713aSLionel Sambuc   // source.
1603f4a2713aSLionel Sambuc })
1604f4a2713aSLionel Sambuc 
1605f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(EnumDecl, {
1606f4a2713aSLionel Sambuc   if (D->getTypeForDecl())
1607f4a2713aSLionel Sambuc     TRY_TO(TraverseType(QualType(D->getTypeForDecl(), 0)));
1608f4a2713aSLionel Sambuc 
1609f4a2713aSLionel Sambuc   TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1610f4a2713aSLionel Sambuc   // The enumerators are already traversed by
1611f4a2713aSLionel Sambuc   // decls_begin()/decls_end().
1612f4a2713aSLionel Sambuc })
1613f4a2713aSLionel Sambuc 
1614f4a2713aSLionel Sambuc // Helper methods for RecordDecl and its children.
1615f4a2713aSLionel Sambuc template <typename Derived>
1616*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseRecordHelper(RecordDecl *D) {
1617f4a2713aSLionel Sambuc   // We shouldn't traverse D->getTypeForDecl(); it's a result of
1618f4a2713aSLionel Sambuc   // declaring the type, not something that was written in the source.
1619f4a2713aSLionel Sambuc 
1620f4a2713aSLionel Sambuc   TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1621f4a2713aSLionel Sambuc   return true;
1622f4a2713aSLionel Sambuc }
1623f4a2713aSLionel Sambuc 
1624f4a2713aSLionel Sambuc template <typename Derived>
TraverseCXXRecordHelper(CXXRecordDecl * D)1625*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseCXXRecordHelper(CXXRecordDecl *D) {
1626f4a2713aSLionel Sambuc   if (!TraverseRecordHelper(D))
1627f4a2713aSLionel Sambuc     return false;
1628f4a2713aSLionel Sambuc   if (D->isCompleteDefinition()) {
1629*0a6a1f1dSLionel Sambuc     for (const auto &I : D->bases()) {
1630*0a6a1f1dSLionel Sambuc       TRY_TO(TraverseTypeLoc(I.getTypeSourceInfo()->getTypeLoc()));
1631f4a2713aSLionel Sambuc     }
1632f4a2713aSLionel Sambuc     // We don't traverse the friends or the conversions, as they are
1633f4a2713aSLionel Sambuc     // already in decls_begin()/decls_end().
1634f4a2713aSLionel Sambuc   }
1635f4a2713aSLionel Sambuc   return true;
1636f4a2713aSLionel Sambuc }
1637f4a2713aSLionel Sambuc 
1638*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); })
1639f4a2713aSLionel Sambuc 
1640*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
1641f4a2713aSLionel Sambuc 
1642f4a2713aSLionel Sambuc #define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND)                              \
1643f4a2713aSLionel Sambuc   DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, {                \
1644*0a6a1f1dSLionel Sambuc     /* For implicit instantiations ("set<int> x;"), we don't want to           \
1645*0a6a1f1dSLionel Sambuc        recurse at all, since the instatiated template isn't written in         \
1646*0a6a1f1dSLionel Sambuc        the source code anywhere.  (Note the instatiated *type* --              \
1647*0a6a1f1dSLionel Sambuc        set<int> -- is written, and will still get a callback of                \
1648*0a6a1f1dSLionel Sambuc        TemplateSpecializationType).  For explicit instantiations               \
1649*0a6a1f1dSLionel Sambuc        ("template set<int>;"), we do need a callback, since this               \
1650*0a6a1f1dSLionel Sambuc        is the only callback that's made for this instantiation.                \
1651f4a2713aSLionel Sambuc        We use getTypeAsWritten() to distinguish. */                            \
1652f4a2713aSLionel Sambuc     if (TypeSourceInfo *TSI = D->getTypeAsWritten())                           \
1653f4a2713aSLionel Sambuc       TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));                              \
1654f4a2713aSLionel Sambuc                                                                                \
1655f4a2713aSLionel Sambuc     if (!getDerived().shouldVisitTemplateInstantiations() &&                   \
1656f4a2713aSLionel Sambuc         D->getTemplateSpecializationKind() != TSK_ExplicitSpecialization)      \
1657*0a6a1f1dSLionel Sambuc       /* Returning from here skips traversing the                              \
1658*0a6a1f1dSLionel Sambuc          declaration context of the *TemplateSpecializationDecl                \
1659*0a6a1f1dSLionel Sambuc          (embedded in the DEF_TRAVERSE_DECL() macro)                           \
1660f4a2713aSLionel Sambuc          which contains the instantiated members of the template. */           \
1661f4a2713aSLionel Sambuc       return true;                                                             \
1662f4a2713aSLionel Sambuc   })
1663f4a2713aSLionel Sambuc 
DEF_TRAVERSE_TMPL_SPEC_DECL(Class)1664f4a2713aSLionel Sambuc DEF_TRAVERSE_TMPL_SPEC_DECL(Class)
1665f4a2713aSLionel Sambuc DEF_TRAVERSE_TMPL_SPEC_DECL(Var)
1666f4a2713aSLionel Sambuc 
1667f4a2713aSLionel Sambuc template <typename Derived>
1668f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
1669f4a2713aSLionel Sambuc     const TemplateArgumentLoc *TAL, unsigned Count) {
1670f4a2713aSLionel Sambuc   for (unsigned I = 0; I < Count; ++I) {
1671f4a2713aSLionel Sambuc     TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
1672f4a2713aSLionel Sambuc   }
1673f4a2713aSLionel Sambuc   return true;
1674f4a2713aSLionel Sambuc }
1675f4a2713aSLionel Sambuc 
1676f4a2713aSLionel Sambuc #define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND)               \
1677f4a2713aSLionel Sambuc   DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, {         \
1678f4a2713aSLionel Sambuc     /* The partial specialization. */                                          \
1679f4a2713aSLionel Sambuc     if (TemplateParameterList *TPL = D->getTemplateParameters()) {             \
1680f4a2713aSLionel Sambuc       for (TemplateParameterList::iterator I = TPL->begin(), E = TPL->end();   \
1681f4a2713aSLionel Sambuc            I != E; ++I) {                                                      \
1682f4a2713aSLionel Sambuc         TRY_TO(TraverseDecl(*I));                                              \
1683f4a2713aSLionel Sambuc       }                                                                        \
1684f4a2713aSLionel Sambuc     }                                                                          \
1685f4a2713aSLionel Sambuc     /* The args that remains unspecialized. */                                 \
1686f4a2713aSLionel Sambuc     TRY_TO(TraverseTemplateArgumentLocsHelper(                                 \
1687f4a2713aSLionel Sambuc         D->getTemplateArgsAsWritten()->getTemplateArgs(),                      \
1688f4a2713aSLionel Sambuc         D->getTemplateArgsAsWritten()->NumTemplateArgs));                      \
1689f4a2713aSLionel Sambuc                                                                                \
1690*0a6a1f1dSLionel Sambuc     /* Don't need the *TemplatePartialSpecializationHelper, even               \
1691*0a6a1f1dSLionel Sambuc        though that's our parent class -- we already visit all the              \
1692f4a2713aSLionel Sambuc        template args here. */                                                  \
1693f4a2713aSLionel Sambuc     TRY_TO(Traverse##DECLKIND##Helper(D));                                     \
1694f4a2713aSLionel Sambuc                                                                                \
1695f4a2713aSLionel Sambuc     /* Instantiations will have been visited with the primary template. */     \
1696f4a2713aSLionel Sambuc   })
1697f4a2713aSLionel Sambuc 
DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Class,CXXRecord)1698f4a2713aSLionel Sambuc DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Class, CXXRecord)
1699f4a2713aSLionel Sambuc DEF_TRAVERSE_TMPL_PART_SPEC_DECL(Var, Var)
1700f4a2713aSLionel Sambuc 
1701*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_DECL(EnumConstantDecl, { TRY_TO(TraverseStmt(D->getInitExpr())); })
1702f4a2713aSLionel Sambuc 
1703f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(UnresolvedUsingValueDecl, {
1704f4a2713aSLionel Sambuc   // Like UnresolvedUsingTypenameDecl, but without the 'typename':
1705f4a2713aSLionel Sambuc   //    template <class T> Class A : public Base<T> { using Base<T>::foo; };
1706f4a2713aSLionel Sambuc   TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1707f4a2713aSLionel Sambuc   TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
1708f4a2713aSLionel Sambuc })
1709f4a2713aSLionel Sambuc 
1710f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(IndirectFieldDecl, {})
1711f4a2713aSLionel Sambuc 
1712f4a2713aSLionel Sambuc template <typename Derived>
1713f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseDeclaratorHelper(DeclaratorDecl *D) {
1714f4a2713aSLionel Sambuc   TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1715f4a2713aSLionel Sambuc   if (D->getTypeSourceInfo())
1716f4a2713aSLionel Sambuc     TRY_TO(TraverseTypeLoc(D->getTypeSourceInfo()->getTypeLoc()));
1717f4a2713aSLionel Sambuc   else
1718f4a2713aSLionel Sambuc     TRY_TO(TraverseType(D->getType()));
1719f4a2713aSLionel Sambuc   return true;
1720f4a2713aSLionel Sambuc }
1721f4a2713aSLionel Sambuc 
1722*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_DECL(MSPropertyDecl, { TRY_TO(TraverseDeclaratorHelper(D)); })
1723f4a2713aSLionel Sambuc 
1724f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(FieldDecl, {
1725f4a2713aSLionel Sambuc   TRY_TO(TraverseDeclaratorHelper(D));
1726f4a2713aSLionel Sambuc   if (D->isBitField())
1727f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(D->getBitWidth()));
1728f4a2713aSLionel Sambuc   else if (D->hasInClassInitializer())
1729f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(D->getInClassInitializer()));
1730f4a2713aSLionel Sambuc })
1731f4a2713aSLionel Sambuc 
1732f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(ObjCAtDefsFieldDecl, {
1733f4a2713aSLionel Sambuc   TRY_TO(TraverseDeclaratorHelper(D));
1734f4a2713aSLionel Sambuc   if (D->isBitField())
1735f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(D->getBitWidth()));
1736f4a2713aSLionel Sambuc   // FIXME: implement the rest.
1737f4a2713aSLionel Sambuc })
1738f4a2713aSLionel Sambuc 
1739f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(ObjCIvarDecl, {
1740f4a2713aSLionel Sambuc   TRY_TO(TraverseDeclaratorHelper(D));
1741f4a2713aSLionel Sambuc   if (D->isBitField())
1742f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(D->getBitWidth()));
1743f4a2713aSLionel Sambuc   // FIXME: implement the rest.
1744f4a2713aSLionel Sambuc })
1745f4a2713aSLionel Sambuc 
1746f4a2713aSLionel Sambuc template <typename Derived>
TraverseFunctionHelper(FunctionDecl * D)1747f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseFunctionHelper(FunctionDecl *D) {
1748f4a2713aSLionel Sambuc   TRY_TO(TraverseNestedNameSpecifierLoc(D->getQualifierLoc()));
1749f4a2713aSLionel Sambuc   TRY_TO(TraverseDeclarationNameInfo(D->getNameInfo()));
1750f4a2713aSLionel Sambuc 
1751f4a2713aSLionel Sambuc   // If we're an explicit template specialization, iterate over the
1752f4a2713aSLionel Sambuc   // template args that were explicitly specified.  If we were doing
1753f4a2713aSLionel Sambuc   // this in typing order, we'd do it between the return type and
1754f4a2713aSLionel Sambuc   // the function args, but both are handled by the FunctionTypeLoc
1755f4a2713aSLionel Sambuc   // above, so we have to choose one side.  I've decided to do before.
1756f4a2713aSLionel Sambuc   if (const FunctionTemplateSpecializationInfo *FTSI =
1757f4a2713aSLionel Sambuc           D->getTemplateSpecializationInfo()) {
1758f4a2713aSLionel Sambuc     if (FTSI->getTemplateSpecializationKind() != TSK_Undeclared &&
1759f4a2713aSLionel Sambuc         FTSI->getTemplateSpecializationKind() != TSK_ImplicitInstantiation) {
1760f4a2713aSLionel Sambuc       // A specialization might not have explicit template arguments if it has
1761f4a2713aSLionel Sambuc       // a templated return type and concrete arguments.
1762f4a2713aSLionel Sambuc       if (const ASTTemplateArgumentListInfo *TALI =
1763f4a2713aSLionel Sambuc               FTSI->TemplateArgumentsAsWritten) {
1764f4a2713aSLionel Sambuc         TRY_TO(TraverseTemplateArgumentLocsHelper(TALI->getTemplateArgs(),
1765f4a2713aSLionel Sambuc                                                   TALI->NumTemplateArgs));
1766f4a2713aSLionel Sambuc       }
1767f4a2713aSLionel Sambuc     }
1768f4a2713aSLionel Sambuc   }
1769f4a2713aSLionel Sambuc 
1770f4a2713aSLionel Sambuc   // Visit the function type itself, which can be either
1771f4a2713aSLionel Sambuc   // FunctionNoProtoType or FunctionProtoType, or a typedef.  This
1772f4a2713aSLionel Sambuc   // also covers the return type and the function parameters,
1773f4a2713aSLionel Sambuc   // including exception specifications.
1774f4a2713aSLionel Sambuc   if (TypeSourceInfo *TSI = D->getTypeSourceInfo()) {
1775f4a2713aSLionel Sambuc     TRY_TO(TraverseTypeLoc(TSI->getTypeLoc()));
1776f4a2713aSLionel Sambuc   } else if (getDerived().shouldVisitImplicitCode()) {
1777f4a2713aSLionel Sambuc     // Visit parameter variable declarations of the implicit function
1778f4a2713aSLionel Sambuc     // if the traverser is visiting implicit code. Parameter variable
1779f4a2713aSLionel Sambuc     // declarations do not have valid TypeSourceInfo, so to visit them
1780f4a2713aSLionel Sambuc     // we need to traverse the declarations explicitly.
1781f4a2713aSLionel Sambuc     for (FunctionDecl::param_const_iterator I = D->param_begin(),
1782*0a6a1f1dSLionel Sambuc                                             E = D->param_end();
1783*0a6a1f1dSLionel Sambuc          I != E; ++I)
1784f4a2713aSLionel Sambuc       TRY_TO(TraverseDecl(*I));
1785f4a2713aSLionel Sambuc   }
1786f4a2713aSLionel Sambuc 
1787f4a2713aSLionel Sambuc   if (CXXConstructorDecl *Ctor = dyn_cast<CXXConstructorDecl>(D)) {
1788f4a2713aSLionel Sambuc     // Constructor initializers.
1789*0a6a1f1dSLionel Sambuc     for (auto *I : Ctor->inits()) {
1790*0a6a1f1dSLionel Sambuc       TRY_TO(TraverseConstructorInitializer(I));
1791f4a2713aSLionel Sambuc     }
1792f4a2713aSLionel Sambuc   }
1793f4a2713aSLionel Sambuc 
1794f4a2713aSLionel Sambuc   if (D->isThisDeclarationADefinition()) {
1795f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(D->getBody())); // Function body.
1796f4a2713aSLionel Sambuc   }
1797f4a2713aSLionel Sambuc   return true;
1798f4a2713aSLionel Sambuc }
1799f4a2713aSLionel Sambuc 
1800f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(FunctionDecl, {
1801f4a2713aSLionel Sambuc   // We skip decls_begin/decls_end, which are already covered by
1802f4a2713aSLionel Sambuc   // TraverseFunctionHelper().
1803f4a2713aSLionel Sambuc   return TraverseFunctionHelper(D);
1804f4a2713aSLionel Sambuc })
1805f4a2713aSLionel Sambuc 
1806f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(CXXMethodDecl, {
1807f4a2713aSLionel Sambuc   // We skip decls_begin/decls_end, which are already covered by
1808f4a2713aSLionel Sambuc   // TraverseFunctionHelper().
1809f4a2713aSLionel Sambuc   return TraverseFunctionHelper(D);
1810f4a2713aSLionel Sambuc })
1811f4a2713aSLionel Sambuc 
1812f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(CXXConstructorDecl, {
1813f4a2713aSLionel Sambuc   // We skip decls_begin/decls_end, which are already covered by
1814f4a2713aSLionel Sambuc   // TraverseFunctionHelper().
1815f4a2713aSLionel Sambuc   return TraverseFunctionHelper(D);
1816f4a2713aSLionel Sambuc })
1817f4a2713aSLionel Sambuc 
1818f4a2713aSLionel Sambuc // CXXConversionDecl is the declaration of a type conversion operator.
1819f4a2713aSLionel Sambuc // It's not a cast expression.
1820f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(CXXConversionDecl, {
1821f4a2713aSLionel Sambuc   // We skip decls_begin/decls_end, which are already covered by
1822f4a2713aSLionel Sambuc   // TraverseFunctionHelper().
1823f4a2713aSLionel Sambuc   return TraverseFunctionHelper(D);
1824f4a2713aSLionel Sambuc })
1825f4a2713aSLionel Sambuc 
1826f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(CXXDestructorDecl, {
1827f4a2713aSLionel Sambuc   // We skip decls_begin/decls_end, which are already covered by
1828f4a2713aSLionel Sambuc   // TraverseFunctionHelper().
1829f4a2713aSLionel Sambuc   return TraverseFunctionHelper(D);
1830f4a2713aSLionel Sambuc })
1831f4a2713aSLionel Sambuc 
1832f4a2713aSLionel Sambuc template <typename Derived>
TraverseVarHelper(VarDecl * D)1833f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseVarHelper(VarDecl *D) {
1834f4a2713aSLionel Sambuc   TRY_TO(TraverseDeclaratorHelper(D));
1835f4a2713aSLionel Sambuc   // Default params are taken care of when we traverse the ParmVarDecl.
1836f4a2713aSLionel Sambuc   if (!isa<ParmVarDecl>(D) &&
1837f4a2713aSLionel Sambuc       (!D->isCXXForRangeDecl() || getDerived().shouldVisitImplicitCode()))
1838f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(D->getInit()));
1839f4a2713aSLionel Sambuc   return true;
1840f4a2713aSLionel Sambuc }
1841f4a2713aSLionel Sambuc 
1842*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_DECL(VarDecl, { TRY_TO(TraverseVarHelper(D)); })
1843f4a2713aSLionel Sambuc 
1844*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_DECL(ImplicitParamDecl, { TRY_TO(TraverseVarHelper(D)); })
1845f4a2713aSLionel Sambuc 
1846f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(NonTypeTemplateParmDecl, {
1847f4a2713aSLionel Sambuc   // A non-type template parameter, e.g. "S" in template<int S> class Foo ...
1848f4a2713aSLionel Sambuc   TRY_TO(TraverseDeclaratorHelper(D));
1849f4a2713aSLionel Sambuc   if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited())
1850f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(D->getDefaultArgument()));
1851f4a2713aSLionel Sambuc })
1852f4a2713aSLionel Sambuc 
1853f4a2713aSLionel Sambuc DEF_TRAVERSE_DECL(ParmVarDecl, {
1854f4a2713aSLionel Sambuc   TRY_TO(TraverseVarHelper(D));
1855f4a2713aSLionel Sambuc 
1856*0a6a1f1dSLionel Sambuc   if (D->hasDefaultArg() && D->hasUninstantiatedDefaultArg() &&
1857f4a2713aSLionel Sambuc       !D->hasUnparsedDefaultArg())
1858f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(D->getUninstantiatedDefaultArg()));
1859f4a2713aSLionel Sambuc 
1860*0a6a1f1dSLionel Sambuc   if (D->hasDefaultArg() && !D->hasUninstantiatedDefaultArg() &&
1861f4a2713aSLionel Sambuc       !D->hasUnparsedDefaultArg())
1862f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(D->getDefaultArg()));
1863f4a2713aSLionel Sambuc })
1864f4a2713aSLionel Sambuc 
1865f4a2713aSLionel Sambuc #undef DEF_TRAVERSE_DECL
1866f4a2713aSLionel Sambuc 
1867f4a2713aSLionel Sambuc // ----------------- Stmt traversal -----------------
1868f4a2713aSLionel Sambuc //
1869f4a2713aSLionel Sambuc // For stmts, we automate (in the DEF_TRAVERSE_STMT macro) iterating
1870f4a2713aSLionel Sambuc // over the children defined in children() (every stmt defines these,
1871f4a2713aSLionel Sambuc // though sometimes the range is empty).  Each individual Traverse*
1872f4a2713aSLionel Sambuc // method only needs to worry about children other than those.  To see
1873f4a2713aSLionel Sambuc // what children() does for a given class, see, e.g.,
1874f4a2713aSLionel Sambuc //   http://clang.llvm.org/doxygen/Stmt_8cpp_source.html
1875f4a2713aSLionel Sambuc 
1876f4a2713aSLionel Sambuc // This macro makes available a variable S, the passed-in stmt.
1877f4a2713aSLionel Sambuc #define DEF_TRAVERSE_STMT(STMT, CODE)                                          \
1878f4a2713aSLionel Sambuc   template <typename Derived>                                                  \
1879f4a2713aSLionel Sambuc   bool RecursiveASTVisitor<Derived>::Traverse##STMT(STMT *S) {                 \
1880f4a2713aSLionel Sambuc     TRY_TO(WalkUpFrom##STMT(S));                                               \
1881f4a2713aSLionel Sambuc     { CODE; }                                                                  \
1882f4a2713aSLionel Sambuc     for (Stmt::child_range range = S->children(); range; ++range) {            \
1883f4a2713aSLionel Sambuc       TRY_TO(TraverseStmt(*range));                                            \
1884f4a2713aSLionel Sambuc     }                                                                          \
1885f4a2713aSLionel Sambuc     return true;                                                               \
1886f4a2713aSLionel Sambuc   }
1887f4a2713aSLionel Sambuc 
1888f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(GCCAsmStmt, {
1889f4a2713aSLionel Sambuc   TRY_TO(TraverseStmt(S->getAsmString()));
1890f4a2713aSLionel Sambuc   for (unsigned I = 0, E = S->getNumInputs(); I < E; ++I) {
1891f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(S->getInputConstraintLiteral(I)));
1892f4a2713aSLionel Sambuc   }
1893f4a2713aSLionel Sambuc   for (unsigned I = 0, E = S->getNumOutputs(); I < E; ++I) {
1894f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(S->getOutputConstraintLiteral(I)));
1895f4a2713aSLionel Sambuc   }
1896f4a2713aSLionel Sambuc   for (unsigned I = 0, E = S->getNumClobbers(); I < E; ++I) {
1897f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(S->getClobberStringLiteral(I)));
1898f4a2713aSLionel Sambuc   }
1899f4a2713aSLionel Sambuc   // children() iterates over inputExpr and outputExpr.
1900f4a2713aSLionel Sambuc })
1901f4a2713aSLionel Sambuc 
1902*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(
1903*0a6a1f1dSLionel Sambuc     MSAsmStmt,
1904*0a6a1f1dSLionel Sambuc     {// FIXME: MS Asm doesn't currently parse Constraints, Clobbers, etc.  Once
1905f4a2713aSLionel Sambuc      // added this needs to be implemented.
1906f4a2713aSLionel Sambuc     })
1907f4a2713aSLionel Sambuc 
1908f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXCatchStmt, {
1909f4a2713aSLionel Sambuc   TRY_TO(TraverseDecl(S->getExceptionDecl()));
1910f4a2713aSLionel Sambuc   // children() iterates over the handler block.
1911f4a2713aSLionel Sambuc })
1912f4a2713aSLionel Sambuc 
1913f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(DeclStmt, {
1914*0a6a1f1dSLionel Sambuc   for (auto *I : S->decls()) {
1915*0a6a1f1dSLionel Sambuc     TRY_TO(TraverseDecl(I));
1916f4a2713aSLionel Sambuc   }
1917f4a2713aSLionel Sambuc   // Suppress the default iteration over children() by
1918f4a2713aSLionel Sambuc   // returning.  Here's why: A DeclStmt looks like 'type var [=
1919f4a2713aSLionel Sambuc   // initializer]'.  The decls above already traverse over the
1920f4a2713aSLionel Sambuc   // initializers, so we don't have to do it again (which
1921f4a2713aSLionel Sambuc   // children() would do).
1922f4a2713aSLionel Sambuc   return true;
1923f4a2713aSLionel Sambuc })
1924f4a2713aSLionel Sambuc 
1925f4a2713aSLionel Sambuc // These non-expr stmts (most of them), do not need any action except
1926f4a2713aSLionel Sambuc // iterating over the children.
1927f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(BreakStmt, {})
1928f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXTryStmt, {})
1929f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CaseStmt, {})
1930f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CompoundStmt, {})
1931f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ContinueStmt, {})
1932f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(DefaultStmt, {})
1933f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(DoStmt, {})
1934f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ForStmt, {})
1935f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(GotoStmt, {})
1936f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(IfStmt, {})
1937f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(IndirectGotoStmt, {})
1938f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(LabelStmt, {})
1939f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(AttributedStmt, {})
1940f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(NullStmt, {})
1941f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ObjCAtCatchStmt, {})
1942f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ObjCAtFinallyStmt, {})
1943f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ObjCAtSynchronizedStmt, {})
1944f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ObjCAtThrowStmt, {})
1945f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ObjCAtTryStmt, {})
1946f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ObjCForCollectionStmt, {})
1947f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ObjCAutoreleasePoolStmt, {})
1948f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXForRangeStmt, {
1949f4a2713aSLionel Sambuc   if (!getDerived().shouldVisitImplicitCode()) {
1950f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(S->getLoopVarStmt()));
1951f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(S->getRangeInit()));
1952f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(S->getBody()));
1953f4a2713aSLionel Sambuc     // Visit everything else only if shouldVisitImplicitCode().
1954f4a2713aSLionel Sambuc     return true;
1955f4a2713aSLionel Sambuc   }
1956f4a2713aSLionel Sambuc })
1957f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(MSDependentExistsStmt, {
1958f4a2713aSLionel Sambuc   TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
1959f4a2713aSLionel Sambuc   TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
1960f4a2713aSLionel Sambuc })
1961f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ReturnStmt, {})
1962f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(SwitchStmt, {})
1963f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(WhileStmt, {})
1964f4a2713aSLionel Sambuc 
1965f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXDependentScopeMemberExpr, {
1966f4a2713aSLionel Sambuc   TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
1967f4a2713aSLionel Sambuc   TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
1968f4a2713aSLionel Sambuc   if (S->hasExplicitTemplateArgs()) {
1969*0a6a1f1dSLionel Sambuc     TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
1970*0a6a1f1dSLionel Sambuc                                               S->getNumTemplateArgs()));
1971f4a2713aSLionel Sambuc   }
1972f4a2713aSLionel Sambuc })
1973f4a2713aSLionel Sambuc 
1974f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(DeclRefExpr, {
1975f4a2713aSLionel Sambuc   TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
1976f4a2713aSLionel Sambuc   TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
1977*0a6a1f1dSLionel Sambuc   TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
1978*0a6a1f1dSLionel Sambuc                                             S->getNumTemplateArgs()));
1979f4a2713aSLionel Sambuc })
1980f4a2713aSLionel Sambuc 
1981f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(DependentScopeDeclRefExpr, {
1982f4a2713aSLionel Sambuc   TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
1983f4a2713aSLionel Sambuc   TRY_TO(TraverseDeclarationNameInfo(S->getNameInfo()));
1984f4a2713aSLionel Sambuc   if (S->hasExplicitTemplateArgs()) {
1985f4a2713aSLionel Sambuc     TRY_TO(TraverseTemplateArgumentLocsHelper(
1986f4a2713aSLionel Sambuc         S->getExplicitTemplateArgs().getTemplateArgs(),
1987f4a2713aSLionel Sambuc         S->getNumTemplateArgs()));
1988f4a2713aSLionel Sambuc   }
1989f4a2713aSLionel Sambuc })
1990f4a2713aSLionel Sambuc 
1991f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(MemberExpr, {
1992f4a2713aSLionel Sambuc   TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
1993f4a2713aSLionel Sambuc   TRY_TO(TraverseDeclarationNameInfo(S->getMemberNameInfo()));
1994*0a6a1f1dSLionel Sambuc   TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
1995*0a6a1f1dSLionel Sambuc                                             S->getNumTemplateArgs()));
1996f4a2713aSLionel Sambuc })
1997f4a2713aSLionel Sambuc 
1998*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(
1999*0a6a1f1dSLionel Sambuc     ImplicitCastExpr,
2000*0a6a1f1dSLionel Sambuc     {// We don't traverse the cast type, as it's not written in the
2001f4a2713aSLionel Sambuc      // source code.
2002f4a2713aSLionel Sambuc     })
2003f4a2713aSLionel Sambuc 
2004f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CStyleCastExpr, {
2005f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2006f4a2713aSLionel Sambuc })
2007f4a2713aSLionel Sambuc 
2008f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXFunctionalCastExpr, {
2009f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2010f4a2713aSLionel Sambuc })
2011f4a2713aSLionel Sambuc 
2012f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXConstCastExpr, {
2013f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2014f4a2713aSLionel Sambuc })
2015f4a2713aSLionel Sambuc 
2016f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXDynamicCastExpr, {
2017f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2018f4a2713aSLionel Sambuc })
2019f4a2713aSLionel Sambuc 
2020f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXReinterpretCastExpr, {
2021f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2022f4a2713aSLionel Sambuc })
2023f4a2713aSLionel Sambuc 
2024f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXStaticCastExpr, {
2025f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2026f4a2713aSLionel Sambuc })
2027f4a2713aSLionel Sambuc 
2028f4a2713aSLionel Sambuc // InitListExpr is a tricky one, because we want to do all our work on
2029f4a2713aSLionel Sambuc // the syntactic form of the listexpr, but this method takes the
2030f4a2713aSLionel Sambuc // semantic form by default.  We can't use the macro helper because it
2031f4a2713aSLionel Sambuc // calls WalkUp*() on the semantic form, before our code can convert
2032f4a2713aSLionel Sambuc // to the syntactic form.
2033f4a2713aSLionel Sambuc template <typename Derived>
TraverseInitListExpr(InitListExpr * S)2034f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseInitListExpr(InitListExpr *S) {
2035f4a2713aSLionel Sambuc   if (InitListExpr *Syn = S->getSyntacticForm())
2036f4a2713aSLionel Sambuc     S = Syn;
2037f4a2713aSLionel Sambuc   TRY_TO(WalkUpFromInitListExpr(S));
2038f4a2713aSLionel Sambuc   // All we need are the default actions.  FIXME: use a helper function.
2039f4a2713aSLionel Sambuc   for (Stmt::child_range range = S->children(); range; ++range) {
2040f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(*range));
2041f4a2713aSLionel Sambuc   }
2042f4a2713aSLionel Sambuc   return true;
2043f4a2713aSLionel Sambuc }
2044f4a2713aSLionel Sambuc 
2045f4a2713aSLionel Sambuc // GenericSelectionExpr is a special case because the types and expressions
2046f4a2713aSLionel Sambuc // are interleaved.  We also need to watch out for null types (default
2047f4a2713aSLionel Sambuc // generic associations).
2048f4a2713aSLionel Sambuc template <typename Derived>
TraverseGenericSelectionExpr(GenericSelectionExpr * S)2049*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseGenericSelectionExpr(
2050*0a6a1f1dSLionel Sambuc     GenericSelectionExpr *S) {
2051f4a2713aSLionel Sambuc   TRY_TO(WalkUpFromGenericSelectionExpr(S));
2052f4a2713aSLionel Sambuc   TRY_TO(TraverseStmt(S->getControllingExpr()));
2053f4a2713aSLionel Sambuc   for (unsigned i = 0; i != S->getNumAssocs(); ++i) {
2054f4a2713aSLionel Sambuc     if (TypeSourceInfo *TS = S->getAssocTypeSourceInfo(i))
2055f4a2713aSLionel Sambuc       TRY_TO(TraverseTypeLoc(TS->getTypeLoc()));
2056f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(S->getAssocExpr(i)));
2057f4a2713aSLionel Sambuc   }
2058f4a2713aSLionel Sambuc   return true;
2059f4a2713aSLionel Sambuc }
2060f4a2713aSLionel Sambuc 
2061f4a2713aSLionel Sambuc // PseudoObjectExpr is a special case because of the wierdness with
2062f4a2713aSLionel Sambuc // syntactic expressions and opaque values.
2063f4a2713aSLionel Sambuc template <typename Derived>
2064*0a6a1f1dSLionel Sambuc bool
TraversePseudoObjectExpr(PseudoObjectExpr * S)2065*0a6a1f1dSLionel Sambuc RecursiveASTVisitor<Derived>::TraversePseudoObjectExpr(PseudoObjectExpr *S) {
2066f4a2713aSLionel Sambuc   TRY_TO(WalkUpFromPseudoObjectExpr(S));
2067f4a2713aSLionel Sambuc   TRY_TO(TraverseStmt(S->getSyntacticForm()));
2068*0a6a1f1dSLionel Sambuc   for (PseudoObjectExpr::semantics_iterator i = S->semantics_begin(),
2069*0a6a1f1dSLionel Sambuc                                             e = S->semantics_end();
2070*0a6a1f1dSLionel Sambuc        i != e; ++i) {
2071f4a2713aSLionel Sambuc     Expr *sub = *i;
2072f4a2713aSLionel Sambuc     if (OpaqueValueExpr *OVE = dyn_cast<OpaqueValueExpr>(sub))
2073f4a2713aSLionel Sambuc       sub = OVE->getSourceExpr();
2074f4a2713aSLionel Sambuc     TRY_TO(TraverseStmt(sub));
2075f4a2713aSLionel Sambuc   }
2076f4a2713aSLionel Sambuc   return true;
2077f4a2713aSLionel Sambuc }
2078f4a2713aSLionel Sambuc 
2079f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXScalarValueInitExpr, {
2080f4a2713aSLionel Sambuc   // This is called for code like 'return T()' where T is a built-in
2081f4a2713aSLionel Sambuc   // (i.e. non-class) type.
2082f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2083f4a2713aSLionel Sambuc })
2084f4a2713aSLionel Sambuc 
2085f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXNewExpr, {
2086f4a2713aSLionel Sambuc   // The child-iterator will pick up the other arguments.
2087f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(S->getAllocatedTypeSourceInfo()->getTypeLoc()));
2088f4a2713aSLionel Sambuc })
2089f4a2713aSLionel Sambuc 
2090f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(OffsetOfExpr, {
2091f4a2713aSLionel Sambuc   // The child-iterator will pick up the expression representing
2092f4a2713aSLionel Sambuc   // the field.
2093f4a2713aSLionel Sambuc   // FIMXE: for code like offsetof(Foo, a.b.c), should we get
2094f4a2713aSLionel Sambuc   // making a MemberExpr callbacks for Foo.a, Foo.a.b, and Foo.a.b.c?
2095f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2096f4a2713aSLionel Sambuc })
2097f4a2713aSLionel Sambuc 
2098f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(UnaryExprOrTypeTraitExpr, {
2099f4a2713aSLionel Sambuc   // The child-iterator will pick up the arg if it's an expression,
2100f4a2713aSLionel Sambuc   // but not if it's a type.
2101f4a2713aSLionel Sambuc   if (S->isArgumentType())
2102f4a2713aSLionel Sambuc     TRY_TO(TraverseTypeLoc(S->getArgumentTypeInfo()->getTypeLoc()));
2103f4a2713aSLionel Sambuc })
2104f4a2713aSLionel Sambuc 
2105f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXTypeidExpr, {
2106f4a2713aSLionel Sambuc   // The child-iterator will pick up the arg if it's an expression,
2107f4a2713aSLionel Sambuc   // but not if it's a type.
2108f4a2713aSLionel Sambuc   if (S->isTypeOperand())
2109f4a2713aSLionel Sambuc     TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
2110f4a2713aSLionel Sambuc })
2111f4a2713aSLionel Sambuc 
2112f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(MSPropertyRefExpr, {
2113f4a2713aSLionel Sambuc   TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2114f4a2713aSLionel Sambuc })
2115f4a2713aSLionel Sambuc 
2116f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXUuidofExpr, {
2117f4a2713aSLionel Sambuc   // The child-iterator will pick up the arg if it's an expression,
2118f4a2713aSLionel Sambuc   // but not if it's a type.
2119f4a2713aSLionel Sambuc   if (S->isTypeOperand())
2120f4a2713aSLionel Sambuc     TRY_TO(TraverseTypeLoc(S->getTypeOperandSourceInfo()->getTypeLoc()));
2121f4a2713aSLionel Sambuc })
2122f4a2713aSLionel Sambuc 
2123f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(TypeTraitExpr, {
2124f4a2713aSLionel Sambuc   for (unsigned I = 0, N = S->getNumArgs(); I != N; ++I)
2125f4a2713aSLionel Sambuc     TRY_TO(TraverseTypeLoc(S->getArg(I)->getTypeLoc()));
2126f4a2713aSLionel Sambuc })
2127f4a2713aSLionel Sambuc 
2128f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ArrayTypeTraitExpr, {
2129f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(S->getQueriedTypeSourceInfo()->getTypeLoc()));
2130f4a2713aSLionel Sambuc })
2131f4a2713aSLionel Sambuc 
2132*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(ExpressionTraitExpr,
2133*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseStmt(S->getQueriedExpression())); })
2134f4a2713aSLionel Sambuc 
2135f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(VAArgExpr, {
2136f4a2713aSLionel Sambuc   // The child-iterator will pick up the expression argument.
2137f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(S->getWrittenTypeInfo()->getTypeLoc()));
2138f4a2713aSLionel Sambuc })
2139f4a2713aSLionel Sambuc 
2140f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXTemporaryObjectExpr, {
2141f4a2713aSLionel Sambuc   // This is called for code like 'return T()' where T is a class type.
2142f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2143f4a2713aSLionel Sambuc })
2144f4a2713aSLionel Sambuc 
2145f4a2713aSLionel Sambuc // Walk only the visible parts of lambda expressions.
2146f4a2713aSLionel Sambuc template <typename Derived>
TraverseLambdaExpr(LambdaExpr * S)2147f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseLambdaExpr(LambdaExpr *S) {
2148f4a2713aSLionel Sambuc   TRY_TO(WalkUpFromLambdaExpr(S));
2149f4a2713aSLionel Sambuc 
2150f4a2713aSLionel Sambuc   for (LambdaExpr::capture_iterator C = S->explicit_capture_begin(),
2151f4a2713aSLionel Sambuc                                     CEnd = S->explicit_capture_end();
2152f4a2713aSLionel Sambuc        C != CEnd; ++C) {
2153f4a2713aSLionel Sambuc     TRY_TO(TraverseLambdaCapture(S, C));
2154f4a2713aSLionel Sambuc   }
2155f4a2713aSLionel Sambuc 
2156f4a2713aSLionel Sambuc   TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
2157*0a6a1f1dSLionel Sambuc   FunctionProtoTypeLoc Proto = TL.castAs<FunctionProtoTypeLoc>();
2158*0a6a1f1dSLionel Sambuc 
2159f4a2713aSLionel Sambuc   if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
2160f4a2713aSLionel Sambuc     // Visit the whole type.
2161f4a2713aSLionel Sambuc     TRY_TO(TraverseTypeLoc(TL));
2162*0a6a1f1dSLionel Sambuc   } else {
2163f4a2713aSLionel Sambuc     if (S->hasExplicitParameters()) {
2164f4a2713aSLionel Sambuc       // Visit parameters.
2165*0a6a1f1dSLionel Sambuc       for (unsigned I = 0, N = Proto.getNumParams(); I != N; ++I) {
2166*0a6a1f1dSLionel Sambuc         TRY_TO(TraverseDecl(Proto.getParam(I)));
2167f4a2713aSLionel Sambuc       }
2168*0a6a1f1dSLionel Sambuc     } else if (S->hasExplicitResultType()) {
2169*0a6a1f1dSLionel Sambuc       TRY_TO(TraverseTypeLoc(Proto.getReturnLoc()));
2170f4a2713aSLionel Sambuc     }
2171*0a6a1f1dSLionel Sambuc 
2172*0a6a1f1dSLionel Sambuc     auto *T = Proto.getTypePtr();
2173*0a6a1f1dSLionel Sambuc     for (const auto &E : T->exceptions()) {
2174*0a6a1f1dSLionel Sambuc       TRY_TO(TraverseType(E));
2175f4a2713aSLionel Sambuc     }
2176*0a6a1f1dSLionel Sambuc 
2177*0a6a1f1dSLionel Sambuc     if (Expr *NE = T->getNoexceptExpr())
2178*0a6a1f1dSLionel Sambuc       TRY_TO(TraverseStmt(NE));
2179f4a2713aSLionel Sambuc   }
2180f4a2713aSLionel Sambuc 
2181f4a2713aSLionel Sambuc   TRY_TO(TraverseLambdaBody(S));
2182f4a2713aSLionel Sambuc   return true;
2183f4a2713aSLionel Sambuc }
2184f4a2713aSLionel Sambuc 
2185f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXUnresolvedConstructExpr, {
2186f4a2713aSLionel Sambuc   // This is called for code like 'T()', where T is a template argument.
2187f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2188f4a2713aSLionel Sambuc })
2189f4a2713aSLionel Sambuc 
2190f4a2713aSLionel Sambuc // These expressions all might take explicit template arguments.
2191f4a2713aSLionel Sambuc // We traverse those if so.  FIXME: implement these.
2192f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXConstructExpr, {})
2193f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CallExpr, {})
2194f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXMemberCallExpr, {})
2195f4a2713aSLionel Sambuc 
2196f4a2713aSLionel Sambuc // These exprs (most of them), do not need any action except iterating
2197f4a2713aSLionel Sambuc // over the children.
2198f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(AddrLabelExpr, {})
2199f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ArraySubscriptExpr, {})
2200f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(BlockExpr, {
2201f4a2713aSLionel Sambuc   TRY_TO(TraverseDecl(S->getBlockDecl()));
2202f4a2713aSLionel Sambuc   return true; // no child statements to loop through.
2203f4a2713aSLionel Sambuc })
2204f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ChooseExpr, {})
2205f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CompoundLiteralExpr, {
2206f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(S->getTypeSourceInfo()->getTypeLoc()));
2207f4a2713aSLionel Sambuc })
2208f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXBindTemporaryExpr, {})
2209f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXBoolLiteralExpr, {})
2210f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXDefaultArgExpr, {})
2211f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXDefaultInitExpr, {})
2212f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXDeleteExpr, {})
2213f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ExprWithCleanups, {})
2214f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXNullPtrLiteralExpr, {})
2215f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXStdInitializerListExpr, {})
2216f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXPseudoDestructorExpr, {
2217f4a2713aSLionel Sambuc   TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2218f4a2713aSLionel Sambuc   if (TypeSourceInfo *ScopeInfo = S->getScopeTypeInfo())
2219f4a2713aSLionel Sambuc     TRY_TO(TraverseTypeLoc(ScopeInfo->getTypeLoc()));
2220f4a2713aSLionel Sambuc   if (TypeSourceInfo *DestroyedTypeInfo = S->getDestroyedTypeInfo())
2221f4a2713aSLionel Sambuc     TRY_TO(TraverseTypeLoc(DestroyedTypeInfo->getTypeLoc()));
2222f4a2713aSLionel Sambuc })
2223f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXThisExpr, {})
2224f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXThrowExpr, {})
2225f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(UserDefinedLiteral, {})
2226f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(DesignatedInitExpr, {})
2227f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ExtVectorElementExpr, {})
2228f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(GNUNullExpr, {})
2229f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ImplicitValueInitExpr, {})
2230f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ObjCBoolLiteralExpr, {})
2231f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ObjCEncodeExpr, {
2232f4a2713aSLionel Sambuc   if (TypeSourceInfo *TInfo = S->getEncodedTypeSourceInfo())
2233f4a2713aSLionel Sambuc     TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
2234f4a2713aSLionel Sambuc })
2235f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ObjCIsaExpr, {})
2236f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ObjCIvarRefExpr, {})
2237f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ObjCMessageExpr, {
2238f4a2713aSLionel Sambuc   if (TypeSourceInfo *TInfo = S->getClassReceiverTypeInfo())
2239f4a2713aSLionel Sambuc     TRY_TO(TraverseTypeLoc(TInfo->getTypeLoc()));
2240f4a2713aSLionel Sambuc })
2241f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ObjCPropertyRefExpr, {})
2242f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ObjCSubscriptRefExpr, {})
2243f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ObjCProtocolExpr, {})
2244f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ObjCSelectorExpr, {})
2245f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ObjCIndirectCopyRestoreExpr, {})
2246f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ObjCBridgedCastExpr, {
2247f4a2713aSLionel Sambuc   TRY_TO(TraverseTypeLoc(S->getTypeInfoAsWritten()->getTypeLoc()));
2248f4a2713aSLionel Sambuc })
2249f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ParenExpr, {})
2250f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ParenListExpr, {})
2251f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(PredefinedExpr, {})
2252f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ShuffleVectorExpr, {})
2253f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ConvertVectorExpr, {})
2254f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(StmtExpr, {})
2255f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(UnresolvedLookupExpr, {
2256f4a2713aSLionel Sambuc   TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2257f4a2713aSLionel Sambuc   if (S->hasExplicitTemplateArgs()) {
2258f4a2713aSLionel Sambuc     TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2259f4a2713aSLionel Sambuc                                               S->getNumTemplateArgs()));
2260f4a2713aSLionel Sambuc   }
2261f4a2713aSLionel Sambuc })
2262f4a2713aSLionel Sambuc 
2263f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(UnresolvedMemberExpr, {
2264f4a2713aSLionel Sambuc   TRY_TO(TraverseNestedNameSpecifierLoc(S->getQualifierLoc()));
2265f4a2713aSLionel Sambuc   if (S->hasExplicitTemplateArgs()) {
2266f4a2713aSLionel Sambuc     TRY_TO(TraverseTemplateArgumentLocsHelper(S->getTemplateArgs(),
2267f4a2713aSLionel Sambuc                                               S->getNumTemplateArgs()));
2268f4a2713aSLionel Sambuc   }
2269f4a2713aSLionel Sambuc })
2270f4a2713aSLionel Sambuc 
2271f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(SEHTryStmt, {})
2272f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(SEHExceptStmt, {})
2273f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(SEHFinallyStmt, {})
2274*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(SEHLeaveStmt, {})
2275*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(CapturedStmt, { TRY_TO(TraverseDecl(S->getCapturedDecl())); })
2276f4a2713aSLionel Sambuc 
2277f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXOperatorCallExpr, {})
2278f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(OpaqueValueExpr, {})
2279*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(TypoExpr, {})
2280f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CUDAKernelCallExpr, {})
2281f4a2713aSLionel Sambuc 
2282f4a2713aSLionel Sambuc // These operators (all of them) do not need any action except
2283f4a2713aSLionel Sambuc // iterating over the children.
2284f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(BinaryConditionalOperator, {})
2285f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ConditionalOperator, {})
2286f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(UnaryOperator, {})
2287f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(BinaryOperator, {})
2288f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CompoundAssignOperator, {})
2289f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CXXNoexceptExpr, {})
2290f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(PackExpansionExpr, {})
2291f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(SizeOfPackExpr, {})
2292f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmPackExpr, {})
2293f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(SubstNonTypeTemplateParmExpr, {})
2294f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(FunctionParmPackExpr, {})
2295f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(MaterializeTemporaryExpr, {})
2296*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(CXXFoldExpr, {})
2297f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(AtomicExpr, {})
2298f4a2713aSLionel Sambuc 
2299f4a2713aSLionel Sambuc // These literals (all of them) do not need any action.
2300f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(IntegerLiteral, {})
2301f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(CharacterLiteral, {})
2302f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(FloatingLiteral, {})
2303f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ImaginaryLiteral, {})
2304f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(StringLiteral, {})
2305f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ObjCStringLiteral, {})
2306f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ObjCBoxedExpr, {})
2307f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ObjCArrayLiteral, {})
2308f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(ObjCDictionaryLiteral, {})
2309f4a2713aSLionel Sambuc 
2310f4a2713aSLionel Sambuc // Traverse OpenCL: AsType, Convert.
2311f4a2713aSLionel Sambuc DEF_TRAVERSE_STMT(AsTypeExpr, {})
2312f4a2713aSLionel Sambuc 
2313f4a2713aSLionel Sambuc // OpenMP directives.
2314f4a2713aSLionel Sambuc template <typename Derived>
TraverseOMPExecutableDirective(OMPExecutableDirective * S)2315*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseOMPExecutableDirective(
2316*0a6a1f1dSLionel Sambuc     OMPExecutableDirective *S) {
2317*0a6a1f1dSLionel Sambuc   for (auto *C : S->clauses()) {
2318*0a6a1f1dSLionel Sambuc     TRY_TO(TraverseOMPClause(C));
2319f4a2713aSLionel Sambuc   }
2320f4a2713aSLionel Sambuc   return true;
2321f4a2713aSLionel Sambuc }
2322f4a2713aSLionel Sambuc 
2323f4a2713aSLionel Sambuc template <typename Derived>
2324*0a6a1f1dSLionel Sambuc bool
TraverseOMPLoopDirective(OMPLoopDirective * S)2325*0a6a1f1dSLionel Sambuc RecursiveASTVisitor<Derived>::TraverseOMPLoopDirective(OMPLoopDirective *S) {
2326*0a6a1f1dSLionel Sambuc   return TraverseOMPExecutableDirective(S);
2327*0a6a1f1dSLionel Sambuc }
2328*0a6a1f1dSLionel Sambuc 
2329*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(OMPParallelDirective,
2330*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
2331*0a6a1f1dSLionel Sambuc 
2332*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(OMPSimdDirective,
2333*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
2334*0a6a1f1dSLionel Sambuc 
2335*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(OMPForDirective,
2336*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
2337*0a6a1f1dSLionel Sambuc 
2338*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(OMPForSimdDirective,
2339*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
2340*0a6a1f1dSLionel Sambuc 
2341*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(OMPSectionsDirective,
2342*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
2343*0a6a1f1dSLionel Sambuc 
2344*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(OMPSectionDirective,
2345*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
2346*0a6a1f1dSLionel Sambuc 
2347*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(OMPSingleDirective,
2348*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
2349*0a6a1f1dSLionel Sambuc 
2350*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(OMPMasterDirective,
2351*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
2352*0a6a1f1dSLionel Sambuc 
2353*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(OMPCriticalDirective, {
2354*0a6a1f1dSLionel Sambuc   TRY_TO(TraverseDeclarationNameInfo(S->getDirectiveName()));
2355*0a6a1f1dSLionel Sambuc   TRY_TO(TraverseOMPExecutableDirective(S));
2356*0a6a1f1dSLionel Sambuc })
2357*0a6a1f1dSLionel Sambuc 
2358*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(OMPParallelForDirective,
2359*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
2360*0a6a1f1dSLionel Sambuc 
2361*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(OMPParallelForSimdDirective,
2362*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
2363*0a6a1f1dSLionel Sambuc 
2364*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(OMPParallelSectionsDirective,
2365*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
2366*0a6a1f1dSLionel Sambuc 
2367*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(OMPTaskDirective,
2368*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
2369*0a6a1f1dSLionel Sambuc 
2370*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(OMPTaskyieldDirective,
2371*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
2372*0a6a1f1dSLionel Sambuc 
2373*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(OMPBarrierDirective,
2374*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
2375*0a6a1f1dSLionel Sambuc 
2376*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(OMPTaskwaitDirective,
2377*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
2378*0a6a1f1dSLionel Sambuc 
2379*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(OMPFlushDirective,
2380*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
2381*0a6a1f1dSLionel Sambuc 
2382*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(OMPOrderedDirective,
2383*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
2384*0a6a1f1dSLionel Sambuc 
2385*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(OMPAtomicDirective,
2386*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
2387*0a6a1f1dSLionel Sambuc 
2388*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(OMPTargetDirective,
2389*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
2390*0a6a1f1dSLionel Sambuc 
2391*0a6a1f1dSLionel Sambuc DEF_TRAVERSE_STMT(OMPTeamsDirective,
2392*0a6a1f1dSLionel Sambuc                   { TRY_TO(TraverseOMPExecutableDirective(S)); })
2393*0a6a1f1dSLionel Sambuc 
2394*0a6a1f1dSLionel Sambuc // OpenMP clauses.
2395*0a6a1f1dSLionel Sambuc template <typename Derived>
TraverseOMPClause(OMPClause * C)2396*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::TraverseOMPClause(OMPClause *C) {
2397*0a6a1f1dSLionel Sambuc   if (!C)
2398*0a6a1f1dSLionel Sambuc     return true;
2399*0a6a1f1dSLionel Sambuc   switch (C->getClauseKind()) {
2400*0a6a1f1dSLionel Sambuc #define OPENMP_CLAUSE(Name, Class)                                             \
2401*0a6a1f1dSLionel Sambuc   case OMPC_##Name:                                                            \
2402*0a6a1f1dSLionel Sambuc     TRY_TO(Visit##Class(static_cast<Class *>(C)));                             \
2403*0a6a1f1dSLionel Sambuc     break;
2404*0a6a1f1dSLionel Sambuc #include "clang/Basic/OpenMPKinds.def"
2405*0a6a1f1dSLionel Sambuc   case OMPC_threadprivate:
2406*0a6a1f1dSLionel Sambuc   case OMPC_unknown:
2407*0a6a1f1dSLionel Sambuc     break;
2408*0a6a1f1dSLionel Sambuc   }
2409*0a6a1f1dSLionel Sambuc   return true;
2410*0a6a1f1dSLionel Sambuc }
2411*0a6a1f1dSLionel Sambuc 
2412*0a6a1f1dSLionel Sambuc template <typename Derived>
VisitOMPIfClause(OMPIfClause * C)2413*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::VisitOMPIfClause(OMPIfClause *C) {
2414*0a6a1f1dSLionel Sambuc   TRY_TO(TraverseStmt(C->getCondition()));
2415*0a6a1f1dSLionel Sambuc   return true;
2416*0a6a1f1dSLionel Sambuc }
2417*0a6a1f1dSLionel Sambuc 
2418*0a6a1f1dSLionel Sambuc template <typename Derived>
VisitOMPFinalClause(OMPFinalClause * C)2419*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::VisitOMPFinalClause(OMPFinalClause *C) {
2420*0a6a1f1dSLionel Sambuc   TRY_TO(TraverseStmt(C->getCondition()));
2421*0a6a1f1dSLionel Sambuc   return true;
2422*0a6a1f1dSLionel Sambuc }
2423*0a6a1f1dSLionel Sambuc 
2424*0a6a1f1dSLionel Sambuc template <typename Derived>
2425*0a6a1f1dSLionel Sambuc bool
VisitOMPNumThreadsClause(OMPNumThreadsClause * C)2426*0a6a1f1dSLionel Sambuc RecursiveASTVisitor<Derived>::VisitOMPNumThreadsClause(OMPNumThreadsClause *C) {
2427*0a6a1f1dSLionel Sambuc   TRY_TO(TraverseStmt(C->getNumThreads()));
2428*0a6a1f1dSLionel Sambuc   return true;
2429*0a6a1f1dSLionel Sambuc }
2430*0a6a1f1dSLionel Sambuc 
2431*0a6a1f1dSLionel Sambuc template <typename Derived>
VisitOMPSafelenClause(OMPSafelenClause * C)2432*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::VisitOMPSafelenClause(OMPSafelenClause *C) {
2433*0a6a1f1dSLionel Sambuc   TRY_TO(TraverseStmt(C->getSafelen()));
2434*0a6a1f1dSLionel Sambuc   return true;
2435*0a6a1f1dSLionel Sambuc }
2436*0a6a1f1dSLionel Sambuc 
2437*0a6a1f1dSLionel Sambuc template <typename Derived>
2438*0a6a1f1dSLionel Sambuc bool
VisitOMPCollapseClause(OMPCollapseClause * C)2439*0a6a1f1dSLionel Sambuc RecursiveASTVisitor<Derived>::VisitOMPCollapseClause(OMPCollapseClause *C) {
2440*0a6a1f1dSLionel Sambuc   TRY_TO(TraverseStmt(C->getNumForLoops()));
2441*0a6a1f1dSLionel Sambuc   return true;
2442*0a6a1f1dSLionel Sambuc }
2443*0a6a1f1dSLionel Sambuc 
2444*0a6a1f1dSLionel Sambuc template <typename Derived>
VisitOMPDefaultClause(OMPDefaultClause *)2445*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::VisitOMPDefaultClause(OMPDefaultClause *) {
2446*0a6a1f1dSLionel Sambuc   return true;
2447*0a6a1f1dSLionel Sambuc }
2448*0a6a1f1dSLionel Sambuc 
2449*0a6a1f1dSLionel Sambuc template <typename Derived>
VisitOMPProcBindClause(OMPProcBindClause *)2450*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::VisitOMPProcBindClause(OMPProcBindClause *) {
2451*0a6a1f1dSLionel Sambuc   return true;
2452*0a6a1f1dSLionel Sambuc }
2453*0a6a1f1dSLionel Sambuc 
2454*0a6a1f1dSLionel Sambuc template <typename Derived>
2455*0a6a1f1dSLionel Sambuc bool
VisitOMPScheduleClause(OMPScheduleClause * C)2456*0a6a1f1dSLionel Sambuc RecursiveASTVisitor<Derived>::VisitOMPScheduleClause(OMPScheduleClause *C) {
2457*0a6a1f1dSLionel Sambuc   TRY_TO(TraverseStmt(C->getChunkSize()));
2458*0a6a1f1dSLionel Sambuc   return true;
2459*0a6a1f1dSLionel Sambuc }
2460*0a6a1f1dSLionel Sambuc 
2461*0a6a1f1dSLionel Sambuc template <typename Derived>
VisitOMPOrderedClause(OMPOrderedClause *)2462*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::VisitOMPOrderedClause(OMPOrderedClause *) {
2463*0a6a1f1dSLionel Sambuc   return true;
2464*0a6a1f1dSLionel Sambuc }
2465*0a6a1f1dSLionel Sambuc 
2466*0a6a1f1dSLionel Sambuc template <typename Derived>
VisitOMPNowaitClause(OMPNowaitClause *)2467*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::VisitOMPNowaitClause(OMPNowaitClause *) {
2468*0a6a1f1dSLionel Sambuc   return true;
2469*0a6a1f1dSLionel Sambuc }
2470*0a6a1f1dSLionel Sambuc 
2471*0a6a1f1dSLionel Sambuc template <typename Derived>
VisitOMPUntiedClause(OMPUntiedClause *)2472*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::VisitOMPUntiedClause(OMPUntiedClause *) {
2473*0a6a1f1dSLionel Sambuc   return true;
2474*0a6a1f1dSLionel Sambuc }
2475*0a6a1f1dSLionel Sambuc 
2476*0a6a1f1dSLionel Sambuc template <typename Derived>
2477*0a6a1f1dSLionel Sambuc bool
VisitOMPMergeableClause(OMPMergeableClause *)2478*0a6a1f1dSLionel Sambuc RecursiveASTVisitor<Derived>::VisitOMPMergeableClause(OMPMergeableClause *) {
2479*0a6a1f1dSLionel Sambuc   return true;
2480*0a6a1f1dSLionel Sambuc }
2481*0a6a1f1dSLionel Sambuc 
2482*0a6a1f1dSLionel Sambuc template <typename Derived>
VisitOMPReadClause(OMPReadClause *)2483*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::VisitOMPReadClause(OMPReadClause *) {
2484*0a6a1f1dSLionel Sambuc   return true;
2485*0a6a1f1dSLionel Sambuc }
2486*0a6a1f1dSLionel Sambuc 
2487*0a6a1f1dSLionel Sambuc template <typename Derived>
VisitOMPWriteClause(OMPWriteClause *)2488*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::VisitOMPWriteClause(OMPWriteClause *) {
2489*0a6a1f1dSLionel Sambuc   return true;
2490*0a6a1f1dSLionel Sambuc }
2491*0a6a1f1dSLionel Sambuc 
2492*0a6a1f1dSLionel Sambuc template <typename Derived>
VisitOMPUpdateClause(OMPUpdateClause *)2493*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::VisitOMPUpdateClause(OMPUpdateClause *) {
2494*0a6a1f1dSLionel Sambuc   return true;
2495*0a6a1f1dSLionel Sambuc }
2496*0a6a1f1dSLionel Sambuc 
2497*0a6a1f1dSLionel Sambuc template <typename Derived>
VisitOMPCaptureClause(OMPCaptureClause *)2498*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::VisitOMPCaptureClause(OMPCaptureClause *) {
2499*0a6a1f1dSLionel Sambuc   return true;
2500*0a6a1f1dSLionel Sambuc }
2501*0a6a1f1dSLionel Sambuc 
2502*0a6a1f1dSLionel Sambuc template <typename Derived>
VisitOMPSeqCstClause(OMPSeqCstClause *)2503*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::VisitOMPSeqCstClause(OMPSeqCstClause *) {
2504f4a2713aSLionel Sambuc   return true;
2505f4a2713aSLionel Sambuc }
2506f4a2713aSLionel Sambuc 
2507f4a2713aSLionel Sambuc template <typename Derived>
2508f4a2713aSLionel Sambuc template <typename T>
VisitOMPClauseList(T * Node)2509*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::VisitOMPClauseList(T *Node) {
2510*0a6a1f1dSLionel Sambuc   for (auto *E : Node->varlists()) {
2511*0a6a1f1dSLionel Sambuc     TRY_TO(TraverseStmt(E));
2512*0a6a1f1dSLionel Sambuc   }
2513*0a6a1f1dSLionel Sambuc   return true;
2514f4a2713aSLionel Sambuc }
2515f4a2713aSLionel Sambuc 
2516f4a2713aSLionel Sambuc template <typename Derived>
VisitOMPPrivateClause(OMPPrivateClause * C)2517f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::VisitOMPPrivateClause(OMPPrivateClause *C) {
2518*0a6a1f1dSLionel Sambuc   TRY_TO(VisitOMPClauseList(C));
2519*0a6a1f1dSLionel Sambuc   for (auto *E : C->private_copies()) {
2520*0a6a1f1dSLionel Sambuc     TRY_TO(TraverseStmt(E));
2521*0a6a1f1dSLionel Sambuc   }
2522f4a2713aSLionel Sambuc   return true;
2523f4a2713aSLionel Sambuc }
2524f4a2713aSLionel Sambuc 
2525f4a2713aSLionel Sambuc template <typename Derived>
VisitOMPFirstprivateClause(OMPFirstprivateClause * C)2526f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::VisitOMPFirstprivateClause(
2527f4a2713aSLionel Sambuc     OMPFirstprivateClause *C) {
2528*0a6a1f1dSLionel Sambuc   TRY_TO(VisitOMPClauseList(C));
2529*0a6a1f1dSLionel Sambuc   for (auto *E : C->private_copies()) {
2530*0a6a1f1dSLionel Sambuc     TRY_TO(TraverseStmt(E));
2531*0a6a1f1dSLionel Sambuc   }
2532*0a6a1f1dSLionel Sambuc   for (auto *E : C->inits()) {
2533*0a6a1f1dSLionel Sambuc     TRY_TO(TraverseStmt(E));
2534*0a6a1f1dSLionel Sambuc   }
2535*0a6a1f1dSLionel Sambuc   return true;
2536*0a6a1f1dSLionel Sambuc }
2537*0a6a1f1dSLionel Sambuc 
2538*0a6a1f1dSLionel Sambuc template <typename Derived>
VisitOMPLastprivateClause(OMPLastprivateClause * C)2539*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::VisitOMPLastprivateClause(
2540*0a6a1f1dSLionel Sambuc     OMPLastprivateClause *C) {
2541*0a6a1f1dSLionel Sambuc   TRY_TO(VisitOMPClauseList(C));
2542f4a2713aSLionel Sambuc   return true;
2543f4a2713aSLionel Sambuc }
2544f4a2713aSLionel Sambuc 
2545f4a2713aSLionel Sambuc template <typename Derived>
VisitOMPSharedClause(OMPSharedClause * C)2546f4a2713aSLionel Sambuc bool RecursiveASTVisitor<Derived>::VisitOMPSharedClause(OMPSharedClause *C) {
2547*0a6a1f1dSLionel Sambuc   TRY_TO(VisitOMPClauseList(C));
2548*0a6a1f1dSLionel Sambuc   return true;
2549*0a6a1f1dSLionel Sambuc }
2550*0a6a1f1dSLionel Sambuc 
2551*0a6a1f1dSLionel Sambuc template <typename Derived>
VisitOMPLinearClause(OMPLinearClause * C)2552*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::VisitOMPLinearClause(OMPLinearClause *C) {
2553*0a6a1f1dSLionel Sambuc   TRY_TO(TraverseStmt(C->getStep()));
2554*0a6a1f1dSLionel Sambuc   TRY_TO(VisitOMPClauseList(C));
2555*0a6a1f1dSLionel Sambuc   return true;
2556*0a6a1f1dSLionel Sambuc }
2557*0a6a1f1dSLionel Sambuc 
2558*0a6a1f1dSLionel Sambuc template <typename Derived>
VisitOMPAlignedClause(OMPAlignedClause * C)2559*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::VisitOMPAlignedClause(OMPAlignedClause *C) {
2560*0a6a1f1dSLionel Sambuc   TRY_TO(TraverseStmt(C->getAlignment()));
2561*0a6a1f1dSLionel Sambuc   TRY_TO(VisitOMPClauseList(C));
2562*0a6a1f1dSLionel Sambuc   return true;
2563*0a6a1f1dSLionel Sambuc }
2564*0a6a1f1dSLionel Sambuc 
2565*0a6a1f1dSLionel Sambuc template <typename Derived>
VisitOMPCopyinClause(OMPCopyinClause * C)2566*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::VisitOMPCopyinClause(OMPCopyinClause *C) {
2567*0a6a1f1dSLionel Sambuc   TRY_TO(VisitOMPClauseList(C));
2568*0a6a1f1dSLionel Sambuc   return true;
2569*0a6a1f1dSLionel Sambuc }
2570*0a6a1f1dSLionel Sambuc 
2571*0a6a1f1dSLionel Sambuc template <typename Derived>
VisitOMPCopyprivateClause(OMPCopyprivateClause * C)2572*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::VisitOMPCopyprivateClause(
2573*0a6a1f1dSLionel Sambuc     OMPCopyprivateClause *C) {
2574*0a6a1f1dSLionel Sambuc   TRY_TO(VisitOMPClauseList(C));
2575*0a6a1f1dSLionel Sambuc   return true;
2576*0a6a1f1dSLionel Sambuc }
2577*0a6a1f1dSLionel Sambuc 
2578*0a6a1f1dSLionel Sambuc template <typename Derived>
2579*0a6a1f1dSLionel Sambuc bool
VisitOMPReductionClause(OMPReductionClause * C)2580*0a6a1f1dSLionel Sambuc RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) {
2581*0a6a1f1dSLionel Sambuc   TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
2582*0a6a1f1dSLionel Sambuc   TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
2583*0a6a1f1dSLionel Sambuc   TRY_TO(VisitOMPClauseList(C));
2584*0a6a1f1dSLionel Sambuc   return true;
2585*0a6a1f1dSLionel Sambuc }
2586*0a6a1f1dSLionel Sambuc 
2587*0a6a1f1dSLionel Sambuc template <typename Derived>
VisitOMPFlushClause(OMPFlushClause * C)2588*0a6a1f1dSLionel Sambuc bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
2589*0a6a1f1dSLionel Sambuc   TRY_TO(VisitOMPClauseList(C));
2590f4a2713aSLionel Sambuc   return true;
2591f4a2713aSLionel Sambuc }
2592f4a2713aSLionel Sambuc 
2593f4a2713aSLionel Sambuc // FIXME: look at the following tricky-seeming exprs to see if we
2594f4a2713aSLionel Sambuc // need to recurse on anything.  These are ones that have methods
2595f4a2713aSLionel Sambuc // returning decls or qualtypes or nestednamespecifier -- though I'm
2596f4a2713aSLionel Sambuc // not sure if they own them -- or just seemed very complicated, or
2597f4a2713aSLionel Sambuc // had lots of sub-types to explore.
2598f4a2713aSLionel Sambuc //
2599f4a2713aSLionel Sambuc // VisitOverloadExpr and its children: recurse on template args? etc?
2600f4a2713aSLionel Sambuc 
2601f4a2713aSLionel Sambuc // FIXME: go through all the stmts and exprs again, and see which of them
2602f4a2713aSLionel Sambuc // create new types, and recurse on the types (TypeLocs?) of those.
2603f4a2713aSLionel Sambuc // Candidates:
2604f4a2713aSLionel Sambuc //
2605f4a2713aSLionel Sambuc //    http://clang.llvm.org/doxygen/classclang_1_1CXXTypeidExpr.html
2606f4a2713aSLionel Sambuc //    http://clang.llvm.org/doxygen/classclang_1_1UnaryExprOrTypeTraitExpr.html
2607f4a2713aSLionel Sambuc //    http://clang.llvm.org/doxygen/classclang_1_1TypesCompatibleExpr.html
2608f4a2713aSLionel Sambuc //    Every class that has getQualifier.
2609f4a2713aSLionel Sambuc 
2610f4a2713aSLionel Sambuc #undef DEF_TRAVERSE_STMT
2611f4a2713aSLionel Sambuc 
2612f4a2713aSLionel Sambuc #undef TRY_TO
2613f4a2713aSLionel Sambuc 
2614f4a2713aSLionel Sambuc } // end namespace clang
2615f4a2713aSLionel Sambuc 
2616f4a2713aSLionel Sambuc #endif // LLVM_CLANG_AST_RECURSIVEASTVISITOR_H
2617