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/// \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 // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
405