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
561

source code of clang/include/clang/ASTMatchers/ASTMatchersMacros.h