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