• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #endif // LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H
225