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 \
54 : public MatcherInterface<Type> { \
56 explicit matcher_##DefineMatcher##Matcher() {} \
57 virtual bool matches( \
58 const Type &Node, ASTMatchFinder *Finder, \
59 BoundNodesTreeBuilder *Builder) const; \
62 inline internal::Matcher<Type> DefineMatcher() { \
63 return internal::makeMatcher( \
64 new internal::matcher_##DefineMatcher##Matcher()); \
66 inline bool internal::matcher_##DefineMatcher##Matcher::matches( \
67 const Type &Node, ASTMatchFinder *Finder, \
68 BoundNodesTreeBuilder *Builder) const
70 /// \brief AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... }
71 /// defines a single-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 /// Param: the parameter passed to the function; its type
79 /// Finder: an ASTMatchFinder*.
80 /// Builder: a BoundNodesTreeBuilder*.
82 /// The code should return true if 'Node' matches.
83 #define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) \
84 namespace internal { \
85 class matcher_##DefineMatcher##Matcher \
86 : public MatcherInterface<Type> { \
88 explicit matcher_##DefineMatcher##Matcher( \
89 const ParamType &A##Param) : Param(A##Param) {} \
90 virtual bool matches( \
91 const Type &Node, ASTMatchFinder *Finder, \
92 BoundNodesTreeBuilder *Builder) const; \
94 const ParamType Param; \
97 inline internal::Matcher<Type> DefineMatcher(const ParamType &Param) { \
98 return internal::makeMatcher( \
99 new internal::matcher_##DefineMatcher##Matcher(Param)); \
101 inline bool internal::matcher_##DefineMatcher##Matcher::matches( \
102 const Type &Node, ASTMatchFinder *Finder, \
103 BoundNodesTreeBuilder *Builder) const
105 /// \brief AST_MATCHER_P2(
106 /// Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
107 /// defines a two-parameter function named DefineMatcher() that returns a
108 /// Matcher<Type> object.
110 /// The code between the curly braces has access to the following variables:
112 /// Node: the AST node being matched; its type is Type.
113 /// Param1, Param2: the parameters passed to the function; their types
114 /// are ParamType1 and ParamType2.
115 /// Finder: an ASTMatchFinder*.
116 /// Builder: a BoundNodesTreeBuilder*.
118 /// The code should return true if 'Node' matches.
119 #define AST_MATCHER_P2( \
120 Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2) \
121 namespace internal { \
122 class matcher_##DefineMatcher##Matcher \
123 : public MatcherInterface<Type> { \
125 matcher_##DefineMatcher##Matcher( \
126 const ParamType1 &A##Param1, const ParamType2 &A##Param2) \
127 : Param1(A##Param1), Param2(A##Param2) {} \
128 virtual bool matches( \
129 const Type &Node, ASTMatchFinder *Finder, \
130 BoundNodesTreeBuilder *Builder) const; \
132 const ParamType1 Param1; \
133 const ParamType2 Param2; \
136 inline internal::Matcher<Type> DefineMatcher( \
137 const ParamType1 &Param1, const ParamType2 &Param2) { \
138 return internal::makeMatcher( \
139 new internal::matcher_##DefineMatcher##Matcher( \
142 inline bool internal::matcher_##DefineMatcher##Matcher::matches( \
143 const Type &Node, ASTMatchFinder *Finder, \
144 BoundNodesTreeBuilder *Builder) const
146 /// \brief AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... }
147 /// defines a single-parameter function named DefineMatcher() that is
148 /// polymorphic in the return type.
150 /// The variables are the same as for
151 /// AST_MATCHER_P, with the addition of NodeType, which specifies the node type
152 /// of the matcher Matcher<NodeType> returned by the function matcher().
154 /// FIXME: Pull out common code with above macro?
155 #define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) \
156 namespace internal { \
157 template <typename NodeType, typename ParamT> \
158 class matcher_##DefineMatcher##Matcher \
159 : public MatcherInterface<NodeType> { \
161 explicit matcher_##DefineMatcher##Matcher( \
162 const ParamType &A##Param) : Param(A##Param) {} \
163 virtual bool matches( \
164 const NodeType &Node, ASTMatchFinder *Finder, \
165 BoundNodesTreeBuilder *Builder) const; \
167 const ParamType Param; \
170 inline internal::PolymorphicMatcherWithParam1< \
171 internal::matcher_##DefineMatcher##Matcher, \
173 DefineMatcher(const ParamType &Param) { \
174 return internal::PolymorphicMatcherWithParam1< \
175 internal::matcher_##DefineMatcher##Matcher, \
176 ParamType >(Param); \
178 template <typename NodeType, typename ParamT> \
179 bool internal::matcher_##DefineMatcher##Matcher<NodeType, ParamT>::matches( \
180 const NodeType &Node, ASTMatchFinder *Finder, \
181 BoundNodesTreeBuilder *Builder) const
183 /// \brief AST_POLYMORPHIC_MATCHER_P2(
184 /// DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
185 /// defines a two-parameter function named matcher() that is polymorphic in
188 /// The variables are the same as for AST_MATCHER_P2, with the
189 /// addition of NodeType, which specifies the node type of the matcher
190 /// Matcher<NodeType> returned by the function DefineMatcher().
191 #define AST_POLYMORPHIC_MATCHER_P2( \
192 DefineMatcher, ParamType1, Param1, ParamType2, Param2) \
193 namespace internal { \
194 template <typename NodeType, typename ParamT1, typename ParamT2> \
195 class matcher_##DefineMatcher##Matcher \
196 : public MatcherInterface<NodeType> { \
198 matcher_##DefineMatcher##Matcher( \
199 const ParamType1 &A##Param1, const ParamType2 &A##Param2) \
200 : Param1(A##Param1), Param2(A##Param2) {} \
201 virtual bool matches( \
202 const NodeType &Node, ASTMatchFinder *Finder, \
203 BoundNodesTreeBuilder *Builder) const; \
205 const ParamType1 Param1; \
206 const ParamType2 Param2; \
209 inline internal::PolymorphicMatcherWithParam2< \
210 internal::matcher_##DefineMatcher##Matcher, \
211 ParamType1, ParamType2 > \
212 DefineMatcher(const ParamType1 &Param1, const ParamType2 &Param2) { \
213 return internal::PolymorphicMatcherWithParam2< \
214 internal::matcher_##DefineMatcher##Matcher, \
215 ParamType1, ParamType2 >( \
218 template <typename NodeType, typename ParamT1, typename ParamT2> \
219 bool internal::matcher_##DefineMatcher##Matcher< \
220 NodeType, ParamT1, ParamT2>::matches( \
221 const NodeType &Node, ASTMatchFinder *Finder, \
222 BoundNodesTreeBuilder *Builder) const
224 /// \brief Creates a variadic matcher for both a specific \c Type as well as
225 /// the corresponding \c TypeLoc.
226 #define AST_TYPE_MATCHER(NodeType, MatcherName) \
227 const internal::VariadicDynCastAllOfMatcher<Type, NodeType> MatcherName; \
228 const internal::VariadicDynCastAllOfMatcher<TypeLoc, \
229 NodeType##Loc> MatcherName##Loc
231 /// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
232 /// the matcher \c MatcherName that can be used to traverse from one \c Type
235 /// For a specific \c SpecificType, the traversal is done using
236 /// \c SpecificType::FunctionName. The existance of such a function determines
237 /// whether a corresponding matcher can be used on \c SpecificType.
238 #define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) \
239 class Polymorphic##MatcherName##TypeMatcher { \
241 Polymorphic##MatcherName##TypeMatcher( \
242 const internal::Matcher<QualType> &InnerMatcher) \
243 : InnerMatcher(InnerMatcher) {} \
244 template <typename T> operator internal::Matcher<T>() { \
245 return internal::Matcher<T>(new internal::TypeTraverseMatcher<T>( \
246 InnerMatcher, &T::FunctionName)); \
249 const internal::Matcher<QualType> InnerMatcher; \
251 class Variadic##MatcherName##TypeTraverseMatcher \
252 : public llvm::VariadicFunction< \
253 Polymorphic##MatcherName##TypeMatcher, \
254 internal::Matcher<QualType>, \
255 internal::makeTypeAllOfComposite< \
256 Polymorphic##MatcherName##TypeMatcher, QualType> > { \
258 Variadic##MatcherName##TypeTraverseMatcher() {} \
260 const Variadic##MatcherName##TypeTraverseMatcher MatcherName
262 /// \brief AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works
263 /// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs.
264 #define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) \
265 class Polymorphic##MatcherName##TypeLocMatcher { \
267 Polymorphic##MatcherName##TypeLocMatcher( \
268 const internal::Matcher<TypeLoc> &InnerMatcher) \
269 : InnerMatcher(InnerMatcher) {} \
270 template <typename T> operator internal::Matcher<T>() { \
271 return internal::Matcher<T>(new internal::TypeLocTraverseMatcher<T>( \
272 InnerMatcher, &T::FunctionName##Loc)); \
275 const internal::Matcher<TypeLoc> InnerMatcher; \
277 class Variadic##MatcherName##TypeLocTraverseMatcher \
278 : public llvm::VariadicFunction< \
279 Polymorphic##MatcherName##TypeLocMatcher, \
280 internal::Matcher<TypeLoc>, \
281 internal::makeTypeAllOfComposite< \
282 Polymorphic##MatcherName##TypeLocMatcher, TypeLoc> > { \
284 Variadic##MatcherName##TypeLocTraverseMatcher() {} \
286 const Variadic##MatcherName##TypeLocTraverseMatcher MatcherName##Loc; \
287 AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type)
289 #endif // LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H