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, put it into your own namespace. This would 24// help to prevent ODR violations in case a matcher with the same name is 25// defined in multiple translation units: 26// 27// namespace my_matchers { 28// AST_MATCHER_P(clang::MemberExpr, Member, 29// clang::ast_matchers::internal::Matcher<clang::ValueDecl>, 30// InnerMatcher) { 31// return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder); 32// } 33// } // namespace my_matchers 34// 35// Alternatively, an unnamed namespace may be used: 36// 37// namespace clang { 38// namespace ast_matchers { 39// namespace { 40// AST_MATCHER_P(MemberExpr, Member, 41// internal::Matcher<ValueDecl>, InnerMatcher) { 42// return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder); 43// } 44// } // namespace 45// } // namespace ast_matchers 46// } // namespace clang 47// 48//===----------------------------------------------------------------------===// 49 50#ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H 51#define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H 52 53/// \brief AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) { ... } 54/// defines a zero parameter function named DefineMatcher() that returns a 55/// ReturnType object. 56#define AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) \ 57 inline ReturnType DefineMatcher##_getInstance(); \ 58 inline ReturnType DefineMatcher() { \ 59 return ::clang::ast_matchers::internal::MemoizedMatcher< \ 60 ReturnType, DefineMatcher##_getInstance>::getInstance(); \ 61 } \ 62 inline ReturnType DefineMatcher##_getInstance() 63 64/// \brief AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) { 65/// ... } 66/// defines a single-parameter function named DefineMatcher() that returns a 67/// ReturnType object. 68/// 69/// The code between the curly braces has access to the following variables: 70/// 71/// Param: the parameter passed to the function; its type 72/// is ParamType. 73/// 74/// The code should return an instance of ReturnType. 75#define AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) \ 76 AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, Param, \ 77 0) 78#define AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, \ 79 Param, OverloadId) \ 80 inline ReturnType DefineMatcher(ParamType const &Param); \ 81 typedef ReturnType (&DefineMatcher##_Type##OverloadId)(ParamType const &); \ 82 inline ReturnType DefineMatcher(ParamType const &Param) 83 84/// \brief AST_MATCHER(Type, DefineMatcher) { ... } 85/// defines a zero parameter function named DefineMatcher() that returns a 86/// Matcher<Type> object. 87/// 88/// The code between the curly braces has access to the following variables: 89/// 90/// Node: the AST node being matched; its type is Type. 91/// Finder: an ASTMatchFinder*. 92/// Builder: a BoundNodesTreeBuilder*. 93/// 94/// The code should return true if 'Node' matches. 95#define AST_MATCHER(Type, DefineMatcher) \ 96 namespace internal { \ 97 class matcher_##DefineMatcher##Matcher \ 98 : public ::clang::ast_matchers::internal::MatcherInterface<Type> { \ 99 public: \ 100 explicit matcher_##DefineMatcher##Matcher() {} \ 101 bool matches(const Type &Node, \ 102 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 103 ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ 104 *Builder) const override; \ 105 }; \ 106 } \ 107 inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher() { \ 108 return ::clang::ast_matchers::internal::makeMatcher( \ 109 new internal::matcher_##DefineMatcher##Matcher()); \ 110 } \ 111 inline bool internal::matcher_##DefineMatcher##Matcher::matches( \ 112 const Type &Node, \ 113 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 114 ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const 115 116/// \brief AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... } 117/// defines a single-parameter function named DefineMatcher() that returns a 118/// Matcher<Type> object. 119/// 120/// The code between the curly braces has access to the following variables: 121/// 122/// Node: the AST node being matched; its type is Type. 123/// Param: the parameter passed to the function; its type 124/// is ParamType. 125/// Finder: an ASTMatchFinder*. 126/// Builder: a BoundNodesTreeBuilder*. 127/// 128/// The code should return true if 'Node' matches. 129#define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) \ 130 AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, 0) 131 132#define AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, \ 133 OverloadId) \ 134 namespace internal { \ 135 class matcher_##DefineMatcher##OverloadId##Matcher \ 136 : public ::clang::ast_matchers::internal::MatcherInterface<Type> { \ 137 public: \ 138 explicit matcher_##DefineMatcher##OverloadId##Matcher( \ 139 ParamType const &A##Param) \ 140 : Param(A##Param) {} \ 141 bool matches(const Type &Node, \ 142 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 143 ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ 144 *Builder) const override; \ 145 \ 146 private: \ 147 ParamType const Param; \ 148 }; \ 149 } \ 150 inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \ 151 ParamType const &Param) { \ 152 return ::clang::ast_matchers::internal::makeMatcher( \ 153 new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param)); \ 154 } \ 155 typedef ::clang::ast_matchers::internal::Matcher<Type>( \ 156 &DefineMatcher##_Type##OverloadId)(ParamType const &Param); \ 157 inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \ 158 const Type &Node, \ 159 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 160 ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const 161 162/// \brief AST_MATCHER_P2( 163/// Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... } 164/// defines a two-parameter function named DefineMatcher() that returns a 165/// Matcher<Type> object. 166/// 167/// The code between the curly braces has access to the following variables: 168/// 169/// Node: the AST node being matched; its type is Type. 170/// Param1, Param2: the parameters passed to the function; their types 171/// are ParamType1 and ParamType2. 172/// Finder: an ASTMatchFinder*. 173/// Builder: a BoundNodesTreeBuilder*. 174/// 175/// The code should return true if 'Node' matches. 176#define AST_MATCHER_P2(Type, DefineMatcher, ParamType1, Param1, ParamType2, \ 177 Param2) \ 178 AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, ParamType2, \ 179 Param2, 0) 180 181#define AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, \ 182 ParamType2, Param2, OverloadId) \ 183 namespace internal { \ 184 class matcher_##DefineMatcher##OverloadId##Matcher \ 185 : public ::clang::ast_matchers::internal::MatcherInterface<Type> { \ 186 public: \ 187 matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1, \ 188 ParamType2 const &A##Param2) \ 189 : Param1(A##Param1), Param2(A##Param2) {} \ 190 bool matches(const Type &Node, \ 191 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 192 ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ 193 *Builder) const override; \ 194 \ 195 private: \ 196 ParamType1 const Param1; \ 197 ParamType2 const Param2; \ 198 }; \ 199 } \ 200 inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \ 201 ParamType1 const &Param1, ParamType2 const &Param2) { \ 202 return ::clang::ast_matchers::internal::makeMatcher( \ 203 new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1, \ 204 Param2)); \ 205 } \ 206 typedef ::clang::ast_matchers::internal::Matcher<Type>( \ 207 &DefineMatcher##_Type##OverloadId)(ParamType1 const &Param1, \ 208 ParamType2 const &Param2); \ 209 inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \ 210 const Type &Node, \ 211 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 212 ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const 213 214/// \brief Construct a type-list to be passed to the AST_POLYMORPHIC_MATCHER* 215/// macros. 216/// 217/// You can't pass something like \c TypeList<Foo, Bar> to a macro, because it 218/// will look at that as two arguments. However, you can pass 219/// \c void(TypeList<Foo, Bar>), which works thanks to the parenthesis. 220/// The \c PolymorphicMatcherWithParam* classes will unpack the function type to 221/// extract the TypeList object. 222#define AST_POLYMORPHIC_SUPPORTED_TYPES(...) \ 223 void(::clang::ast_matchers::internal::TypeList<__VA_ARGS__>) 224 225/// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... } 226/// defines a single-parameter function named DefineMatcher() that is 227/// polymorphic in the return type. 228/// 229/// The variables are the same as for AST_MATCHER, but NodeType will be deduced 230/// from the calling context. 231#define AST_POLYMORPHIC_MATCHER(DefineMatcher, ReturnTypesF) \ 232 namespace internal { \ 233 template <typename NodeType> \ 234 class matcher_##DefineMatcher##Matcher \ 235 : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \ 236 public: \ 237 bool matches(const NodeType &Node, \ 238 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 239 ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ 240 *Builder) const override; \ 241 }; \ 242 } \ 243 inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam0< \ 244 internal::matcher_##DefineMatcher##Matcher, ReturnTypesF> \ 245 DefineMatcher() { \ 246 return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam0< \ 247 internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>(); \ 248 } \ 249 template <typename NodeType> \ 250 bool internal::matcher_##DefineMatcher##Matcher<NodeType>::matches( \ 251 const NodeType &Node, \ 252 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 253 ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const 254 255/// \brief AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... } 256/// defines a single-parameter function named DefineMatcher() that is 257/// polymorphic in the return type. 258/// 259/// The variables are the same as for 260/// AST_MATCHER_P, with the addition of NodeType, which specifies the node type 261/// of the matcher Matcher<NodeType> returned by the function matcher(). 262/// 263/// FIXME: Pull out common code with above macro? 264#define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ReturnTypesF, ParamType, \ 265 Param) \ 266 AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType, \ 267 Param, 0) 268 269#define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, \ 270 ParamType, Param, OverloadId) \ 271 namespace internal { \ 272 template <typename NodeType, typename ParamT> \ 273 class matcher_##DefineMatcher##OverloadId##Matcher \ 274 : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \ 275 public: \ 276 explicit matcher_##DefineMatcher##OverloadId##Matcher( \ 277 ParamType const &A##Param) \ 278 : Param(A##Param) {} \ 279 bool matches(const NodeType &Node, \ 280 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 281 ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ 282 *Builder) const override; \ 283 \ 284 private: \ 285 ParamType const Param; \ 286 }; \ 287 } \ 288 inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \ 289 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \ 290 ReturnTypesF> \ 291 DefineMatcher(ParamType const &Param) { \ 292 return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \ 293 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \ 294 ReturnTypesF>(Param); \ 295 } \ 296 typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \ 297 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \ 298 ReturnTypesF>(&DefineMatcher##_Type##OverloadId)( \ 299 ParamType const &Param); \ 300 template <typename NodeType, typename ParamT> \ 301 bool internal:: \ 302 matcher_##DefineMatcher##OverloadId##Matcher<NodeType, ParamT>::matches( \ 303 const NodeType &Node, \ 304 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 305 ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) \ 306 const 307 308/// \brief AST_POLYMORPHIC_MATCHER_P2( 309/// DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... } 310/// defines a two-parameter function named matcher() that is polymorphic in 311/// the return type. 312/// 313/// The variables are the same as for AST_MATCHER_P2, with the 314/// addition of NodeType, which specifies the node type of the matcher 315/// Matcher<NodeType> returned by the function DefineMatcher(). 316#define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ReturnTypesF, ParamType1, \ 317 Param1, ParamType2, Param2) \ 318 AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType1, \ 319 Param1, ParamType2, Param2, 0) 320 321#define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, \ 322 ParamType1, Param1, ParamType2, \ 323 Param2, OverloadId) \ 324 namespace internal { \ 325 template <typename NodeType, typename ParamT1, typename ParamT2> \ 326 class matcher_##DefineMatcher##OverloadId##Matcher \ 327 : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \ 328 public: \ 329 matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1, \ 330 ParamType2 const &A##Param2) \ 331 : Param1(A##Param1), Param2(A##Param2) {} \ 332 bool matches(const NodeType &Node, \ 333 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 334 ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ 335 *Builder) const override; \ 336 \ 337 private: \ 338 ParamType1 const Param1; \ 339 ParamType2 const Param2; \ 340 }; \ 341 } \ 342 inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2< \ 343 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \ 344 ParamType2, ReturnTypesF> \ 345 DefineMatcher(ParamType1 const &Param1, ParamType2 const &Param2) { \ 346 return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2< \ 347 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \ 348 ParamType2, ReturnTypesF>(Param1, Param2); \ 349 } \ 350 typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2< \ 351 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \ 352 ParamType2, ReturnTypesF>(&DefineMatcher##_Type##OverloadId)( \ 353 ParamType1 const &Param1, ParamType2 const &Param2); \ 354 template <typename NodeType, typename ParamT1, typename ParamT2> \ 355 bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \ 356 NodeType, ParamT1, ParamT2>:: \ 357 matches(const NodeType &Node, \ 358 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 359 ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) \ 360 const 361 362/// \brief Creates a variadic matcher for both a specific \c Type as well as 363/// the corresponding \c TypeLoc. 364#define AST_TYPE_MATCHER(NodeType, MatcherName) \ 365 const ::clang::ast_matchers::internal::VariadicDynCastAllOfMatcher< \ 366 Type, NodeType> MatcherName 367// FIXME: add a matcher for TypeLoc derived classes using its custom casting 368// API (no longer dyn_cast) if/when we need such matching 369 370/// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines 371/// the matcher \c MatcherName that can be used to traverse from one \c Type 372/// to another. 373/// 374/// For a specific \c SpecificType, the traversal is done using 375/// \c SpecificType::FunctionName. The existence of such a function determines 376/// whether a corresponding matcher can be used on \c SpecificType. 377#define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \ 378 namespace internal { \ 379 template <typename T> struct TypeMatcher##MatcherName##Getter { \ 380 static QualType (T::*value())() const { return &T::FunctionName; } \ 381 }; \ 382 } \ 383 const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \ 384 QualType, \ 385 ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter, \ 386 ::clang::ast_matchers::internal::TypeTraverseMatcher, \ 387 ReturnTypesF>::Func MatcherName 388 389/// \brief AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works 390/// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs. 391#define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \ 392 namespace internal { \ 393 template <typename T> struct TypeLocMatcher##MatcherName##Getter { \ 394 static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; } \ 395 }; \ 396 } \ 397 const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \ 398 TypeLoc, \ 399 ::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter, \ 400 ::clang::ast_matchers::internal::TypeLocTraverseMatcher, \ 401 ReturnTypesF>::Func MatcherName##Loc; \ 402 AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF) 403 404#endif 405