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