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