1 //===--- ASTMatchersMacros.h - Structural query framework -------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
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
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.
23 // To define a matcher in user code, put it into your own namespace. This would
24 // help to prevent ODR violations in case a matcher with the same name is
25 // defined in multiple translation units:
27 // namespace my_matchers {
28 // AST_MATCHER_P(clang::MemberExpr, Member,
29 // clang::ast_matchers::internal::Matcher<clang::ValueDecl>,
31 // return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
33 // } // namespace my_matchers
35 // Alternatively, an unnamed namespace may be used:
38 // namespace ast_matchers {
40 // AST_MATCHER_P(MemberExpr, Member,
41 // internal::Matcher<ValueDecl>, InnerMatcher) {
42 // return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
45 // } // namespace ast_matchers
46 // } // namespace clang
48 //===----------------------------------------------------------------------===//
50 #ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
51 #define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
53 /// \brief AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) { ... }
54 /// defines a zero parameter function named DefineMatcher() that returns a
55 /// ReturnType object.
56 #define AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) \
57 inline ReturnType DefineMatcher##_getInstance(); \
58 inline ReturnType DefineMatcher() { \
59 return ::clang::ast_matchers::internal::MemoizedMatcher< \
60 ReturnType, DefineMatcher##_getInstance>::getInstance(); \
62 inline ReturnType DefineMatcher##_getInstance()
64 /// \brief AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) {
66 /// defines a single-parameter function named DefineMatcher() that returns a
67 /// ReturnType object.
69 /// The code between the curly braces has access to the following variables:
71 /// Param: the parameter passed to the function; its type
74 /// The code should return an instance of ReturnType.
75 #define AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) \
76 AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, Param, \
78 #define AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, \
80 inline ReturnType DefineMatcher(ParamType const &Param); \
81 typedef ReturnType (&DefineMatcher##_Type##OverloadId)(ParamType const &); \
82 inline ReturnType DefineMatcher(ParamType const &Param)
84 /// \brief AST_MATCHER(Type, DefineMatcher) { ... }
85 /// defines a zero parameter function named DefineMatcher() that returns a
86 /// Matcher<Type> object.
88 /// The code between the curly braces has access to the following variables:
90 /// Node: the AST node being matched; its type is Type.
91 /// Finder: an ASTMatchFinder*.
92 /// Builder: a BoundNodesTreeBuilder*.
94 /// The code should return true if 'Node' matches.
95 #define AST_MATCHER(Type, DefineMatcher) \
96 namespace internal { \
97 class matcher_##DefineMatcher##Matcher \
98 : public ::clang::ast_matchers::internal::MatcherInterface<Type> { \
100 explicit matcher_##DefineMatcher##Matcher() {} \
101 bool matches(const Type &Node, \
102 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
103 ::clang::ast_matchers::internal::BoundNodesTreeBuilder \
104 *Builder) const override; \
107 inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher() { \
108 return ::clang::ast_matchers::internal::makeMatcher( \
109 new internal::matcher_##DefineMatcher##Matcher()); \
111 inline bool internal::matcher_##DefineMatcher##Matcher::matches( \
113 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
114 ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
116 /// \brief AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... }
117 /// defines a single-parameter function named DefineMatcher() that returns a
118 /// Matcher<Type> object.
120 /// The code between the curly braces has access to the following variables:
122 /// Node: the AST node being matched; its type is Type.
123 /// Param: the parameter passed to the function; its type
125 /// Finder: an ASTMatchFinder*.
126 /// Builder: a BoundNodesTreeBuilder*.
128 /// The code should return true if 'Node' matches.
129 #define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) \
130 AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, 0)
132 #define AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, \
134 namespace internal { \
135 class matcher_##DefineMatcher##OverloadId##Matcher \
136 : public ::clang::ast_matchers::internal::MatcherInterface<Type> { \
138 explicit matcher_##DefineMatcher##OverloadId##Matcher( \
139 ParamType const &A##Param) \
140 : Param(A##Param) {} \
141 bool matches(const Type &Node, \
142 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
143 ::clang::ast_matchers::internal::BoundNodesTreeBuilder \
144 *Builder) const override; \
147 ParamType const Param; \
150 inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \
151 ParamType const &Param) { \
152 return ::clang::ast_matchers::internal::makeMatcher( \
153 new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param)); \
155 typedef ::clang::ast_matchers::internal::Matcher<Type>( \
156 &DefineMatcher##_Type##OverloadId)(ParamType const &Param); \
157 inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
159 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
160 ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
162 /// \brief AST_MATCHER_P2(
163 /// Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
164 /// defines a two-parameter function named DefineMatcher() that returns a
165 /// Matcher<Type> object.
167 /// The code between the curly braces has access to the following variables:
169 /// Node: the AST node being matched; its type is Type.
170 /// Param1, Param2: the parameters passed to the function; their types
171 /// are ParamType1 and ParamType2.
172 /// Finder: an ASTMatchFinder*.
173 /// Builder: a BoundNodesTreeBuilder*.
175 /// The code should return true if 'Node' matches.
176 #define AST_MATCHER_P2(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
178 AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
181 #define AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, \
182 ParamType2, Param2, OverloadId) \
183 namespace internal { \
184 class matcher_##DefineMatcher##OverloadId##Matcher \
185 : public ::clang::ast_matchers::internal::MatcherInterface<Type> { \
187 matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1, \
188 ParamType2 const &A##Param2) \
189 : Param1(A##Param1), Param2(A##Param2) {} \
190 bool matches(const Type &Node, \
191 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
192 ::clang::ast_matchers::internal::BoundNodesTreeBuilder \
193 *Builder) const override; \
196 ParamType1 const Param1; \
197 ParamType2 const Param2; \
200 inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \
201 ParamType1 const &Param1, ParamType2 const &Param2) { \
202 return ::clang::ast_matchers::internal::makeMatcher( \
203 new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1, \
206 typedef ::clang::ast_matchers::internal::Matcher<Type>( \
207 &DefineMatcher##_Type##OverloadId)(ParamType1 const &Param1, \
208 ParamType2 const &Param2); \
209 inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
211 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
212 ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
214 /// \brief Construct a type-list to be passed to the AST_POLYMORPHIC_MATCHER*
217 /// You can't pass something like \c TypeList<Foo, Bar> to a macro, because it
218 /// will look at that as two arguments. However, you can pass
219 /// \c void(TypeList<Foo, Bar>), which works thanks to the parenthesis.
220 /// The \c PolymorphicMatcherWithParam* classes will unpack the function type to
221 /// extract the TypeList object.
222 #define AST_POLYMORPHIC_SUPPORTED_TYPES(...) \
223 void(::clang::ast_matchers::internal::TypeList<__VA_ARGS__>)
225 /// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... }
226 /// defines a single-parameter function named DefineMatcher() that is
227 /// polymorphic in the return type.
229 /// The variables are the same as for AST_MATCHER, but NodeType will be deduced
230 /// from the calling context.
231 #define AST_POLYMORPHIC_MATCHER(DefineMatcher, ReturnTypesF) \
232 namespace internal { \
233 template <typename NodeType> \
234 class matcher_##DefineMatcher##Matcher \
235 : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \
237 bool matches(const NodeType &Node, \
238 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
239 ::clang::ast_matchers::internal::BoundNodesTreeBuilder \
240 *Builder) const override; \
243 inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam0< \
244 internal::matcher_##DefineMatcher##Matcher, ReturnTypesF> \
246 return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam0< \
247 internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>(); \
249 template <typename NodeType> \
250 bool internal::matcher_##DefineMatcher##Matcher<NodeType>::matches( \
251 const NodeType &Node, \
252 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
253 ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
255 /// \brief AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... }
256 /// defines a single-parameter function named DefineMatcher() that is
257 /// polymorphic in the return type.
259 /// The variables are the same as for
260 /// AST_MATCHER_P, with the addition of NodeType, which specifies the node type
261 /// of the matcher Matcher<NodeType> returned by the function matcher().
263 /// FIXME: Pull out common code with above macro?
264 #define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ReturnTypesF, ParamType, \
266 AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType, \
269 #define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, \
270 ParamType, Param, OverloadId) \
271 namespace internal { \
272 template <typename NodeType, typename ParamT> \
273 class matcher_##DefineMatcher##OverloadId##Matcher \
274 : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \
276 explicit matcher_##DefineMatcher##OverloadId##Matcher( \
277 ParamType const &A##Param) \
278 : Param(A##Param) {} \
279 bool matches(const NodeType &Node, \
280 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
281 ::clang::ast_matchers::internal::BoundNodesTreeBuilder \
282 *Builder) const override; \
285 ParamType const Param; \
288 inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \
289 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \
291 DefineMatcher(ParamType const &Param) { \
292 return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \
293 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \
294 ReturnTypesF>(Param); \
296 typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1< \
297 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \
298 ReturnTypesF>(&DefineMatcher##_Type##OverloadId)( \
299 ParamType const &Param); \
300 template <typename NodeType, typename ParamT> \
302 matcher_##DefineMatcher##OverloadId##Matcher<NodeType, ParamT>::matches( \
303 const NodeType &Node, \
304 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
305 ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) \
308 /// \brief AST_POLYMORPHIC_MATCHER_P2(
309 /// DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
310 /// defines a two-parameter function named matcher() that is polymorphic in
313 /// The variables are the same as for AST_MATCHER_P2, with the
314 /// addition of NodeType, which specifies the node type of the matcher
315 /// Matcher<NodeType> returned by the function DefineMatcher().
316 #define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ReturnTypesF, ParamType1, \
317 Param1, ParamType2, Param2) \
318 AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType1, \
319 Param1, ParamType2, Param2, 0)
321 #define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, \
322 ParamType1, Param1, ParamType2, \
323 Param2, OverloadId) \
324 namespace internal { \
325 template <typename NodeType, typename ParamT1, typename ParamT2> \
326 class matcher_##DefineMatcher##OverloadId##Matcher \
327 : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \
329 matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1, \
330 ParamType2 const &A##Param2) \
331 : Param1(A##Param1), Param2(A##Param2) {} \
332 bool matches(const NodeType &Node, \
333 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
334 ::clang::ast_matchers::internal::BoundNodesTreeBuilder \
335 *Builder) const override; \
338 ParamType1 const Param1; \
339 ParamType2 const Param2; \
342 inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2< \
343 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \
344 ParamType2, ReturnTypesF> \
345 DefineMatcher(ParamType1 const &Param1, ParamType2 const &Param2) { \
346 return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2< \
347 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \
348 ParamType2, ReturnTypesF>(Param1, Param2); \
350 typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2< \
351 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \
352 ParamType2, ReturnTypesF>(&DefineMatcher##_Type##OverloadId)( \
353 ParamType1 const &Param1, ParamType2 const &Param2); \
354 template <typename NodeType, typename ParamT1, typename ParamT2> \
355 bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \
356 NodeType, ParamT1, ParamT2>:: \
357 matches(const NodeType &Node, \
358 ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \
359 ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) \
362 /// \brief Creates a variadic matcher for both a specific \c Type as well as
363 /// the corresponding \c TypeLoc.
364 #define AST_TYPE_MATCHER(NodeType, MatcherName) \
365 const ::clang::ast_matchers::internal::VariadicDynCastAllOfMatcher< \
366 Type, NodeType> MatcherName
367 // FIXME: add a matcher for TypeLoc derived classes using its custom casting
368 // API (no longer dyn_cast) if/when we need such matching
370 /// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
371 /// the matcher \c MatcherName that can be used to traverse from one \c Type
374 /// For a specific \c SpecificType, the traversal is done using
375 /// \c SpecificType::FunctionName. The existence of such a function determines
376 /// whether a corresponding matcher can be used on \c SpecificType.
377 #define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \
378 namespace internal { \
379 template <typename T> struct TypeMatcher##MatcherName##Getter { \
380 static QualType (T::*value())() const { return &T::FunctionName; } \
383 const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \
385 ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter, \
386 ::clang::ast_matchers::internal::TypeTraverseMatcher, \
387 ReturnTypesF>::Func MatcherName
389 /// \brief AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works
390 /// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs.
391 #define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \
392 namespace internal { \
393 template <typename T> struct TypeLocMatcher##MatcherName##Getter { \
394 static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; } \
397 const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \
399 ::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter, \
400 ::clang::ast_matchers::internal::TypeLocTraverseMatcher, \
401 ReturnTypesF>::Func MatcherName##Loc; \
402 AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF)