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 const 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 const Param1; \ 196 ParamType2 const 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::PolymorphicMatcherWithParam0< \ 243 internal::matcher_##DefineMatcher##Matcher, ReturnTypesF> \ 244 DefineMatcher() { \ 245 return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam0< \ 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 const Param; \ 285 }; \ 286 } \ 287 inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \ 288 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \ 289 ReturnTypesF> \ 290 DefineMatcher(ParamType const &Param) { \ 291 return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \ 292 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \ 293 ReturnTypesF>(Param); \ 294 } \ 295 typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \ 296 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \ 297 ReturnTypesF>(&DefineMatcher##_Type##OverloadId)( \ 298 ParamType const &Param); \ 299 template <typename NodeType, typename ParamT> \ 300 bool internal:: \ 301 matcher_##DefineMatcher##OverloadId##Matcher<NodeType, ParamT>::matches( \ 302 const NodeType &Node, \ 303 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 304 ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) \ 305 const 306 307 /// AST_POLYMORPHIC_MATCHER_P2( 308 /// DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... } 309 /// defines a two-parameter function named matcher() that is polymorphic in 310 /// the return type. 311 /// 312 /// The variables are the same as for AST_MATCHER_P2, with the 313 /// addition of NodeType, which specifies the node type of the matcher 314 /// Matcher<NodeType> returned by the function DefineMatcher(). 315 #define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ReturnTypesF, ParamType1, \ 316 Param1, ParamType2, Param2) \ 317 AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType1, \ 318 Param1, ParamType2, Param2, 0) 319 320 #define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, \ 321 ParamType1, Param1, ParamType2, \ 322 Param2, OverloadId) \ 323 namespace internal { \ 324 template <typename NodeType, typename ParamT1, typename ParamT2> \ 325 class matcher_##DefineMatcher##OverloadId##Matcher \ 326 : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \ 327 public: \ 328 matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1, \ 329 ParamType2 const &A##Param2) \ 330 : Param1(A##Param1), Param2(A##Param2) {} \ 331 bool matches(const NodeType &Node, \ 332 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 333 ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ 334 *Builder) const override; \ 335 \ 336 private: \ 337 ParamType1 const Param1; \ 338 ParamType2 const Param2; \ 339 }; \ 340 } \ 341 inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2< \ 342 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \ 343 ParamType2, ReturnTypesF> \ 344 DefineMatcher(ParamType1 const &Param1, ParamType2 const &Param2) { \ 345 return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2< \ 346 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \ 347 ParamType2, ReturnTypesF>(Param1, Param2); \ 348 } \ 349 typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2< \ 350 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \ 351 ParamType2, ReturnTypesF>(&DefineMatcher##_Type##OverloadId)( \ 352 ParamType1 const &Param1, ParamType2 const &Param2); \ 353 template <typename NodeType, typename ParamT1, typename ParamT2> \ 354 bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \ 355 NodeType, ParamT1, ParamT2>:: \ 356 matches(const NodeType &Node, \ 357 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ 358 ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) \ 359 const 360 361 // FIXME: add a matcher for TypeLoc derived classes using its custom casting 362 // API (no longer dyn_cast) if/when we need such matching 363 364 #define AST_TYPE_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName, \ 365 ReturnTypesF) \ 366 namespace internal { \ 367 template <typename T> struct TypeMatcher##MatcherName##Getter { \ 368 static QualType (T::*value())() const { return &T::FunctionName; } \ 369 }; \ 370 } \ 371 extern const ::clang::ast_matchers::internal:: \ 372 TypeTraversePolymorphicMatcher< \ 373 QualType, \ 374 ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter, \ 375 ::clang::ast_matchers::internal::TypeTraverseMatcher, \ 376 ReturnTypesF>::Func MatcherName 377 378 #define AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF) \ 379 const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \ 380 QualType, \ 381 ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter, \ 382 ::clang::ast_matchers::internal::TypeTraverseMatcher, \ 383 ReturnTypesF>::Func MatcherName 384 385 /// AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines 386 /// the matcher \c MatcherName that can be used to traverse from one \c Type 387 /// to another. 388 /// 389 /// For a specific \c SpecificType, the traversal is done using 390 /// \c SpecificType::FunctionName. The existence of such a function determines 391 /// whether a corresponding matcher can be used on \c SpecificType. 392 #define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \ 393 namespace internal { \ 394 template <typename T> struct TypeMatcher##MatcherName##Getter { \ 395 static QualType (T::*value())() const { return &T::FunctionName; } \ 396 }; \ 397 } \ 398 const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \ 399 QualType, \ 400 ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter, \ 401 ::clang::ast_matchers::internal::TypeTraverseMatcher, \ 402 ReturnTypesF>::Func MatcherName 403 404 #define AST_TYPELOC_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName, \ 405 ReturnTypesF) \ 406 namespace internal { \ 407 template <typename T> struct TypeLocMatcher##MatcherName##Getter { \ 408 static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; } \ 409 }; \ 410 } \ 411 extern const ::clang::ast_matchers::internal:: \ 412 TypeTraversePolymorphicMatcher< \ 413 TypeLoc, \ 414 ::clang::ast_matchers::internal:: \ 415 TypeLocMatcher##MatcherName##Getter, \ 416 ::clang::ast_matchers::internal::TypeLocTraverseMatcher, \ 417 ReturnTypesF>::Func MatcherName##Loc; \ 418 AST_TYPE_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName##Type, ReturnTypesF) 419 420 #define AST_TYPELOC_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF) \ 421 const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \ 422 TypeLoc, \ 423 ::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter, \ 424 ::clang::ast_matchers::internal::TypeLocTraverseMatcher, \ 425 ReturnTypesF>::Func MatcherName##Loc; \ 426 AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF) 427 428 /// AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works 429 /// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs. 430 #define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \ 431 namespace internal { \ 432 template <typename T> struct TypeLocMatcher##MatcherName##Getter { \ 433 static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; } \ 434 }; \ 435 } \ 436 const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \ 437 TypeLoc, \ 438 ::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter, \ 439 ::clang::ast_matchers::internal::TypeLocTraverseMatcher, \ 440 ReturnTypesF>::Func MatcherName##Loc; \ 441 AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF) 442 443 #endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H 444