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