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 AST_MATCHER_OVERLOAD(Type, DefineMatcher, 0)
54 #define AST_MATCHER_OVERLOAD(Type, DefineMatcher, OverloadId) \
55 namespace internal { \
56 class matcher_##DefineMatcher##OverloadId##Matcher \
57 : public MatcherInterface<Type> { \
59 explicit matcher_##DefineMatcher##OverloadId##Matcher() {} \
60 virtual bool matches(const Type &Node, ASTMatchFinder *Finder, \
61 BoundNodesTreeBuilder *Builder) const; \
64 inline internal::Matcher<Type> DefineMatcher() { \
65 return internal::makeMatcher( \
66 new internal::matcher_##DefineMatcher##OverloadId##Matcher()); \
68 inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
69 const Type &Node, ASTMatchFinder *Finder, \
70 BoundNodesTreeBuilder *Builder) const
72 /// \brief AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... }
73 /// defines a single-parameter function named DefineMatcher() that returns a
74 /// Matcher<Type> object.
76 /// The code between the curly braces has access to the following variables:
78 /// Node: the AST node being matched; its type is Type.
79 /// Param: the parameter passed to the function; its type
81 /// Finder: an ASTMatchFinder*.
82 /// Builder: a BoundNodesTreeBuilder*.
84 /// The code should return true if 'Node' matches.
85 #define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) \
86 AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, 0)
88 #define AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, \
90 namespace internal { \
91 class matcher_##DefineMatcher##OverloadId##Matcher \
92 : public MatcherInterface<Type> { \
94 explicit matcher_##DefineMatcher##OverloadId##Matcher( \
95 const ParamType &A##Param) \
98 virtual bool matches(const Type &Node, ASTMatchFinder *Finder, \
99 BoundNodesTreeBuilder *Builder) const; \
101 const ParamType Param; \
104 inline internal::Matcher<Type> DefineMatcher(const ParamType &Param) { \
105 return internal::makeMatcher( \
106 new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param)); \
108 inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
109 const Type &Node, ASTMatchFinder *Finder, \
110 BoundNodesTreeBuilder *Builder) const
112 /// \brief AST_MATCHER_P2(
113 /// Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
114 /// defines a two-parameter function named DefineMatcher() that returns a
115 /// Matcher<Type> object.
117 /// The code between the curly braces has access to the following variables:
119 /// Node: the AST node being matched; its type is Type.
120 /// Param1, Param2: the parameters passed to the function; their types
121 /// are ParamType1 and ParamType2.
122 /// Finder: an ASTMatchFinder*.
123 /// Builder: a BoundNodesTreeBuilder*.
125 /// The code should return true if 'Node' matches.
126 #define AST_MATCHER_P2(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
128 AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
131 #define AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, \
132 ParamType2, Param2, OverloadId) \
133 namespace internal { \
134 class matcher_##DefineMatcher##OverloadId##Matcher \
135 : public MatcherInterface<Type> { \
137 matcher_##DefineMatcher##OverloadId##Matcher(const ParamType1 &A##Param1, \
138 const ParamType2 &A##Param2) \
139 : Param1(A##Param1), Param2(A##Param2) { \
141 virtual bool matches(const Type &Node, ASTMatchFinder *Finder, \
142 BoundNodesTreeBuilder *Builder) const; \
144 const ParamType1 Param1; \
145 const ParamType2 Param2; \
148 inline internal::Matcher<Type> \
149 DefineMatcher(const ParamType1 &Param1, const ParamType2 &Param2) { \
150 return internal::makeMatcher( \
151 new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1, \
154 inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
155 const Type &Node, ASTMatchFinder *Finder, \
156 BoundNodesTreeBuilder *Builder) const
158 /// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... }
159 /// defines a single-parameter function named DefineMatcher() that is
160 /// polymorphic in the return type.
162 /// The variables are the same as for AST_MATCHER, but NodeType will be deduced
163 /// from the calling context.
164 #define AST_POLYMORPHIC_MATCHER(DefineMatcher) \
165 AST_POLYMORPHIC_MATCHER_OVERLOAD(DefineMatcher, 0)
167 #define AST_POLYMORPHIC_MATCHER_OVERLOAD(DefineMatcher, OverloadId) \
168 namespace internal { \
169 template <typename NodeType> \
170 class matcher_##DefineMatcher##OverloadId##Matcher \
171 : public MatcherInterface<NodeType> { \
173 virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder, \
174 BoundNodesTreeBuilder *Builder) const; \
177 inline internal::PolymorphicMatcherWithParam0< \
178 internal::matcher_##DefineMatcher##OverloadId##Matcher> DefineMatcher() {\
179 return internal::PolymorphicMatcherWithParam0< \
180 internal::matcher_##DefineMatcher##OverloadId##Matcher>(); \
182 template <typename NodeType> \
183 bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \
184 NodeType>::matches(const NodeType &Node, ASTMatchFinder *Finder, \
185 BoundNodesTreeBuilder *Builder) const
187 /// \brief AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... }
188 /// defines a single-parameter function named DefineMatcher() that is
189 /// polymorphic in the return type.
191 /// The variables are the same as for
192 /// AST_MATCHER_P, with the addition of NodeType, which specifies the node type
193 /// of the matcher Matcher<NodeType> returned by the function matcher().
195 /// FIXME: Pull out common code with above macro?
196 #define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) \
197 AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ParamType, Param, 0)
199 #define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ParamType, Param, \
201 namespace internal { \
202 template <typename NodeType, typename ParamT> \
203 class matcher_##DefineMatcher##OverloadId##Matcher \
204 : public MatcherInterface<NodeType> { \
206 explicit matcher_##DefineMatcher##OverloadId##Matcher( \
207 const ParamType &A##Param) \
208 : Param(A##Param) { \
210 virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder, \
211 BoundNodesTreeBuilder *Builder) const; \
213 const ParamType Param; \
216 inline internal::PolymorphicMatcherWithParam1< \
217 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType> \
218 DefineMatcher(const ParamType &Param) { \
219 return internal::PolymorphicMatcherWithParam1< \
220 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType>( \
223 template <typename NodeType, typename ParamT> \
224 bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \
225 NodeType, ParamT>::matches(const NodeType &Node, ASTMatchFinder *Finder, \
226 BoundNodesTreeBuilder *Builder) const
228 /// \brief AST_POLYMORPHIC_MATCHER_P2(
229 /// DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
230 /// defines a two-parameter function named matcher() that is polymorphic in
233 /// The variables are the same as for AST_MATCHER_P2, with the
234 /// addition of NodeType, which specifies the node type of the matcher
235 /// Matcher<NodeType> returned by the function DefineMatcher().
236 #define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ParamType1, Param1, \
237 ParamType2, Param2) \
238 AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ParamType1, Param1, \
239 ParamType2, Param2, 0)
241 #define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ParamType1, Param1, \
242 ParamType2, Param2, OverloadId) \
243 namespace internal { \
244 template <typename NodeType, typename ParamT1, typename ParamT2> \
245 class matcher_##DefineMatcher##OverloadId##Matcher \
246 : public MatcherInterface<NodeType> { \
248 matcher_##DefineMatcher##OverloadId##Matcher(const ParamType1 &A##Param1, \
249 const ParamType2 &A##Param2) \
250 : Param1(A##Param1), Param2(A##Param2) { \
252 virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder, \
253 BoundNodesTreeBuilder *Builder) const; \
255 const ParamType1 Param1; \
256 const ParamType2 Param2; \
259 inline internal::PolymorphicMatcherWithParam2< \
260 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \
262 DefineMatcher(const ParamType1 &Param1, const ParamType2 &Param2) { \
263 return internal::PolymorphicMatcherWithParam2< \
264 internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \
265 ParamType2>(Param1, Param2); \
267 template <typename NodeType, typename ParamT1, typename ParamT2> \
268 bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \
269 NodeType, ParamT1, ParamT2>::matches( \
270 const NodeType &Node, ASTMatchFinder *Finder, \
271 BoundNodesTreeBuilder *Builder) const
273 /// \brief Creates a variadic matcher for both a specific \c Type as well as
274 /// the corresponding \c TypeLoc.
275 #define AST_TYPE_MATCHER(NodeType, MatcherName) \
276 const internal::VariadicDynCastAllOfMatcher<Type, NodeType> MatcherName
277 // FIXME: add a matcher for TypeLoc derived classes using its custom casting
278 // API (no longer dyn_cast) if/when we need such matching
280 /// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
281 /// the matcher \c MatcherName that can be used to traverse from one \c Type
284 /// For a specific \c SpecificType, the traversal is done using
285 /// \c SpecificType::FunctionName. The existance of such a function determines
286 /// whether a corresponding matcher can be used on \c SpecificType.
287 #define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) \
288 class Polymorphic##MatcherName##TypeMatcher { \
290 Polymorphic##MatcherName##TypeMatcher( \
291 const internal::Matcher<QualType> &InnerMatcher) \
292 : InnerMatcher(InnerMatcher) { \
294 template <typename T> operator internal:: Matcher< T>() { \
295 return internal::Matcher<T>(new internal::TypeTraverseMatcher<T>( \
296 InnerMatcher, &T::FunctionName)); \
299 const internal::Matcher<QualType> InnerMatcher; \
302 class Variadic##MatcherName##TypeTraverseMatcher \
303 : public llvm::VariadicFunction< \
304 Polymorphic##MatcherName##TypeMatcher, internal::Matcher<QualType>, \
305 internal::makeTypeAllOfComposite< \
306 Polymorphic##MatcherName##TypeMatcher, QualType> > { \
308 Variadic##MatcherName##TypeTraverseMatcher() { \
312 const Variadic##MatcherName##TypeTraverseMatcher MatcherName
314 /// \brief AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works
315 /// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs.
316 #define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) \
317 class Polymorphic##MatcherName##TypeLocMatcher { \
319 Polymorphic##MatcherName##TypeLocMatcher( \
320 const internal::Matcher<TypeLoc> &InnerMatcher) \
321 : InnerMatcher(InnerMatcher) { \
323 template <typename T> operator internal:: Matcher< T>() { \
324 return internal::Matcher<T>( \
325 new internal::TypeLocTraverseMatcher<T>(InnerMatcher, \
326 &T::FunctionName##Loc)); \
329 const internal::Matcher<TypeLoc> InnerMatcher; \
332 class Variadic##MatcherName##TypeLocTraverseMatcher \
333 : public llvm::VariadicFunction< \
334 Polymorphic##MatcherName##TypeLocMatcher, internal::Matcher<TypeLoc>,\
335 internal::makeTypeAllOfComposite< \
336 Polymorphic##MatcherName##TypeLocMatcher, TypeLoc> > { \
338 Variadic##MatcherName##TypeLocTraverseMatcher() { \
342 const Variadic##MatcherName##TypeLocTraverseMatcher MatcherName##Loc; \
343 AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type)
345 #endif // LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H