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