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