Clang Project

clang_source_code/include/clang/ASTMatchers/ASTMatchersMacros.h
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 const 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 const Param1;                                                   \
196    ParamType2 const 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::PolymorphicMatcherWithParam0<        \
243      internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>                \
244  DefineMatcher() {                                                            \
245    return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam0<      \
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 const Param;                                                     \
285  };                                                                           \
286  }                                                                            \
287  inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1<        \
288      internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,       \
289      ReturnTypesF>                                                            \
290  DefineMatcher(ParamType const &Param) {                                      \
291    return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1<      \
292        internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,     \
293        ReturnTypesF>(Param);                                                  \
294  }                                                                            \
295  typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1<       \
296      internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,       \
297      ReturnTypesF>(&DefineMatcher##_Type##OverloadId)(                        \
298      ParamType const &Param);                                                 \
299  template <typename NodeType, typename ParamT>                                \
300  bool internal::                                                              \
301      matcher_##DefineMatcher##OverloadId##Matcher<NodeType, ParamT>::matches( \
302          const NodeType &Node,                                                \
303          ::clang::ast_matchers::internal::ASTMatchFinder *Finder,             \
304          ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder)     \
305          const
306
307/// AST_POLYMORPHIC_MATCHER_P2(
308///     DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
309/// defines a two-parameter function named matcher() that is polymorphic in
310/// the return type.
311///
312/// The variables are the same as for AST_MATCHER_P2, with the
313/// addition of NodeType, which specifies the node type of the matcher
314/// Matcher<NodeType> returned by the function DefineMatcher().
315#define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ReturnTypesF, ParamType1,    \
316                                   Param1, ParamType2, Param2)                 \
317  AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType1, \
318                                      Param1, ParamType2, Param2, 0)
319
320#define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF,       \
321                                            ParamType1, Param1, ParamType2,    \
322                                            Param2, OverloadId)                \
323  namespace internal {                                                         \
324  template <typename NodeType, typename ParamT1, typename ParamT2>             \
325  class matcher_##DefineMatcher##OverloadId##Matcher                           \
326      : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> {   \
327  public:                                                                      \
328    matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1,  \
329                                                 ParamType2 const &A##Param2)  \
330        : Param1(A##Param1), Param2(A##Param2) {}                              \
331    bool matches(const NodeType &Node,                                         \
332                 ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \
333                 ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \
334                     *Builder) const override;                                 \
335                                                                               \
336  private:                                                                     \
337    ParamType1 const Param1;                                                   \
338    ParamType2 const Param2;                                                   \
339  };                                                                           \
340  }                                                                            \
341  inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2<        \
342      internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,      \
343      ParamType2, ReturnTypesF>                                                \
344  DefineMatcher(ParamType1 const &Param1, ParamType2 const &Param2) {          \
345    return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2<      \
346        internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,    \
347        ParamType2, ReturnTypesF>(Param1, Param2);                             \
348  }                                                                            \
349  typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2<       \
350      internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,      \
351      ParamType2, ReturnTypesF>(&DefineMatcher##_Type##OverloadId)(            \
352      ParamType1 const &Param1, ParamType2 const &Param2);                     \
353  template <typename NodeType, typename ParamT1, typename ParamT2>             \
354  bool internal::matcher_##DefineMatcher##OverloadId##Matcher<                 \
355      NodeType, ParamT1, ParamT2>::                                            \
356      matches(const NodeType &Node,                                            \
357              ::clang::ast_matchers::internal::ASTMatchFinder *Finder,         \
358              ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) \
359          const
360
361// FIXME: add a matcher for TypeLoc derived classes using its custom casting
362// API (no longer dyn_cast) if/when we need such matching
363
364#define AST_TYPE_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName,              \
365                                       ReturnTypesF)                           \
366  namespace internal {                                                         \
367  template <typename T> struct TypeMatcher##MatcherName##Getter {              \
368    static QualType (T::*value())() const { return &T::FunctionName; }         \
369  };                                                                           \
370  }                                                                            \
371  extern const ::clang::ast_matchers::internal::                               \
372      TypeTraversePolymorphicMatcher<                                          \
373          QualType,                                                            \
374          ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter,   \
375          ::clang::ast_matchers::internal::TypeTraverseMatcher,                \
376          ReturnTypesF>::Func MatcherName
377
378#define AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF)               \
379  const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher<       \
380      QualType,                                                                \
381      ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter,       \
382      ::clang::ast_matchers::internal::TypeTraverseMatcher,                    \
383      ReturnTypesF>::Func MatcherName
384
385/// AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
386/// the matcher \c MatcherName that can be used to traverse from one \c Type
387/// to another.
388///
389/// For a specific \c SpecificType, the traversal is done using
390/// \c SpecificType::FunctionName. The existence of such a function determines
391/// whether a corresponding matcher can be used on \c SpecificType.
392#define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF)     \
393  namespace internal {                                                         \
394  template <typename T> struct TypeMatcher##MatcherName##Getter {              \
395    static QualType (T::*value())() const { return &T::FunctionName; }         \
396  };                                                                           \
397  }                                                                            \
398  const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher<       \
399      QualType,                                                                \
400      ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter,       \
401      ::clang::ast_matchers::internal::TypeTraverseMatcher,                    \
402      ReturnTypesF>::Func MatcherName
403
404#define AST_TYPELOC_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName,           \
405                                          ReturnTypesF)                        \
406  namespace internal {                                                         \
407  template <typename T> struct TypeLocMatcher##MatcherName##Getter {           \
408    static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; }     \
409  };                                                                           \
410  }                                                                            \
411  extern const ::clang::ast_matchers::internal::                               \
412      TypeTraversePolymorphicMatcher<                                          \
413          TypeLoc,                                                             \
414          ::clang::ast_matchers::internal::                                    \
415              TypeLocMatcher##MatcherName##Getter,                             \
416          ::clang::ast_matchers::internal::TypeLocTraverseMatcher,             \
417          ReturnTypesF>::Func MatcherName##Loc;                                \
418  AST_TYPE_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName##Type, ReturnTypesF)
419
420#define AST_TYPELOC_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF)            \
421  const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher<       \
422      TypeLoc,                                                                 \
423      ::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter,    \
424      ::clang::ast_matchers::internal::TypeLocTraverseMatcher,                 \
425      ReturnTypesF>::Func MatcherName##Loc;                                    \
426  AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF)
427
428/// AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works
429/// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs.
430#define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF)  \
431  namespace internal {                                                         \
432  template <typename T> struct TypeLocMatcher##MatcherName##Getter {           \
433    static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; }     \
434  };                                                                           \
435  }                                                                            \
436  const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher<       \
437      TypeLoc,                                                                 \
438      ::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter,    \
439      ::clang::ast_matchers::internal::TypeLocTraverseMatcher,                 \
440      ReturnTypesF>::Func MatcherName##Loc;                                    \
441  AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF)
442
443#endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
444