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