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(...) \
197 void(internal::TypeList<__VA_ARGS__>)
199 /// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... }
200 /// defines a single-parameter function named DefineMatcher() that is
201 /// polymorphic in the return type.
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> { \
210 bool matches(const NodeType &Node, ASTMatchFinder *Finder, \
211 BoundNodesTreeBuilder *Builder) const override; \
214 inline internal::PolymorphicMatcherWithParam0< \
215 internal::matcher_##DefineMatcher##Matcher, ReturnTypesF> \
217 return internal::PolymorphicMatcherWithParam0< \
218 internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>(); \
220 template <typename NodeType> \
221 bool internal::matcher_##DefineMatcher##Matcher<NodeType>::matches( \
222 const NodeType &Node, ASTMatchFinder *Finder, \
223 BoundNodesTreeBuilder *Builder) const
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.
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().
233 /// FIXME: Pull out common code with above macro?
234 #define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ReturnTypesF, ParamType, \
236 AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType, \
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> { \
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; \
253 ParamType const Param; \
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); \
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
272 /// \brief AST_POLYMORPHIC_MATCHER_P2(
273 /// DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
274 /// defines a two-parameter function named matcher() that is polymorphic in
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)
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> { \
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; \
300 ParamType1 const Param1; \
301 ParamType2 const Param2; \
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); \
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
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
329 /// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
330 /// the matcher \c MatcherName that can be used to traverse from one \c Type
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; } \
342 const internal::TypeTraversePolymorphicMatcher< \
343 QualType, internal::TypeMatcher##MatcherName##Getter, \
344 internal::TypeTraverseMatcher, ReturnTypesF>::Func MatcherName
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; } \
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)