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