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, 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 existance 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