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_AST_MATCHERS_AST_MATCHERS_MACROS_H
38 #define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H
40 /// \brief AST_MATCHER(Type, DefineMatcher) { ... }
41 /// defines a zero parameter function named DefineMatcher() that returns a
42 /// Matcher<Type> object.
44 /// The code between the curly braces has access to the following variables:
46 /// Node: the AST node being matched; its type is Type.
47 /// Finder: an ASTMatchFinder*.
48 /// Builder: a BoundNodesTreeBuilder*.
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> { \
55 explicit matcher_##DefineMatcher##Matcher() {} \
56 virtual bool matches(const Type &Node, ASTMatchFinder *Finder, \
57 BoundNodesTreeBuilder *Builder) const; \
60 inline internal::Matcher<Type> DefineMatcher() { \
61 return internal::makeMatcher( \
62 new internal::matcher_##DefineMatcher##Matcher()); \
64 inline bool internal::matcher_##DefineMatcher##Matcher::matches( \
65 const Type &Node, ASTMatchFinder *Finder, \
66 BoundNodesTreeBuilder *Builder) const
68 /// \brief AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... }
69 /// defines a single-parameter function named DefineMatcher() that returns a
70 /// Matcher<Type> object.
72 /// The code between the curly braces has access to the following variables:
74 /// Node: the AST node being matched; its type is Type.
75 /// Param: the parameter passed to the function; its type
77 /// Finder: an ASTMatchFinder*.
78 /// Builder: a BoundNodesTreeBuilder*.
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)
84 #define AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, \
86 namespace internal { \
87 class matcher_##DefineMatcher##OverloadId##Matcher \
88 : public MatcherInterface<Type> { \
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; \
97 const ParamType Param; \
100 inline internal::Matcher<Type> DefineMatcher(const ParamType &Param) { \
101 return internal::makeMatcher( \
102 new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param)); \
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
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.
115 /// The code between the curly braces has access to the following variables:
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*.
123 /// The code should return true if 'Node' matches.
124 #define AST_MATCHER_P2(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
126 AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
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> { \
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; \
142 const ParamType1 Param1; \
143 const ParamType2 Param2; \
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, \
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
158 /// \brief Construct a type-list to be passed to the AST_POLYMORPHIC_MATCHER*
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, internal::TypeList<t4, t5> >)
176 /// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... }
177 /// defines a single-parameter function named DefineMatcher() that is
178 /// polymorphic in the return type.
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> { \
187 virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder, \
188 BoundNodesTreeBuilder *Builder) const; \
191 inline internal::PolymorphicMatcherWithParam0< \
192 internal::matcher_##DefineMatcher##Matcher, ReturnTypesF> \
194 return internal::PolymorphicMatcherWithParam0< \
195 internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>(); \
197 template <typename NodeType> \
198 bool internal::matcher_##DefineMatcher##Matcher<NodeType>::matches( \
199 const NodeType &Node, ASTMatchFinder *Finder, \
200 BoundNodesTreeBuilder *Builder) const
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.
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().
210 /// FIXME: Pull out common code with above macro?
211 #define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ReturnTypesF, ParamType, \
213 AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType, \
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> { \
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; \
230 const ParamType Param; \
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); \
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
249 /// \brief AST_POLYMORPHIC_MATCHER_P2(
250 /// DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
251 /// defines a two-parameter function named matcher() that is polymorphic in
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)
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> { \
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; \
277 const ParamType1 Param1; \
278 const ParamType2 Param2; \
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); \
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
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
306 /// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
307 /// the matcher \c MatcherName that can be used to traverse from one \c Type
310 /// For a specific \c SpecificType, the traversal is done using
311 /// \c SpecificType::FunctionName. The existence 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; } \
319 const internal::TypeTraversePolymorphicMatcher< \
320 QualType, internal::TypeMatcher##MatcherName##Getter, \
321 internal::TypeTraverseMatcher, ReturnTypesF>::Func MatcherName
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; } \
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)
336 #endif // LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H