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