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