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