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, always put it into the clang::ast_matchers
24 // namespace and refer to the internal types via the 'internal::':
27 // namespace ast_matchers {
28 // AST_MATCHER_P(MemberExpr, Member,
29 // internal::Matcher<ValueDecl>, InnerMatcher) {
30 // return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
32 // } // end namespace ast_matchers
33 // } // end namespace clang
35 //===----------------------------------------------------------------------===//
37 #ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
38 #define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
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(); \
49 inline ReturnType DefineMatcher##_getInstance()
51 /// \brief AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) {
52 /// defines a single-parameter function named DefineMatcher() that returns a
53 /// ReturnType object.
55 /// The code between the curly braces has access to the following variables:
57 /// Param: the parameter passed to the function; its type
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, \
64 #define AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, \
66 inline ReturnType DefineMatcher(ParamType const &Param); \
67 typedef ReturnType (&DefineMatcher##_Type##OverloadId)(ParamType const &); \
68 inline ReturnType DefineMatcher(ParamType const &Param)
70 /// \brief AST_MATCHER(Type, DefineMatcher) { ... }
71 /// defines a zero parameter function named DefineMatcher() that returns a
72 /// Matcher<Type> object.
74 /// The code between the curly braces has access to the following variables:
76 /// Node: the AST node being matched; its type is Type.
77 /// Finder: an ASTMatchFinder*.
78 /// Builder: a BoundNodesTreeBuilder*.
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> { \
85 explicit matcher_##DefineMatcher##Matcher() {} \
86 bool matches(const Type &Node, ASTMatchFinder *Finder, \
87 BoundNodesTreeBuilder *Builder) const override; \
90 inline internal::Matcher<Type> DefineMatcher() { \
91 return internal::makeMatcher( \
92 new internal::matcher_##DefineMatcher##Matcher()); \
94 inline bool internal::matcher_##DefineMatcher##Matcher::matches( \
95 const Type &Node, ASTMatchFinder *Finder, \
96 BoundNodesTreeBuilder *Builder) const
98 /// \brief AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... }
99 /// defines a single-parameter function named DefineMatcher() that returns a
100 /// Matcher<Type> object.
102 /// The code between the curly braces has access to the following variables:
104 /// Node: the AST node being matched; its type is Type.
105 /// Param: the parameter passed to the function; its type
107 /// Finder: an ASTMatchFinder*.
108 /// Builder: a BoundNodesTreeBuilder*.
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)
114 #define AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, \
116 namespace internal { \
117 class matcher_##DefineMatcher##OverloadId##Matcher \
118 : public MatcherInterface<Type> { \
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; \
127 ParamType const Param; \
130 inline internal::Matcher<Type> DefineMatcher(ParamType const &Param) { \
131 return internal::makeMatcher( \
132 new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param)); \
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
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.
145 /// The code between the curly braces has access to the following variables:
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*.
153 /// The code should return true if 'Node' matches.
154 #define AST_MATCHER_P2(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
156 AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
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> { \
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; \
172 ParamType1 const Param1; \
173 ParamType2 const Param2; \
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, \
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
188 /// \brief Construct a type-list to be passed to the AST_POLYMORPHIC_MATCHER*
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_1(t1) void(internal::TypeList<t1>)
197 #define AST_POLYMORPHIC_SUPPORTED_TYPES_2(t1, t2) \
198 void(internal::TypeList<t1, t2>)
199 #define AST_POLYMORPHIC_SUPPORTED_TYPES_3(t1, t2, t3) \
200 void(internal::TypeList<t1, t2, t3>)
201 #define AST_POLYMORPHIC_SUPPORTED_TYPES_4(t1, t2, t3, t4) \
202 void(internal::TypeList<t1, t2, t3, t4>)
203 #define AST_POLYMORPHIC_SUPPORTED_TYPES_5(t1, t2, t3, t4, t5) \
204 void(internal::TypeList<t1, t2, t3, internal::TypeList<t4, t5> >)
206 /// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... }
207 /// defines a single-parameter function named DefineMatcher() that is
208 /// polymorphic in the return type.
210 /// The variables are the same as for AST_MATCHER, but NodeType will be deduced
211 /// from the calling context.
212 #define AST_POLYMORPHIC_MATCHER(DefineMatcher, ReturnTypesF) \
213 namespace internal { \
214 template <typename NodeType> \
215 class matcher_##DefineMatcher##Matcher : public MatcherInterface<NodeType> { \
217 bool matches(const NodeType &Node, ASTMatchFinder *Finder, \
218 BoundNodesTreeBuilder *Builder) const override; \
221 inline internal::PolymorphicMatcherWithParam0< \
222 internal::matcher_##DefineMatcher##Matcher, ReturnTypesF> \
224 return internal::PolymorphicMatcherWithParam0< \
225 internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>(); \
227 template <typename NodeType> \
228 bool internal::matcher_##DefineMatcher##Matcher<NodeType>::matches( \
229 const NodeType &Node, ASTMatchFinder *Finder, \
230 BoundNodesTreeBuilder *Builder) const
232 /// \brief AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... }
233 /// defines a single-parameter function named DefineMatcher() that is
234 /// polymorphic in the return type.
236 /// The variables are the same as for
237 /// AST_MATCHER_P, with the addition of NodeType, which specifies the node type
238 /// of the matcher Matcher<NodeType> returned by the function matcher().
240 /// FIXME: Pull out common code with above macro?
241 #define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ReturnTypesF, ParamType, \
243 AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType, \
246 #define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, \
247 ParamType, Param, OverloadId) \
248 namespace internal { \
249 template <typename NodeType, typename ParamT> \
250 class matcher_##DefineMatcher##OverloadId##Matcher \
251 : public MatcherInterface<NodeType> { \
253 explicit matcher_##DefineMatcher##OverloadId##Matcher( \
254 ParamType const &A##Param) \
255 : Param(A##Param) {} \
256 bool matches(const NodeType &Node, ASTMatchFinder *Finder, \
257 BoundNodesTreeBuilder *Builder) const override; \
260 ParamType const Param; \
263 inline internal::PolymorphicMatcherWithParam1< \
264 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \
265 ReturnTypesF> DefineMatcher(ParamType const &Param) { \
266 return internal::PolymorphicMatcherWithParam1< \
267 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \
268 ReturnTypesF>(Param); \
270 typedef internal::PolymorphicMatcherWithParam1< \
271 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \
272 ReturnTypesF>(&DefineMatcher##_Type##OverloadId)( \
273 ParamType const &Param); \
274 template <typename NodeType, typename ParamT> \
275 bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \
276 NodeType, ParamT>::matches(const NodeType &Node, ASTMatchFinder *Finder, \
277 BoundNodesTreeBuilder *Builder) const
279 /// \brief AST_POLYMORPHIC_MATCHER_P2(
280 /// DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
281 /// defines a two-parameter function named matcher() that is polymorphic in
284 /// The variables are the same as for AST_MATCHER_P2, with the
285 /// addition of NodeType, which specifies the node type of the matcher
286 /// Matcher<NodeType> returned by the function DefineMatcher().
287 #define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ReturnTypesF, ParamType1, \
288 Param1, ParamType2, Param2) \
289 AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType1, \
290 Param1, ParamType2, Param2, 0)
292 #define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, \
293 ParamType1, Param1, ParamType2, \
294 Param2, OverloadId) \
295 namespace internal { \
296 template <typename NodeType, typename ParamT1, typename ParamT2> \
297 class matcher_##DefineMatcher##OverloadId##Matcher \
298 : public MatcherInterface<NodeType> { \
300 matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1, \
301 ParamType2 const &A##Param2) \
302 : Param1(A##Param1), Param2(A##Param2) {} \
303 bool matches(const NodeType &Node, ASTMatchFinder *Finder, \
304 BoundNodesTreeBuilder *Builder) const override; \
307 ParamType1 const Param1; \
308 ParamType2 const Param2; \
311 inline internal::PolymorphicMatcherWithParam2< \
312 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \
313 ParamType2, ReturnTypesF> DefineMatcher(ParamType1 const &Param1, \
314 ParamType2 const &Param2) { \
315 return internal::PolymorphicMatcherWithParam2< \
316 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \
317 ParamType2, ReturnTypesF>(Param1, Param2); \
319 typedef internal::PolymorphicMatcherWithParam2< \
320 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \
321 ParamType2, ReturnTypesF>(&DefineMatcher##_Type##OverloadId)( \
322 ParamType1 const &Param1, ParamType2 const &Param2); \
323 template <typename NodeType, typename ParamT1, typename ParamT2> \
324 bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \
325 NodeType, ParamT1, ParamT2>::matches( \
326 const NodeType &Node, ASTMatchFinder *Finder, \
327 BoundNodesTreeBuilder *Builder) const
329 /// \brief Creates a variadic matcher for both a specific \c Type as well as
330 /// the corresponding \c TypeLoc.
331 #define AST_TYPE_MATCHER(NodeType, MatcherName) \
332 const internal::VariadicDynCastAllOfMatcher<Type, NodeType> MatcherName
333 // FIXME: add a matcher for TypeLoc derived classes using its custom casting
334 // API (no longer dyn_cast) if/when we need such matching
336 /// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
337 /// the matcher \c MatcherName that can be used to traverse from one \c Type
340 /// For a specific \c SpecificType, the traversal is done using
341 /// \c SpecificType::FunctionName. The existence of such a function determines
342 /// whether a corresponding matcher can be used on \c SpecificType.
343 #define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \
344 namespace internal { \
345 template <typename T> struct TypeMatcher##MatcherName##Getter { \
346 static QualType (T::*value())() const { return &T::FunctionName; } \
349 const internal::TypeTraversePolymorphicMatcher< \
350 QualType, internal::TypeMatcher##MatcherName##Getter, \
351 internal::TypeTraverseMatcher, ReturnTypesF>::Func MatcherName
353 /// \brief AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works
354 /// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs.
355 #define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \
356 namespace internal { \
357 template <typename T> struct TypeLocMatcher##MatcherName##Getter { \
358 static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; } \
361 const internal::TypeTraversePolymorphicMatcher< \
362 TypeLoc, internal::TypeLocMatcher##MatcherName##Getter, \
363 internal::TypeLocTraverseMatcher, ReturnTypesF>::Func MatcherName##Loc; \
364 AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF)