10b57cec5SDimitry Andric //===--- ASTMatchersMacros.h - Structural query framework -------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric //  Defines macros that enable us to define new matchers in a single place.
100b57cec5SDimitry Andric //  Since a matcher is a function which returns a Matcher<T> object, where
110b57cec5SDimitry Andric //  T is the type of the actual implementation of the matcher, the macros allow
120b57cec5SDimitry Andric //  us to write matchers like functions and take care of the definition of the
130b57cec5SDimitry Andric //  class boilerplate.
140b57cec5SDimitry Andric //
150b57cec5SDimitry Andric //  Note that when you define a matcher with an AST_MATCHER* macro, only the
160b57cec5SDimitry Andric //  function which creates the matcher goes into the current namespace - the
170b57cec5SDimitry Andric //  class that implements the actual matcher, which gets returned by the
180b57cec5SDimitry Andric //  generator function, is put into the 'internal' namespace. This allows us
190b57cec5SDimitry Andric //  to only have the functions (which is all the user cares about) in the
200b57cec5SDimitry Andric //  'ast_matchers' namespace and hide the boilerplate.
210b57cec5SDimitry Andric //
220b57cec5SDimitry Andric //  To define a matcher in user code, put it into your own namespace. This would
230b57cec5SDimitry Andric //  help to prevent ODR violations in case a matcher with the same name is
240b57cec5SDimitry Andric //  defined in multiple translation units:
250b57cec5SDimitry Andric //
260b57cec5SDimitry Andric //  namespace my_matchers {
270b57cec5SDimitry Andric //  AST_MATCHER_P(clang::MemberExpr, Member,
280b57cec5SDimitry Andric //                clang::ast_matchers::internal::Matcher<clang::ValueDecl>,
290b57cec5SDimitry Andric //                InnerMatcher) {
300b57cec5SDimitry Andric //    return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
310b57cec5SDimitry Andric //  }
320b57cec5SDimitry Andric //  } // namespace my_matchers
330b57cec5SDimitry Andric //
340b57cec5SDimitry Andric //  Alternatively, an unnamed namespace may be used:
350b57cec5SDimitry Andric //
360b57cec5SDimitry Andric //  namespace clang {
370b57cec5SDimitry Andric //  namespace ast_matchers {
380b57cec5SDimitry Andric //  namespace {
390b57cec5SDimitry Andric //  AST_MATCHER_P(MemberExpr, Member,
400b57cec5SDimitry Andric //                internal::Matcher<ValueDecl>, InnerMatcher) {
410b57cec5SDimitry Andric //    return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
420b57cec5SDimitry Andric //  }
430b57cec5SDimitry Andric //  } // namespace
440b57cec5SDimitry Andric //  } // namespace ast_matchers
450b57cec5SDimitry Andric //  } // namespace clang
460b57cec5SDimitry Andric //
470b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
480b57cec5SDimitry Andric 
490b57cec5SDimitry Andric #ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
500b57cec5SDimitry Andric #define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric /// AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) { ... }
530b57cec5SDimitry Andric /// defines a zero parameter function named DefineMatcher() that returns a
540b57cec5SDimitry Andric /// ReturnType object.
550b57cec5SDimitry Andric #define AST_MATCHER_FUNCTION(ReturnType, DefineMatcher)                        \
560b57cec5SDimitry Andric   inline ReturnType DefineMatcher##_getInstance();                             \
570b57cec5SDimitry Andric   inline ReturnType DefineMatcher() {                                          \
580b57cec5SDimitry Andric     return ::clang::ast_matchers::internal::MemoizedMatcher<                   \
590b57cec5SDimitry Andric         ReturnType, DefineMatcher##_getInstance>::getInstance();               \
600b57cec5SDimitry Andric   }                                                                            \
610b57cec5SDimitry Andric   inline ReturnType DefineMatcher##_getInstance()
620b57cec5SDimitry Andric 
630b57cec5SDimitry Andric /// AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) {
640b57cec5SDimitry Andric /// ... }
650b57cec5SDimitry Andric /// defines a single-parameter function named DefineMatcher() that returns a
660b57cec5SDimitry Andric /// ReturnType object.
670b57cec5SDimitry Andric ///
680b57cec5SDimitry Andric /// The code between the curly braces has access to the following variables:
690b57cec5SDimitry Andric ///
700b57cec5SDimitry Andric ///   Param:                 the parameter passed to the function; its type
710b57cec5SDimitry Andric ///                          is ParamType.
720b57cec5SDimitry Andric ///
730b57cec5SDimitry Andric /// The code should return an instance of ReturnType.
740b57cec5SDimitry Andric #define AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param)    \
750b57cec5SDimitry Andric   AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, Param, \
760b57cec5SDimitry Andric                                   0)
770b57cec5SDimitry Andric #define AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType,  \
780b57cec5SDimitry Andric                                         Param, OverloadId)                     \
790b57cec5SDimitry Andric   inline ReturnType DefineMatcher(ParamType const &Param);                     \
800b57cec5SDimitry Andric   typedef ReturnType (&DefineMatcher##_Type##OverloadId)(ParamType const &);   \
810b57cec5SDimitry Andric   inline ReturnType DefineMatcher(ParamType const &Param)
820b57cec5SDimitry Andric 
830b57cec5SDimitry Andric /// AST_MATCHER(Type, DefineMatcher) { ... }
840b57cec5SDimitry Andric /// defines a zero parameter function named DefineMatcher() that returns a
850b57cec5SDimitry Andric /// Matcher<Type> object.
860b57cec5SDimitry Andric ///
870b57cec5SDimitry Andric /// The code between the curly braces has access to the following variables:
880b57cec5SDimitry Andric ///
890b57cec5SDimitry Andric ///   Node:                  the AST node being matched; its type is Type.
900b57cec5SDimitry Andric ///   Finder:                an ASTMatchFinder*.
910b57cec5SDimitry Andric ///   Builder:               a BoundNodesTreeBuilder*.
920b57cec5SDimitry Andric ///
930b57cec5SDimitry Andric /// The code should return true if 'Node' matches.
940b57cec5SDimitry Andric #define AST_MATCHER(Type, DefineMatcher)                                       \
950b57cec5SDimitry Andric   namespace internal {                                                         \
960b57cec5SDimitry Andric   class matcher_##DefineMatcher##Matcher                                       \
970b57cec5SDimitry Andric       : public ::clang::ast_matchers::internal::MatcherInterface<Type> {       \
980b57cec5SDimitry Andric   public:                                                                      \
990b57cec5SDimitry Andric     explicit matcher_##DefineMatcher##Matcher() = default;                     \
1000b57cec5SDimitry Andric     bool matches(const Type &Node,                                             \
1010b57cec5SDimitry Andric                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \
1020b57cec5SDimitry Andric                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \
1030b57cec5SDimitry Andric                      *Builder) const override;                                 \
1040b57cec5SDimitry Andric   };                                                                           \
1050b57cec5SDimitry Andric   }                                                                            \
1060b57cec5SDimitry Andric   inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher() {      \
1070b57cec5SDimitry Andric     return ::clang::ast_matchers::internal::makeMatcher(                       \
1080b57cec5SDimitry Andric         new internal::matcher_##DefineMatcher##Matcher());                     \
1090b57cec5SDimitry Andric   }                                                                            \
1100b57cec5SDimitry Andric   inline bool internal::matcher_##DefineMatcher##Matcher::matches(             \
1110b57cec5SDimitry Andric       const Type &Node,                                                        \
1120b57cec5SDimitry Andric       ::clang::ast_matchers::internal::ASTMatchFinder *Finder,                 \
1130b57cec5SDimitry Andric       ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
1140b57cec5SDimitry Andric 
1150b57cec5SDimitry Andric /// AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... }
1160b57cec5SDimitry Andric /// defines a single-parameter function named DefineMatcher() that returns a
1170b57cec5SDimitry Andric /// Matcher<Type> object.
1180b57cec5SDimitry Andric ///
1190b57cec5SDimitry Andric /// The code between the curly braces has access to the following variables:
1200b57cec5SDimitry Andric ///
1210b57cec5SDimitry Andric ///   Node:                  the AST node being matched; its type is Type.
1220b57cec5SDimitry Andric ///   Param:                 the parameter passed to the function; its type
1230b57cec5SDimitry Andric ///                          is ParamType.
1240b57cec5SDimitry Andric ///   Finder:                an ASTMatchFinder*.
1250b57cec5SDimitry Andric ///   Builder:               a BoundNodesTreeBuilder*.
1260b57cec5SDimitry Andric ///
1270b57cec5SDimitry Andric /// The code should return true if 'Node' matches.
1280b57cec5SDimitry Andric #define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param)                   \
1290b57cec5SDimitry Andric   AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, 0)
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric #define AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param,          \
1320b57cec5SDimitry Andric                                OverloadId)                                     \
1330b57cec5SDimitry Andric   namespace internal {                                                         \
1340b57cec5SDimitry Andric   class matcher_##DefineMatcher##OverloadId##Matcher                           \
1350b57cec5SDimitry Andric       : public ::clang::ast_matchers::internal::MatcherInterface<Type> {       \
1360b57cec5SDimitry Andric   public:                                                                      \
1370b57cec5SDimitry Andric     explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
1380b57cec5SDimitry Andric         ParamType const &A##Param)                                             \
1390b57cec5SDimitry Andric         : Param(A##Param) {}                                                   \
1400b57cec5SDimitry Andric     bool matches(const Type &Node,                                             \
1410b57cec5SDimitry Andric                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \
1420b57cec5SDimitry Andric                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \
1430b57cec5SDimitry Andric                      *Builder) const override;                                 \
1440b57cec5SDimitry Andric                                                                                \
1450b57cec5SDimitry Andric   private:                                                                     \
1460b57cec5SDimitry Andric     ParamType Param;                                                           \
1470b57cec5SDimitry Andric   };                                                                           \
1480b57cec5SDimitry Andric   }                                                                            \
1490b57cec5SDimitry Andric   inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher(         \
1500b57cec5SDimitry Andric       ParamType const &Param) {                                                \
1510b57cec5SDimitry Andric     return ::clang::ast_matchers::internal::makeMatcher(                       \
1520b57cec5SDimitry Andric         new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param));    \
1530b57cec5SDimitry Andric   }                                                                            \
1540b57cec5SDimitry Andric   typedef ::clang::ast_matchers::internal::Matcher<Type> (                     \
1550b57cec5SDimitry Andric       &DefineMatcher##_Type##OverloadId)(ParamType const &Param);              \
1560b57cec5SDimitry Andric   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
1570b57cec5SDimitry Andric       const Type &Node,                                                        \
1580b57cec5SDimitry Andric       ::clang::ast_matchers::internal::ASTMatchFinder *Finder,                 \
1590b57cec5SDimitry Andric       ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
1600b57cec5SDimitry Andric 
1610b57cec5SDimitry Andric /// AST_MATCHER_P2(
1620b57cec5SDimitry Andric ///     Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
1630b57cec5SDimitry Andric /// defines a two-parameter function named DefineMatcher() that returns a
1640b57cec5SDimitry Andric /// Matcher<Type> object.
1650b57cec5SDimitry Andric ///
1660b57cec5SDimitry Andric /// The code between the curly braces has access to the following variables:
1670b57cec5SDimitry Andric ///
1680b57cec5SDimitry Andric ///   Node:                  the AST node being matched; its type is Type.
1690b57cec5SDimitry Andric ///   Param1, Param2:        the parameters passed to the function; their types
1700b57cec5SDimitry Andric ///                          are ParamType1 and ParamType2.
1710b57cec5SDimitry Andric ///   Finder:                an ASTMatchFinder*.
1720b57cec5SDimitry Andric ///   Builder:               a BoundNodesTreeBuilder*.
1730b57cec5SDimitry Andric ///
1740b57cec5SDimitry Andric /// The code should return true if 'Node' matches.
1750b57cec5SDimitry Andric #define AST_MATCHER_P2(Type, DefineMatcher, ParamType1, Param1, ParamType2,    \
1760b57cec5SDimitry Andric                        Param2)                                                 \
1770b57cec5SDimitry Andric   AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
1780b57cec5SDimitry Andric                           Param2, 0)
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric #define AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1,       \
1810b57cec5SDimitry Andric                                 ParamType2, Param2, OverloadId)                \
1820b57cec5SDimitry Andric   namespace internal {                                                         \
1830b57cec5SDimitry Andric   class matcher_##DefineMatcher##OverloadId##Matcher                           \
1840b57cec5SDimitry Andric       : public ::clang::ast_matchers::internal::MatcherInterface<Type> {       \
1850b57cec5SDimitry Andric   public:                                                                      \
1860b57cec5SDimitry Andric     matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1,  \
1870b57cec5SDimitry Andric                                                  ParamType2 const &A##Param2)  \
1880b57cec5SDimitry Andric         : Param1(A##Param1), Param2(A##Param2) {}                              \
1890b57cec5SDimitry Andric     bool matches(const Type &Node,                                             \
1900b57cec5SDimitry Andric                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \
1910b57cec5SDimitry Andric                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \
1920b57cec5SDimitry Andric                      *Builder) const override;                                 \
1930b57cec5SDimitry Andric                                                                                \
1940b57cec5SDimitry Andric   private:                                                                     \
1950b57cec5SDimitry Andric     ParamType1 Param1;                                                         \
1960b57cec5SDimitry Andric     ParamType2 Param2;                                                         \
1970b57cec5SDimitry Andric   };                                                                           \
1980b57cec5SDimitry Andric   }                                                                            \
1990b57cec5SDimitry Andric   inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher(         \
2000b57cec5SDimitry Andric       ParamType1 const &Param1, ParamType2 const &Param2) {                    \
2010b57cec5SDimitry Andric     return ::clang::ast_matchers::internal::makeMatcher(                       \
2020b57cec5SDimitry Andric         new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1,     \
2030b57cec5SDimitry Andric                                                                    Param2));   \
2040b57cec5SDimitry Andric   }                                                                            \
2050b57cec5SDimitry Andric   typedef ::clang::ast_matchers::internal::Matcher<Type> (                     \
2060b57cec5SDimitry Andric       &DefineMatcher##_Type##OverloadId)(ParamType1 const &Param1,             \
2070b57cec5SDimitry Andric                                          ParamType2 const &Param2);            \
2080b57cec5SDimitry Andric   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
2090b57cec5SDimitry Andric       const Type &Node,                                                        \
2100b57cec5SDimitry Andric       ::clang::ast_matchers::internal::ASTMatchFinder *Finder,                 \
2110b57cec5SDimitry Andric       ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
2120b57cec5SDimitry Andric 
2130b57cec5SDimitry Andric /// Construct a type-list to be passed to the AST_POLYMORPHIC_MATCHER*
2140b57cec5SDimitry Andric ///   macros.
2150b57cec5SDimitry Andric ///
2160b57cec5SDimitry Andric /// You can't pass something like \c TypeList<Foo, Bar> to a macro, because it
2170b57cec5SDimitry Andric /// will look at that as two arguments. However, you can pass
2180b57cec5SDimitry Andric /// \c void(TypeList<Foo, Bar>), which works thanks to the parenthesis.
2190b57cec5SDimitry Andric /// The \c PolymorphicMatcherWithParam* classes will unpack the function type to
2200b57cec5SDimitry Andric /// extract the TypeList object.
2210b57cec5SDimitry Andric #define AST_POLYMORPHIC_SUPPORTED_TYPES(...)                                   \
2220b57cec5SDimitry Andric   void(::clang::ast_matchers::internal::TypeList<__VA_ARGS__>)
2230b57cec5SDimitry Andric 
2240b57cec5SDimitry Andric /// AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... }
2250b57cec5SDimitry Andric /// defines a single-parameter function named DefineMatcher() that is
2260b57cec5SDimitry Andric /// polymorphic in the return type.
2270b57cec5SDimitry Andric ///
2280b57cec5SDimitry Andric /// The variables are the same as for AST_MATCHER, but NodeType will be deduced
2290b57cec5SDimitry Andric /// from the calling context.
2300b57cec5SDimitry Andric #define AST_POLYMORPHIC_MATCHER(DefineMatcher, ReturnTypesF)                   \
2310b57cec5SDimitry Andric   namespace internal {                                                         \
2320b57cec5SDimitry Andric   template <typename NodeType>                                                 \
2330b57cec5SDimitry Andric   class matcher_##DefineMatcher##Matcher                                       \
2340b57cec5SDimitry Andric       : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> {   \
2350b57cec5SDimitry Andric   public:                                                                      \
2360b57cec5SDimitry Andric     bool matches(const NodeType &Node,                                         \
2370b57cec5SDimitry Andric                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \
2380b57cec5SDimitry Andric                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \
2390b57cec5SDimitry Andric                      *Builder) const override;                                 \
2400b57cec5SDimitry Andric   };                                                                           \
2410b57cec5SDimitry Andric   }                                                                            \
2420b57cec5SDimitry Andric   inline ::clang::ast_matchers::internal::PolymorphicMatcher<                  \
2430b57cec5SDimitry Andric       internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>                \
2440b57cec5SDimitry Andric   DefineMatcher() {                                                            \
2450b57cec5SDimitry Andric     return ::clang::ast_matchers::internal::PolymorphicMatcher<                \
2460b57cec5SDimitry Andric         internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>();           \
2470b57cec5SDimitry Andric   }                                                                            \
2480b57cec5SDimitry Andric   template <typename NodeType>                                                 \
2490b57cec5SDimitry Andric   bool internal::matcher_##DefineMatcher##Matcher<NodeType>::matches(          \
2500b57cec5SDimitry Andric       const NodeType &Node,                                                    \
2510b57cec5SDimitry Andric       ::clang::ast_matchers::internal::ASTMatchFinder *Finder,                 \
2520b57cec5SDimitry Andric       ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
2530b57cec5SDimitry Andric 
2540b57cec5SDimitry Andric /// AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... }
2550b57cec5SDimitry Andric /// defines a single-parameter function named DefineMatcher() that is
2560b57cec5SDimitry Andric /// polymorphic in the return type.
2570b57cec5SDimitry Andric ///
2580b57cec5SDimitry Andric /// The variables are the same as for
2590b57cec5SDimitry Andric /// AST_MATCHER_P, with the addition of NodeType, which specifies the node type
2600b57cec5SDimitry Andric /// of the matcher Matcher<NodeType> returned by the function matcher().
2610b57cec5SDimitry Andric ///
2620b57cec5SDimitry Andric /// FIXME: Pull out common code with above macro?
2630b57cec5SDimitry Andric #define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ReturnTypesF, ParamType,      \
2640b57cec5SDimitry Andric                                   Param)                                       \
2650b57cec5SDimitry Andric   AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType,   \
2660b57cec5SDimitry Andric                                      Param, 0)
2670b57cec5SDimitry Andric 
2680b57cec5SDimitry Andric #define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF,        \
2690b57cec5SDimitry Andric                                            ParamType, Param, OverloadId)       \
2700b57cec5SDimitry Andric   namespace internal {                                                         \
2710b57cec5SDimitry Andric   template <typename NodeType, typename ParamT>                                \
2720b57cec5SDimitry Andric   class matcher_##DefineMatcher##OverloadId##Matcher                           \
2730b57cec5SDimitry Andric       : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> {   \
2740b57cec5SDimitry Andric   public:                                                                      \
2750b57cec5SDimitry Andric     explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
2760b57cec5SDimitry Andric         ParamType const &A##Param)                                             \
2770b57cec5SDimitry Andric         : Param(A##Param) {}                                                   \
2780b57cec5SDimitry Andric     bool matches(const NodeType &Node,                                         \
2790b57cec5SDimitry Andric                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \
2800b57cec5SDimitry Andric                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \
2810b57cec5SDimitry Andric                      *Builder) const override;                                 \
2820b57cec5SDimitry Andric                                                                                \
2830b57cec5SDimitry Andric   private:                                                                     \
2840b57cec5SDimitry Andric     ParamType Param;                                                           \
2850b57cec5SDimitry Andric   };                                                                           \
2860b57cec5SDimitry Andric   }                                                                            \
2870b57cec5SDimitry Andric   inline ::clang::ast_matchers::internal::PolymorphicMatcher<                  \
2880b57cec5SDimitry Andric       internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,    \
2890b57cec5SDimitry Andric       ParamType>                                                               \
2900b57cec5SDimitry Andric   DefineMatcher(ParamType const &Param) {                                      \
2910b57cec5SDimitry Andric     return ::clang::ast_matchers::internal::PolymorphicMatcher<                \
2920b57cec5SDimitry Andric         internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,  \
2930b57cec5SDimitry Andric         ParamType>(Param);                                                     \
2940b57cec5SDimitry Andric   }                                                                            \
2950b57cec5SDimitry Andric   typedef ::clang::ast_matchers::internal::PolymorphicMatcher<                 \
2960b57cec5SDimitry Andric       internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,    \
2970b57cec5SDimitry Andric       ParamType> (&DefineMatcher##_Type##OverloadId)(ParamType const &Param);  \
2980b57cec5SDimitry Andric   template <typename NodeType, typename ParamT>                                \
2990b57cec5SDimitry Andric   bool internal::                                                              \
3000b57cec5SDimitry Andric       matcher_##DefineMatcher##OverloadId##Matcher<NodeType, ParamT>::matches( \
3010b57cec5SDimitry Andric           const NodeType &Node,                                                \
3020b57cec5SDimitry Andric           ::clang::ast_matchers::internal::ASTMatchFinder *Finder,             \
3030b57cec5SDimitry Andric           ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder)     \
3040b57cec5SDimitry Andric           const
3050b57cec5SDimitry Andric 
3060b57cec5SDimitry Andric /// AST_POLYMORPHIC_MATCHER_P2(
3070b57cec5SDimitry Andric ///     DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
3080b57cec5SDimitry Andric /// defines a two-parameter function named matcher() that is polymorphic in
3090b57cec5SDimitry Andric /// the return type.
3100b57cec5SDimitry Andric ///
3110b57cec5SDimitry Andric /// The variables are the same as for AST_MATCHER_P2, with the
3120b57cec5SDimitry Andric /// addition of NodeType, which specifies the node type of the matcher
3130b57cec5SDimitry Andric /// Matcher<NodeType> returned by the function DefineMatcher().
3140b57cec5SDimitry Andric #define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ReturnTypesF, ParamType1,    \
3150b57cec5SDimitry Andric                                    Param1, ParamType2, Param2)                 \
3160b57cec5SDimitry Andric   AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType1, \
3170b57cec5SDimitry Andric                                       Param1, ParamType2, Param2, 0)
3180b57cec5SDimitry Andric 
3190b57cec5SDimitry Andric #define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF,       \
3200b57cec5SDimitry Andric                                             ParamType1, Param1, ParamType2,    \
3210b57cec5SDimitry Andric                                             Param2, OverloadId)                \
3220b57cec5SDimitry Andric   namespace internal {                                                         \
3230b57cec5SDimitry Andric   template <typename NodeType, typename ParamT1, typename ParamT2>             \
3240b57cec5SDimitry Andric   class matcher_##DefineMatcher##OverloadId##Matcher                           \
3250b57cec5SDimitry Andric       : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> {   \
3260b57cec5SDimitry Andric   public:                                                                      \
3270b57cec5SDimitry Andric     matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1,  \
3280b57cec5SDimitry Andric                                                  ParamType2 const &A##Param2)  \
3290b57cec5SDimitry Andric         : Param1(A##Param1), Param2(A##Param2) {}                              \
3300b57cec5SDimitry Andric     bool matches(const NodeType &Node,                                         \
3310b57cec5SDimitry Andric                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \
3320b57cec5SDimitry Andric                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \
3330b57cec5SDimitry Andric                      *Builder) const override;                                 \
3340b57cec5SDimitry Andric                                                                                \
3350b57cec5SDimitry Andric   private:                                                                     \
3360b57cec5SDimitry Andric     ParamType1 Param1;                                                         \
3370b57cec5SDimitry Andric     ParamType2 Param2;                                                         \
3380b57cec5SDimitry Andric   };                                                                           \
3390b57cec5SDimitry Andric   }                                                                            \
3400b57cec5SDimitry Andric   inline ::clang::ast_matchers::internal::PolymorphicMatcher<                  \
3410b57cec5SDimitry Andric       internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,    \
3420b57cec5SDimitry Andric       ParamType1, ParamType2>                                                  \
3430b57cec5SDimitry Andric   DefineMatcher(ParamType1 const &Param1, ParamType2 const &Param2) {          \
3440b57cec5SDimitry Andric     return ::clang::ast_matchers::internal::PolymorphicMatcher<                \
3450b57cec5SDimitry Andric         internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,  \
3460b57cec5SDimitry Andric         ParamType1, ParamType2>(Param1, Param2);                               \
3470b57cec5SDimitry Andric   }                                                                            \
3480b57cec5SDimitry Andric   typedef ::clang::ast_matchers::internal::PolymorphicMatcher<                 \
3490b57cec5SDimitry Andric       internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,    \
3500b57cec5SDimitry Andric       ParamType1, ParamType2> (&DefineMatcher##_Type##OverloadId)(             \
3510b57cec5SDimitry Andric       ParamType1 const &Param1, ParamType2 const &Param2);                     \
3520b57cec5SDimitry Andric   template <typename NodeType, typename ParamT1, typename ParamT2>             \
3530b57cec5SDimitry Andric   bool internal::matcher_##DefineMatcher##OverloadId##Matcher<                 \
3540b57cec5SDimitry Andric       NodeType, ParamT1, ParamT2>::                                            \
3550b57cec5SDimitry Andric       matches(const NodeType &Node,                                            \
3560b57cec5SDimitry Andric               ::clang::ast_matchers::internal::ASTMatchFinder *Finder,         \
3570b57cec5SDimitry Andric               ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) \
3580b57cec5SDimitry Andric           const
3590b57cec5SDimitry Andric 
3600b57cec5SDimitry Andric // FIXME: add a matcher for TypeLoc derived classes using its custom casting
3610b57cec5SDimitry Andric // API (no longer dyn_cast) if/when we need such matching
3620b57cec5SDimitry Andric 
3630b57cec5SDimitry Andric #define AST_TYPE_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName,              \
3640b57cec5SDimitry Andric                                        ReturnTypesF)                           \
3650b57cec5SDimitry Andric   namespace internal {                                                         \
3660b57cec5SDimitry Andric   template <typename T> struct TypeMatcher##MatcherName##Getter {              \
3670b57cec5SDimitry Andric     static QualType (T::*value())() const { return &T::FunctionName; }         \
3680b57cec5SDimitry Andric   };                                                                           \
3690b57cec5SDimitry Andric   }                                                                            \
3700b57cec5SDimitry Andric   extern const ::clang::ast_matchers::internal::                               \
3710b57cec5SDimitry Andric       TypeTraversePolymorphicMatcher<                                          \
3720b57cec5SDimitry Andric           QualType,                                                            \
3730b57cec5SDimitry Andric           ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter,   \
3740b57cec5SDimitry Andric           ::clang::ast_matchers::internal::TypeTraverseMatcher,                \
3750b57cec5SDimitry Andric           ReturnTypesF>::Func MatcherName
3760b57cec5SDimitry Andric 
3770b57cec5SDimitry Andric #define AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF)               \
3780b57cec5SDimitry Andric   const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher<       \
3790b57cec5SDimitry Andric       QualType,                                                                \
3800b57cec5SDimitry Andric       ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter,       \
3810b57cec5SDimitry Andric       ::clang::ast_matchers::internal::TypeTraverseMatcher,                    \
3820b57cec5SDimitry Andric       ReturnTypesF>::Func MatcherName
3830b57cec5SDimitry Andric 
3840b57cec5SDimitry Andric /// AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
3850b57cec5SDimitry Andric /// the matcher \c MatcherName that can be used to traverse from one \c Type
3860b57cec5SDimitry Andric /// to another.
3870b57cec5SDimitry Andric ///
3880b57cec5SDimitry Andric /// For a specific \c SpecificType, the traversal is done using
3890b57cec5SDimitry Andric /// \c SpecificType::FunctionName. The existence of such a function determines
3900b57cec5SDimitry Andric /// whether a corresponding matcher can be used on \c SpecificType.
3910b57cec5SDimitry Andric #define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF)     \
3920b57cec5SDimitry Andric   namespace internal {                                                         \
3930b57cec5SDimitry Andric   template <typename T> struct TypeMatcher##MatcherName##Getter {              \
3940b57cec5SDimitry Andric     static QualType (T::*value())() const { return &T::FunctionName; }         \
3950b57cec5SDimitry Andric   };                                                                           \
3960b57cec5SDimitry Andric   }                                                                            \
3970b57cec5SDimitry Andric   const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher<       \
3980b57cec5SDimitry Andric       QualType,                                                                \
3990b57cec5SDimitry Andric       ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter,       \
4000b57cec5SDimitry Andric       ::clang::ast_matchers::internal::TypeTraverseMatcher,                    \
4010b57cec5SDimitry Andric       ReturnTypesF>::Func MatcherName
4020b57cec5SDimitry Andric 
4030b57cec5SDimitry Andric #define AST_TYPELOC_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName,           \
4040b57cec5SDimitry Andric                                           ReturnTypesF)                        \
4050b57cec5SDimitry Andric   namespace internal {                                                         \
4060b57cec5SDimitry Andric   template <typename T> struct TypeLocMatcher##MatcherName##Getter {           \
4070b57cec5SDimitry Andric     static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; }     \
4080b57cec5SDimitry Andric   };                                                                           \
4090b57cec5SDimitry Andric   }                                                                            \
4100b57cec5SDimitry Andric   extern const ::clang::ast_matchers::internal::                               \
4110b57cec5SDimitry Andric       TypeTraversePolymorphicMatcher<                                          \
4120b57cec5SDimitry Andric           TypeLoc,                                                             \
4130b57cec5SDimitry Andric           ::clang::ast_matchers::internal::                                    \
4140b57cec5SDimitry Andric               TypeLocMatcher##MatcherName##Getter,                             \
4150b57cec5SDimitry Andric           ::clang::ast_matchers::internal::TypeLocTraverseMatcher,             \
4160b57cec5SDimitry Andric           ReturnTypesF>::Func MatcherName##Loc;                                \
4170b57cec5SDimitry Andric   AST_TYPE_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName##Type, ReturnTypesF)
4180b57cec5SDimitry Andric 
4190b57cec5SDimitry Andric #define AST_TYPELOC_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF)            \
4200b57cec5SDimitry Andric   const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher<       \
4210b57cec5SDimitry Andric       TypeLoc,                                                                 \
4220b57cec5SDimitry Andric       ::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter,    \
4230b57cec5SDimitry Andric       ::clang::ast_matchers::internal::TypeLocTraverseMatcher,                 \
4240b57cec5SDimitry Andric       ReturnTypesF>::Func MatcherName##Loc;                                    \
4250b57cec5SDimitry Andric   AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF)
4260b57cec5SDimitry Andric 
4270b57cec5SDimitry Andric /// AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works
4280b57cec5SDimitry Andric /// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs.
4290b57cec5SDimitry Andric #define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF)  \
4300b57cec5SDimitry Andric   namespace internal {                                                         \
4310b57cec5SDimitry Andric   template <typename T> struct TypeLocMatcher##MatcherName##Getter {           \
4320b57cec5SDimitry Andric     static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; }     \
4330b57cec5SDimitry Andric   };                                                                           \
4340b57cec5SDimitry Andric   }                                                                            \
4350b57cec5SDimitry Andric   const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher<       \
4360b57cec5SDimitry Andric       TypeLoc,                                                                 \
4370b57cec5SDimitry Andric       ::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter,    \
4380b57cec5SDimitry Andric       ::clang::ast_matchers::internal::TypeLocTraverseMatcher,                 \
4390b57cec5SDimitry Andric       ReturnTypesF>::Func MatcherName##Loc;                                    \
4400b57cec5SDimitry Andric   AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF)
4410b57cec5SDimitry Andric 
4420b57cec5SDimitry Andric /// AST_MATCHER_REGEX(Type, DefineMatcher, Param) { ... }
4430b57cec5SDimitry Andric /// 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