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(...) \ 197 void(internal::TypeList<__VA_ARGS__>) 198 199 /// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... } 200 /// defines a single-parameter function named DefineMatcher() that is 201 /// polymorphic in the return type. 202 /// 203 /// The variables are the same as for AST_MATCHER, but NodeType will be deduced 204 /// from the calling context. 205 #define AST_POLYMORPHIC_MATCHER(DefineMatcher, ReturnTypesF) \ 206 namespace internal { \ 207 template <typename NodeType> \ 208 class matcher_##DefineMatcher##Matcher : public MatcherInterface<NodeType> { \ 209 public: \ 210 bool matches(const NodeType &Node, ASTMatchFinder *Finder, \ 211 BoundNodesTreeBuilder *Builder) const override; \ 212 }; \ 213 } \ 214 inline internal::PolymorphicMatcherWithParam0< \ 215 internal::matcher_##DefineMatcher##Matcher, ReturnTypesF> \ 216 DefineMatcher() { \ 217 return internal::PolymorphicMatcherWithParam0< \ 218 internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>(); \ 219 } \ 220 template <typename NodeType> \ 221 bool internal::matcher_##DefineMatcher##Matcher<NodeType>::matches( \ 222 const NodeType &Node, ASTMatchFinder *Finder, \ 223 BoundNodesTreeBuilder *Builder) const 224 225 /// \brief AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... } 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 230 /// AST_MATCHER_P, with the addition of NodeType, which specifies the node type 231 /// of the matcher Matcher<NodeType> returned by the function matcher(). 232 /// 233 /// FIXME: Pull out common code with above macro? 234 #define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ReturnTypesF, ParamType, \ 235 Param) \ 236 AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType, \ 237 Param, 0) 238 239 #define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, \ 240 ParamType, Param, OverloadId) \ 241 namespace internal { \ 242 template <typename NodeType, typename ParamT> \ 243 class matcher_##DefineMatcher##OverloadId##Matcher \ 244 : public MatcherInterface<NodeType> { \ 245 public: \ 246 explicit matcher_##DefineMatcher##OverloadId##Matcher( \ 247 ParamType const &A##Param) \ 248 : Param(A##Param) {} \ 249 bool matches(const NodeType &Node, ASTMatchFinder *Finder, \ 250 BoundNodesTreeBuilder *Builder) const override; \ 251 \ 252 private: \ 253 ParamType const Param; \ 254 }; \ 255 } \ 256 inline internal::PolymorphicMatcherWithParam1< \ 257 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \ 258 ReturnTypesF> DefineMatcher(ParamType const &Param) { \ 259 return internal::PolymorphicMatcherWithParam1< \ 260 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \ 261 ReturnTypesF>(Param); \ 262 } \ 263 typedef internal::PolymorphicMatcherWithParam1< \ 264 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \ 265 ReturnTypesF>(&DefineMatcher##_Type##OverloadId)( \ 266 ParamType const &Param); \ 267 template <typename NodeType, typename ParamT> \ 268 bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \ 269 NodeType, ParamT>::matches(const NodeType &Node, ASTMatchFinder *Finder, \ 270 BoundNodesTreeBuilder *Builder) const 271 272 /// \brief AST_POLYMORPHIC_MATCHER_P2( 273 /// DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... } 274 /// defines a two-parameter function named matcher() that is polymorphic in 275 /// the return type. 276 /// 277 /// The variables are the same as for AST_MATCHER_P2, with the 278 /// addition of NodeType, which specifies the node type of the matcher 279 /// Matcher<NodeType> returned by the function DefineMatcher(). 280 #define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ReturnTypesF, ParamType1, \ 281 Param1, ParamType2, Param2) \ 282 AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType1, \ 283 Param1, ParamType2, Param2, 0) 284 285 #define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, \ 286 ParamType1, Param1, ParamType2, \ 287 Param2, OverloadId) \ 288 namespace internal { \ 289 template <typename NodeType, typename ParamT1, typename ParamT2> \ 290 class matcher_##DefineMatcher##OverloadId##Matcher \ 291 : public MatcherInterface<NodeType> { \ 292 public: \ 293 matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1, \ 294 ParamType2 const &A##Param2) \ 295 : Param1(A##Param1), Param2(A##Param2) {} \ 296 bool matches(const NodeType &Node, ASTMatchFinder *Finder, \ 297 BoundNodesTreeBuilder *Builder) const override; \ 298 \ 299 private: \ 300 ParamType1 const Param1; \ 301 ParamType2 const Param2; \ 302 }; \ 303 } \ 304 inline internal::PolymorphicMatcherWithParam2< \ 305 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \ 306 ParamType2, ReturnTypesF> DefineMatcher(ParamType1 const &Param1, \ 307 ParamType2 const &Param2) { \ 308 return internal::PolymorphicMatcherWithParam2< \ 309 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \ 310 ParamType2, ReturnTypesF>(Param1, Param2); \ 311 } \ 312 typedef internal::PolymorphicMatcherWithParam2< \ 313 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \ 314 ParamType2, ReturnTypesF>(&DefineMatcher##_Type##OverloadId)( \ 315 ParamType1 const &Param1, ParamType2 const &Param2); \ 316 template <typename NodeType, typename ParamT1, typename ParamT2> \ 317 bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \ 318 NodeType, ParamT1, ParamT2>::matches( \ 319 const NodeType &Node, ASTMatchFinder *Finder, \ 320 BoundNodesTreeBuilder *Builder) const 321 322 /// \brief Creates a variadic matcher for both a specific \c Type as well as 323 /// the corresponding \c TypeLoc. 324 #define AST_TYPE_MATCHER(NodeType, MatcherName) \ 325 const internal::VariadicDynCastAllOfMatcher<Type, NodeType> MatcherName 326 // FIXME: add a matcher for TypeLoc derived classes using its custom casting 327 // API (no longer dyn_cast) if/when we need such matching 328 329 /// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines 330 /// the matcher \c MatcherName that can be used to traverse from one \c Type 331 /// to another. 332 /// 333 /// For a specific \c SpecificType, the traversal is done using 334 /// \c SpecificType::FunctionName. The existence of such a function determines 335 /// whether a corresponding matcher can be used on \c SpecificType. 336 #define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \ 337 namespace internal { \ 338 template <typename T> struct TypeMatcher##MatcherName##Getter { \ 339 static QualType (T::*value())() const { return &T::FunctionName; } \ 340 }; \ 341 } \ 342 const internal::TypeTraversePolymorphicMatcher< \ 343 QualType, internal::TypeMatcher##MatcherName##Getter, \ 344 internal::TypeTraverseMatcher, ReturnTypesF>::Func MatcherName 345 346 /// \brief AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works 347 /// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs. 348 #define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \ 349 namespace internal { \ 350 template <typename T> struct TypeLocMatcher##MatcherName##Getter { \ 351 static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; } \ 352 }; \ 353 } \ 354 const internal::TypeTraversePolymorphicMatcher< \ 355 TypeLoc, internal::TypeLocMatcher##MatcherName##Getter, \ 356 internal::TypeLocTraverseMatcher, ReturnTypesF>::Func MatcherName##Loc; \ 357 AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF) 358 359 #endif 360