clang  6.0.0svn
ASTMatchersMacros.h
Go to the documentation of this file.
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() = default; \
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 #define AST_TYPE_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName, \
371  ReturnTypesF) \
372  namespace internal { \
373  template <typename T> struct TypeMatcher##MatcherName##Getter { \
374  static QualType (T::*value())() const { return &T::FunctionName; } \
375  }; \
376  } \
377  extern const ::clang::ast_matchers::internal:: \
378  TypeTraversePolymorphicMatcher< \
379  QualType, \
380  ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter, \
381  ::clang::ast_matchers::internal::TypeTraverseMatcher, \
382  ReturnTypesF>::Func MatcherName
383 
384 #define AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF) \
385  const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \
386  QualType, \
387  ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter, \
388  ::clang::ast_matchers::internal::TypeTraverseMatcher, \
389  ReturnTypesF>::Func MatcherName
390 
391 /// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
392 /// the matcher \c MatcherName that can be used to traverse from one \c Type
393 /// to another.
394 ///
395 /// For a specific \c SpecificType, the traversal is done using
396 /// \c SpecificType::FunctionName. The existence of such a function determines
397 /// whether a corresponding matcher can be used on \c SpecificType.
398 #define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \
399  namespace internal { \
400  template <typename T> struct TypeMatcher##MatcherName##Getter { \
401  static QualType (T::*value())() const { return &T::FunctionName; } \
402  }; \
403  } \
404  const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \
405  QualType, \
406  ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter, \
407  ::clang::ast_matchers::internal::TypeTraverseMatcher, \
408  ReturnTypesF>::Func MatcherName
409 
410 #define AST_TYPELOC_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName, \
411  ReturnTypesF) \
412  namespace internal { \
413  template <typename T> struct TypeLocMatcher##MatcherName##Getter { \
414  static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; } \
415  }; \
416  } \
417  extern const ::clang::ast_matchers::internal:: \
418  TypeTraversePolymorphicMatcher< \
419  TypeLoc, \
420  ::clang::ast_matchers::internal:: \
421  TypeLocMatcher##MatcherName##Getter, \
422  ::clang::ast_matchers::internal::TypeLocTraverseMatcher, \
423  ReturnTypesF>::Func MatcherName##Loc; \
424  AST_TYPE_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName##Type, ReturnTypesF)
425 
426 #define AST_TYPELOC_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF) \
427  const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \
428  TypeLoc, \
429  ::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter, \
430  ::clang::ast_matchers::internal::TypeLocTraverseMatcher, \
431  ReturnTypesF>::Func MatcherName##Loc; \
432  AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF)
433 
434 /// \brief AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works
435 /// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs.
436 #define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \
437  namespace internal { \
438  template <typename T> struct TypeLocMatcher##MatcherName##Getter { \
439  static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; } \
440  }; \
441  } \
442  const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \
443  TypeLoc, \
444  ::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter, \
445  ::clang::ast_matchers::internal::TypeLocTraverseMatcher, \
446  ReturnTypesF>::Func MatcherName##Loc; \
447  AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF)
448 
449 #endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H