]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersMacros.h
Merge sendmail 8.15.2 to HEAD
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / ASTMatchers / ASTMatchersMacros.h
1 //===--- ASTMatchersMacros.h - Structural query framework -------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 //  Defines macros that enable us to define new matchers in a single place.
11 //  Since a matcher is a function which returns a Matcher<T> object, where
12 //  T is the type of the actual implementation of the matcher, the macros allow
13 //  us to write matchers like functions and take care of the definition of the
14 //  class boilerplate.
15 //
16 //  Note that when you define a matcher with an AST_MATCHER* macro, only the
17 //  function which creates the matcher goes into the current namespace - the
18 //  class that implements the actual matcher, which gets returned by the
19 //  generator function, is put into the 'internal' namespace. This allows us
20 //  to only have the functions (which is all the user cares about) in the
21 //  'ast_matchers' namespace and hide the boilerplate.
22 //
23 //  To define a matcher in user code, always put it into the clang::ast_matchers
24 //  namespace and refer to the internal types via the 'internal::':
25 //
26 //  namespace clang {
27 //  namespace ast_matchers {
28 //  AST_MATCHER_P(MemberExpr, Member,
29 //                internal::Matcher<ValueDecl>, InnerMatcher) {
30 //    return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
31 //  }
32 //  } // end namespace ast_matchers
33 //  } // end namespace clang
34 //
35 //===----------------------------------------------------------------------===//
36
37 #ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
38 #define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
39
40 /// \brief AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) {
41 /// defines a zero parameter function named DefineMatcher() that returns a
42 /// ReturnType object.
43 #define AST_MATCHER_FUNCTION(ReturnType, DefineMatcher)                        \
44   inline ReturnType DefineMatcher##_getInstance();                             \
45   inline ReturnType DefineMatcher() {                                          \
46     return internal::MemoizedMatcher<                                          \
47         ReturnType, DefineMatcher##_getInstance>::getInstance();               \
48   }                                                                            \
49   inline ReturnType DefineMatcher##_getInstance()
50
51 /// \brief AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) {
52 /// defines a single-parameter function named DefineMatcher() that returns a
53 /// ReturnType object.
54 ///
55 /// The code between the curly braces has access to the following variables:
56 ///
57 ///   Param:                 the parameter passed to the function; its type
58 ///                          is ParamType.
59 ///
60 /// The code should return an instance of ReturnType.
61 #define AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param)    \
62   AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, Param, \
63                                   0)
64 #define AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType,  \
65                                         Param, OverloadId)                     \
66   inline ReturnType DefineMatcher(ParamType const &Param);                     \
67   typedef ReturnType (&DefineMatcher##_Type##OverloadId)(ParamType const &);   \
68   inline ReturnType DefineMatcher(ParamType const &Param)
69
70 /// \brief AST_MATCHER(Type, DefineMatcher) { ... }
71 /// defines a zero parameter function named DefineMatcher() that returns a
72 /// Matcher<Type> object.
73 ///
74 /// The code between the curly braces has access to the following variables:
75 ///
76 ///   Node:                  the AST node being matched; its type is Type.
77 ///   Finder:                an ASTMatchFinder*.
78 ///   Builder:               a BoundNodesTreeBuilder*.
79 ///
80 /// The code should return true if 'Node' matches.
81 #define AST_MATCHER(Type, DefineMatcher)                                       \
82   namespace internal {                                                         \
83   class matcher_##DefineMatcher##Matcher : public MatcherInterface<Type> {     \
84   public:                                                                      \
85     explicit matcher_##DefineMatcher##Matcher() {}                             \
86     bool matches(const Type &Node, ASTMatchFinder *Finder,                     \
87                  BoundNodesTreeBuilder *Builder) const override;               \
88   };                                                                           \
89   }                                                                            \
90   inline internal::Matcher<Type> DefineMatcher() {                             \
91     return internal::makeMatcher(                                              \
92         new internal::matcher_##DefineMatcher##Matcher());                     \
93   }                                                                            \
94   inline bool internal::matcher_##DefineMatcher##Matcher::matches(             \
95       const Type &Node, ASTMatchFinder *Finder,                                \
96       BoundNodesTreeBuilder *Builder) const
97
98 /// \brief AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... }
99 /// defines a single-parameter function named DefineMatcher() that returns a
100 /// Matcher<Type> object.
101 ///
102 /// The code between the curly braces has access to the following variables:
103 ///
104 ///   Node:                  the AST node being matched; its type is Type.
105 ///   Param:                 the parameter passed to the function; its type
106 ///                          is ParamType.
107 ///   Finder:                an ASTMatchFinder*.
108 ///   Builder:               a BoundNodesTreeBuilder*.
109 ///
110 /// The code should return true if 'Node' matches.
111 #define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param)                   \
112   AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, 0)
113
114 #define AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param,          \
115                                OverloadId)                                     \
116   namespace internal {                                                         \
117   class matcher_##DefineMatcher##OverloadId##Matcher                           \
118       : public MatcherInterface<Type> {                                        \
119   public:                                                                      \
120     explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
121         ParamType const &A##Param)                                             \
122         : Param(A##Param) {}                                                   \
123     bool matches(const Type &Node, ASTMatchFinder *Finder,                     \
124                  BoundNodesTreeBuilder *Builder) const override;               \
125                                                                                \
126   private:                                                                     \
127     ParamType const Param;                                                     \
128   };                                                                           \
129   }                                                                            \
130   inline internal::Matcher<Type> DefineMatcher(ParamType const &Param) {       \
131     return internal::makeMatcher(                                              \
132         new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param));    \
133   }                                                                            \
134   typedef internal::Matcher<Type>(&DefineMatcher##_Type##OverloadId)(          \
135       ParamType const &Param);                                                 \
136   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
137       const Type &Node, ASTMatchFinder *Finder,                                \
138       BoundNodesTreeBuilder *Builder) const
139
140 /// \brief AST_MATCHER_P2(
141 ///     Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
142 /// defines a two-parameter function named DefineMatcher() that returns a
143 /// Matcher<Type> object.
144 ///
145 /// The code between the curly braces has access to the following variables:
146 ///
147 ///   Node:                  the AST node being matched; its type is Type.
148 ///   Param1, Param2:        the parameters passed to the function; their types
149 ///                          are ParamType1 and ParamType2.
150 ///   Finder:                an ASTMatchFinder*.
151 ///   Builder:               a BoundNodesTreeBuilder*.
152 ///
153 /// The code should return true if 'Node' matches.
154 #define AST_MATCHER_P2(Type, DefineMatcher, ParamType1, Param1, ParamType2,    \
155                        Param2)                                                 \
156   AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
157                           Param2, 0)
158
159 #define AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1,       \
160                                 ParamType2, Param2, OverloadId)                \
161   namespace internal {                                                         \
162   class matcher_##DefineMatcher##OverloadId##Matcher                           \
163       : public MatcherInterface<Type> {                                        \
164   public:                                                                      \
165     matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1,  \
166                                                  ParamType2 const &A##Param2)  \
167         : Param1(A##Param1), Param2(A##Param2) {}                              \
168     bool matches(const Type &Node, ASTMatchFinder *Finder,                     \
169                  BoundNodesTreeBuilder *Builder) const override;               \
170                                                                                \
171   private:                                                                     \
172     ParamType1 const Param1;                                                   \
173     ParamType2 const Param2;                                                   \
174   };                                                                           \
175   }                                                                            \
176   inline internal::Matcher<Type> DefineMatcher(ParamType1 const &Param1,       \
177                                                ParamType2 const &Param2) {     \
178     return internal::makeMatcher(                                              \
179         new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1,     \
180                                                                    Param2));   \
181   }                                                                            \
182   typedef internal::Matcher<Type>(&DefineMatcher##_Type##OverloadId)(          \
183       ParamType1 const &Param1, ParamType2 const &Param2);                     \
184   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
185       const Type &Node, ASTMatchFinder *Finder,                                \
186       BoundNodesTreeBuilder *Builder) const
187
188 /// \brief Construct a type-list to be passed to the AST_POLYMORPHIC_MATCHER*
189 ///   macros.
190 ///
191 /// You can't pass something like \c TypeList<Foo, Bar> to a macro, because it
192 /// will look at that as two arguments. However, you can pass
193 /// \c void(TypeList<Foo, Bar>), which works thanks to the parenthesis.
194 /// The \c PolymorphicMatcherWithParam* classes will unpack the function type to
195 /// extract the TypeList object.
196 #define AST_POLYMORPHIC_SUPPORTED_TYPES_1(t1) void(internal::TypeList<t1>)
197 #define AST_POLYMORPHIC_SUPPORTED_TYPES_2(t1, t2)                              \
198   void(internal::TypeList<t1, t2>)
199 #define AST_POLYMORPHIC_SUPPORTED_TYPES_3(t1, t2, t3)                          \
200   void(internal::TypeList<t1, t2, t3>)
201 #define AST_POLYMORPHIC_SUPPORTED_TYPES_4(t1, t2, t3, t4)                      \
202   void(internal::TypeList<t1, t2, t3, t4>)
203 #define AST_POLYMORPHIC_SUPPORTED_TYPES_5(t1, t2, t3, t4, t5)                  \
204   void(internal::TypeList<t1, t2, t3, internal::TypeList<t4, t5> >)
205
206 /// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... }
207 /// defines a single-parameter function named DefineMatcher() that is
208 /// polymorphic in the return type.
209 ///
210 /// The variables are the same as for AST_MATCHER, but NodeType will be deduced
211 /// from the calling context.
212 #define AST_POLYMORPHIC_MATCHER(DefineMatcher, ReturnTypesF)                   \
213   namespace internal {                                                         \
214   template <typename NodeType>                                                 \
215   class matcher_##DefineMatcher##Matcher : public MatcherInterface<NodeType> { \
216   public:                                                                      \
217     bool matches(const NodeType &Node, ASTMatchFinder *Finder,                 \
218                  BoundNodesTreeBuilder *Builder) const override;               \
219   };                                                                           \
220   }                                                                            \
221   inline internal::PolymorphicMatcherWithParam0<                               \
222       internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>                \
223   DefineMatcher() {                                                            \
224     return internal::PolymorphicMatcherWithParam0<                             \
225         internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>();           \
226   }                                                                            \
227   template <typename NodeType>                                                 \
228   bool internal::matcher_##DefineMatcher##Matcher<NodeType>::matches(          \
229       const NodeType &Node, ASTMatchFinder *Finder,                            \
230       BoundNodesTreeBuilder *Builder) const
231
232 /// \brief AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... }
233 /// defines a single-parameter function named DefineMatcher() that is
234 /// polymorphic in the return type.
235 ///
236 /// The variables are the same as for
237 /// AST_MATCHER_P, with the addition of NodeType, which specifies the node type
238 /// of the matcher Matcher<NodeType> returned by the function matcher().
239 ///
240 /// FIXME: Pull out common code with above macro?
241 #define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ReturnTypesF, ParamType,      \
242                                   Param)                                       \
243   AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType,   \
244                                      Param, 0)
245
246 #define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF,        \
247                                            ParamType, Param, OverloadId)       \
248   namespace internal {                                                         \
249   template <typename NodeType, typename ParamT>                                \
250   class matcher_##DefineMatcher##OverloadId##Matcher                           \
251       : public MatcherInterface<NodeType> {                                    \
252   public:                                                                      \
253     explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
254         ParamType const &A##Param)                                             \
255         : Param(A##Param) {}                                                   \
256     bool matches(const NodeType &Node, ASTMatchFinder *Finder,                 \
257                  BoundNodesTreeBuilder *Builder) const override;               \
258                                                                                \
259   private:                                                                     \
260     ParamType const Param;                                                     \
261   };                                                                           \
262   }                                                                            \
263   inline internal::PolymorphicMatcherWithParam1<                               \
264       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,       \
265       ReturnTypesF> DefineMatcher(ParamType const &Param) {                    \
266     return internal::PolymorphicMatcherWithParam1<                             \
267         internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,     \
268         ReturnTypesF>(Param);                                                  \
269   }                                                                            \
270   typedef internal::PolymorphicMatcherWithParam1<                              \
271       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,       \
272       ReturnTypesF>(&DefineMatcher##_Type##OverloadId)(                        \
273       ParamType const &Param);                                                 \
274   template <typename NodeType, typename ParamT>                                \
275   bool internal::matcher_##DefineMatcher##OverloadId##Matcher<                 \
276       NodeType, ParamT>::matches(const NodeType &Node, ASTMatchFinder *Finder, \
277                                  BoundNodesTreeBuilder *Builder) const
278
279 /// \brief AST_POLYMORPHIC_MATCHER_P2(
280 ///     DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
281 /// defines a two-parameter function named matcher() that is polymorphic in
282 /// the return type.
283 ///
284 /// The variables are the same as for AST_MATCHER_P2, with the
285 /// addition of NodeType, which specifies the node type of the matcher
286 /// Matcher<NodeType> returned by the function DefineMatcher().
287 #define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ReturnTypesF, ParamType1,    \
288                                    Param1, ParamType2, Param2)                 \
289   AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType1, \
290                                       Param1, ParamType2, Param2, 0)
291
292 #define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF,       \
293                                             ParamType1, Param1, ParamType2,    \
294                                             Param2, OverloadId)                \
295   namespace internal {                                                         \
296   template <typename NodeType, typename ParamT1, typename ParamT2>             \
297   class matcher_##DefineMatcher##OverloadId##Matcher                           \
298       : public MatcherInterface<NodeType> {                                    \
299   public:                                                                      \
300     matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1,  \
301                                                  ParamType2 const &A##Param2)  \
302         : Param1(A##Param1), Param2(A##Param2) {}                              \
303      bool matches(const NodeType &Node, ASTMatchFinder *Finder,                \
304                   BoundNodesTreeBuilder *Builder) const override;              \
305                                                                                \
306   private:                                                                     \
307     ParamType1 const Param1;                                                   \
308     ParamType2 const Param2;                                                   \
309   };                                                                           \
310   }                                                                            \
311   inline internal::PolymorphicMatcherWithParam2<                               \
312       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,      \
313       ParamType2, ReturnTypesF> DefineMatcher(ParamType1 const &Param1,        \
314                                               ParamType2 const &Param2) {      \
315     return internal::PolymorphicMatcherWithParam2<                             \
316         internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,    \
317         ParamType2, ReturnTypesF>(Param1, Param2);                             \
318   }                                                                            \
319   typedef internal::PolymorphicMatcherWithParam2<                              \
320       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,      \
321       ParamType2, ReturnTypesF>(&DefineMatcher##_Type##OverloadId)(            \
322       ParamType1 const &Param1, ParamType2 const &Param2);                     \
323   template <typename NodeType, typename ParamT1, typename ParamT2>             \
324   bool internal::matcher_##DefineMatcher##OverloadId##Matcher<                 \
325       NodeType, ParamT1, ParamT2>::matches(                                    \
326       const NodeType &Node, ASTMatchFinder *Finder,                            \
327       BoundNodesTreeBuilder *Builder) const
328
329 /// \brief Creates a variadic matcher for both a specific \c Type as well as
330 /// the corresponding \c TypeLoc.
331 #define AST_TYPE_MATCHER(NodeType, MatcherName)                                \
332   const internal::VariadicDynCastAllOfMatcher<Type, NodeType> MatcherName
333 // FIXME: add a matcher for TypeLoc derived classes using its custom casting
334 // API (no longer dyn_cast) if/when we need such matching
335
336 /// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
337 /// the matcher \c MatcherName that can be used to traverse from one \c Type
338 /// to another.
339 ///
340 /// For a specific \c SpecificType, the traversal is done using 
341 /// \c SpecificType::FunctionName. The existence of such a function determines
342 /// whether a corresponding matcher can be used on \c SpecificType.
343 #define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF)     \
344   namespace internal {                                                         \
345   template <typename T> struct TypeMatcher##MatcherName##Getter {              \
346     static QualType (T::*value())() const { return &T::FunctionName; }         \
347   };                                                                           \
348   }                                                                            \
349   const internal::TypeTraversePolymorphicMatcher<                              \
350       QualType, internal::TypeMatcher##MatcherName##Getter,                    \
351       internal::TypeTraverseMatcher, ReturnTypesF>::Func MatcherName
352
353 /// \brief AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works
354 /// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs.
355 #define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF)  \
356   namespace internal {                                                         \
357   template <typename T> struct TypeLocMatcher##MatcherName##Getter {           \
358     static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; }     \
359   };                                                                           \
360   }                                                                            \
361   const internal::TypeTraversePolymorphicMatcher<                              \
362       TypeLoc, internal::TypeLocMatcher##MatcherName##Getter,                  \
363       internal::TypeLocTraverseMatcher, ReturnTypesF>::Func MatcherName##Loc;  \
364   AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF)
365
366 #endif