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