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