14da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//===--- ASTMatchersMacros.h - Structural query framework -------*- C++ -*-===// 24da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// 34da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// The LLVM Compiler Infrastructure 44da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// 54da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// This file is distributed under the University of Illinois Open Source 64da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// License. See LICENSE.TXT for details. 74da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// 84da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//===----------------------------------------------------------------------===// 94da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// 104da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// Defines macros that enable us to define new matchers in a single place. 114da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// Since a matcher is a function which returns a Matcher<T> object, where 124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// T is the type of the actual implementation of the matcher, the macros allow 134da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// us to write matchers like functions and take care of the definition of the 144da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// class boilerplate. 154da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// 164da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// Note that when you define a matcher with an AST_MATCHER* macro, only the 174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// function which creates the matcher goes into the current namespace - the 184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// class that implements the actual matcher, which gets returned by the 194da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// generator function, is put into the 'internal' namespace. This allows us 204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// to only have the functions (which is all the user cares about) in the 214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// 'ast_matchers' namespace and hide the boilerplate. 224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// 234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// To define a matcher in user code, always put it into the clang::ast_matchers 244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// namespace and refer to the internal types via the 'internal::': 254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// 264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// namespace clang { 274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// namespace ast_matchers { 284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// AST_MATCHER_P(MemberExpr, Member, 294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// internal::Matcher<ValueDecl>, InnerMatcher) { 304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder); 314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// } 324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// } // end namespace ast_matchers 334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// } // end namespace clang 344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek// 354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek//===----------------------------------------------------------------------===// 364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#ifndef LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H 384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H 394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 40651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// \brief AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) { 41651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// defines a single-parameter function named DefineMatcher() that returns a 42651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// ReturnType object. 43651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// 44651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// The code between the curly braces has access to the following variables: 45651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// 46651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// Param: the parameter passed to the function; its type 47651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// is ParamType. 48651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// 49651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines/// The code should return an instance of ReturnType. 50651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#define AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) \ 51651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, Param, \ 52651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 0) 53651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines#define AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, \ 54651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines Param, OverloadId) \ 55ef8225444452a1486bd721f3285301fe84643b00Stephen Hines inline ReturnType DefineMatcher(ParamType const &Param); \ 56ef8225444452a1486bd721f3285301fe84643b00Stephen Hines typedef ReturnType (&DefineMatcher##_Type##OverloadId)(ParamType const &); \ 57ef8225444452a1486bd721f3285301fe84643b00Stephen Hines inline ReturnType DefineMatcher(ParamType const &Param) 58651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 594da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief AST_MATCHER(Type, DefineMatcher) { ... } 604da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// defines a zero parameter function named DefineMatcher() that returns a 614da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Matcher<Type> object. 624da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// The code between the curly braces has access to the following variables: 644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 654da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Node: the AST node being matched; its type is Type. 664da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Finder: an ASTMatchFinder*. 674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Builder: a BoundNodesTreeBuilder*. 684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// The code should return true if 'Node' matches. 704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#define AST_MATCHER(Type, DefineMatcher) \ 714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek namespace internal { \ 720e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen class matcher_##DefineMatcher##Matcher : public MatcherInterface<Type> { \ 737bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek public: \ 740e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen explicit matcher_##DefineMatcher##Matcher() {} \ 75651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matches(const Type &Node, ASTMatchFinder *Finder, \ 76651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BoundNodesTreeBuilder *Builder) const override; \ 774da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek }; \ 784da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } \ 794da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek inline internal::Matcher<Type> DefineMatcher() { \ 804da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek return internal::makeMatcher( \ 810e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen new internal::matcher_##DefineMatcher##Matcher()); \ 824da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } \ 830e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen inline bool internal::matcher_##DefineMatcher##Matcher::matches( \ 844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek const Type &Node, ASTMatchFinder *Finder, \ 854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek BoundNodesTreeBuilder *Builder) const 864da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 874da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... } 884da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// defines a single-parameter function named DefineMatcher() that returns a 894da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Matcher<Type> object. 904da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 914da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// The code between the curly braces has access to the following variables: 924da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 934da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Node: the AST node being matched; its type is Type. 944da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Param: the parameter passed to the function; its type 954da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// is ParamType. 964da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Finder: an ASTMatchFinder*. 974da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Builder: a BoundNodesTreeBuilder*. 984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// The code should return true if 'Node' matches. 1004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) \ 101415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, 0) 102415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek 103415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek#define AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, \ 104415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek OverloadId) \ 1054da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek namespace internal { \ 106415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek class matcher_##DefineMatcher##OverloadId##Matcher \ 107415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek : public MatcherInterface<Type> { \ 1087bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek public: \ 109415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek explicit matcher_##DefineMatcher##OverloadId##Matcher( \ 110ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ParamType const &A##Param) \ 1110e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen : Param(A##Param) {} \ 112651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matches(const Type &Node, ASTMatchFinder *Finder, \ 113651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BoundNodesTreeBuilder *Builder) const override; \ 1140e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen \ 1157bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek private: \ 116ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ParamType const Param; \ 1174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek }; \ 1184da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } \ 119ef8225444452a1486bd721f3285301fe84643b00Stephen Hines inline internal::Matcher<Type> DefineMatcher(ParamType const &Param) { \ 1204da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek return internal::makeMatcher( \ 121415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param)); \ 1224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } \ 1230e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen typedef internal::Matcher<Type>(&DefineMatcher##_Type##OverloadId)( \ 124ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ParamType const &Param); \ 125415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \ 1264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek const Type &Node, ASTMatchFinder *Finder, \ 1274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek BoundNodesTreeBuilder *Builder) const 1284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 1294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief AST_MATCHER_P2( 1304da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... } 1314da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// defines a two-parameter function named DefineMatcher() that returns a 1324da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Matcher<Type> object. 1334da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 1344da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// The code between the curly braces has access to the following variables: 1354da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 1364da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Node: the AST node being matched; its type is Type. 1374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Param1, Param2: the parameters passed to the function; their types 1384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// are ParamType1 and ParamType2. 1394da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Finder: an ASTMatchFinder*. 1404da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Builder: a BoundNodesTreeBuilder*. 1414da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 1424da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// The code should return true if 'Node' matches. 1437bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek#define AST_MATCHER_P2(Type, DefineMatcher, ParamType1, Param1, ParamType2, \ 1447bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek Param2) \ 145415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, ParamType2, \ 146415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek Param2, 0) 147415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek 148415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek#define AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, \ 149415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek ParamType2, Param2, OverloadId) \ 1504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek namespace internal { \ 151415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek class matcher_##DefineMatcher##OverloadId##Matcher \ 152415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek : public MatcherInterface<Type> { \ 1537bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek public: \ 154ef8225444452a1486bd721f3285301fe84643b00Stephen Hines matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1, \ 155ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ParamType2 const &A##Param2) \ 1560e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen : Param1(A##Param1), Param2(A##Param2) {} \ 157651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matches(const Type &Node, ASTMatchFinder *Finder, \ 158651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BoundNodesTreeBuilder *Builder) const override; \ 1590e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen \ 1607bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek private: \ 161ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ParamType1 const Param1; \ 162ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ParamType2 const Param2; \ 1634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek }; \ 1644da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } \ 165ef8225444452a1486bd721f3285301fe84643b00Stephen Hines inline internal::Matcher<Type> DefineMatcher(ParamType1 const &Param1, \ 166ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ParamType2 const &Param2) { \ 1674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek return internal::makeMatcher( \ 168415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1, \ 169415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek Param2)); \ 1704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } \ 1710e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen typedef internal::Matcher<Type>(&DefineMatcher##_Type##OverloadId)( \ 172ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ParamType1 const &Param1, ParamType2 const &Param2); \ 173415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \ 1744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek const Type &Node, ASTMatchFinder *Finder, \ 1754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek BoundNodesTreeBuilder *Builder) const 1764da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 177ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// \brief Construct a type-list to be passed to the AST_POLYMORPHIC_MATCHER* 178ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// macros. 179ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// 180ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// You can't pass something like \c TypeList<Foo, Bar> to a macro, because it 181ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// will look at that as two arguments. However, you can pass 182ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// \c void(TypeList<Foo, Bar>), which works thanks to the parenthesis. 183ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// The \c PolymorphicMatcherWithParam* classes will unpack the function type to 184ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen/// extract the TypeList object. 1853f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen#define AST_POLYMORPHIC_SUPPORTED_TYPES_1(t1) void(internal::TypeList<t1>) 186ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen#define AST_POLYMORPHIC_SUPPORTED_TYPES_2(t1, t2) \ 187ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen void(internal::TypeList<t1, t2>) 188ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen#define AST_POLYMORPHIC_SUPPORTED_TYPES_3(t1, t2, t3) \ 189ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen void(internal::TypeList<t1, t2, t3>) 190ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen#define AST_POLYMORPHIC_SUPPORTED_TYPES_4(t1, t2, t3, t4) \ 191ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen void(internal::TypeList<t1, t2, t3, t4>) 192ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen#define AST_POLYMORPHIC_SUPPORTED_TYPES_5(t1, t2, t3, t4, t5) \ 1936c1dc7870f457803a9b256ed868da82532be820bSamuel Benzaquen void(internal::TypeList<t1, t2, t3, internal::TypeList<t4, t5> >) 194ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen 195415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek/// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... } 196415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek/// defines a single-parameter function named DefineMatcher() that is 197415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek/// polymorphic in the return type. 198415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek/// 199415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek/// The variables are the same as for AST_MATCHER, but NodeType will be deduced 200415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek/// from the calling context. 201ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen#define AST_POLYMORPHIC_MATCHER(DefineMatcher, ReturnTypesF) \ 202415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek namespace internal { \ 203415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek template <typename NodeType> \ 2040e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen class matcher_##DefineMatcher##Matcher : public MatcherInterface<NodeType> { \ 205415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek public: \ 206651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matches(const NodeType &Node, ASTMatchFinder *Finder, \ 207651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BoundNodesTreeBuilder *Builder) const override; \ 208415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek }; \ 209415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek } \ 210415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek inline internal::PolymorphicMatcherWithParam0< \ 2110e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen internal::matcher_##DefineMatcher##Matcher, ReturnTypesF> \ 212ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen DefineMatcher() { \ 213415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek return internal::PolymorphicMatcherWithParam0< \ 2140e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>(); \ 215415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek } \ 216415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek template <typename NodeType> \ 2170e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen bool internal::matcher_##DefineMatcher##Matcher<NodeType>::matches( \ 2180e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen const NodeType &Node, ASTMatchFinder *Finder, \ 2190e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen BoundNodesTreeBuilder *Builder) const 220415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek 2214da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... } 2224da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// defines a single-parameter function named DefineMatcher() that is 2234da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// polymorphic in the return type. 2244da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 2254da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// The variables are the same as for 2264da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// AST_MATCHER_P, with the addition of NodeType, which specifies the node type 2274da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// of the matcher Matcher<NodeType> returned by the function matcher(). 2284da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 2294da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// FIXME: Pull out common code with above macro? 230ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen#define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ReturnTypesF, ParamType, \ 231ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen Param) \ 232ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType, \ 233ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen Param, 0) 234415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek 235ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen#define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, \ 236ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen ParamType, Param, OverloadId) \ 2374da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek namespace internal { \ 2384da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek template <typename NodeType, typename ParamT> \ 239415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek class matcher_##DefineMatcher##OverloadId##Matcher \ 240415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek : public MatcherInterface<NodeType> { \ 2417bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek public: \ 242415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek explicit matcher_##DefineMatcher##OverloadId##Matcher( \ 243ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ParamType const &A##Param) \ 2440e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen : Param(A##Param) {} \ 245651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matches(const NodeType &Node, ASTMatchFinder *Finder, \ 246651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BoundNodesTreeBuilder *Builder) const override; \ 2470e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen \ 2487bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek private: \ 249ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ParamType const Param; \ 2504da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek }; \ 2514da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } \ 2524da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek inline internal::PolymorphicMatcherWithParam1< \ 253ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \ 254ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ReturnTypesF> DefineMatcher(ParamType const &Param) { \ 2554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek return internal::PolymorphicMatcherWithParam1< \ 256ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \ 257ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen ReturnTypesF>(Param); \ 2584da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } \ 2590e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen typedef internal::PolymorphicMatcherWithParam1< \ 2600e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \ 2610e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen ReturnTypesF>(&DefineMatcher##_Type##OverloadId)( \ 262ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ParamType const &Param); \ 2634da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek template <typename NodeType, typename ParamT> \ 264415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \ 265415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek NodeType, ParamT>::matches(const NodeType &Node, ASTMatchFinder *Finder, \ 266415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek BoundNodesTreeBuilder *Builder) const 2674da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 2684da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// \brief AST_POLYMORPHIC_MATCHER_P2( 2694da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... } 2704da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// defines a two-parameter function named matcher() that is polymorphic in 2714da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// the return type. 2724da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// 2734da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// The variables are the same as for AST_MATCHER_P2, with the 2744da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// addition of NodeType, which specifies the node type of the matcher 2754da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek/// Matcher<NodeType> returned by the function DefineMatcher(). 276ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen#define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ReturnTypesF, ParamType1, \ 277ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen Param1, ParamType2, Param2) \ 278ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType1, \ 279ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen Param1, ParamType2, Param2, 0) 280415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek 281ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen#define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, \ 282ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen ParamType1, Param1, ParamType2, \ 283ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen Param2, OverloadId) \ 2844da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek namespace internal { \ 2854da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek template <typename NodeType, typename ParamT1, typename ParamT2> \ 286415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek class matcher_##DefineMatcher##OverloadId##Matcher \ 287415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek : public MatcherInterface<NodeType> { \ 2887bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek public: \ 289ef8225444452a1486bd721f3285301fe84643b00Stephen Hines matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1, \ 290ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ParamType2 const &A##Param2) \ 2910e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen : Param1(A##Param1), Param2(A##Param2) {} \ 292651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines bool matches(const NodeType &Node, ASTMatchFinder *Finder, \ 293651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines BoundNodesTreeBuilder *Builder) const override; \ 2940e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen \ 2957bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek private: \ 296ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ParamType1 const Param1; \ 297ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ParamType2 const Param2; \ 2984da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek }; \ 2994da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } \ 3004da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek inline internal::PolymorphicMatcherWithParam2< \ 301415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \ 302ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ParamType2, ReturnTypesF> DefineMatcher(ParamType1 const &Param1, \ 303ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ParamType2 const &Param2) { \ 3044da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek return internal::PolymorphicMatcherWithParam2< \ 305415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \ 306ef7eb024397a6a9d1455b31bc7b10288a817ac3bSamuel Benzaquen ParamType2, ReturnTypesF>(Param1, Param2); \ 3074da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek } \ 3080e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen typedef internal::PolymorphicMatcherWithParam2< \ 3090e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \ 3100e1896a753845deee5206b28cdbde1640abb9cacSamuel Benzaquen ParamType2, ReturnTypesF>(&DefineMatcher##_Type##OverloadId)( \ 311ef8225444452a1486bd721f3285301fe84643b00Stephen Hines ParamType1 const &Param1, ParamType2 const &Param2); \ 3124da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek template <typename NodeType, typename ParamT1, typename ParamT2> \ 313415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \ 314415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek NodeType, ParamT1, ParamT2>::matches( \ 315415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek const NodeType &Node, ASTMatchFinder *Finder, \ 316415514d5fbc2761b7f2938aa9112b079249820d6Manuel Klimek BoundNodesTreeBuilder *Builder) const 3174da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek 318ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper/// \brief Creates a variadic matcher for both a specific \c Type as well as 319ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper/// the corresponding \c TypeLoc. 320ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper#define AST_TYPE_MATCHER(NodeType, MatcherName) \ 3215be093c0ef46c7749c942d0d9056af6dc3d591a4David Blaikie const internal::VariadicDynCastAllOfMatcher<Type, NodeType> MatcherName 3225be093c0ef46c7749c942d0d9056af6dc3d591a4David Blaikie// FIXME: add a matcher for TypeLoc derived classes using its custom casting 3235be093c0ef46c7749c942d0d9056af6dc3d591a4David Blaikie// API (no longer dyn_cast) if/when we need such matching 324ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper 325ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper/// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines 326ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper/// the matcher \c MatcherName that can be used to traverse from one \c Type 327ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper/// to another. 328a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper/// 329ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper/// For a specific \c SpecificType, the traversal is done using 330063820655db8121f0022a7c51458463c7250324cBenjamin Kramer/// \c SpecificType::FunctionName. The existence of such a function determines 331ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper/// whether a corresponding matcher can be used on \c SpecificType. 3323f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen#define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \ 3333f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen namespace internal { \ 3343f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen template <typename T> struct TypeMatcher##MatcherName##Getter { \ 3353f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen static QualType (T::*value())() const { return &T::FunctionName; } \ 3363f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen }; \ 3377bb7fb634d20d9f3f5c6b5058a514a4b41b6f33dManuel Klimek } \ 3383f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen const internal::TypeTraversePolymorphicMatcher< \ 3393f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen QualType, internal::TypeMatcher##MatcherName##Getter, \ 3403f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen internal::TypeTraverseMatcher, ReturnTypesF>::Func MatcherName 341ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper 342ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper/// \brief AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works 343ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper/// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs. 3443f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen#define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \ 3453f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen namespace internal { \ 3463f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen template <typename T> struct TypeLocMatcher##MatcherName##Getter { \ 3473f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; } \ 3483f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen }; \ 349ce62007526cdf718faed10df5e9fc7c3cd160cdeDaniel Jasper } \ 3503f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen const internal::TypeTraversePolymorphicMatcher< \ 3513f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen TypeLoc, internal::TypeLocMatcher##MatcherName##Getter, \ 3523f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen internal::TypeLocTraverseMatcher, ReturnTypesF>::Func MatcherName##Loc; \ 3533f84bb341bfb1312842b09db71d76bc3898ba247Samuel Benzaquen AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF) 354a7564433191601cb8851196b8dde39392c9c05eeDaniel Jasper 3554da216637fa1ad4bdfd31bc265edb57ca35c2c12Manuel Klimek#endif // LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H 356