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 #include "clang/Support/Compiler.h" 53 54 /// AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) { ... } 55 /// defines a zero parameter function named DefineMatcher() that returns a 56 /// ReturnType object. 57 #define AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) \ 58 inline ReturnType DefineMatcher##_getInstance(); \ 59 inline ReturnType DefineMatcher() { \ 60 return ::clang::ast_matchers::internal::MemoizedMatcher< \ 61 ReturnType, DefineMatcher##_getInstance>::getInstance(); \ 62 } \ 63 inline ReturnType DefineMatcher##_getInstance() 64 65 /// AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) { 66 /// ... } 67 /// defines a single-parameter function named DefineMatcher() that returns a 68 /// ReturnType object. 69 /// 70 /// The code between the curly braces has access to the following variables: 71 /// 72 /// Param: the parameter passed to the function; its type 73 /// is ParamType. 74 /// 75 /// The code should return an instance of ReturnType. 76 #define AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) \ 77 AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, Param, \ 78 0) 79 #define AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, \ 80 Param, OverloadId) \ 81 inline ReturnType DefineMatcher(ParamType const &Param); \ 82 typedef ReturnType (&DefineMatcher##_Type##OverloadId)(ParamType const &); \ 83 inline ReturnType DefineMatcher(ParamType const &Param) 84 85 /// AST_MATCHER(Type, DefineMatcher) { ... } 86 /// defines a zero parameter function named DefineMatcher() that returns a 87 /// Matcher<Type> object. 88 /// 89 /// The code between the curly braces has access to the following variables: 90 /// 91 /// Node: the AST node being matched; its type is Type. 92 /// Finder: an ASTMatchFinder*. 93 /// Builder: a BoundNodesTreeBuilder*. 94 /// 95 /// The code should return true if 'Node' matches. 96 #define AST_MATCHER(Type, DefineMatcher) \ 97 namespace internal { \ 98 class matcher_##DefineMatcher##Matcher \ 99 : public ::clang::ast_matchers::internal::MatcherInterface<Type> { \ 100 public: \ 101 explicit matcher_##DefineMatcher##Matcher() = default; \ 102 bool matches(const Type &Node, \ 103 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 104 ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ 105 *Builder) const override; \ 106 }; \ 107 } \ 108 inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher() { \ 109 return ::clang::ast_matchers::internal::makeMatcher( \ 110 new internal::matcher_##DefineMatcher##Matcher()); \ 111 } \ 112 inline bool internal::matcher_##DefineMatcher##Matcher::matches( \ 113 const Type &Node, \ 114 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 115 ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const 116 117 /// AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... } 118 /// defines a single-parameter function named DefineMatcher() that returns a 119 /// Matcher<Type> object. 120 /// 121 /// The code between the curly braces has access to the following variables: 122 /// 123 /// Node: the AST node being matched; its type is Type. 124 /// Param: the parameter passed to the function; its type 125 /// is ParamType. 126 /// Finder: an ASTMatchFinder*. 127 /// Builder: a BoundNodesTreeBuilder*. 128 /// 129 /// The code should return true if 'Node' matches. 130 #define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) \ 131 AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, 0) 132 133 #define AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, \ 134 OverloadId) \ 135 namespace internal { \ 136 class matcher_##DefineMatcher##OverloadId##Matcher \ 137 : public ::clang::ast_matchers::internal::MatcherInterface<Type> { \ 138 public: \ 139 explicit matcher_##DefineMatcher##OverloadId##Matcher( \ 140 ParamType const &A##Param) \ 141 : Param(A##Param) {} \ 142 bool matches(const Type &Node, \ 143 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 144 ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ 145 *Builder) const override; \ 146 \ 147 private: \ 148 ParamType Param; \ 149 }; \ 150 } \ 151 inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \ 152 ParamType const &Param) { \ 153 return ::clang::ast_matchers::internal::makeMatcher( \ 154 new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param)); \ 155 } \ 156 typedef ::clang::ast_matchers::internal::Matcher<Type> ( \ 157 &DefineMatcher##_Type##OverloadId)(ParamType const &Param); \ 158 inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \ 159 const Type &Node, \ 160 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 161 ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const 162 163 /// AST_MATCHER_P2( 164 /// Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... } 165 /// defines a two-parameter function named DefineMatcher() that returns a 166 /// Matcher<Type> object. 167 /// 168 /// The code between the curly braces has access to the following variables: 169 /// 170 /// Node: the AST node being matched; its type is Type. 171 /// Param1, Param2: the parameters passed to the function; their types 172 /// are ParamType1 and ParamType2. 173 /// Finder: an ASTMatchFinder*. 174 /// Builder: a BoundNodesTreeBuilder*. 175 /// 176 /// The code should return true if 'Node' matches. 177 #define AST_MATCHER_P2(Type, DefineMatcher, ParamType1, Param1, ParamType2, \ 178 Param2) \ 179 AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, ParamType2, \ 180 Param2, 0) 181 182 #define AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, \ 183 ParamType2, Param2, OverloadId) \ 184 namespace internal { \ 185 class matcher_##DefineMatcher##OverloadId##Matcher \ 186 : public ::clang::ast_matchers::internal::MatcherInterface<Type> { \ 187 public: \ 188 matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1, \ 189 ParamType2 const &A##Param2) \ 190 : Param1(A##Param1), Param2(A##Param2) {} \ 191 bool matches(const Type &Node, \ 192 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 193 ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ 194 *Builder) const override; \ 195 \ 196 private: \ 197 ParamType1 Param1; \ 198 ParamType2 Param2; \ 199 }; \ 200 } \ 201 inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \ 202 ParamType1 const &Param1, ParamType2 const &Param2) { \ 203 return ::clang::ast_matchers::internal::makeMatcher( \ 204 new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1, \ 205 Param2)); \ 206 } \ 207 typedef ::clang::ast_matchers::internal::Matcher<Type> ( \ 208 &DefineMatcher##_Type##OverloadId)(ParamType1 const &Param1, \ 209 ParamType2 const &Param2); \ 210 inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \ 211 const Type &Node, \ 212 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 213 ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const 214 215 /// Construct a type-list to be passed to the AST_POLYMORPHIC_MATCHER* 216 /// macros. 217 /// 218 /// You can't pass something like \c TypeList<Foo, Bar> to a macro, because it 219 /// will look at that as two arguments. However, you can pass 220 /// \c void(TypeList<Foo, Bar>), which works thanks to the parenthesis. 221 /// The \c PolymorphicMatcherWithParam* classes will unpack the function type to 222 /// extract the TypeList object. 223 #define AST_POLYMORPHIC_SUPPORTED_TYPES(...) \ 224 void(::clang::ast_matchers::internal::TypeList<__VA_ARGS__>) 225 226 /// AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... } 227 /// defines a single-parameter function named DefineMatcher() that is 228 /// polymorphic in the return type. 229 /// 230 /// The variables are the same as for AST_MATCHER, but NodeType will be deduced 231 /// from the calling context. 232 #define AST_POLYMORPHIC_MATCHER(DefineMatcher, ReturnTypesF) \ 233 namespace internal { \ 234 template <typename NodeType> \ 235 class matcher_##DefineMatcher##Matcher \ 236 : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \ 237 public: \ 238 bool matches(const NodeType &Node, \ 239 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 240 ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ 241 *Builder) const override; \ 242 }; \ 243 } \ 244 inline ::clang::ast_matchers::internal::PolymorphicMatcher< \ 245 internal::matcher_##DefineMatcher##Matcher, ReturnTypesF> \ 246 DefineMatcher() { \ 247 return ::clang::ast_matchers::internal::PolymorphicMatcher< \ 248 internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>(); \ 249 } \ 250 template <typename NodeType> \ 251 bool internal::matcher_##DefineMatcher##Matcher<NodeType>::matches( \ 252 const NodeType &Node, \ 253 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 254 ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const 255 256 /// AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... } 257 /// defines a single-parameter function named DefineMatcher() that is 258 /// polymorphic in the return type. 259 /// 260 /// The variables are the same as for 261 /// AST_MATCHER_P, with the addition of NodeType, which specifies the node type 262 /// of the matcher Matcher<NodeType> returned by the function matcher(). 263 /// 264 /// FIXME: Pull out common code with above macro? 265 #define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ReturnTypesF, ParamType, \ 266 Param) \ 267 AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType, \ 268 Param, 0) 269 270 #define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, \ 271 ParamType, Param, OverloadId) \ 272 namespace internal { \ 273 template <typename NodeType, typename ParamT> \ 274 class matcher_##DefineMatcher##OverloadId##Matcher \ 275 : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \ 276 public: \ 277 explicit matcher_##DefineMatcher##OverloadId##Matcher( \ 278 ParamType const &A##Param) \ 279 : Param(A##Param) {} \ 280 bool matches(const NodeType &Node, \ 281 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 282 ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ 283 *Builder) const override; \ 284 \ 285 private: \ 286 ParamType Param; \ 287 }; \ 288 } \ 289 inline ::clang::ast_matchers::internal::PolymorphicMatcher< \ 290 internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \ 291 ParamType> \ 292 DefineMatcher(ParamType const &Param) { \ 293 return ::clang::ast_matchers::internal::PolymorphicMatcher< \ 294 internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \ 295 ParamType>(Param); \ 296 } \ 297 typedef ::clang::ast_matchers::internal::PolymorphicMatcher< \ 298 internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \ 299 ParamType> (&DefineMatcher##_Type##OverloadId)(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 /// 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 Param1; \ 339 ParamType2 Param2; \ 340 }; \ 341 } \ 342 inline ::clang::ast_matchers::internal::PolymorphicMatcher< \ 343 internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \ 344 ParamType1, ParamType2> \ 345 DefineMatcher(ParamType1 const &Param1, ParamType2 const &Param2) { \ 346 return ::clang::ast_matchers::internal::PolymorphicMatcher< \ 347 internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \ 348 ParamType1, ParamType2>(Param1, Param2); \ 349 } \ 350 typedef ::clang::ast_matchers::internal::PolymorphicMatcher< \ 351 internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \ 352 ParamType1, ParamType2> (&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 // FIXME: add a matcher for TypeLoc derived classes using its custom casting 363 // API (no longer dyn_cast) if/when we need such matching 364 365 #define AST_TYPE_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName, \ 366 ReturnTypesF) \ 367 namespace internal { \ 368 template <typename T> struct TypeMatcher##MatcherName##Getter { \ 369 static QualType (T::*value())() const { return &T::FunctionName; } \ 370 }; \ 371 } \ 372 CLANG_ABI extern const ::clang::ast_matchers::internal:: \ 373 TypeTraversePolymorphicMatcher< \ 374 QualType, \ 375 ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter, \ 376 ::clang::ast_matchers::internal::TypeTraverseMatcher, \ 377 ReturnTypesF>::Func MatcherName 378 379 #define AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF) \ 380 const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \ 381 QualType, \ 382 ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter, \ 383 ::clang::ast_matchers::internal::TypeTraverseMatcher, \ 384 ReturnTypesF>::Func MatcherName 385 386 /// AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines 387 /// the matcher \c MatcherName that can be used to traverse from one \c Type 388 /// to another. 389 /// 390 /// For a specific \c SpecificType, the traversal is done using 391 /// \c SpecificType::FunctionName. The existence of such a function determines 392 /// whether a corresponding matcher can be used on \c SpecificType. 393 #define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \ 394 namespace internal { \ 395 template <typename T> struct TypeMatcher##MatcherName##Getter { \ 396 static QualType (T::*value())() const { return &T::FunctionName; } \ 397 }; \ 398 } \ 399 const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \ 400 QualType, \ 401 ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter, \ 402 ::clang::ast_matchers::internal::TypeTraverseMatcher, \ 403 ReturnTypesF>::Func MatcherName 404 405 #define AST_TYPELOC_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName, \ 406 ReturnTypesF) \ 407 namespace internal { \ 408 template <typename T> struct TypeLocMatcher##MatcherName##Getter { \ 409 static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; } \ 410 }; \ 411 } \ 412 CLANG_ABI extern const ::clang::ast_matchers::internal:: \ 413 TypeTraversePolymorphicMatcher< \ 414 TypeLoc, \ 415 ::clang::ast_matchers::internal:: \ 416 TypeLocMatcher##MatcherName##Getter, \ 417 ::clang::ast_matchers::internal::TypeLocTraverseMatcher, \ 418 ReturnTypesF>::Func MatcherName##Loc; \ 419 AST_TYPE_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName##Type, ReturnTypesF) 420 421 #define AST_TYPELOC_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF) \ 422 const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \ 423 TypeLoc, \ 424 ::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter, \ 425 ::clang::ast_matchers::internal::TypeLocTraverseMatcher, \ 426 ReturnTypesF>::Func MatcherName##Loc; \ 427 AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF) 428 429 /// AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works 430 /// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs. 431 #define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \ 432 namespace internal { \ 433 template <typename T> struct TypeLocMatcher##MatcherName##Getter { \ 434 static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; } \ 435 }; \ 436 } \ 437 const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \ 438 TypeLoc, \ 439 ::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter, \ 440 ::clang::ast_matchers::internal::TypeLocTraverseMatcher, \ 441 ReturnTypesF>::Func MatcherName##Loc; \ 442 AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF) 443 444 /// AST_MATCHER_REGEX(Type, DefineMatcher, Param) { ... } 445 /// defines a function named DefineMatcher() that takes a regular expression 446 /// string paramater and an optional RegexFlags parameter and returns a 447 /// Matcher<Type> object. 448 /// 449 /// The code between the curly braces has access to the following variables: 450 /// 451 /// Node: the AST node being matched; its type is Type. 452 /// Param: a pointer to an \ref llvm::Regex object 453 /// Finder: an ASTMatchFinder*. 454 /// Builder: a BoundNodesTreeBuilder*. 455 /// 456 /// The code should return true if 'Node' matches. 457 #define AST_MATCHER_REGEX(Type, DefineMatcher, Param) \ 458 AST_MATCHER_REGEX_OVERLOAD(Type, DefineMatcher, Param, 0) 459 460 #define AST_MATCHER_REGEX_OVERLOAD(Type, DefineMatcher, Param, OverloadId) \ 461 namespace internal { \ 462 class matcher_##DefineMatcher##OverloadId##Matcher \ 463 : public ::clang::ast_matchers::internal::MatcherInterface<Type> { \ 464 public: \ 465 explicit matcher_##DefineMatcher##OverloadId##Matcher( \ 466 std::shared_ptr<llvm::Regex> RE) \ 467 : Param(std::move(RE)) {} \ 468 bool matches(const Type &Node, \ 469 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 470 ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ 471 *Builder) const override; \ 472 \ 473 private: \ 474 std::shared_ptr<llvm::Regex> Param; \ 475 }; \ 476 } \ 477 inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \ 478 llvm::StringRef Param, llvm::Regex::RegexFlags RegexFlags) { \ 479 return ::clang::ast_matchers::internal::makeMatcher( \ 480 new internal::matcher_##DefineMatcher##OverloadId##Matcher( \ 481 ::clang::ast_matchers::internal::createAndVerifyRegex( \ 482 Param, RegexFlags, #DefineMatcher))); \ 483 } \ 484 inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \ 485 llvm::StringRef Param) { \ 486 return DefineMatcher(Param, llvm::Regex::NoFlags); \ 487 } \ 488 \ 489 typedef ::clang::ast_matchers::internal::Matcher<Type> ( \ 490 &DefineMatcher##_Type##OverloadId##Flags)(llvm::StringRef, \ 491 llvm::Regex::RegexFlags); \ 492 typedef ::clang::ast_matchers::internal::Matcher<Type> ( \ 493 &DefineMatcher##_Type##OverloadId)(llvm::StringRef); \ 494 inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \ 495 const Type &Node, \ 496 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 497 ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const 498 499 /// AST_POLYMORPHIC_MATCHER_REGEX(DefineMatcher, ReturnTypesF, Param) { ... } 500 /// defines a function named DefineMatcher() that takes a regular expression 501 /// string paramater and an optional RegexFlags parameter that is polymorphic in 502 /// the return type. 503 /// 504 /// The variables are the same as for 505 /// AST_MATCHER_REGEX, with the addition of NodeType, which specifies the node 506 /// type of the matcher Matcher<NodeType> returned by the function matcher(). 507 #define AST_POLYMORPHIC_MATCHER_REGEX(DefineMatcher, ReturnTypesF, Param) \ 508 AST_POLYMORPHIC_MATCHER_REGEX_OVERLOAD(DefineMatcher, ReturnTypesF, Param, 0) 509 510 #define AST_POLYMORPHIC_MATCHER_REGEX_OVERLOAD(DefineMatcher, ReturnTypesF, \ 511 Param, OverloadId) \ 512 namespace internal { \ 513 template <typename NodeType, typename ParamT> \ 514 class matcher_##DefineMatcher##OverloadId##Matcher \ 515 : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \ 516 public: \ 517 explicit matcher_##DefineMatcher##OverloadId##Matcher( \ 518 std::shared_ptr<llvm::Regex> RE) \ 519 : Param(std::move(RE)) {} \ 520 bool matches(const NodeType &Node, \ 521 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 522 ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ 523 *Builder) const override; \ 524 \ 525 private: \ 526 std::shared_ptr<llvm::Regex> Param; \ 527 }; \ 528 } \ 529 inline ::clang::ast_matchers::internal::PolymorphicMatcher< \ 530 internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \ 531 std::shared_ptr<llvm::Regex>> \ 532 DefineMatcher(llvm::StringRef Param, llvm::Regex::RegexFlags RegexFlags) { \ 533 return ::clang::ast_matchers::internal::PolymorphicMatcher< \ 534 internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \ 535 std::shared_ptr<llvm::Regex>>( \ 536 ::clang::ast_matchers::internal::createAndVerifyRegex( \ 537 Param, RegexFlags, #DefineMatcher)); \ 538 } \ 539 inline ::clang::ast_matchers::internal::PolymorphicMatcher< \ 540 internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \ 541 std::shared_ptr<llvm::Regex>> \ 542 DefineMatcher(llvm::StringRef Param) { \ 543 return DefineMatcher(Param, llvm::Regex::NoFlags); \ 544 } \ 545 typedef ::clang::ast_matchers::internal::PolymorphicMatcher< \ 546 internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \ 547 std::shared_ptr<llvm::Regex>> ( \ 548 &DefineMatcher##_Type##OverloadId##Flags)( \ 549 llvm::StringRef Param, llvm::Regex::RegexFlags RegexFlags); \ 550 typedef ::clang::ast_matchers::internal::PolymorphicMatcher< \ 551 internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \ 552 std::shared_ptr<llvm::Regex>> (&DefineMatcher##_Type##OverloadId)( \ 553 llvm::StringRef Param); \ 554 template <typename NodeType, typename ParamT> \ 555 bool internal:: \ 556 matcher_##DefineMatcher##OverloadId##Matcher<NodeType, ParamT>::matches( \ 557 const NodeType &Node, \ 558 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 559 ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) \ 560 const 561 562 #endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H 563