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