Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. //===--- ASTMatchersMacros.h - Structural query framework -------*- C++ -*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. //  Defines macros that enable us to define new matchers in a single place.
  10. //  Since a matcher is a function which returns a Matcher<T> object, where
  11. //  T is the type of the actual implementation of the matcher, the macros allow
  12. //  us to write matchers like functions and take care of the definition of the
  13. //  class boilerplate.
  14. //
  15. //  Note that when you define a matcher with an AST_MATCHER* macro, only the
  16. //  function which creates the matcher goes into the current namespace - the
  17. //  class that implements the actual matcher, which gets returned by the
  18. //  generator function, is put into the 'internal' namespace. This allows us
  19. //  to only have the functions (which is all the user cares about) in the
  20. //  'ast_matchers' namespace and hide the boilerplate.
  21. //
  22. //  To define a matcher in user code, put it into your own namespace. This would
  23. //  help to prevent ODR violations in case a matcher with the same name is
  24. //  defined in multiple translation units:
  25. //
  26. //  namespace my_matchers {
  27. //  AST_MATCHER_P(clang::MemberExpr, Member,
  28. //                clang::ast_matchers::internal::Matcher<clang::ValueDecl>,
  29. //                InnerMatcher) {
  30. //    return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
  31. //  }
  32. //  } // namespace my_matchers
  33. //
  34. //  Alternatively, an unnamed namespace may be used:
  35. //
  36. //  namespace clang {
  37. //  namespace ast_matchers {
  38. //  namespace {
  39. //  AST_MATCHER_P(MemberExpr, Member,
  40. //                internal::Matcher<ValueDecl>, InnerMatcher) {
  41. //    return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
  42. //  }
  43. //  } // namespace
  44. //  } // namespace ast_matchers
  45. //  } // namespace clang
  46. //
  47. //===----------------------------------------------------------------------===//
  48.  
  49. #ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
  50. #define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
  51.  
  52. /// AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) { ... }
  53. /// defines a zero parameter function named DefineMatcher() that returns a
  54. /// ReturnType object.
  55. #define AST_MATCHER_FUNCTION(ReturnType, DefineMatcher)                        \
  56.   inline ReturnType DefineMatcher##_getInstance();                             \
  57.   inline ReturnType DefineMatcher() {                                          \
  58.     return ::clang::ast_matchers::internal::MemoizedMatcher<                   \
  59.         ReturnType, DefineMatcher##_getInstance>::getInstance();               \
  60.   }                                                                            \
  61.   inline ReturnType DefineMatcher##_getInstance()
  62.  
  63. /// AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) {
  64. /// ... }
  65. /// defines a single-parameter function named DefineMatcher() that returns a
  66. /// ReturnType object.
  67. ///
  68. /// The code between the curly braces has access to the following variables:
  69. ///
  70. ///   Param:                 the parameter passed to the function; its type
  71. ///                          is ParamType.
  72. ///
  73. /// The code should return an instance of ReturnType.
  74. #define AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param)    \
  75.   AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, Param, \
  76.                                   0)
  77. #define AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType,  \
  78.                                         Param, OverloadId)                     \
  79.   inline ReturnType DefineMatcher(ParamType const &Param);                     \
  80.   typedef ReturnType (&DefineMatcher##_Type##OverloadId)(ParamType const &);   \
  81.   inline ReturnType DefineMatcher(ParamType const &Param)
  82.  
  83. /// AST_MATCHER(Type, DefineMatcher) { ... }
  84. /// defines a zero parameter function named DefineMatcher() that returns a
  85. /// Matcher<Type> object.
  86. ///
  87. /// The code between the curly braces has access to the following variables:
  88. ///
  89. ///   Node:                  the AST node being matched; its type is Type.
  90. ///   Finder:                an ASTMatchFinder*.
  91. ///   Builder:               a BoundNodesTreeBuilder*.
  92. ///
  93. /// The code should return true if 'Node' matches.
  94. #define AST_MATCHER(Type, DefineMatcher)                                       \
  95.   namespace internal {                                                         \
  96.   class matcher_##DefineMatcher##Matcher                                       \
  97.       : public ::clang::ast_matchers::internal::MatcherInterface<Type> {       \
  98.   public:                                                                      \
  99.     explicit matcher_##DefineMatcher##Matcher() = default;                     \
  100.     bool matches(const Type &Node,                                             \
  101.                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \
  102.                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \
  103.                      *Builder) const override;                                 \
  104.   };                                                                           \
  105.   }                                                                            \
  106.   inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher() {      \
  107.     return ::clang::ast_matchers::internal::makeMatcher(                       \
  108.         new internal::matcher_##DefineMatcher##Matcher());                     \
  109.   }                                                                            \
  110.   inline bool internal::matcher_##DefineMatcher##Matcher::matches(             \
  111.       const Type &Node,                                                        \
  112.       ::clang::ast_matchers::internal::ASTMatchFinder *Finder,                 \
  113.       ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
  114.  
  115. /// AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... }
  116. /// defines a single-parameter function named DefineMatcher() that returns a
  117. /// Matcher<Type> object.
  118. ///
  119. /// The code between the curly braces has access to the following variables:
  120. ///
  121. ///   Node:                  the AST node being matched; its type is Type.
  122. ///   Param:                 the parameter passed to the function; its type
  123. ///                          is ParamType.
  124. ///   Finder:                an ASTMatchFinder*.
  125. ///   Builder:               a BoundNodesTreeBuilder*.
  126. ///
  127. /// The code should return true if 'Node' matches.
  128. #define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param)                   \
  129.   AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, 0)
  130.  
  131. #define AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param,          \
  132.                                OverloadId)                                     \
  133.   namespace internal {                                                         \
  134.   class matcher_##DefineMatcher##OverloadId##Matcher                           \
  135.       : public ::clang::ast_matchers::internal::MatcherInterface<Type> {       \
  136.   public:                                                                      \
  137.     explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
  138.         ParamType const &A##Param)                                             \
  139.         : Param(A##Param) {}                                                   \
  140.     bool matches(const Type &Node,                                             \
  141.                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \
  142.                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \
  143.                      *Builder) const override;                                 \
  144.                                                                                \
  145.   private:                                                                     \
  146.     ParamType Param;                                                           \
  147.   };                                                                           \
  148.   }                                                                            \
  149.   inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher(         \
  150.       ParamType const &Param) {                                                \
  151.     return ::clang::ast_matchers::internal::makeMatcher(                       \
  152.         new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param));    \
  153.   }                                                                            \
  154.   typedef ::clang::ast_matchers::internal::Matcher<Type> (                     \
  155.       &DefineMatcher##_Type##OverloadId)(ParamType const &Param);              \
  156.   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
  157.       const Type &Node,                                                        \
  158.       ::clang::ast_matchers::internal::ASTMatchFinder *Finder,                 \
  159.       ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
  160.  
  161. /// AST_MATCHER_P2(
  162. ///     Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
  163. /// defines a two-parameter function named DefineMatcher() that returns a
  164. /// Matcher<Type> object.
  165. ///
  166. /// The code between the curly braces has access to the following variables:
  167. ///
  168. ///   Node:                  the AST node being matched; its type is Type.
  169. ///   Param1, Param2:        the parameters passed to the function; their types
  170. ///                          are ParamType1 and ParamType2.
  171. ///   Finder:                an ASTMatchFinder*.
  172. ///   Builder:               a BoundNodesTreeBuilder*.
  173. ///
  174. /// The code should return true if 'Node' matches.
  175. #define AST_MATCHER_P2(Type, DefineMatcher, ParamType1, Param1, ParamType2,    \
  176.                        Param2)                                                 \
  177.   AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
  178.                           Param2, 0)
  179.  
  180. #define AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1,       \
  181.                                 ParamType2, Param2, OverloadId)                \
  182.   namespace internal {                                                         \
  183.   class matcher_##DefineMatcher##OverloadId##Matcher                           \
  184.       : public ::clang::ast_matchers::internal::MatcherInterface<Type> {       \
  185.   public:                                                                      \
  186.     matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1,  \
  187.                                                  ParamType2 const &A##Param2)  \
  188.         : Param1(A##Param1), Param2(A##Param2) {}                              \
  189.     bool matches(const Type &Node,                                             \
  190.                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \
  191.                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \
  192.                      *Builder) const override;                                 \
  193.                                                                                \
  194.   private:                                                                     \
  195.     ParamType1 Param1;                                                         \
  196.     ParamType2 Param2;                                                         \
  197.   };                                                                           \
  198.   }                                                                            \
  199.   inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher(         \
  200.       ParamType1 const &Param1, ParamType2 const &Param2) {                    \
  201.     return ::clang::ast_matchers::internal::makeMatcher(                       \
  202.         new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1,     \
  203.                                                                    Param2));   \
  204.   }                                                                            \
  205.   typedef ::clang::ast_matchers::internal::Matcher<Type> (                     \
  206.       &DefineMatcher##_Type##OverloadId)(ParamType1 const &Param1,             \
  207.                                          ParamType2 const &Param2);            \
  208.   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
  209.       const Type &Node,                                                        \
  210.       ::clang::ast_matchers::internal::ASTMatchFinder *Finder,                 \
  211.       ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
  212.  
  213. /// Construct a type-list to be passed to the AST_POLYMORPHIC_MATCHER*
  214. ///   macros.
  215. ///
  216. /// You can't pass something like \c TypeList<Foo, Bar> to a macro, because it
  217. /// will look at that as two arguments. However, you can pass
  218. /// \c void(TypeList<Foo, Bar>), which works thanks to the parenthesis.
  219. /// The \c PolymorphicMatcherWithParam* classes will unpack the function type to
  220. /// extract the TypeList object.
  221. #define AST_POLYMORPHIC_SUPPORTED_TYPES(...)                                   \
  222.   void(::clang::ast_matchers::internal::TypeList<__VA_ARGS__>)
  223.  
  224. /// AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... }
  225. /// defines a single-parameter function named DefineMatcher() that is
  226. /// polymorphic in the return type.
  227. ///
  228. /// The variables are the same as for AST_MATCHER, but NodeType will be deduced
  229. /// from the calling context.
  230. #define AST_POLYMORPHIC_MATCHER(DefineMatcher, ReturnTypesF)                   \
  231.   namespace internal {                                                         \
  232.   template <typename NodeType>                                                 \
  233.   class matcher_##DefineMatcher##Matcher                                       \
  234.       : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> {   \
  235.   public:                                                                      \
  236.     bool matches(const NodeType &Node,                                         \
  237.                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \
  238.                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \
  239.                      *Builder) const override;                                 \
  240.   };                                                                           \
  241.   }                                                                            \
  242.   inline ::clang::ast_matchers::internal::PolymorphicMatcher<                  \
  243.       internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>                \
  244.   DefineMatcher() {                                                            \
  245.     return ::clang::ast_matchers::internal::PolymorphicMatcher<                \
  246.         internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>();           \
  247.   }                                                                            \
  248.   template <typename NodeType>                                                 \
  249.   bool internal::matcher_##DefineMatcher##Matcher<NodeType>::matches(          \
  250.       const NodeType &Node,                                                    \
  251.       ::clang::ast_matchers::internal::ASTMatchFinder *Finder,                 \
  252.       ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
  253.  
  254. /// AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... }
  255. /// defines a single-parameter function named DefineMatcher() that is
  256. /// polymorphic in the return type.
  257. ///
  258. /// The variables are the same as for
  259. /// AST_MATCHER_P, with the addition of NodeType, which specifies the node type
  260. /// of the matcher Matcher<NodeType> returned by the function matcher().
  261. ///
  262. /// FIXME: Pull out common code with above macro?
  263. #define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ReturnTypesF, ParamType,      \
  264.                                   Param)                                       \
  265.   AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType,   \
  266.                                      Param, 0)
  267.  
  268. #define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF,        \
  269.                                            ParamType, Param, OverloadId)       \
  270.   namespace internal {                                                         \
  271.   template <typename NodeType, typename ParamT>                                \
  272.   class matcher_##DefineMatcher##OverloadId##Matcher                           \
  273.       : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> {   \
  274.   public:                                                                      \
  275.     explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
  276.         ParamType const &A##Param)                                             \
  277.         : Param(A##Param) {}                                                   \
  278.     bool matches(const NodeType &Node,                                         \
  279.                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \
  280.                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \
  281.                      *Builder) const override;                                 \
  282.                                                                                \
  283.   private:                                                                     \
  284.     ParamType Param;                                                           \
  285.   };                                                                           \
  286.   }                                                                            \
  287.   inline ::clang::ast_matchers::internal::PolymorphicMatcher<                  \
  288.       internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,    \
  289.       ParamType>                                                               \
  290.   DefineMatcher(ParamType const &Param) {                                      \
  291.     return ::clang::ast_matchers::internal::PolymorphicMatcher<                \
  292.         internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,  \
  293.         ParamType>(Param);                                                     \
  294.   }                                                                            \
  295.   typedef ::clang::ast_matchers::internal::PolymorphicMatcher<                 \
  296.       internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,    \
  297.       ParamType> (&DefineMatcher##_Type##OverloadId)(ParamType const &Param);  \
  298.   template <typename NodeType, typename ParamT>                                \
  299.   bool internal::                                                              \
  300.       matcher_##DefineMatcher##OverloadId##Matcher<NodeType, ParamT>::matches( \
  301.           const NodeType &Node,                                                \
  302.           ::clang::ast_matchers::internal::ASTMatchFinder *Finder,             \
  303.           ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder)     \
  304.           const
  305.  
  306. /// AST_POLYMORPHIC_MATCHER_P2(
  307. ///     DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
  308. /// defines a two-parameter function named matcher() that is polymorphic in
  309. /// the return type.
  310. ///
  311. /// The variables are the same as for AST_MATCHER_P2, with the
  312. /// addition of NodeType, which specifies the node type of the matcher
  313. /// Matcher<NodeType> returned by the function DefineMatcher().
  314. #define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ReturnTypesF, ParamType1,    \
  315.                                    Param1, ParamType2, Param2)                 \
  316.   AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType1, \
  317.                                       Param1, ParamType2, Param2, 0)
  318.  
  319. #define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF,       \
  320.                                             ParamType1, Param1, ParamType2,    \
  321.                                             Param2, OverloadId)                \
  322.   namespace internal {                                                         \
  323.   template <typename NodeType, typename ParamT1, typename ParamT2>             \
  324.   class matcher_##DefineMatcher##OverloadId##Matcher                           \
  325.       : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> {   \
  326.   public:                                                                      \
  327.     matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1,  \
  328.                                                  ParamType2 const &A##Param2)  \
  329.         : Param1(A##Param1), Param2(A##Param2) {}                              \
  330.     bool matches(const NodeType &Node,                                         \
  331.                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \
  332.                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \
  333.                      *Builder) const override;                                 \
  334.                                                                                \
  335.   private:                                                                     \
  336.     ParamType1 Param1;                                                         \
  337.     ParamType2 Param2;                                                         \
  338.   };                                                                           \
  339.   }                                                                            \
  340.   inline ::clang::ast_matchers::internal::PolymorphicMatcher<                  \
  341.       internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,    \
  342.       ParamType1, ParamType2>                                                  \
  343.   DefineMatcher(ParamType1 const &Param1, ParamType2 const &Param2) {          \
  344.     return ::clang::ast_matchers::internal::PolymorphicMatcher<                \
  345.         internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,  \
  346.         ParamType1, ParamType2>(Param1, Param2);                               \
  347.   }                                                                            \
  348.   typedef ::clang::ast_matchers::internal::PolymorphicMatcher<                 \
  349.       internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,    \
  350.       ParamType1, ParamType2> (&DefineMatcher##_Type##OverloadId)(             \
  351.       ParamType1 const &Param1, ParamType2 const &Param2);                     \
  352.   template <typename NodeType, typename ParamT1, typename ParamT2>             \
  353.   bool internal::matcher_##DefineMatcher##OverloadId##Matcher<                 \
  354.       NodeType, ParamT1, ParamT2>::                                            \
  355.       matches(const NodeType &Node,                                            \
  356.               ::clang::ast_matchers::internal::ASTMatchFinder *Finder,         \
  357.               ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) \
  358.           const
  359.  
  360. // FIXME: add a matcher for TypeLoc derived classes using its custom casting
  361. // API (no longer dyn_cast) if/when we need such matching
  362.  
  363. #define AST_TYPE_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName,              \
  364.                                        ReturnTypesF)                           \
  365.   namespace internal {                                                         \
  366.   template <typename T> struct TypeMatcher##MatcherName##Getter {              \
  367.     static QualType (T::*value())() const { return &T::FunctionName; }         \
  368.   };                                                                           \
  369.   }                                                                            \
  370.   extern const ::clang::ast_matchers::internal::                               \
  371.       TypeTraversePolymorphicMatcher<                                          \
  372.           QualType,                                                            \
  373.           ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter,   \
  374.           ::clang::ast_matchers::internal::TypeTraverseMatcher,                \
  375.           ReturnTypesF>::Func MatcherName
  376.  
  377. #define AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF)               \
  378.   const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher<       \
  379.       QualType,                                                                \
  380.       ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter,       \
  381.       ::clang::ast_matchers::internal::TypeTraverseMatcher,                    \
  382.       ReturnTypesF>::Func MatcherName
  383.  
  384. /// AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
  385. /// the matcher \c MatcherName that can be used to traverse from one \c Type
  386. /// to another.
  387. ///
  388. /// For a specific \c SpecificType, the traversal is done using
  389. /// \c SpecificType::FunctionName. The existence of such a function determines
  390. /// whether a corresponding matcher can be used on \c SpecificType.
  391. #define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF)     \
  392.   namespace internal {                                                         \
  393.   template <typename T> struct TypeMatcher##MatcherName##Getter {              \
  394.     static QualType (T::*value())() const { return &T::FunctionName; }         \
  395.   };                                                                           \
  396.   }                                                                            \
  397.   const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher<       \
  398.       QualType,                                                                \
  399.       ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter,       \
  400.       ::clang::ast_matchers::internal::TypeTraverseMatcher,                    \
  401.       ReturnTypesF>::Func MatcherName
  402.  
  403. #define AST_TYPELOC_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName,           \
  404.                                           ReturnTypesF)                        \
  405.   namespace internal {                                                         \
  406.   template <typename T> struct TypeLocMatcher##MatcherName##Getter {           \
  407.     static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; }     \
  408.   };                                                                           \
  409.   }                                                                            \
  410.   extern const ::clang::ast_matchers::internal::                               \
  411.       TypeTraversePolymorphicMatcher<                                          \
  412.           TypeLoc,                                                             \
  413.           ::clang::ast_matchers::internal::                                    \
  414.               TypeLocMatcher##MatcherName##Getter,                             \
  415.           ::clang::ast_matchers::internal::TypeLocTraverseMatcher,             \
  416.           ReturnTypesF>::Func MatcherName##Loc;                                \
  417.   AST_TYPE_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName##Type, ReturnTypesF)
  418.  
  419. #define AST_TYPELOC_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF)            \
  420.   const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher<       \
  421.       TypeLoc,                                                                 \
  422.       ::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter,    \
  423.       ::clang::ast_matchers::internal::TypeLocTraverseMatcher,                 \
  424.       ReturnTypesF>::Func MatcherName##Loc;                                    \
  425.   AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF)
  426.  
  427. /// AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works
  428. /// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs.
  429. #define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF)  \
  430.   namespace internal {                                                         \
  431.   template <typename T> struct TypeLocMatcher##MatcherName##Getter {           \
  432.     static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; }     \
  433.   };                                                                           \
  434.   }                                                                            \
  435.   const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher<       \
  436.       TypeLoc,                                                                 \
  437.       ::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter,    \
  438.       ::clang::ast_matchers::internal::TypeLocTraverseMatcher,                 \
  439.       ReturnTypesF>::Func MatcherName##Loc;                                    \
  440.   AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF)
  441.  
  442. /// AST_MATCHER_REGEX(Type, DefineMatcher, Param) { ... }
  443. /// defines a function named DefineMatcher() that takes a regular expression
  444. /// string paramater and an optional RegexFlags parameter and returns a
  445. /// Matcher<Type> object.
  446. ///
  447. /// The code between the curly braces has access to the following variables:
  448. ///
  449. ///   Node:                  the AST node being matched; its type is Type.
  450. ///   Param:                 a pointer to an \ref llvm::Regex object
  451. ///   Finder:                an ASTMatchFinder*.
  452. ///   Builder:               a BoundNodesTreeBuilder*.
  453. ///
  454. /// The code should return true if 'Node' matches.
  455. #define AST_MATCHER_REGEX(Type, DefineMatcher, Param)                          \
  456.   AST_MATCHER_REGEX_OVERLOAD(Type, DefineMatcher, Param, 0)
  457.  
  458. #define AST_MATCHER_REGEX_OVERLOAD(Type, DefineMatcher, Param, OverloadId)     \
  459.   namespace internal {                                                         \
  460.   class matcher_##DefineMatcher##OverloadId##Matcher                           \
  461.       : public ::clang::ast_matchers::internal::MatcherInterface<Type> {       \
  462.   public:                                                                      \
  463.     explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
  464.         std::shared_ptr<llvm::Regex> RE)                                       \
  465.         : Param(std::move(RE)) {}                                              \
  466.     bool matches(const Type &Node,                                             \
  467.                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \
  468.                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \
  469.                      *Builder) const override;                                 \
  470.                                                                                \
  471.   private:                                                                     \
  472.     std::shared_ptr<llvm::Regex> Param;                                        \
  473.   };                                                                           \
  474.   }                                                                            \
  475.   inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher(         \
  476.       llvm::StringRef Param, llvm::Regex::RegexFlags RegexFlags) {             \
  477.     return ::clang::ast_matchers::internal::makeMatcher(                       \
  478.         new internal::matcher_##DefineMatcher##OverloadId##Matcher(            \
  479.             ::clang::ast_matchers::internal::createAndVerifyRegex(             \
  480.                 Param, RegexFlags, #DefineMatcher)));                          \
  481.   }                                                                            \
  482.   inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher(         \
  483.       llvm::StringRef Param) {                                                 \
  484.     return DefineMatcher(Param, llvm::Regex::NoFlags);                         \
  485.   }                                                                            \
  486.                                                                                \
  487.   typedef ::clang::ast_matchers::internal::Matcher<Type> (                     \
  488.       &DefineMatcher##_Type##OverloadId##Flags)(llvm::StringRef,               \
  489.                                                 llvm::Regex::RegexFlags);      \
  490.   typedef ::clang::ast_matchers::internal::Matcher<Type> (                     \
  491.       &DefineMatcher##_Type##OverloadId)(llvm::StringRef);                     \
  492.   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
  493.       const Type &Node,                                                        \
  494.       ::clang::ast_matchers::internal::ASTMatchFinder *Finder,                 \
  495.       ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
  496.  
  497. /// AST_POLYMORPHIC_MATCHER_REGEX(DefineMatcher, ReturnTypesF, Param) { ... }
  498. /// defines a function named DefineMatcher() that takes a regular expression
  499. /// string paramater and an optional RegexFlags parameter that is polymorphic in
  500. /// the return type.
  501. ///
  502. /// The variables are the same as for
  503. /// AST_MATCHER_REGEX, with the addition of NodeType, which specifies the node
  504. /// type of the matcher Matcher<NodeType> returned by the function matcher().
  505. #define AST_POLYMORPHIC_MATCHER_REGEX(DefineMatcher, ReturnTypesF, Param)      \
  506.   AST_POLYMORPHIC_MATCHER_REGEX_OVERLOAD(DefineMatcher, ReturnTypesF, Param, 0)
  507.  
  508. #define AST_POLYMORPHIC_MATCHER_REGEX_OVERLOAD(DefineMatcher, ReturnTypesF,    \
  509.                                                Param, OverloadId)              \
  510.   namespace internal {                                                         \
  511.   template <typename NodeType, typename ParamT>                                \
  512.   class matcher_##DefineMatcher##OverloadId##Matcher                           \
  513.       : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> {   \
  514.   public:                                                                      \
  515.     explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
  516.         std::shared_ptr<llvm::Regex> RE)                                       \
  517.         : Param(std::move(RE)) {}                                              \
  518.     bool matches(const NodeType &Node,                                         \
  519.                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \
  520.                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \
  521.                      *Builder) const override;                                 \
  522.                                                                                \
  523.   private:                                                                     \
  524.     std::shared_ptr<llvm::Regex> Param;                                        \
  525.   };                                                                           \
  526.   }                                                                            \
  527.   inline ::clang::ast_matchers::internal::PolymorphicMatcher<                  \
  528.       internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,    \
  529.       std::shared_ptr<llvm::Regex>>                                            \
  530.   DefineMatcher(llvm::StringRef Param, llvm::Regex::RegexFlags RegexFlags) {   \
  531.     return ::clang::ast_matchers::internal::PolymorphicMatcher<                \
  532.         internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,  \
  533.         std::shared_ptr<llvm::Regex>>(                                         \
  534.         ::clang::ast_matchers::internal::createAndVerifyRegex(                 \
  535.             Param, RegexFlags, #DefineMatcher));                               \
  536.   }                                                                            \
  537.   inline ::clang::ast_matchers::internal::PolymorphicMatcher<                  \
  538.       internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,    \
  539.       std::shared_ptr<llvm::Regex>>                                            \
  540.   DefineMatcher(llvm::StringRef Param) {                                       \
  541.     return DefineMatcher(Param, llvm::Regex::NoFlags);                         \
  542.   }                                                                            \
  543.   typedef ::clang::ast_matchers::internal::PolymorphicMatcher<                 \
  544.       internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,    \
  545.       std::shared_ptr<llvm::Regex>> (                                          \
  546.       &DefineMatcher##_Type##OverloadId##Flags)(                               \
  547.       llvm::StringRef Param, llvm::Regex::RegexFlags RegexFlags);              \
  548.   typedef ::clang::ast_matchers::internal::PolymorphicMatcher<                 \
  549.       internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,    \
  550.       std::shared_ptr<llvm::Regex>> (&DefineMatcher##_Type##OverloadId)(       \
  551.       llvm::StringRef Param);                                                  \
  552.   template <typename NodeType, typename ParamT>                                \
  553.   bool internal::                                                              \
  554.       matcher_##DefineMatcher##OverloadId##Matcher<NodeType, ParamT>::matches( \
  555.           const NodeType &Node,                                                \
  556.           ::clang::ast_matchers::internal::ASTMatchFinder *Finder,             \
  557.           ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder)     \
  558.           const
  559.  
  560. #endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
  561.