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