]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/llvm/tools/clang/include/clang/ASTMatchers/ASTMatchersMacros.h
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.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_AST_MATCHERS_AST_MATCHERS_MACROS_H
38 #define LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H
39
40 /// \brief AST_MATCHER(Type, DefineMatcher) { ... }
41 /// defines a zero parameter function named DefineMatcher() that returns a
42 /// Matcher<Type> object.
43 ///
44 /// The code between the curly braces has access to the following variables:
45 ///
46 ///   Node:                  the AST node being matched; its type is Type.
47 ///   Finder:                an ASTMatchFinder*.
48 ///   Builder:               a BoundNodesTreeBuilder*.
49 ///
50 /// The code should return true if 'Node' matches.
51 #define AST_MATCHER(Type, DefineMatcher)                                       \
52   namespace internal {                                                         \
53   class matcher_##DefineMatcher##Matcher : public MatcherInterface<Type> {     \
54   public:                                                                      \
55     explicit matcher_##DefineMatcher##Matcher() {}                             \
56     virtual bool matches(const Type &Node, ASTMatchFinder *Finder,             \
57                          BoundNodesTreeBuilder *Builder) const;                \
58   };                                                                           \
59   }                                                                            \
60   inline internal::Matcher<Type> DefineMatcher() {                             \
61     return internal::makeMatcher(                                              \
62         new internal::matcher_##DefineMatcher##Matcher());                     \
63   }                                                                            \
64   inline bool internal::matcher_##DefineMatcher##Matcher::matches(             \
65       const Type &Node, ASTMatchFinder *Finder,                                \
66       BoundNodesTreeBuilder *Builder) const
67
68 /// \brief AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... }
69 /// defines a single-parameter function named DefineMatcher() that returns a
70 /// Matcher<Type> object.
71 ///
72 /// The code between the curly braces has access to the following variables:
73 ///
74 ///   Node:                  the AST node being matched; its type is Type.
75 ///   Param:                 the parameter passed to the function; its type
76 ///                          is ParamType.
77 ///   Finder:                an ASTMatchFinder*.
78 ///   Builder:               a BoundNodesTreeBuilder*.
79 ///
80 /// The code should return true if 'Node' matches.
81 #define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param)                   \
82   AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, 0)
83
84 #define AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param,          \
85                                OverloadId)                                     \
86   namespace internal {                                                         \
87   class matcher_##DefineMatcher##OverloadId##Matcher                           \
88       : public MatcherInterface<Type> {                                        \
89   public:                                                                      \
90     explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
91         const ParamType &A##Param)                                             \
92         : Param(A##Param) {}                                                   \
93     virtual bool matches(const Type &Node, ASTMatchFinder *Finder,             \
94                          BoundNodesTreeBuilder *Builder) const;                \
95                                                                                \
96   private:                                                                     \
97     const ParamType Param;                                                     \
98   };                                                                           \
99   }                                                                            \
100   inline internal::Matcher<Type> DefineMatcher(const ParamType &Param) {       \
101     return internal::makeMatcher(                                              \
102         new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param));    \
103   }                                                                            \
104   typedef internal::Matcher<Type>(&DefineMatcher##_Type##OverloadId)(          \
105       const ParamType &Param);                                                 \
106   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
107       const Type &Node, ASTMatchFinder *Finder,                                \
108       BoundNodesTreeBuilder *Builder) const
109
110 /// \brief AST_MATCHER_P2(
111 ///     Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
112 /// defines a two-parameter function named DefineMatcher() that returns a
113 /// Matcher<Type> object.
114 ///
115 /// The code between the curly braces has access to the following variables:
116 ///
117 ///   Node:                  the AST node being matched; its type is Type.
118 ///   Param1, Param2:        the parameters passed to the function; their types
119 ///                          are ParamType1 and ParamType2.
120 ///   Finder:                an ASTMatchFinder*.
121 ///   Builder:               a BoundNodesTreeBuilder*.
122 ///
123 /// The code should return true if 'Node' matches.
124 #define AST_MATCHER_P2(Type, DefineMatcher, ParamType1, Param1, ParamType2,    \
125                        Param2)                                                 \
126   AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
127                           Param2, 0)
128
129 #define AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1,       \
130                                 ParamType2, Param2, OverloadId)                \
131   namespace internal {                                                         \
132   class matcher_##DefineMatcher##OverloadId##Matcher                           \
133       : public MatcherInterface<Type> {                                        \
134   public:                                                                      \
135     matcher_##DefineMatcher##OverloadId##Matcher(const ParamType1 &A##Param1,  \
136                                                  const ParamType2 &A##Param2)  \
137         : Param1(A##Param1), Param2(A##Param2) {}                              \
138     virtual bool matches(const Type &Node, ASTMatchFinder *Finder,             \
139                          BoundNodesTreeBuilder *Builder) const;                \
140                                                                                \
141   private:                                                                     \
142     const ParamType1 Param1;                                                   \
143     const ParamType2 Param2;                                                   \
144   };                                                                           \
145   }                                                                            \
146   inline internal::Matcher<Type> DefineMatcher(const ParamType1 &Param1,       \
147                                                const ParamType2 &Param2) {     \
148     return internal::makeMatcher(                                              \
149         new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1,     \
150                                                                    Param2));   \
151   }                                                                            \
152   typedef internal::Matcher<Type>(&DefineMatcher##_Type##OverloadId)(          \
153       const ParamType1 &Param1, const ParamType2 &Param2);                     \
154   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
155       const Type &Node, ASTMatchFinder *Finder,                                \
156       BoundNodesTreeBuilder *Builder) const
157
158 /// \brief Construct a type-list to be passed to the AST_POLYMORPHIC_MATCHER*
159 ///   macros.
160 ///
161 /// You can't pass something like \c TypeList<Foo, Bar> to a macro, because it
162 /// will look at that as two arguments. However, you can pass
163 /// \c void(TypeList<Foo, Bar>), which works thanks to the parenthesis.
164 /// The \c PolymorphicMatcherWithParam* classes will unpack the function type to
165 /// extract the TypeList object.
166 #define AST_POLYMORPHIC_SUPPORTED_TYPES_1(t1) void(internal::TypeList<t1>)
167 #define AST_POLYMORPHIC_SUPPORTED_TYPES_2(t1, t2)                              \
168   void(internal::TypeList<t1, t2>)
169 #define AST_POLYMORPHIC_SUPPORTED_TYPES_3(t1, t2, t3)                          \
170   void(internal::TypeList<t1, t2, t3>)
171 #define AST_POLYMORPHIC_SUPPORTED_TYPES_4(t1, t2, t3, t4)                      \
172   void(internal::TypeList<t1, t2, t3, t4>)
173 #define AST_POLYMORPHIC_SUPPORTED_TYPES_5(t1, t2, t3, t4, t5)                  \
174   void(internal::TypeList<t1, t2, t3, internal::TypeList<t4, t5> >)
175
176 /// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... }
177 /// defines a single-parameter function named DefineMatcher() that is
178 /// polymorphic in the return type.
179 ///
180 /// The variables are the same as for AST_MATCHER, but NodeType will be deduced
181 /// from the calling context.
182 #define AST_POLYMORPHIC_MATCHER(DefineMatcher, ReturnTypesF)                   \
183   namespace internal {                                                         \
184   template <typename NodeType>                                                 \
185   class matcher_##DefineMatcher##Matcher : public MatcherInterface<NodeType> { \
186   public:                                                                      \
187     virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder,         \
188                          BoundNodesTreeBuilder *Builder) const;                \
189   };                                                                           \
190   }                                                                            \
191   inline internal::PolymorphicMatcherWithParam0<                               \
192       internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>                \
193   DefineMatcher() {                                                            \
194     return internal::PolymorphicMatcherWithParam0<                             \
195         internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>();           \
196   }                                                                            \
197   template <typename NodeType>                                                 \
198   bool internal::matcher_##DefineMatcher##Matcher<NodeType>::matches(          \
199       const NodeType &Node, ASTMatchFinder *Finder,                            \
200       BoundNodesTreeBuilder *Builder) const
201
202 /// \brief AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... }
203 /// defines a single-parameter function named DefineMatcher() that is
204 /// polymorphic in the return type.
205 ///
206 /// The variables are the same as for
207 /// AST_MATCHER_P, with the addition of NodeType, which specifies the node type
208 /// of the matcher Matcher<NodeType> returned by the function matcher().
209 ///
210 /// FIXME: Pull out common code with above macro?
211 #define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ReturnTypesF, ParamType,      \
212                                   Param)                                       \
213   AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType,   \
214                                      Param, 0)
215
216 #define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF,        \
217                                            ParamType, Param, OverloadId)       \
218   namespace internal {                                                         \
219   template <typename NodeType, typename ParamT>                                \
220   class matcher_##DefineMatcher##OverloadId##Matcher                           \
221       : public MatcherInterface<NodeType> {                                    \
222   public:                                                                      \
223     explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
224         const ParamType &A##Param)                                             \
225         : Param(A##Param) {}                                                   \
226     virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder,         \
227                          BoundNodesTreeBuilder *Builder) const;                \
228                                                                                \
229   private:                                                                     \
230     const ParamType Param;                                                     \
231   };                                                                           \
232   }                                                                            \
233   inline internal::PolymorphicMatcherWithParam1<                               \
234       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,       \
235       ReturnTypesF> DefineMatcher(const ParamType &Param) {                    \
236     return internal::PolymorphicMatcherWithParam1<                             \
237         internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,     \
238         ReturnTypesF>(Param);                                                  \
239   }                                                                            \
240   typedef internal::PolymorphicMatcherWithParam1<                              \
241       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,       \
242       ReturnTypesF>(&DefineMatcher##_Type##OverloadId)(                        \
243       const ParamType &Param);                                                 \
244   template <typename NodeType, typename ParamT>                                \
245   bool internal::matcher_##DefineMatcher##OverloadId##Matcher<                 \
246       NodeType, ParamT>::matches(const NodeType &Node, ASTMatchFinder *Finder, \
247                                  BoundNodesTreeBuilder *Builder) const
248
249 /// \brief AST_POLYMORPHIC_MATCHER_P2(
250 ///     DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
251 /// defines a two-parameter function named matcher() that is polymorphic in
252 /// the return type.
253 ///
254 /// The variables are the same as for AST_MATCHER_P2, with the
255 /// addition of NodeType, which specifies the node type of the matcher
256 /// Matcher<NodeType> returned by the function DefineMatcher().
257 #define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ReturnTypesF, ParamType1,    \
258                                    Param1, ParamType2, Param2)                 \
259   AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType1, \
260                                       Param1, ParamType2, Param2, 0)
261
262 #define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF,       \
263                                             ParamType1, Param1, ParamType2,    \
264                                             Param2, OverloadId)                \
265   namespace internal {                                                         \
266   template <typename NodeType, typename ParamT1, typename ParamT2>             \
267   class matcher_##DefineMatcher##OverloadId##Matcher                           \
268       : public MatcherInterface<NodeType> {                                    \
269   public:                                                                      \
270     matcher_##DefineMatcher##OverloadId##Matcher(const ParamType1 &A##Param1,  \
271                                                  const ParamType2 &A##Param2)  \
272         : Param1(A##Param1), Param2(A##Param2) {}                              \
273     virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder,         \
274                          BoundNodesTreeBuilder *Builder) const;                \
275                                                                                \
276   private:                                                                     \
277     const ParamType1 Param1;                                                   \
278     const ParamType2 Param2;                                                   \
279   };                                                                           \
280   }                                                                            \
281   inline internal::PolymorphicMatcherWithParam2<                               \
282       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,      \
283       ParamType2, ReturnTypesF> DefineMatcher(const ParamType1 &Param1,        \
284                                               const ParamType2 &Param2) {      \
285     return internal::PolymorphicMatcherWithParam2<                             \
286         internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,    \
287         ParamType2, ReturnTypesF>(Param1, Param2);                             \
288   }                                                                            \
289   typedef internal::PolymorphicMatcherWithParam2<                              \
290       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,      \
291       ParamType2, ReturnTypesF>(&DefineMatcher##_Type##OverloadId)(            \
292       const ParamType1 &Param1, const ParamType2 &Param2);                     \
293   template <typename NodeType, typename ParamT1, typename ParamT2>             \
294   bool internal::matcher_##DefineMatcher##OverloadId##Matcher<                 \
295       NodeType, ParamT1, ParamT2>::matches(                                    \
296       const NodeType &Node, ASTMatchFinder *Finder,                            \
297       BoundNodesTreeBuilder *Builder) const
298
299 /// \brief Creates a variadic matcher for both a specific \c Type as well as
300 /// the corresponding \c TypeLoc.
301 #define AST_TYPE_MATCHER(NodeType, MatcherName)                                \
302   const internal::VariadicDynCastAllOfMatcher<Type, NodeType> MatcherName
303 // FIXME: add a matcher for TypeLoc derived classes using its custom casting
304 // API (no longer dyn_cast) if/when we need such matching
305
306 /// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
307 /// the matcher \c MatcherName that can be used to traverse from one \c Type
308 /// to another.
309 ///
310 /// For a specific \c SpecificType, the traversal is done using 
311 /// \c SpecificType::FunctionName. The existence of such a function determines
312 /// whether a corresponding matcher can be used on \c SpecificType.
313 #define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF)     \
314   namespace internal {                                                         \
315   template <typename T> struct TypeMatcher##MatcherName##Getter {              \
316     static QualType (T::*value())() const { return &T::FunctionName; }         \
317   };                                                                           \
318   }                                                                            \
319   const internal::TypeTraversePolymorphicMatcher<                              \
320       QualType, internal::TypeMatcher##MatcherName##Getter,                    \
321       internal::TypeTraverseMatcher, ReturnTypesF>::Func MatcherName
322
323 /// \brief AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works
324 /// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs.
325 #define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF)  \
326   namespace internal {                                                         \
327   template <typename T> struct TypeLocMatcher##MatcherName##Getter {           \
328     static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; }     \
329   };                                                                           \
330   }                                                                            \
331   const internal::TypeTraversePolymorphicMatcher<                              \
332       TypeLoc, internal::TypeLocMatcher##MatcherName##Getter,                  \
333       internal::TypeLocTraverseMatcher, ReturnTypesF>::Func MatcherName##Loc;  \
334   AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF)
335
336 #endif // LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H