xref: /minix3/external/bsd/llvm/dist/clang/include/clang/ASTMatchers/ASTMatchersMacros.h (revision 0a6a1f1d05b60e214de2f05a7310ddd1f0e590e7)
1f4a2713aSLionel Sambuc //===--- ASTMatchersMacros.h - Structural query framework -------*- 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 //  Defines macros that enable us to define new matchers in a single place.
11f4a2713aSLionel Sambuc //  Since a matcher is a function which returns a Matcher<T> object, where
12f4a2713aSLionel Sambuc //  T is the type of the actual implementation of the matcher, the macros allow
13f4a2713aSLionel Sambuc //  us to write matchers like functions and take care of the definition of the
14f4a2713aSLionel Sambuc //  class boilerplate.
15f4a2713aSLionel Sambuc //
16f4a2713aSLionel Sambuc //  Note that when you define a matcher with an AST_MATCHER* macro, only the
17f4a2713aSLionel Sambuc //  function which creates the matcher goes into the current namespace - the
18f4a2713aSLionel Sambuc //  class that implements the actual matcher, which gets returned by the
19f4a2713aSLionel Sambuc //  generator function, is put into the 'internal' namespace. This allows us
20f4a2713aSLionel Sambuc //  to only have the functions (which is all the user cares about) in the
21f4a2713aSLionel Sambuc //  'ast_matchers' namespace and hide the boilerplate.
22f4a2713aSLionel Sambuc //
23f4a2713aSLionel Sambuc //  To define a matcher in user code, always put it into the clang::ast_matchers
24f4a2713aSLionel Sambuc //  namespace and refer to the internal types via the 'internal::':
25f4a2713aSLionel Sambuc //
26f4a2713aSLionel Sambuc //  namespace clang {
27f4a2713aSLionel Sambuc //  namespace ast_matchers {
28f4a2713aSLionel Sambuc //  AST_MATCHER_P(MemberExpr, Member,
29f4a2713aSLionel Sambuc //                internal::Matcher<ValueDecl>, InnerMatcher) {
30f4a2713aSLionel Sambuc //    return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
31f4a2713aSLionel Sambuc //  }
32f4a2713aSLionel Sambuc //  } // end namespace ast_matchers
33f4a2713aSLionel Sambuc //  } // end namespace clang
34f4a2713aSLionel Sambuc //
35f4a2713aSLionel Sambuc //===----------------------------------------------------------------------===//
36f4a2713aSLionel Sambuc 
37*0a6a1f1dSLionel Sambuc #ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
38*0a6a1f1dSLionel Sambuc #define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
39*0a6a1f1dSLionel Sambuc 
40*0a6a1f1dSLionel Sambuc /// \brief AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) {
41*0a6a1f1dSLionel Sambuc /// defines a zero parameter function named DefineMatcher() that returns a
42*0a6a1f1dSLionel Sambuc /// ReturnType object.
43*0a6a1f1dSLionel Sambuc #define AST_MATCHER_FUNCTION(ReturnType, DefineMatcher)                        \
44*0a6a1f1dSLionel Sambuc   inline ReturnType DefineMatcher##_getInstance();                             \
45*0a6a1f1dSLionel Sambuc   inline ReturnType DefineMatcher() {                                          \
46*0a6a1f1dSLionel Sambuc     return internal::MemoizedMatcher<                                          \
47*0a6a1f1dSLionel Sambuc         ReturnType, DefineMatcher##_getInstance>::getInstance();               \
48*0a6a1f1dSLionel Sambuc   }                                                                            \
49*0a6a1f1dSLionel Sambuc   inline ReturnType DefineMatcher##_getInstance()
50*0a6a1f1dSLionel Sambuc 
51*0a6a1f1dSLionel Sambuc /// \brief AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) {
52*0a6a1f1dSLionel Sambuc /// defines a single-parameter function named DefineMatcher() that returns a
53*0a6a1f1dSLionel Sambuc /// ReturnType object.
54*0a6a1f1dSLionel Sambuc ///
55*0a6a1f1dSLionel Sambuc /// The code between the curly braces has access to the following variables:
56*0a6a1f1dSLionel Sambuc ///
57*0a6a1f1dSLionel Sambuc ///   Param:                 the parameter passed to the function; its type
58*0a6a1f1dSLionel Sambuc ///                          is ParamType.
59*0a6a1f1dSLionel Sambuc ///
60*0a6a1f1dSLionel Sambuc /// The code should return an instance of ReturnType.
61*0a6a1f1dSLionel Sambuc #define AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param)    \
62*0a6a1f1dSLionel Sambuc   AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, Param, \
63*0a6a1f1dSLionel Sambuc                                   0)
64*0a6a1f1dSLionel Sambuc #define AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType,  \
65*0a6a1f1dSLionel Sambuc                                         Param, OverloadId)                     \
66*0a6a1f1dSLionel Sambuc   inline ReturnType DefineMatcher(ParamType const &Param);                     \
67*0a6a1f1dSLionel Sambuc   typedef ReturnType (&DefineMatcher##_Type##OverloadId)(ParamType const &);   \
68*0a6a1f1dSLionel Sambuc   inline ReturnType DefineMatcher(ParamType const &Param)
69f4a2713aSLionel Sambuc 
70f4a2713aSLionel Sambuc /// \brief AST_MATCHER(Type, DefineMatcher) { ... }
71f4a2713aSLionel Sambuc /// defines a zero parameter function named DefineMatcher() that returns a
72f4a2713aSLionel Sambuc /// Matcher<Type> object.
73f4a2713aSLionel Sambuc ///
74f4a2713aSLionel Sambuc /// The code between the curly braces has access to the following variables:
75f4a2713aSLionel Sambuc ///
76f4a2713aSLionel Sambuc ///   Node:                  the AST node being matched; its type is Type.
77f4a2713aSLionel Sambuc ///   Finder:                an ASTMatchFinder*.
78f4a2713aSLionel Sambuc ///   Builder:               a BoundNodesTreeBuilder*.
79f4a2713aSLionel Sambuc ///
80f4a2713aSLionel Sambuc /// The code should return true if 'Node' matches.
81f4a2713aSLionel Sambuc #define AST_MATCHER(Type, DefineMatcher)                                       \
82f4a2713aSLionel Sambuc   namespace internal {                                                         \
83f4a2713aSLionel Sambuc   class matcher_##DefineMatcher##Matcher : public MatcherInterface<Type> {     \
84f4a2713aSLionel Sambuc   public:                                                                      \
85f4a2713aSLionel Sambuc     explicit matcher_##DefineMatcher##Matcher() {}                             \
86*0a6a1f1dSLionel Sambuc     bool matches(const Type &Node, ASTMatchFinder *Finder,                     \
87*0a6a1f1dSLionel Sambuc                  BoundNodesTreeBuilder *Builder) const override;               \
88f4a2713aSLionel Sambuc   };                                                                           \
89f4a2713aSLionel Sambuc   }                                                                            \
90f4a2713aSLionel Sambuc   inline internal::Matcher<Type> DefineMatcher() {                             \
91f4a2713aSLionel Sambuc     return internal::makeMatcher(                                              \
92f4a2713aSLionel Sambuc         new internal::matcher_##DefineMatcher##Matcher());                     \
93f4a2713aSLionel Sambuc   }                                                                            \
94f4a2713aSLionel Sambuc   inline bool internal::matcher_##DefineMatcher##Matcher::matches(             \
95f4a2713aSLionel Sambuc       const Type &Node, ASTMatchFinder *Finder,                                \
96f4a2713aSLionel Sambuc       BoundNodesTreeBuilder *Builder) const
97f4a2713aSLionel Sambuc 
98f4a2713aSLionel Sambuc /// \brief AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... }
99f4a2713aSLionel Sambuc /// defines a single-parameter function named DefineMatcher() that returns a
100f4a2713aSLionel Sambuc /// Matcher<Type> object.
101f4a2713aSLionel Sambuc ///
102f4a2713aSLionel Sambuc /// The code between the curly braces has access to the following variables:
103f4a2713aSLionel Sambuc ///
104f4a2713aSLionel Sambuc ///   Node:                  the AST node being matched; its type is Type.
105f4a2713aSLionel Sambuc ///   Param:                 the parameter passed to the function; its type
106f4a2713aSLionel Sambuc ///                          is ParamType.
107f4a2713aSLionel Sambuc ///   Finder:                an ASTMatchFinder*.
108f4a2713aSLionel Sambuc ///   Builder:               a BoundNodesTreeBuilder*.
109f4a2713aSLionel Sambuc ///
110f4a2713aSLionel Sambuc /// The code should return true if 'Node' matches.
111f4a2713aSLionel Sambuc #define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param)                   \
112f4a2713aSLionel Sambuc   AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, 0)
113f4a2713aSLionel Sambuc 
114f4a2713aSLionel Sambuc #define AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param,          \
115f4a2713aSLionel Sambuc                                OverloadId)                                     \
116f4a2713aSLionel Sambuc   namespace internal {                                                         \
117f4a2713aSLionel Sambuc   class matcher_##DefineMatcher##OverloadId##Matcher                           \
118f4a2713aSLionel Sambuc       : public MatcherInterface<Type> {                                        \
119f4a2713aSLionel Sambuc   public:                                                                      \
120f4a2713aSLionel Sambuc     explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
121*0a6a1f1dSLionel Sambuc         ParamType const &A##Param)                                             \
122f4a2713aSLionel Sambuc         : Param(A##Param) {}                                                   \
123*0a6a1f1dSLionel Sambuc     bool matches(const Type &Node, ASTMatchFinder *Finder,                     \
124*0a6a1f1dSLionel Sambuc                  BoundNodesTreeBuilder *Builder) const override;               \
125f4a2713aSLionel Sambuc                                                                                \
126f4a2713aSLionel Sambuc   private:                                                                     \
127*0a6a1f1dSLionel Sambuc     ParamType const Param;                                                     \
128f4a2713aSLionel Sambuc   };                                                                           \
129f4a2713aSLionel Sambuc   }                                                                            \
130*0a6a1f1dSLionel Sambuc   inline internal::Matcher<Type> DefineMatcher(ParamType const &Param) {       \
131f4a2713aSLionel Sambuc     return internal::makeMatcher(                                              \
132f4a2713aSLionel Sambuc         new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param));    \
133f4a2713aSLionel Sambuc   }                                                                            \
134f4a2713aSLionel Sambuc   typedef internal::Matcher<Type>(&DefineMatcher##_Type##OverloadId)(          \
135*0a6a1f1dSLionel Sambuc       ParamType const &Param);                                                 \
136f4a2713aSLionel Sambuc   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
137f4a2713aSLionel Sambuc       const Type &Node, ASTMatchFinder *Finder,                                \
138f4a2713aSLionel Sambuc       BoundNodesTreeBuilder *Builder) const
139f4a2713aSLionel Sambuc 
140f4a2713aSLionel Sambuc /// \brief AST_MATCHER_P2(
141f4a2713aSLionel Sambuc ///     Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
142f4a2713aSLionel Sambuc /// defines a two-parameter function named DefineMatcher() that returns a
143f4a2713aSLionel Sambuc /// Matcher<Type> object.
144f4a2713aSLionel Sambuc ///
145f4a2713aSLionel Sambuc /// The code between the curly braces has access to the following variables:
146f4a2713aSLionel Sambuc ///
147f4a2713aSLionel Sambuc ///   Node:                  the AST node being matched; its type is Type.
148f4a2713aSLionel Sambuc ///   Param1, Param2:        the parameters passed to the function; their types
149f4a2713aSLionel Sambuc ///                          are ParamType1 and ParamType2.
150f4a2713aSLionel Sambuc ///   Finder:                an ASTMatchFinder*.
151f4a2713aSLionel Sambuc ///   Builder:               a BoundNodesTreeBuilder*.
152f4a2713aSLionel Sambuc ///
153f4a2713aSLionel Sambuc /// The code should return true if 'Node' matches.
154f4a2713aSLionel Sambuc #define AST_MATCHER_P2(Type, DefineMatcher, ParamType1, Param1, ParamType2,    \
155f4a2713aSLionel Sambuc                        Param2)                                                 \
156f4a2713aSLionel Sambuc   AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
157f4a2713aSLionel Sambuc                           Param2, 0)
158f4a2713aSLionel Sambuc 
159f4a2713aSLionel Sambuc #define AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1,       \
160f4a2713aSLionel Sambuc                                 ParamType2, Param2, OverloadId)                \
161f4a2713aSLionel Sambuc   namespace internal {                                                         \
162f4a2713aSLionel Sambuc   class matcher_##DefineMatcher##OverloadId##Matcher                           \
163f4a2713aSLionel Sambuc       : public MatcherInterface<Type> {                                        \
164f4a2713aSLionel Sambuc   public:                                                                      \
165*0a6a1f1dSLionel Sambuc     matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1,  \
166*0a6a1f1dSLionel Sambuc                                                  ParamType2 const &A##Param2)  \
167f4a2713aSLionel Sambuc         : Param1(A##Param1), Param2(A##Param2) {}                              \
168*0a6a1f1dSLionel Sambuc     bool matches(const Type &Node, ASTMatchFinder *Finder,                     \
169*0a6a1f1dSLionel Sambuc                  BoundNodesTreeBuilder *Builder) const override;               \
170f4a2713aSLionel Sambuc                                                                                \
171f4a2713aSLionel Sambuc   private:                                                                     \
172*0a6a1f1dSLionel Sambuc     ParamType1 const Param1;                                                   \
173*0a6a1f1dSLionel Sambuc     ParamType2 const Param2;                                                   \
174f4a2713aSLionel Sambuc   };                                                                           \
175f4a2713aSLionel Sambuc   }                                                                            \
176*0a6a1f1dSLionel Sambuc   inline internal::Matcher<Type> DefineMatcher(ParamType1 const &Param1,       \
177*0a6a1f1dSLionel Sambuc                                                ParamType2 const &Param2) {     \
178f4a2713aSLionel Sambuc     return internal::makeMatcher(                                              \
179f4a2713aSLionel Sambuc         new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1,     \
180f4a2713aSLionel Sambuc                                                                    Param2));   \
181f4a2713aSLionel Sambuc   }                                                                            \
182f4a2713aSLionel Sambuc   typedef internal::Matcher<Type>(&DefineMatcher##_Type##OverloadId)(          \
183*0a6a1f1dSLionel Sambuc       ParamType1 const &Param1, ParamType2 const &Param2);                     \
184f4a2713aSLionel Sambuc   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
185f4a2713aSLionel Sambuc       const Type &Node, ASTMatchFinder *Finder,                                \
186f4a2713aSLionel Sambuc       BoundNodesTreeBuilder *Builder) const
187f4a2713aSLionel Sambuc 
188f4a2713aSLionel Sambuc /// \brief Construct a type-list to be passed to the AST_POLYMORPHIC_MATCHER*
189f4a2713aSLionel Sambuc ///   macros.
190f4a2713aSLionel Sambuc ///
191f4a2713aSLionel Sambuc /// You can't pass something like \c TypeList<Foo, Bar> to a macro, because it
192f4a2713aSLionel Sambuc /// will look at that as two arguments. However, you can pass
193f4a2713aSLionel Sambuc /// \c void(TypeList<Foo, Bar>), which works thanks to the parenthesis.
194f4a2713aSLionel Sambuc /// The \c PolymorphicMatcherWithParam* classes will unpack the function type to
195f4a2713aSLionel Sambuc /// extract the TypeList object.
196f4a2713aSLionel Sambuc #define AST_POLYMORPHIC_SUPPORTED_TYPES_1(t1) void(internal::TypeList<t1>)
197f4a2713aSLionel Sambuc #define AST_POLYMORPHIC_SUPPORTED_TYPES_2(t1, t2)                              \
198f4a2713aSLionel Sambuc   void(internal::TypeList<t1, t2>)
199f4a2713aSLionel Sambuc #define AST_POLYMORPHIC_SUPPORTED_TYPES_3(t1, t2, t3)                          \
200f4a2713aSLionel Sambuc   void(internal::TypeList<t1, t2, t3>)
201f4a2713aSLionel Sambuc #define AST_POLYMORPHIC_SUPPORTED_TYPES_4(t1, t2, t3, t4)                      \
202f4a2713aSLionel Sambuc   void(internal::TypeList<t1, t2, t3, t4>)
203f4a2713aSLionel Sambuc #define AST_POLYMORPHIC_SUPPORTED_TYPES_5(t1, t2, t3, t4, t5)                  \
204f4a2713aSLionel Sambuc   void(internal::TypeList<t1, t2, t3, internal::TypeList<t4, t5> >)
205f4a2713aSLionel Sambuc 
206f4a2713aSLionel Sambuc /// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... }
207f4a2713aSLionel Sambuc /// defines a single-parameter function named DefineMatcher() that is
208f4a2713aSLionel Sambuc /// polymorphic in the return type.
209f4a2713aSLionel Sambuc ///
210f4a2713aSLionel Sambuc /// The variables are the same as for AST_MATCHER, but NodeType will be deduced
211f4a2713aSLionel Sambuc /// from the calling context.
212f4a2713aSLionel Sambuc #define AST_POLYMORPHIC_MATCHER(DefineMatcher, ReturnTypesF)                   \
213f4a2713aSLionel Sambuc   namespace internal {                                                         \
214f4a2713aSLionel Sambuc   template <typename NodeType>                                                 \
215f4a2713aSLionel Sambuc   class matcher_##DefineMatcher##Matcher : public MatcherInterface<NodeType> { \
216f4a2713aSLionel Sambuc   public:                                                                      \
217*0a6a1f1dSLionel Sambuc     bool matches(const NodeType &Node, ASTMatchFinder *Finder,                 \
218*0a6a1f1dSLionel Sambuc                  BoundNodesTreeBuilder *Builder) const override;               \
219f4a2713aSLionel Sambuc   };                                                                           \
220f4a2713aSLionel Sambuc   }                                                                            \
221f4a2713aSLionel Sambuc   inline internal::PolymorphicMatcherWithParam0<                               \
222f4a2713aSLionel Sambuc       internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>                \
223f4a2713aSLionel Sambuc   DefineMatcher() {                                                            \
224f4a2713aSLionel Sambuc     return internal::PolymorphicMatcherWithParam0<                             \
225f4a2713aSLionel Sambuc         internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>();           \
226f4a2713aSLionel Sambuc   }                                                                            \
227f4a2713aSLionel Sambuc   template <typename NodeType>                                                 \
228f4a2713aSLionel Sambuc   bool internal::matcher_##DefineMatcher##Matcher<NodeType>::matches(          \
229f4a2713aSLionel Sambuc       const NodeType &Node, ASTMatchFinder *Finder,                            \
230f4a2713aSLionel Sambuc       BoundNodesTreeBuilder *Builder) const
231f4a2713aSLionel Sambuc 
232f4a2713aSLionel Sambuc /// \brief AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... }
233f4a2713aSLionel Sambuc /// defines a single-parameter function named DefineMatcher() that is
234f4a2713aSLionel Sambuc /// polymorphic in the return type.
235f4a2713aSLionel Sambuc ///
236f4a2713aSLionel Sambuc /// The variables are the same as for
237f4a2713aSLionel Sambuc /// AST_MATCHER_P, with the addition of NodeType, which specifies the node type
238f4a2713aSLionel Sambuc /// of the matcher Matcher<NodeType> returned by the function matcher().
239f4a2713aSLionel Sambuc ///
240f4a2713aSLionel Sambuc /// FIXME: Pull out common code with above macro?
241f4a2713aSLionel Sambuc #define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ReturnTypesF, ParamType,      \
242f4a2713aSLionel Sambuc                                   Param)                                       \
243f4a2713aSLionel Sambuc   AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType,   \
244f4a2713aSLionel Sambuc                                      Param, 0)
245f4a2713aSLionel Sambuc 
246f4a2713aSLionel Sambuc #define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF,        \
247f4a2713aSLionel Sambuc                                            ParamType, Param, OverloadId)       \
248f4a2713aSLionel Sambuc   namespace internal {                                                         \
249f4a2713aSLionel Sambuc   template <typename NodeType, typename ParamT>                                \
250f4a2713aSLionel Sambuc   class matcher_##DefineMatcher##OverloadId##Matcher                           \
251f4a2713aSLionel Sambuc       : public MatcherInterface<NodeType> {                                    \
252f4a2713aSLionel Sambuc   public:                                                                      \
253f4a2713aSLionel Sambuc     explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
254*0a6a1f1dSLionel Sambuc         ParamType const &A##Param)                                             \
255f4a2713aSLionel Sambuc         : Param(A##Param) {}                                                   \
256*0a6a1f1dSLionel Sambuc     bool matches(const NodeType &Node, ASTMatchFinder *Finder,                 \
257*0a6a1f1dSLionel Sambuc                  BoundNodesTreeBuilder *Builder) const override;               \
258f4a2713aSLionel Sambuc                                                                                \
259f4a2713aSLionel Sambuc   private:                                                                     \
260*0a6a1f1dSLionel Sambuc     ParamType const Param;                                                     \
261f4a2713aSLionel Sambuc   };                                                                           \
262f4a2713aSLionel Sambuc   }                                                                            \
263f4a2713aSLionel Sambuc   inline internal::PolymorphicMatcherWithParam1<                               \
264f4a2713aSLionel Sambuc       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,       \
265*0a6a1f1dSLionel Sambuc       ReturnTypesF> DefineMatcher(ParamType const &Param) {                    \
266f4a2713aSLionel Sambuc     return internal::PolymorphicMatcherWithParam1<                             \
267f4a2713aSLionel Sambuc         internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,     \
268f4a2713aSLionel Sambuc         ReturnTypesF>(Param);                                                  \
269f4a2713aSLionel Sambuc   }                                                                            \
270f4a2713aSLionel Sambuc   typedef internal::PolymorphicMatcherWithParam1<                              \
271f4a2713aSLionel Sambuc       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,       \
272f4a2713aSLionel Sambuc       ReturnTypesF>(&DefineMatcher##_Type##OverloadId)(                        \
273*0a6a1f1dSLionel Sambuc       ParamType const &Param);                                                 \
274f4a2713aSLionel Sambuc   template <typename NodeType, typename ParamT>                                \
275f4a2713aSLionel Sambuc   bool internal::matcher_##DefineMatcher##OverloadId##Matcher<                 \
276f4a2713aSLionel Sambuc       NodeType, ParamT>::matches(const NodeType &Node, ASTMatchFinder *Finder, \
277f4a2713aSLionel Sambuc                                  BoundNodesTreeBuilder *Builder) const
278f4a2713aSLionel Sambuc 
279f4a2713aSLionel Sambuc /// \brief AST_POLYMORPHIC_MATCHER_P2(
280f4a2713aSLionel Sambuc ///     DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
281f4a2713aSLionel Sambuc /// defines a two-parameter function named matcher() that is polymorphic in
282f4a2713aSLionel Sambuc /// the return type.
283f4a2713aSLionel Sambuc ///
284f4a2713aSLionel Sambuc /// The variables are the same as for AST_MATCHER_P2, with the
285f4a2713aSLionel Sambuc /// addition of NodeType, which specifies the node type of the matcher
286f4a2713aSLionel Sambuc /// Matcher<NodeType> returned by the function DefineMatcher().
287f4a2713aSLionel Sambuc #define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ReturnTypesF, ParamType1,    \
288f4a2713aSLionel Sambuc                                    Param1, ParamType2, Param2)                 \
289f4a2713aSLionel Sambuc   AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType1, \
290f4a2713aSLionel Sambuc                                       Param1, ParamType2, Param2, 0)
291f4a2713aSLionel Sambuc 
292f4a2713aSLionel Sambuc #define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF,       \
293f4a2713aSLionel Sambuc                                             ParamType1, Param1, ParamType2,    \
294f4a2713aSLionel Sambuc                                             Param2, OverloadId)                \
295f4a2713aSLionel Sambuc   namespace internal {                                                         \
296f4a2713aSLionel Sambuc   template <typename NodeType, typename ParamT1, typename ParamT2>             \
297f4a2713aSLionel Sambuc   class matcher_##DefineMatcher##OverloadId##Matcher                           \
298f4a2713aSLionel Sambuc       : public MatcherInterface<NodeType> {                                    \
299f4a2713aSLionel Sambuc   public:                                                                      \
300*0a6a1f1dSLionel Sambuc     matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1,  \
301*0a6a1f1dSLionel Sambuc                                                  ParamType2 const &A##Param2)  \
302f4a2713aSLionel Sambuc         : Param1(A##Param1), Param2(A##Param2) {}                              \
303*0a6a1f1dSLionel Sambuc      bool matches(const NodeType &Node, ASTMatchFinder *Finder,                \
304*0a6a1f1dSLionel Sambuc                   BoundNodesTreeBuilder *Builder) const override;              \
305f4a2713aSLionel Sambuc                                                                                \
306f4a2713aSLionel Sambuc   private:                                                                     \
307*0a6a1f1dSLionel Sambuc     ParamType1 const Param1;                                                   \
308*0a6a1f1dSLionel Sambuc     ParamType2 const Param2;                                                   \
309f4a2713aSLionel Sambuc   };                                                                           \
310f4a2713aSLionel Sambuc   }                                                                            \
311f4a2713aSLionel Sambuc   inline internal::PolymorphicMatcherWithParam2<                               \
312f4a2713aSLionel Sambuc       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,      \
313*0a6a1f1dSLionel Sambuc       ParamType2, ReturnTypesF> DefineMatcher(ParamType1 const &Param1,        \
314*0a6a1f1dSLionel Sambuc                                               ParamType2 const &Param2) {      \
315f4a2713aSLionel Sambuc     return internal::PolymorphicMatcherWithParam2<                             \
316f4a2713aSLionel Sambuc         internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,    \
317f4a2713aSLionel Sambuc         ParamType2, ReturnTypesF>(Param1, Param2);                             \
318f4a2713aSLionel Sambuc   }                                                                            \
319f4a2713aSLionel Sambuc   typedef internal::PolymorphicMatcherWithParam2<                              \
320f4a2713aSLionel Sambuc       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,      \
321f4a2713aSLionel Sambuc       ParamType2, ReturnTypesF>(&DefineMatcher##_Type##OverloadId)(            \
322*0a6a1f1dSLionel Sambuc       ParamType1 const &Param1, ParamType2 const &Param2);                     \
323f4a2713aSLionel Sambuc   template <typename NodeType, typename ParamT1, typename ParamT2>             \
324f4a2713aSLionel Sambuc   bool internal::matcher_##DefineMatcher##OverloadId##Matcher<                 \
325f4a2713aSLionel Sambuc       NodeType, ParamT1, ParamT2>::matches(                                    \
326f4a2713aSLionel Sambuc       const NodeType &Node, ASTMatchFinder *Finder,                            \
327f4a2713aSLionel Sambuc       BoundNodesTreeBuilder *Builder) const
328f4a2713aSLionel Sambuc 
329f4a2713aSLionel Sambuc /// \brief Creates a variadic matcher for both a specific \c Type as well as
330f4a2713aSLionel Sambuc /// the corresponding \c TypeLoc.
331f4a2713aSLionel Sambuc #define AST_TYPE_MATCHER(NodeType, MatcherName)                                \
332f4a2713aSLionel Sambuc   const internal::VariadicDynCastAllOfMatcher<Type, NodeType> MatcherName
333f4a2713aSLionel Sambuc // FIXME: add a matcher for TypeLoc derived classes using its custom casting
334f4a2713aSLionel Sambuc // API (no longer dyn_cast) if/when we need such matching
335f4a2713aSLionel Sambuc 
336f4a2713aSLionel Sambuc /// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
337f4a2713aSLionel Sambuc /// the matcher \c MatcherName that can be used to traverse from one \c Type
338f4a2713aSLionel Sambuc /// to another.
339f4a2713aSLionel Sambuc ///
340f4a2713aSLionel Sambuc /// For a specific \c SpecificType, the traversal is done using
341f4a2713aSLionel Sambuc /// \c SpecificType::FunctionName. The existence of such a function determines
342f4a2713aSLionel Sambuc /// whether a corresponding matcher can be used on \c SpecificType.
343f4a2713aSLionel Sambuc #define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF)     \
344f4a2713aSLionel Sambuc   namespace internal {                                                         \
345f4a2713aSLionel Sambuc   template <typename T> struct TypeMatcher##MatcherName##Getter {              \
346f4a2713aSLionel Sambuc     static QualType (T::*value())() const { return &T::FunctionName; }         \
347f4a2713aSLionel Sambuc   };                                                                           \
348f4a2713aSLionel Sambuc   }                                                                            \
349f4a2713aSLionel Sambuc   const internal::TypeTraversePolymorphicMatcher<                              \
350f4a2713aSLionel Sambuc       QualType, internal::TypeMatcher##MatcherName##Getter,                    \
351f4a2713aSLionel Sambuc       internal::TypeTraverseMatcher, ReturnTypesF>::Func MatcherName
352f4a2713aSLionel Sambuc 
353f4a2713aSLionel Sambuc /// \brief AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works
354f4a2713aSLionel Sambuc /// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs.
355f4a2713aSLionel Sambuc #define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF)  \
356f4a2713aSLionel Sambuc   namespace internal {                                                         \
357f4a2713aSLionel Sambuc   template <typename T> struct TypeLocMatcher##MatcherName##Getter {           \
358f4a2713aSLionel Sambuc     static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; }     \
359f4a2713aSLionel Sambuc   };                                                                           \
360f4a2713aSLionel Sambuc   }                                                                            \
361f4a2713aSLionel Sambuc   const internal::TypeTraversePolymorphicMatcher<                              \
362f4a2713aSLionel Sambuc       TypeLoc, internal::TypeLocMatcher##MatcherName##Getter,                  \
363f4a2713aSLionel Sambuc       internal::TypeLocTraverseMatcher, ReturnTypesF>::Func MatcherName##Loc;  \
364f4a2713aSLionel Sambuc   AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF)
365f4a2713aSLionel Sambuc 
366*0a6a1f1dSLionel Sambuc #endif
367