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