Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 1 | //===--- ASTMatchersMacros.h - Structural query framework -------*- C++ -*-===// |
2 | // |
||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
||
4 | // See https://llvm.org/LICENSE.txt for license information. |
||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
||
6 | // |
||
7 | //===----------------------------------------------------------------------===// |
||
8 | // |
||
9 | // Defines macros that enable us to define new matchers in a single place. |
||
10 | // Since a matcher is a function which returns a Matcher<T> object, where |
||
11 | // T is the type of the actual implementation of the matcher, the macros allow |
||
12 | // us to write matchers like functions and take care of the definition of the |
||
13 | // class boilerplate. |
||
14 | // |
||
15 | // Note that when you define a matcher with an AST_MATCHER* macro, only the |
||
16 | // function which creates the matcher goes into the current namespace - the |
||
17 | // class that implements the actual matcher, which gets returned by the |
||
18 | // generator function, is put into the 'internal' namespace. This allows us |
||
19 | // to only have the functions (which is all the user cares about) in the |
||
20 | // 'ast_matchers' namespace and hide the boilerplate. |
||
21 | // |
||
22 | // To define a matcher in user code, put it into your own namespace. This would |
||
23 | // help to prevent ODR violations in case a matcher with the same name is |
||
24 | // defined in multiple translation units: |
||
25 | // |
||
26 | // namespace my_matchers { |
||
27 | // AST_MATCHER_P(clang::MemberExpr, Member, |
||
28 | // clang::ast_matchers::internal::Matcher<clang::ValueDecl>, |
||
29 | // InnerMatcher) { |
||
30 | // return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder); |
||
31 | // } |
||
32 | // } // namespace my_matchers |
||
33 | // |
||
34 | // Alternatively, an unnamed namespace may be used: |
||
35 | // |
||
36 | // namespace clang { |
||
37 | // namespace ast_matchers { |
||
38 | // namespace { |
||
39 | // AST_MATCHER_P(MemberExpr, Member, |
||
40 | // internal::Matcher<ValueDecl>, InnerMatcher) { |
||
41 | // return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder); |
||
42 | // } |
||
43 | // } // namespace |
||
44 | // } // namespace ast_matchers |
||
45 | // } // namespace clang |
||
46 | // |
||
47 | //===----------------------------------------------------------------------===// |
||
48 | |||
49 | #ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H |
||
50 | #define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H |
||
51 | |||
52 | /// AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) { ... } |
||
53 | /// defines a zero parameter function named DefineMatcher() that returns a |
||
54 | /// ReturnType object. |
||
55 | #define AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) \ |
||
56 | inline ReturnType DefineMatcher##_getInstance(); \ |
||
57 | inline ReturnType DefineMatcher() { \ |
||
58 | return ::clang::ast_matchers::internal::MemoizedMatcher< \ |
||
59 | ReturnType, DefineMatcher##_getInstance>::getInstance(); \ |
||
60 | } \ |
||
61 | inline ReturnType DefineMatcher##_getInstance() |
||
62 | |||
63 | /// AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) { |
||
64 | /// ... } |
||
65 | /// defines a single-parameter function named DefineMatcher() that returns a |
||
66 | /// ReturnType object. |
||
67 | /// |
||
68 | /// The code between the curly braces has access to the following variables: |
||
69 | /// |
||
70 | /// Param: the parameter passed to the function; its type |
||
71 | /// is ParamType. |
||
72 | /// |
||
73 | /// The code should return an instance of ReturnType. |
||
74 | #define AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) \ |
||
75 | AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, Param, \ |
||
76 | 0) |
||
77 | #define AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, \ |
||
78 | Param, OverloadId) \ |
||
79 | inline ReturnType DefineMatcher(ParamType const &Param); \ |
||
80 | typedef ReturnType (&DefineMatcher##_Type##OverloadId)(ParamType const &); \ |
||
81 | inline ReturnType DefineMatcher(ParamType const &Param) |
||
82 | |||
83 | /// AST_MATCHER(Type, DefineMatcher) { ... } |
||
84 | /// defines a zero parameter function named DefineMatcher() that returns a |
||
85 | /// Matcher<Type> object. |
||
86 | /// |
||
87 | /// The code between the curly braces has access to the following variables: |
||
88 | /// |
||
89 | /// Node: the AST node being matched; its type is Type. |
||
90 | /// Finder: an ASTMatchFinder*. |
||
91 | /// Builder: a BoundNodesTreeBuilder*. |
||
92 | /// |
||
93 | /// The code should return true if 'Node' matches. |
||
94 | #define AST_MATCHER(Type, DefineMatcher) \ |
||
95 | namespace internal { \ |
||
96 | class matcher_##DefineMatcher##Matcher \ |
||
97 | : public ::clang::ast_matchers::internal::MatcherInterface<Type> { \ |
||
98 | public: \ |
||
99 | explicit matcher_##DefineMatcher##Matcher() = default; \ |
||
100 | bool matches(const Type &Node, \ |
||
101 | ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ |
||
102 | ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ |
||
103 | *Builder) const override; \ |
||
104 | }; \ |
||
105 | } \ |
||
106 | inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher() { \ |
||
107 | return ::clang::ast_matchers::internal::makeMatcher( \ |
||
108 | new internal::matcher_##DefineMatcher##Matcher()); \ |
||
109 | } \ |
||
110 | inline bool internal::matcher_##DefineMatcher##Matcher::matches( \ |
||
111 | const Type &Node, \ |
||
112 | ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ |
||
113 | ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const |
||
114 | |||
115 | /// AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... } |
||
116 | /// defines a single-parameter function named DefineMatcher() that returns a |
||
117 | /// Matcher<Type> object. |
||
118 | /// |
||
119 | /// The code between the curly braces has access to the following variables: |
||
120 | /// |
||
121 | /// Node: the AST node being matched; its type is Type. |
||
122 | /// Param: the parameter passed to the function; its type |
||
123 | /// is ParamType. |
||
124 | /// Finder: an ASTMatchFinder*. |
||
125 | /// Builder: a BoundNodesTreeBuilder*. |
||
126 | /// |
||
127 | /// The code should return true if 'Node' matches. |
||
128 | #define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) \ |
||
129 | AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, 0) |
||
130 | |||
131 | #define AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, \ |
||
132 | OverloadId) \ |
||
133 | namespace internal { \ |
||
134 | class matcher_##DefineMatcher##OverloadId##Matcher \ |
||
135 | : public ::clang::ast_matchers::internal::MatcherInterface<Type> { \ |
||
136 | public: \ |
||
137 | explicit matcher_##DefineMatcher##OverloadId##Matcher( \ |
||
138 | ParamType const &A##Param) \ |
||
139 | : Param(A##Param) {} \ |
||
140 | bool matches(const Type &Node, \ |
||
141 | ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ |
||
142 | ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ |
||
143 | *Builder) const override; \ |
||
144 | \ |
||
145 | private: \ |
||
146 | ParamType Param; \ |
||
147 | }; \ |
||
148 | } \ |
||
149 | inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \ |
||
150 | ParamType const &Param) { \ |
||
151 | return ::clang::ast_matchers::internal::makeMatcher( \ |
||
152 | new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param)); \ |
||
153 | } \ |
||
154 | typedef ::clang::ast_matchers::internal::Matcher<Type> ( \ |
||
155 | &DefineMatcher##_Type##OverloadId)(ParamType const &Param); \ |
||
156 | inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \ |
||
157 | const Type &Node, \ |
||
158 | ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ |
||
159 | ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const |
||
160 | |||
161 | /// AST_MATCHER_P2( |
||
162 | /// Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... } |
||
163 | /// defines a two-parameter function named DefineMatcher() that returns a |
||
164 | /// Matcher<Type> object. |
||
165 | /// |
||
166 | /// The code between the curly braces has access to the following variables: |
||
167 | /// |
||
168 | /// Node: the AST node being matched; its type is Type. |
||
169 | /// Param1, Param2: the parameters passed to the function; their types |
||
170 | /// are ParamType1 and ParamType2. |
||
171 | /// Finder: an ASTMatchFinder*. |
||
172 | /// Builder: a BoundNodesTreeBuilder*. |
||
173 | /// |
||
174 | /// The code should return true if 'Node' matches. |
||
175 | #define AST_MATCHER_P2(Type, DefineMatcher, ParamType1, Param1, ParamType2, \ |
||
176 | Param2) \ |
||
177 | AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, ParamType2, \ |
||
178 | Param2, 0) |
||
179 | |||
180 | #define AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, \ |
||
181 | ParamType2, Param2, OverloadId) \ |
||
182 | namespace internal { \ |
||
183 | class matcher_##DefineMatcher##OverloadId##Matcher \ |
||
184 | : public ::clang::ast_matchers::internal::MatcherInterface<Type> { \ |
||
185 | public: \ |
||
186 | matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1, \ |
||
187 | ParamType2 const &A##Param2) \ |
||
188 | : Param1(A##Param1), Param2(A##Param2) {} \ |
||
189 | bool matches(const Type &Node, \ |
||
190 | ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ |
||
191 | ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ |
||
192 | *Builder) const override; \ |
||
193 | \ |
||
194 | private: \ |
||
195 | ParamType1 Param1; \ |
||
196 | ParamType2 Param2; \ |
||
197 | }; \ |
||
198 | } \ |
||
199 | inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \ |
||
200 | ParamType1 const &Param1, ParamType2 const &Param2) { \ |
||
201 | return ::clang::ast_matchers::internal::makeMatcher( \ |
||
202 | new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1, \ |
||
203 | Param2)); \ |
||
204 | } \ |
||
205 | typedef ::clang::ast_matchers::internal::Matcher<Type> ( \ |
||
206 | &DefineMatcher##_Type##OverloadId)(ParamType1 const &Param1, \ |
||
207 | ParamType2 const &Param2); \ |
||
208 | inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \ |
||
209 | const Type &Node, \ |
||
210 | ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ |
||
211 | ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const |
||
212 | |||
213 | /// Construct a type-list to be passed to the AST_POLYMORPHIC_MATCHER* |
||
214 | /// macros. |
||
215 | /// |
||
216 | /// You can't pass something like \c TypeList<Foo, Bar> to a macro, because it |
||
217 | /// will look at that as two arguments. However, you can pass |
||
218 | /// \c void(TypeList<Foo, Bar>), which works thanks to the parenthesis. |
||
219 | /// The \c PolymorphicMatcherWithParam* classes will unpack the function type to |
||
220 | /// extract the TypeList object. |
||
221 | #define AST_POLYMORPHIC_SUPPORTED_TYPES(...) \ |
||
222 | void(::clang::ast_matchers::internal::TypeList<__VA_ARGS__>) |
||
223 | |||
224 | /// AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... } |
||
225 | /// defines a single-parameter function named DefineMatcher() that is |
||
226 | /// polymorphic in the return type. |
||
227 | /// |
||
228 | /// The variables are the same as for AST_MATCHER, but NodeType will be deduced |
||
229 | /// from the calling context. |
||
230 | #define AST_POLYMORPHIC_MATCHER(DefineMatcher, ReturnTypesF) \ |
||
231 | namespace internal { \ |
||
232 | template <typename NodeType> \ |
||
233 | class matcher_##DefineMatcher##Matcher \ |
||
234 | : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \ |
||
235 | public: \ |
||
236 | bool matches(const NodeType &Node, \ |
||
237 | ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ |
||
238 | ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ |
||
239 | *Builder) const override; \ |
||
240 | }; \ |
||
241 | } \ |
||
242 | inline ::clang::ast_matchers::internal::PolymorphicMatcher< \ |
||
243 | internal::matcher_##DefineMatcher##Matcher, ReturnTypesF> \ |
||
244 | DefineMatcher() { \ |
||
245 | return ::clang::ast_matchers::internal::PolymorphicMatcher< \ |
||
246 | internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>(); \ |
||
247 | } \ |
||
248 | template <typename NodeType> \ |
||
249 | bool internal::matcher_##DefineMatcher##Matcher<NodeType>::matches( \ |
||
250 | const NodeType &Node, \ |
||
251 | ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ |
||
252 | ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const |
||
253 | |||
254 | /// AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... } |
||
255 | /// defines a single-parameter function named DefineMatcher() that is |
||
256 | /// polymorphic in the return type. |
||
257 | /// |
||
258 | /// The variables are the same as for |
||
259 | /// AST_MATCHER_P, with the addition of NodeType, which specifies the node type |
||
260 | /// of the matcher Matcher<NodeType> returned by the function matcher(). |
||
261 | /// |
||
262 | /// FIXME: Pull out common code with above macro? |
||
263 | #define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ReturnTypesF, ParamType, \ |
||
264 | Param) \ |
||
265 | AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType, \ |
||
266 | Param, 0) |
||
267 | |||
268 | #define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, \ |
||
269 | ParamType, Param, OverloadId) \ |
||
270 | namespace internal { \ |
||
271 | template <typename NodeType, typename ParamT> \ |
||
272 | class matcher_##DefineMatcher##OverloadId##Matcher \ |
||
273 | : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \ |
||
274 | public: \ |
||
275 | explicit matcher_##DefineMatcher##OverloadId##Matcher( \ |
||
276 | ParamType const &A##Param) \ |
||
277 | : Param(A##Param) {} \ |
||
278 | bool matches(const NodeType &Node, \ |
||
279 | ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ |
||
280 | ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ |
||
281 | *Builder) const override; \ |
||
282 | \ |
||
283 | private: \ |
||
284 | ParamType Param; \ |
||
285 | }; \ |
||
286 | } \ |
||
287 | inline ::clang::ast_matchers::internal::PolymorphicMatcher< \ |
||
288 | internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \ |
||
289 | ParamType> \ |
||
290 | DefineMatcher(ParamType const &Param) { \ |
||
291 | return ::clang::ast_matchers::internal::PolymorphicMatcher< \ |
||
292 | internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \ |
||
293 | ParamType>(Param); \ |
||
294 | } \ |
||
295 | typedef ::clang::ast_matchers::internal::PolymorphicMatcher< \ |
||
296 | internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \ |
||
297 | ParamType> (&DefineMatcher##_Type##OverloadId)(ParamType const &Param); \ |
||
298 | template <typename NodeType, typename ParamT> \ |
||
299 | bool internal:: \ |
||
300 | matcher_##DefineMatcher##OverloadId##Matcher<NodeType, ParamT>::matches( \ |
||
301 | const NodeType &Node, \ |
||
302 | ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ |
||
303 | ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) \ |
||
304 | const |
||
305 | |||
306 | /// AST_POLYMORPHIC_MATCHER_P2( |
||
307 | /// DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... } |
||
308 | /// defines a two-parameter function named matcher() that is polymorphic in |
||
309 | /// the return type. |
||
310 | /// |
||
311 | /// The variables are the same as for AST_MATCHER_P2, with the |
||
312 | /// addition of NodeType, which specifies the node type of the matcher |
||
313 | /// Matcher<NodeType> returned by the function DefineMatcher(). |
||
314 | #define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ReturnTypesF, ParamType1, \ |
||
315 | Param1, ParamType2, Param2) \ |
||
316 | AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType1, \ |
||
317 | Param1, ParamType2, Param2, 0) |
||
318 | |||
319 | #define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, \ |
||
320 | ParamType1, Param1, ParamType2, \ |
||
321 | Param2, OverloadId) \ |
||
322 | namespace internal { \ |
||
323 | template <typename NodeType, typename ParamT1, typename ParamT2> \ |
||
324 | class matcher_##DefineMatcher##OverloadId##Matcher \ |
||
325 | : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \ |
||
326 | public: \ |
||
327 | matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1, \ |
||
328 | ParamType2 const &A##Param2) \ |
||
329 | : Param1(A##Param1), Param2(A##Param2) {} \ |
||
330 | bool matches(const NodeType &Node, \ |
||
331 | ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ |
||
332 | ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ |
||
333 | *Builder) const override; \ |
||
334 | \ |
||
335 | private: \ |
||
336 | ParamType1 Param1; \ |
||
337 | ParamType2 Param2; \ |
||
338 | }; \ |
||
339 | } \ |
||
340 | inline ::clang::ast_matchers::internal::PolymorphicMatcher< \ |
||
341 | internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \ |
||
342 | ParamType1, ParamType2> \ |
||
343 | DefineMatcher(ParamType1 const &Param1, ParamType2 const &Param2) { \ |
||
344 | return ::clang::ast_matchers::internal::PolymorphicMatcher< \ |
||
345 | internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \ |
||
346 | ParamType1, ParamType2>(Param1, Param2); \ |
||
347 | } \ |
||
348 | typedef ::clang::ast_matchers::internal::PolymorphicMatcher< \ |
||
349 | internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \ |
||
350 | ParamType1, ParamType2> (&DefineMatcher##_Type##OverloadId)( \ |
||
351 | ParamType1 const &Param1, ParamType2 const &Param2); \ |
||
352 | template <typename NodeType, typename ParamT1, typename ParamT2> \ |
||
353 | bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \ |
||
354 | NodeType, ParamT1, ParamT2>:: \ |
||
355 | matches(const NodeType &Node, \ |
||
356 | ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ |
||
357 | ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) \ |
||
358 | const |
||
359 | |||
360 | // FIXME: add a matcher for TypeLoc derived classes using its custom casting |
||
361 | // API (no longer dyn_cast) if/when we need such matching |
||
362 | |||
363 | #define AST_TYPE_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName, \ |
||
364 | ReturnTypesF) \ |
||
365 | namespace internal { \ |
||
366 | template <typename T> struct TypeMatcher##MatcherName##Getter { \ |
||
367 | static QualType (T::*value())() const { return &T::FunctionName; } \ |
||
368 | }; \ |
||
369 | } \ |
||
370 | extern const ::clang::ast_matchers::internal:: \ |
||
371 | TypeTraversePolymorphicMatcher< \ |
||
372 | QualType, \ |
||
373 | ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter, \ |
||
374 | ::clang::ast_matchers::internal::TypeTraverseMatcher, \ |
||
375 | ReturnTypesF>::Func MatcherName |
||
376 | |||
377 | #define AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF) \ |
||
378 | const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \ |
||
379 | QualType, \ |
||
380 | ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter, \ |
||
381 | ::clang::ast_matchers::internal::TypeTraverseMatcher, \ |
||
382 | ReturnTypesF>::Func MatcherName |
||
383 | |||
384 | /// AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines |
||
385 | /// the matcher \c MatcherName that can be used to traverse from one \c Type |
||
386 | /// to another. |
||
387 | /// |
||
388 | /// For a specific \c SpecificType, the traversal is done using |
||
389 | /// \c SpecificType::FunctionName. The existence of such a function determines |
||
390 | /// whether a corresponding matcher can be used on \c SpecificType. |
||
391 | #define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \ |
||
392 | namespace internal { \ |
||
393 | template <typename T> struct TypeMatcher##MatcherName##Getter { \ |
||
394 | static QualType (T::*value())() const { return &T::FunctionName; } \ |
||
395 | }; \ |
||
396 | } \ |
||
397 | const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \ |
||
398 | QualType, \ |
||
399 | ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter, \ |
||
400 | ::clang::ast_matchers::internal::TypeTraverseMatcher, \ |
||
401 | ReturnTypesF>::Func MatcherName |
||
402 | |||
403 | #define AST_TYPELOC_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName, \ |
||
404 | ReturnTypesF) \ |
||
405 | namespace internal { \ |
||
406 | template <typename T> struct TypeLocMatcher##MatcherName##Getter { \ |
||
407 | static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; } \ |
||
408 | }; \ |
||
409 | } \ |
||
410 | extern const ::clang::ast_matchers::internal:: \ |
||
411 | TypeTraversePolymorphicMatcher< \ |
||
412 | TypeLoc, \ |
||
413 | ::clang::ast_matchers::internal:: \ |
||
414 | TypeLocMatcher##MatcherName##Getter, \ |
||
415 | ::clang::ast_matchers::internal::TypeLocTraverseMatcher, \ |
||
416 | ReturnTypesF>::Func MatcherName##Loc; \ |
||
417 | AST_TYPE_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName##Type, ReturnTypesF) |
||
418 | |||
419 | #define AST_TYPELOC_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF) \ |
||
420 | const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \ |
||
421 | TypeLoc, \ |
||
422 | ::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter, \ |
||
423 | ::clang::ast_matchers::internal::TypeLocTraverseMatcher, \ |
||
424 | ReturnTypesF>::Func MatcherName##Loc; \ |
||
425 | AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF) |
||
426 | |||
427 | /// AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works |
||
428 | /// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs. |
||
429 | #define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \ |
||
430 | namespace internal { \ |
||
431 | template <typename T> struct TypeLocMatcher##MatcherName##Getter { \ |
||
432 | static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; } \ |
||
433 | }; \ |
||
434 | } \ |
||
435 | const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher< \ |
||
436 | TypeLoc, \ |
||
437 | ::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter, \ |
||
438 | ::clang::ast_matchers::internal::TypeLocTraverseMatcher, \ |
||
439 | ReturnTypesF>::Func MatcherName##Loc; \ |
||
440 | AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF) |
||
441 | |||
442 | /// AST_MATCHER_REGEX(Type, DefineMatcher, Param) { ... } |
||
443 | /// defines a function named DefineMatcher() that takes a regular expression |
||
444 | /// string paramater and an optional RegexFlags parameter and returns a |
||
445 | /// Matcher<Type> object. |
||
446 | /// |
||
447 | /// The code between the curly braces has access to the following variables: |
||
448 | /// |
||
449 | /// Node: the AST node being matched; its type is Type. |
||
450 | /// Param: a pointer to an \ref llvm::Regex object |
||
451 | /// Finder: an ASTMatchFinder*. |
||
452 | /// Builder: a BoundNodesTreeBuilder*. |
||
453 | /// |
||
454 | /// The code should return true if 'Node' matches. |
||
455 | #define AST_MATCHER_REGEX(Type, DefineMatcher, Param) \ |
||
456 | AST_MATCHER_REGEX_OVERLOAD(Type, DefineMatcher, Param, 0) |
||
457 | |||
458 | #define AST_MATCHER_REGEX_OVERLOAD(Type, DefineMatcher, Param, OverloadId) \ |
||
459 | namespace internal { \ |
||
460 | class matcher_##DefineMatcher##OverloadId##Matcher \ |
||
461 | : public ::clang::ast_matchers::internal::MatcherInterface<Type> { \ |
||
462 | public: \ |
||
463 | explicit matcher_##DefineMatcher##OverloadId##Matcher( \ |
||
464 | std::shared_ptr<llvm::Regex> RE) \ |
||
465 | : Param(std::move(RE)) {} \ |
||
466 | bool matches(const Type &Node, \ |
||
467 | ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ |
||
468 | ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ |
||
469 | *Builder) const override; \ |
||
470 | \ |
||
471 | private: \ |
||
472 | std::shared_ptr<llvm::Regex> Param; \ |
||
473 | }; \ |
||
474 | } \ |
||
475 | inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \ |
||
476 | llvm::StringRef Param, llvm::Regex::RegexFlags RegexFlags) { \ |
||
477 | return ::clang::ast_matchers::internal::makeMatcher( \ |
||
478 | new internal::matcher_##DefineMatcher##OverloadId##Matcher( \ |
||
479 | ::clang::ast_matchers::internal::createAndVerifyRegex( \ |
||
480 | Param, RegexFlags, #DefineMatcher))); \ |
||
481 | } \ |
||
482 | inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher( \ |
||
483 | llvm::StringRef Param) { \ |
||
484 | return DefineMatcher(Param, llvm::Regex::NoFlags); \ |
||
485 | } \ |
||
486 | \ |
||
487 | typedef ::clang::ast_matchers::internal::Matcher<Type> ( \ |
||
488 | &DefineMatcher##_Type##OverloadId##Flags)(llvm::StringRef, \ |
||
489 | llvm::Regex::RegexFlags); \ |
||
490 | typedef ::clang::ast_matchers::internal::Matcher<Type> ( \ |
||
491 | &DefineMatcher##_Type##OverloadId)(llvm::StringRef); \ |
||
492 | inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \ |
||
493 | const Type &Node, \ |
||
494 | ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ |
||
495 | ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const |
||
496 | |||
497 | /// AST_POLYMORPHIC_MATCHER_REGEX(DefineMatcher, ReturnTypesF, Param) { ... } |
||
498 | /// defines a function named DefineMatcher() that takes a regular expression |
||
499 | /// string paramater and an optional RegexFlags parameter that is polymorphic in |
||
500 | /// the return type. |
||
501 | /// |
||
502 | /// The variables are the same as for |
||
503 | /// AST_MATCHER_REGEX, with the addition of NodeType, which specifies the node |
||
504 | /// type of the matcher Matcher<NodeType> returned by the function matcher(). |
||
505 | #define AST_POLYMORPHIC_MATCHER_REGEX(DefineMatcher, ReturnTypesF, Param) \ |
||
506 | AST_POLYMORPHIC_MATCHER_REGEX_OVERLOAD(DefineMatcher, ReturnTypesF, Param, 0) |
||
507 | |||
508 | #define AST_POLYMORPHIC_MATCHER_REGEX_OVERLOAD(DefineMatcher, ReturnTypesF, \ |
||
509 | Param, OverloadId) \ |
||
510 | namespace internal { \ |
||
511 | template <typename NodeType, typename ParamT> \ |
||
512 | class matcher_##DefineMatcher##OverloadId##Matcher \ |
||
513 | : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> { \ |
||
514 | public: \ |
||
515 | explicit matcher_##DefineMatcher##OverloadId##Matcher( \ |
||
516 | std::shared_ptr<llvm::Regex> RE) \ |
||
517 | : Param(std::move(RE)) {} \ |
||
518 | bool matches(const NodeType &Node, \ |
||
519 | ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ |
||
520 | ::clang::ast_matchers::internal::BoundNodesTreeBuilder \ |
||
521 | *Builder) const override; \ |
||
522 | \ |
||
523 | private: \ |
||
524 | std::shared_ptr<llvm::Regex> Param; \ |
||
525 | }; \ |
||
526 | } \ |
||
527 | inline ::clang::ast_matchers::internal::PolymorphicMatcher< \ |
||
528 | internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \ |
||
529 | std::shared_ptr<llvm::Regex>> \ |
||
530 | DefineMatcher(llvm::StringRef Param, llvm::Regex::RegexFlags RegexFlags) { \ |
||
531 | return ::clang::ast_matchers::internal::PolymorphicMatcher< \ |
||
532 | internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \ |
||
533 | std::shared_ptr<llvm::Regex>>( \ |
||
534 | ::clang::ast_matchers::internal::createAndVerifyRegex( \ |
||
535 | Param, RegexFlags, #DefineMatcher)); \ |
||
536 | } \ |
||
537 | inline ::clang::ast_matchers::internal::PolymorphicMatcher< \ |
||
538 | internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \ |
||
539 | std::shared_ptr<llvm::Regex>> \ |
||
540 | DefineMatcher(llvm::StringRef Param) { \ |
||
541 | return DefineMatcher(Param, llvm::Regex::NoFlags); \ |
||
542 | } \ |
||
543 | typedef ::clang::ast_matchers::internal::PolymorphicMatcher< \ |
||
544 | internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \ |
||
545 | std::shared_ptr<llvm::Regex>> ( \ |
||
546 | &DefineMatcher##_Type##OverloadId##Flags)( \ |
||
547 | llvm::StringRef Param, llvm::Regex::RegexFlags RegexFlags); \ |
||
548 | typedef ::clang::ast_matchers::internal::PolymorphicMatcher< \ |
||
549 | internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF, \ |
||
550 | std::shared_ptr<llvm::Regex>> (&DefineMatcher##_Type##OverloadId)( \ |
||
551 | llvm::StringRef Param); \ |
||
552 | template <typename NodeType, typename ParamT> \ |
||
553 | bool internal:: \ |
||
554 | matcher_##DefineMatcher##OverloadId##Matcher<NodeType, ParamT>::matches( \ |
||
555 | const NodeType &Node, \ |
||
556 | ::clang::ast_matchers::internal::ASTMatchFinder *Finder, \ |
||
557 | ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) \ |
||
558 | const |
||
559 | |||
560 | #endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H |