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