14da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//===--- ASTMatchersMacros.h - Structural query framework -------*- C++ -*-===//
24da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//
34da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//                     The LLVM Compiler Infrastructure
44da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//
54da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// This file is distributed under the University of Illinois Open Source
64da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// License. See LICENSE.TXT for details.
74da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//
84da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//===----------------------------------------------------------------------===//
94da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//
104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//  Defines macros that enable us to define new matchers in a single place.
114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//  Since a matcher is a function which returns a Matcher<T> object, where
124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//  T is the type of the actual implementation of the matcher, the macros allow
134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//  us to write matchers like functions and take care of the definition of the
144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//  class boilerplate.
154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//
164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//  Note that when you define a matcher with an AST_MATCHER* macro, only the
174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//  function which creates the matcher goes into the current namespace - the
184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//  class that implements the actual matcher, which gets returned by the
194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//  generator function, is put into the 'internal' namespace. This allows us
204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//  to only have the functions (which is all the user cares about) in the
214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//  'ast_matchers' namespace and hide the boilerplate.
224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//
234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//  To define a matcher in user code, always put it into the clang::ast_matchers
244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//  namespace and refer to the internal types via the 'internal::':
254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//
264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//  namespace clang {
274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//  namespace ast_matchers {
284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//  AST_MATCHER_P(MemberExpr, Member,
294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//                internal::Matcher<ValueDecl>, InnerMatcher) {
304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//    return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//  }
324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//  } // end namespace ast_matchers
334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//  } // end namespace clang
344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//
354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//===----------------------------------------------------------------------===//
364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#ifndef LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H
384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H
394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief AST_MATCHER(Type, DefineMatcher) { ... }
414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// defines a zero parameter function named DefineMatcher() that returns a
424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Matcher<Type> object.
434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///
444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// The code between the curly braces has access to the following variables:
454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///
464da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///   Node:                  the AST node being matched; its type is Type.
474da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///   Finder:                an ASTMatchFinder*.
484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///   Builder:               a BoundNodesTreeBuilder*.
494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///
504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// The code should return true if 'Node' matches.
514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#define AST_MATCHER(Type, DefineMatcher)                                       \
524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  namespace internal {                                                         \
530e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen  class matcher_##DefineMatcher##Matcher : public MatcherInterface<Type> {     \
547bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek  public:                                                                      \
550e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen    explicit matcher_##DefineMatcher##Matcher() {}                             \
567bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek    virtual bool matches(const Type &Node, ASTMatchFinder *Finder,             \
577bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek                         BoundNodesTreeBuilder *Builder) const;                \
584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  };                                                                           \
594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  }                                                                            \
604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  inline internal::Matcher<Type> DefineMatcher() {                             \
614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek    return internal::makeMatcher(                                              \
620e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen        new internal::matcher_##DefineMatcher##Matcher());                     \
634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  }                                                                            \
640e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen  inline bool internal::matcher_##DefineMatcher##Matcher::matches(             \
654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      const Type &Node, ASTMatchFinder *Finder,                                \
664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      BoundNodesTreeBuilder *Builder) const
674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... }
694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// defines a single-parameter function named DefineMatcher() that returns a
704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Matcher<Type> object.
714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///
724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// The code between the curly braces has access to the following variables:
734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///
744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///   Node:                  the AST node being matched; its type is Type.
754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///   Param:                 the parameter passed to the function; its type
764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///                          is ParamType.
774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///   Finder:                an ASTMatchFinder*.
784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///   Builder:               a BoundNodesTreeBuilder*.
794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///
804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// The code should return true if 'Node' matches.
814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param)                   \
82415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek  AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, 0)
83415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek
84415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek#define AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param,          \
85415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek                               OverloadId)                                     \
864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  namespace internal {                                                         \
87415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek  class matcher_##DefineMatcher##OverloadId##Matcher                           \
88415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek      : public MatcherInterface<Type> {                                        \
897bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek  public:                                                                      \
90415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek    explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
91415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek        const ParamType &A##Param)                                             \
920e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen        : Param(A##Param) {}                                                   \
937bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek    virtual bool matches(const Type &Node, ASTMatchFinder *Finder,             \
947bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek                         BoundNodesTreeBuilder *Builder) const;                \
950e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen                                                                               \
967bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek  private:                                                                     \
974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek    const ParamType Param;                                                     \
984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  };                                                                           \
994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  }                                                                            \
1004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  inline internal::Matcher<Type> DefineMatcher(const ParamType &Param) {       \
1014da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek    return internal::makeMatcher(                                              \
102415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek        new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param));    \
1034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  }                                                                            \
1040e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen  typedef internal::Matcher<Type>(&DefineMatcher##_Type##OverloadId)(          \
1050e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen      const ParamType &Param);                                                 \
106415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek  inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
1074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      const Type &Node, ASTMatchFinder *Finder,                                \
1084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      BoundNodesTreeBuilder *Builder) const
1094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
1104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief AST_MATCHER_P2(
1114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///     Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
1124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// defines a two-parameter function named DefineMatcher() that returns a
1134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Matcher<Type> object.
1144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///
1154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// The code between the curly braces has access to the following variables:
1164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///
1174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///   Node:                  the AST node being matched; its type is Type.
1184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///   Param1, Param2:        the parameters passed to the function; their types
1194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///                          are ParamType1 and ParamType2.
1204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///   Finder:                an ASTMatchFinder*.
1214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///   Builder:               a BoundNodesTreeBuilder*.
1224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///
1234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// The code should return true if 'Node' matches.
1247bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek#define AST_MATCHER_P2(Type, DefineMatcher, ParamType1, Param1, ParamType2,    \
1257bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek                       Param2)                                                 \
126415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek  AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
127415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek                          Param2, 0)
128415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek
129415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek#define AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1,       \
130415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek                                ParamType2, Param2, OverloadId)                \
1314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  namespace internal {                                                         \
132415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek  class matcher_##DefineMatcher##OverloadId##Matcher                           \
133415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek      : public MatcherInterface<Type> {                                        \
1347bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek  public:                                                                      \
135415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek    matcher_##DefineMatcher##OverloadId##Matcher(const ParamType1 &A##Param1,  \
136415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek                                                 const ParamType2 &A##Param2)  \
1370e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen        : Param1(A##Param1), Param2(A##Param2) {}                              \
1387bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek    virtual bool matches(const Type &Node, ASTMatchFinder *Finder,             \
1397bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek                         BoundNodesTreeBuilder *Builder) const;                \
1400e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen                                                                               \
1417bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek  private:                                                                     \
1424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek    const ParamType1 Param1;                                                   \
1434da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek    const ParamType2 Param2;                                                   \
1444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  };                                                                           \
1454da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  }                                                                            \
1460e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen  inline internal::Matcher<Type> DefineMatcher(const ParamType1 &Param1,       \
1470e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen                                               const ParamType2 &Param2) {     \
1484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek    return internal::makeMatcher(                                              \
149415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek        new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1,     \
150415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek                                                                   Param2));   \
1514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  }                                                                            \
1520e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen  typedef internal::Matcher<Type>(&DefineMatcher##_Type##OverloadId)(          \
1530e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen      const ParamType1 &Param1, const ParamType2 &Param2);                     \
154415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek  inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
1554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      const Type &Node, ASTMatchFinder *Finder,                                \
1564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek      BoundNodesTreeBuilder *Builder) const
1574da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
158ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// \brief Construct a type-list to be passed to the AST_POLYMORPHIC_MATCHER*
159ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen///   macros.
160ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen///
161ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// You can't pass something like \c TypeList<Foo, Bar> to a macro, because it
162ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// will look at that as two arguments. However, you can pass
163ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// \c void(TypeList<Foo, Bar>), which works thanks to the parenthesis.
164ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// The \c PolymorphicMatcherWithParam* classes will unpack the function type to
165ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// extract the TypeList object.
1663f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen#define AST_POLYMORPHIC_SUPPORTED_TYPES_1(t1) void(internal::TypeList<t1>)
167ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen#define AST_POLYMORPHIC_SUPPORTED_TYPES_2(t1, t2)                              \
168ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  void(internal::TypeList<t1, t2>)
169ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen#define AST_POLYMORPHIC_SUPPORTED_TYPES_3(t1, t2, t3)                          \
170ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  void(internal::TypeList<t1, t2, t3>)
171ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen#define AST_POLYMORPHIC_SUPPORTED_TYPES_4(t1, t2, t3, t4)                      \
172ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  void(internal::TypeList<t1, t2, t3, t4>)
173ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen#define AST_POLYMORPHIC_SUPPORTED_TYPES_5(t1, t2, t3, t4, t5)                  \
174ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  void(internal::TypeList<t1, t2, t3, t4, t5>)
175ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen
176415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek/// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... }
177415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek/// defines a single-parameter function named DefineMatcher() that is
178415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek/// polymorphic in the return type.
179415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek///
180415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek/// The variables are the same as for AST_MATCHER, but NodeType will be deduced
181415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek/// from the calling context.
182ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen#define AST_POLYMORPHIC_MATCHER(DefineMatcher, ReturnTypesF)                   \
183415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek  namespace internal {                                                         \
184415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek  template <typename NodeType>                                                 \
1850e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen  class matcher_##DefineMatcher##Matcher : public MatcherInterface<NodeType> { \
186415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek  public:                                                                      \
187415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek    virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder,         \
188415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek                         BoundNodesTreeBuilder *Builder) const;                \
189415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek  };                                                                           \
190415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek  }                                                                            \
191415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek  inline internal::PolymorphicMatcherWithParam0<                               \
1920e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen      internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>                \
193ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  DefineMatcher() {                                                            \
194415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek    return internal::PolymorphicMatcherWithParam0<                             \
1950e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen        internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>();           \
196415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek  }                                                                            \
197415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek  template <typename NodeType>                                                 \
1980e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen  bool internal::matcher_##DefineMatcher##Matcher<NodeType>::matches(          \
1990e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen      const NodeType &Node, ASTMatchFinder *Finder,                            \
2000e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen      BoundNodesTreeBuilder *Builder) const
201415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek
2024da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... }
2034da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// defines a single-parameter function named DefineMatcher() that is
2044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// polymorphic in the return type.
2054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///
2064da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// The variables are the same as for
2074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// AST_MATCHER_P, with the addition of NodeType, which specifies the node type
2084da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// of the matcher Matcher<NodeType> returned by the function matcher().
2094da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///
2104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// FIXME: Pull out common code with above macro?
211ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen#define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ReturnTypesF, ParamType,      \
212ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                  Param)                                       \
213ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType,   \
214ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                     Param, 0)
215415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek
216ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen#define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF,        \
217ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                           ParamType, Param, OverloadId)       \
2184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  namespace internal {                                                         \
2194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  template <typename NodeType, typename ParamT>                                \
220415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek  class matcher_##DefineMatcher##OverloadId##Matcher                           \
221415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek      : public MatcherInterface<NodeType> {                                    \
2227bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek  public:                                                                      \
223415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek    explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
224415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek        const ParamType &A##Param)                                             \
2250e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen        : Param(A##Param) {}                                                   \
2267bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek    virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder,         \
2277bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek                         BoundNodesTreeBuilder *Builder) const;                \
2280e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen                                                                               \
2297bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek  private:                                                                     \
2304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek    const ParamType Param;                                                     \
2314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  };                                                                           \
2324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  }                                                                            \
2334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  inline internal::PolymorphicMatcherWithParam1<                               \
234ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen      internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,       \
2350e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen      ReturnTypesF> DefineMatcher(const ParamType &Param) {                    \
2364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek    return internal::PolymorphicMatcherWithParam1<                             \
237ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen        internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,     \
238ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen        ReturnTypesF>(Param);                                                  \
2394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  }                                                                            \
2400e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen  typedef internal::PolymorphicMatcherWithParam1<                              \
2410e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen      internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,       \
2420e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen      ReturnTypesF>(&DefineMatcher##_Type##OverloadId)(                        \
2430e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen      const ParamType &Param);                                                 \
2444da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  template <typename NodeType, typename ParamT>                                \
245415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek  bool internal::matcher_##DefineMatcher##OverloadId##Matcher<                 \
246415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek      NodeType, ParamT>::matches(const NodeType &Node, ASTMatchFinder *Finder, \
247415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek                                 BoundNodesTreeBuilder *Builder) const
2484da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
2494da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief AST_POLYMORPHIC_MATCHER_P2(
2504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///     DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
2514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// defines a two-parameter function named matcher() that is polymorphic in
2524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// the return type.
2534da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek///
2544da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// The variables are the same as for AST_MATCHER_P2, with the
2554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// addition of NodeType, which specifies the node type of the matcher
2564da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Matcher<NodeType> returned by the function DefineMatcher().
257ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen#define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ReturnTypesF, ParamType1,    \
258ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                   Param1, ParamType2, Param2)                 \
259ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen  AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType1, \
260ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                      Param1, ParamType2, Param2, 0)
261415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek
262ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen#define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF,       \
263ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                            ParamType1, Param1, ParamType2,    \
264ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen                                            Param2, OverloadId)                \
2654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  namespace internal {                                                         \
2664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  template <typename NodeType, typename ParamT1, typename ParamT2>             \
267415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek  class matcher_##DefineMatcher##OverloadId##Matcher                           \
268415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek      : public MatcherInterface<NodeType> {                                    \
2697bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek  public:                                                                      \
270415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek    matcher_##DefineMatcher##OverloadId##Matcher(const ParamType1 &A##Param1,  \
271415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek                                                 const ParamType2 &A##Param2)  \
2720e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen        : Param1(A##Param1), Param2(A##Param2) {}                              \
2737bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek    virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder,         \
2747bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek                         BoundNodesTreeBuilder *Builder) const;                \
2750e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen                                                                               \
2767bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek  private:                                                                     \
2774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek    const ParamType1 Param1;                                                   \
2784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek    const ParamType2 Param2;                                                   \
2794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  };                                                                           \
2804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  }                                                                            \
2814da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  inline internal::PolymorphicMatcherWithParam2<                               \
282415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek      internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,      \
2830e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen      ParamType2, ReturnTypesF> DefineMatcher(const ParamType1 &Param1,        \
2840e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen                                              const ParamType2 &Param2) {      \
2854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek    return internal::PolymorphicMatcherWithParam2<                             \
286415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek        internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,    \
287ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen        ParamType2, ReturnTypesF>(Param1, Param2);                             \
2884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  }                                                                            \
2890e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen  typedef internal::PolymorphicMatcherWithParam2<                              \
2900e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen      internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,      \
2910e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen      ParamType2, ReturnTypesF>(&DefineMatcher##_Type##OverloadId)(            \
2920e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen      const ParamType1 &Param1, const ParamType2 &Param2);                     \
2934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek  template <typename NodeType, typename ParamT1, typename ParamT2>             \
294415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek  bool internal::matcher_##DefineMatcher##OverloadId##Matcher<                 \
295415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek      NodeType, ParamT1, ParamT2>::matches(                                    \
296415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek      const NodeType &Node, ASTMatchFinder *Finder,                            \
297415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek      BoundNodesTreeBuilder *Builder) const
2984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek
299ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper/// \brief Creates a variadic matcher for both a specific \c Type as well as
300ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper/// the corresponding \c TypeLoc.
301ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper#define AST_TYPE_MATCHER(NodeType, MatcherName)                                \
3025be093c0ef46c7749c942d0d9056af6dc3d591a4David Blaikie  const internal::VariadicDynCastAllOfMatcher<Type, NodeType> MatcherName
3035be093c0ef46c7749c942d0d9056af6dc3d591a4David Blaikie// FIXME: add a matcher for TypeLoc derived classes using its custom casting
3045be093c0ef46c7749c942d0d9056af6dc3d591a4David Blaikie// API (no longer dyn_cast) if/when we need such matching
305ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
306ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper/// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
307ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper/// the matcher \c MatcherName that can be used to traverse from one \c Type
308ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper/// to another.
309a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper///
310ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper/// For a specific \c SpecificType, the traversal is done using
311ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper/// \c SpecificType::FunctionName. The existance of such a function determines
312ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper/// whether a corresponding matcher can be used on \c SpecificType.
3133f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen#define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF)     \
3143f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen  namespace internal {                                                         \
3153f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen  template <typename T> struct TypeMatcher##MatcherName##Getter {              \
3163f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen    static QualType (T::*value())() const { return &T::FunctionName; }         \
3173f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen  };                                                                           \
3187bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek  }                                                                            \
3193f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen  const internal::TypeTraversePolymorphicMatcher<                              \
3203f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen      QualType, internal::TypeMatcher##MatcherName##Getter,                    \
3213f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen      internal::TypeTraverseMatcher, ReturnTypesF>::Func MatcherName
322ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper
323ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper/// \brief AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works
324ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper/// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs.
3253f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen#define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF)  \
3263f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen  namespace internal {                                                         \
3273f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen  template <typename T> struct TypeLocMatcher##MatcherName##Getter {           \
3283f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen    static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; }     \
3293f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen  };                                                                           \
330ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper  }                                                                            \
3313f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen  const internal::TypeTraversePolymorphicMatcher<                              \
3323f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen      TypeLoc, internal::TypeLocMatcher##MatcherName##Getter,                  \
3333f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen      internal::TypeLocTraverseMatcher, ReturnTypesF>::Func MatcherName##Loc;  \
3343f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen  AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF)
335a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper
3364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#endif // LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H
337