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