Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line | 
|---|---|---|---|
| 14 | pmbaty | 1 | //===--- ASTMatchersMacros.h - Structural query framework -------*- C++ -*-===// | 
| 2 | // | ||
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | ||
| 4 | // See https://llvm.org/LICENSE.txt for license information. | ||
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | ||
| 6 | // | ||
| 7 | //===----------------------------------------------------------------------===// | ||
| 8 | // | ||
| 9 | //  Defines macros that enable us to define new matchers in a single place. | ||
| 10 | //  Since a matcher is a function which returns a Matcher<T> object, where | ||
| 11 | //  T is the type of the actual implementation of the matcher, the macros allow | ||
| 12 | //  us to write matchers like functions and take care of the definition of the | ||
| 13 | //  class boilerplate. | ||
| 14 | // | ||
| 15 | //  Note that when you define a matcher with an AST_MATCHER* macro, only the | ||
| 16 | //  function which creates the matcher goes into the current namespace - the | ||
| 17 | //  class that implements the actual matcher, which gets returned by the | ||
| 18 | //  generator function, is put into the 'internal' namespace. This allows us | ||
| 19 | //  to only have the functions (which is all the user cares about) in the | ||
| 20 | //  'ast_matchers' namespace and hide the boilerplate. | ||
| 21 | // | ||
| 22 | //  To define a matcher in user code, put it into your own namespace. This would | ||
| 23 | //  help to prevent ODR violations in case a matcher with the same name is | ||
| 24 | //  defined in multiple translation units: | ||
| 25 | // | ||
| 26 | //  namespace my_matchers { | ||
| 27 | //  AST_MATCHER_P(clang::MemberExpr, Member, | ||
| 28 | //                clang::ast_matchers::internal::Matcher<clang::ValueDecl>, | ||
| 29 | //                InnerMatcher) { | ||
| 30 | //    return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder); | ||
| 31 | //  } | ||
| 32 | //  } // namespace my_matchers | ||
| 33 | // | ||
| 34 | //  Alternatively, an unnamed namespace may be used: | ||
| 35 | // | ||
| 36 | //  namespace clang { | ||
| 37 | //  namespace ast_matchers { | ||
| 38 | //  namespace { | ||
| 39 | //  AST_MATCHER_P(MemberExpr, Member, | ||
| 40 | //                internal::Matcher<ValueDecl>, InnerMatcher) { | ||
| 41 | //    return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder); | ||
| 42 | //  } | ||
| 43 | //  } // namespace | ||
| 44 | //  } // namespace ast_matchers | ||
| 45 | //  } // namespace clang | ||
| 46 | // | ||
| 47 | //===----------------------------------------------------------------------===// | ||
| 48 | |||
| 49 | #ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H | ||
| 50 | #define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H | ||
| 51 | |||
| 52 | /// AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) { ... } | ||
| 53 | /// defines a zero parameter function named DefineMatcher() that returns a | ||
| 54 | /// ReturnType object. | ||
| 55 | #define AST_MATCHER_FUNCTION(ReturnType, DefineMatcher)                        \ | ||
| 56 |   inline ReturnType DefineMatcher##_getInstance();                             \ | ||
| 57 |   inline ReturnType DefineMatcher() {                                          \ | ||
| 58 |     return ::clang::ast_matchers::internal::MemoizedMatcher<                   \ | ||
| 59 |         ReturnType, DefineMatcher##_getInstance>::getInstance();               \ | ||
| 60 |   }                                                                            \ | ||
| 61 |   inline ReturnType DefineMatcher##_getInstance() | ||
| 62 | |||
| 63 | /// AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) { | ||
| 64 | /// ... } | ||
| 65 | /// defines a single-parameter function named DefineMatcher() that returns a | ||
| 66 | /// ReturnType object. | ||
| 67 | /// | ||
| 68 | /// The code between the curly braces has access to the following variables: | ||
| 69 | /// | ||
| 70 | ///   Param:                 the parameter passed to the function; its type | ||
| 71 | ///                          is ParamType. | ||
| 72 | /// | ||
| 73 | /// The code should return an instance of ReturnType. | ||
| 74 | #define AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param)    \ | ||
| 75 |   AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, Param, \ | ||
| 76 |                                   0) | ||
| 77 | #define AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType,  \ | ||
| 78 |                                         Param, OverloadId)                     \ | ||
| 79 |   inline ReturnType DefineMatcher(ParamType const &Param);                     \ | ||
| 80 |   typedef ReturnType (&DefineMatcher##_Type##OverloadId)(ParamType const &);   \ | ||
| 81 |   inline ReturnType DefineMatcher(ParamType const &Param) | ||
| 82 | |||
| 83 | /// AST_MATCHER(Type, DefineMatcher) { ... } | ||
| 84 | /// defines a zero parameter function named DefineMatcher() that returns a | ||
| 85 | /// Matcher<Type> object. | ||
| 86 | /// | ||
| 87 | /// The code between the curly braces has access to the following variables: | ||
| 88 | /// | ||
| 89 | ///   Node:                  the AST node being matched; its type is Type. | ||
| 90 | ///   Finder:                an ASTMatchFinder*. | ||
| 91 | ///   Builder:               a BoundNodesTreeBuilder*. | ||
| 92 | /// | ||
| 93 | /// The code should return true if 'Node' matches. | ||
| 94 | #define AST_MATCHER(Type, DefineMatcher)                                       \ | ||
| 95 |   namespace internal {                                                         \ | ||
| 96 |   class matcher_##DefineMatcher##Matcher                                       \ | ||
| 97 |       : public ::clang::ast_matchers::internal::MatcherInterface<Type> {       \ | ||
| 98 |   public:                                                                      \ | ||
| 99 |     explicit matcher_##DefineMatcher##Matcher() = default;                     \ | ||
| 100 |     bool matches(const Type &Node,                                             \ | ||
| 101 |                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \ | ||
| 102 |                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \ | ||
| 103 |                      *Builder) const override;                                 \ | ||
| 104 |   };                                                                           \ | ||
| 105 |   }                                                                            \ | ||
| 106 |   inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher() {      \ | ||
| 107 |     return ::clang::ast_matchers::internal::makeMatcher(                       \ | ||
| 108 |         new internal::matcher_##DefineMatcher##Matcher());                     \ | ||
| 109 |   }                                                                            \ | ||
| 110 |   inline bool internal::matcher_##DefineMatcher##Matcher::matches(             \ | ||
| 111 |       const Type &Node,                                                        \ | ||
| 112 |       ::clang::ast_matchers::internal::ASTMatchFinder *Finder,                 \ | ||
| 113 |       ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const | ||
| 114 | |||
| 115 | /// AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... } | ||
| 116 | /// defines a single-parameter function named DefineMatcher() that returns a | ||
| 117 | /// Matcher<Type> object. | ||
| 118 | /// | ||
| 119 | /// The code between the curly braces has access to the following variables: | ||
| 120 | /// | ||
| 121 | ///   Node:                  the AST node being matched; its type is Type. | ||
| 122 | ///   Param:                 the parameter passed to the function; its type | ||
| 123 | ///                          is ParamType. | ||
| 124 | ///   Finder:                an ASTMatchFinder*. | ||
| 125 | ///   Builder:               a BoundNodesTreeBuilder*. | ||
| 126 | /// | ||
| 127 | /// The code should return true if 'Node' matches. | ||
| 128 | #define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param)                   \ | ||
| 129 |   AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, 0) | ||
| 130 | |||
| 131 | #define AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param,          \ | ||
| 132 |                                OverloadId)                                     \ | ||
| 133 |   namespace internal {                                                         \ | ||
| 134 |   class matcher_##DefineMatcher##OverloadId##Matcher                           \ | ||
| 135 |       : public ::clang::ast_matchers::internal::MatcherInterface<Type> {       \ | ||
| 136 |   public:                                                                      \ | ||
| 137 |     explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \ | ||
| 138 |         ParamType const &A##Param)                                             \ | ||
| 139 |         : Param(A##Param) {}                                                   \ | ||
| 140 |     bool matches(const Type &Node,                                             \ | ||
| 141 |                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \ | ||
| 142 |                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \ | ||
| 143 |                      *Builder) const override;                                 \ | ||
| 144 |                                                                                \ | ||
| 145 |   private:                                                                     \ | ||
| 146 |     ParamType Param;                                                           \ | ||
| 147 |   };                                                                           \ | ||
| 148 |   }                                                                            \ | ||
| 149 |   inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher(         \ | ||
| 150 |       ParamType const &Param) {                                                \ | ||
| 151 |     return ::clang::ast_matchers::internal::makeMatcher(                       \ | ||
| 152 |         new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param));    \ | ||
| 153 |   }                                                                            \ | ||
| 154 |   typedef ::clang::ast_matchers::internal::Matcher<Type> (                     \ | ||
| 155 |       &DefineMatcher##_Type##OverloadId)(ParamType const &Param);              \ | ||
| 156 |   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \ | ||
| 157 |       const Type &Node,                                                        \ | ||
| 158 |       ::clang::ast_matchers::internal::ASTMatchFinder *Finder,                 \ | ||
| 159 |       ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const | ||
| 160 | |||
| 161 | /// AST_MATCHER_P2( | ||
| 162 | ///     Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... } | ||
| 163 | /// defines a two-parameter function named DefineMatcher() that returns a | ||
| 164 | /// Matcher<Type> object. | ||
| 165 | /// | ||
| 166 | /// The code between the curly braces has access to the following variables: | ||
| 167 | /// | ||
| 168 | ///   Node:                  the AST node being matched; its type is Type. | ||
| 169 | ///   Param1, Param2:        the parameters passed to the function; their types | ||
| 170 | ///                          are ParamType1 and ParamType2. | ||
| 171 | ///   Finder:                an ASTMatchFinder*. | ||
| 172 | ///   Builder:               a BoundNodesTreeBuilder*. | ||
| 173 | /// | ||
| 174 | /// The code should return true if 'Node' matches. | ||
| 175 | #define AST_MATCHER_P2(Type, DefineMatcher, ParamType1, Param1, ParamType2,    \ | ||
| 176 |                        Param2)                                                 \ | ||
| 177 |   AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, ParamType2, \ | ||
| 178 |                           Param2, 0) | ||
| 179 | |||
| 180 | #define AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1,       \ | ||
| 181 |                                 ParamType2, Param2, OverloadId)                \ | ||
| 182 |   namespace internal {                                                         \ | ||
| 183 |   class matcher_##DefineMatcher##OverloadId##Matcher                           \ | ||
| 184 |       : public ::clang::ast_matchers::internal::MatcherInterface<Type> {       \ | ||
| 185 |   public:                                                                      \ | ||
| 186 |     matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1,  \ | ||
| 187 |                                                  ParamType2 const &A##Param2)  \ | ||
| 188 |         : Param1(A##Param1), Param2(A##Param2) {}                              \ | ||
| 189 |     bool matches(const Type &Node,                                             \ | ||
| 190 |                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \ | ||
| 191 |                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \ | ||
| 192 |                      *Builder) const override;                                 \ | ||
| 193 |                                                                                \ | ||
| 194 |   private:                                                                     \ | ||
| 195 |     ParamType1 Param1;                                                         \ | ||
| 196 |     ParamType2 Param2;                                                         \ | ||
| 197 |   };                                                                           \ | ||
| 198 |   }                                                                            \ | ||
| 199 |   inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher(         \ | ||
| 200 |       ParamType1 const &Param1, ParamType2 const &Param2) {                    \ | ||
| 201 |     return ::clang::ast_matchers::internal::makeMatcher(                       \ | ||
| 202 |         new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1,     \ | ||
| 203 |                                                                    Param2));   \ | ||
| 204 |   }                                                                            \ | ||
| 205 |   typedef ::clang::ast_matchers::internal::Matcher<Type> (                     \ | ||
| 206 |       &DefineMatcher##_Type##OverloadId)(ParamType1 const &Param1,             \ | ||
| 207 |                                          ParamType2 const &Param2);            \ | ||
| 208 |   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \ | ||
| 209 |       const Type &Node,                                                        \ | ||
| 210 |       ::clang::ast_matchers::internal::ASTMatchFinder *Finder,                 \ | ||
| 211 |       ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const | ||
| 212 | |||
| 213 | /// Construct a type-list to be passed to the AST_POLYMORPHIC_MATCHER* | ||
| 214 | ///   macros. | ||
| 215 | /// | ||
| 216 | /// You can't pass something like \c TypeList<Foo, Bar> to a macro, because it | ||
| 217 | /// will look at that as two arguments. However, you can pass | ||
| 218 | /// \c void(TypeList<Foo, Bar>), which works thanks to the parenthesis. | ||
| 219 | /// The \c PolymorphicMatcherWithParam* classes will unpack the function type to | ||
| 220 | /// extract the TypeList object. | ||
| 221 | #define AST_POLYMORPHIC_SUPPORTED_TYPES(...)                                   \ | ||
| 222 |   void(::clang::ast_matchers::internal::TypeList<__VA_ARGS__>) | ||
| 223 | |||
| 224 | /// AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... } | ||
| 225 | /// defines a single-parameter function named DefineMatcher() that is | ||
| 226 | /// polymorphic in the return type. | ||
| 227 | /// | ||
| 228 | /// The variables are the same as for AST_MATCHER, but NodeType will be deduced | ||
| 229 | /// from the calling context. | ||
| 230 | #define AST_POLYMORPHIC_MATCHER(DefineMatcher, ReturnTypesF)                   \ | ||
| 231 |   namespace internal {                                                         \ | ||
| 232 |   template <typename NodeType>                                                 \ | ||
| 233 |   class matcher_##DefineMatcher##Matcher                                       \ | ||
| 234 |       : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> {   \ | ||
| 235 |   public:                                                                      \ | ||
| 236 |     bool matches(const NodeType &Node,                                         \ | ||
| 237 |                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \ | ||
| 238 |                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \ | ||
| 239 |                      *Builder) const override;                                 \ | ||
| 240 |   };                                                                           \ | ||
| 241 |   }                                                                            \ | ||
| 242 |   inline ::clang::ast_matchers::internal::PolymorphicMatcher<                  \ | ||
| 243 |       internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>                \ | ||
| 244 |   DefineMatcher() {                                                            \ | ||
| 245 |     return ::clang::ast_matchers::internal::PolymorphicMatcher<                \ | ||
| 246 |         internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>();           \ | ||
| 247 |   }                                                                            \ | ||
| 248 |   template <typename NodeType>                                                 \ | ||
| 249 |   bool internal::matcher_##DefineMatcher##Matcher<NodeType>::matches(          \ | ||
| 250 |       const NodeType &Node,                                                    \ | ||
| 251 |       ::clang::ast_matchers::internal::ASTMatchFinder *Finder,                 \ | ||
| 252 |       ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const | ||
| 253 | |||
| 254 | /// AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... } | ||
| 255 | /// defines a single-parameter function named DefineMatcher() that is | ||
| 256 | /// polymorphic in the return type. | ||
| 257 | /// | ||
| 258 | /// The variables are the same as for | ||
| 259 | /// AST_MATCHER_P, with the addition of NodeType, which specifies the node type | ||
| 260 | /// of the matcher Matcher<NodeType> returned by the function matcher(). | ||
| 261 | /// | ||
| 262 | /// FIXME: Pull out common code with above macro? | ||
| 263 | #define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ReturnTypesF, ParamType,      \ | ||
| 264 |                                   Param)                                       \ | ||
| 265 |   AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType,   \ | ||
| 266 |                                      Param, 0) | ||
| 267 | |||
| 268 | #define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF,        \ | ||
| 269 |                                            ParamType, Param, OverloadId)       \ | ||
| 270 |   namespace internal {                                                         \ | ||
| 271 |   template <typename NodeType, typename ParamT>                                \ | ||
| 272 |   class matcher_##DefineMatcher##OverloadId##Matcher                           \ | ||
| 273 |       : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> {   \ | ||
| 274 |   public:                                                                      \ | ||
| 275 |     explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \ | ||
| 276 |         ParamType const &A##Param)                                             \ | ||
| 277 |         : Param(A##Param) {}                                                   \ | ||
| 278 |     bool matches(const NodeType &Node,                                         \ | ||
| 279 |                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \ | ||
| 280 |                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \ | ||
| 281 |                      *Builder) const override;                                 \ | ||
| 282 |                                                                                \ | ||
| 283 |   private:                                                                     \ | ||
| 284 |     ParamType Param;                                                           \ | ||
| 285 |   };                                                                           \ | ||
| 286 |   }                                                                            \ | ||
| 287 |   inline ::clang::ast_matchers::internal::PolymorphicMatcher<                  \ | ||
| 288 |       internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,    \ | ||
| 289 |       ParamType>                                                               \ | ||
| 290 |   DefineMatcher(ParamType const &Param) {                                      \ | ||
| 291 |     return ::clang::ast_matchers::internal::PolymorphicMatcher<                \ | ||
| 292 |         internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,  \ | ||
| 293 |         ParamType>(Param);                                                     \ | ||
| 294 |   }                                                                            \ | ||
| 295 |   typedef ::clang::ast_matchers::internal::PolymorphicMatcher<                 \ | ||
| 296 |       internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,    \ | ||
| 297 |       ParamType> (&DefineMatcher##_Type##OverloadId)(ParamType const &Param);  \ | ||
| 298 |   template <typename NodeType, typename ParamT>                                \ | ||
| 299 |   bool internal::                                                              \ | ||
| 300 |       matcher_##DefineMatcher##OverloadId##Matcher<NodeType, ParamT>::matches( \ | ||
| 301 |           const NodeType &Node,                                                \ | ||
| 302 |           ::clang::ast_matchers::internal::ASTMatchFinder *Finder,             \ | ||
| 303 |           ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder)     \ | ||
| 304 |           const | ||
| 305 | |||
| 306 | /// AST_POLYMORPHIC_MATCHER_P2( | ||
| 307 | ///     DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... } | ||
| 308 | /// defines a two-parameter function named matcher() that is polymorphic in | ||
| 309 | /// the return type. | ||
| 310 | /// | ||
| 311 | /// The variables are the same as for AST_MATCHER_P2, with the | ||
| 312 | /// addition of NodeType, which specifies the node type of the matcher | ||
| 313 | /// Matcher<NodeType> returned by the function DefineMatcher(). | ||
| 314 | #define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ReturnTypesF, ParamType1,    \ | ||
| 315 |                                    Param1, ParamType2, Param2)                 \ | ||
| 316 |   AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType1, \ | ||
| 317 |                                       Param1, ParamType2, Param2, 0) | ||
| 318 | |||
| 319 | #define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF,       \ | ||
| 320 |                                             ParamType1, Param1, ParamType2,    \ | ||
| 321 |                                             Param2, OverloadId)                \ | ||
| 322 |   namespace internal {                                                         \ | ||
| 323 |   template <typename NodeType, typename ParamT1, typename ParamT2>             \ | ||
| 324 |   class matcher_##DefineMatcher##OverloadId##Matcher                           \ | ||
| 325 |       : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> {   \ | ||
| 326 |   public:                                                                      \ | ||
| 327 |     matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1,  \ | ||
| 328 |                                                  ParamType2 const &A##Param2)  \ | ||
| 329 |         : Param1(A##Param1), Param2(A##Param2) {}                              \ | ||
| 330 |     bool matches(const NodeType &Node,                                         \ | ||
| 331 |                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \ | ||
| 332 |                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \ | ||
| 333 |                      *Builder) const override;                                 \ | ||
| 334 |                                                                                \ | ||
| 335 |   private:                                                                     \ | ||
| 336 |     ParamType1 Param1;                                                         \ | ||
| 337 |     ParamType2 Param2;                                                         \ | ||
| 338 |   };                                                                           \ | ||
| 339 |   }                                                                            \ | ||
| 340 |   inline ::clang::ast_matchers::internal::PolymorphicMatcher<                  \ | ||
| 341 |       internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,    \ | ||
| 342 |       ParamType1, ParamType2>                                                  \ | ||
| 343 |   DefineMatcher(ParamType1 const &Param1, ParamType2 const &Param2) {          \ | ||
| 344 |     return ::clang::ast_matchers::internal::PolymorphicMatcher<                \ | ||
| 345 |         internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,  \ | ||
| 346 |         ParamType1, ParamType2>(Param1, Param2);                               \ | ||
| 347 |   }                                                                            \ | ||
| 348 |   typedef ::clang::ast_matchers::internal::PolymorphicMatcher<                 \ | ||
| 349 |       internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,    \ | ||
| 350 |       ParamType1, ParamType2> (&DefineMatcher##_Type##OverloadId)(             \ | ||
| 351 |       ParamType1 const &Param1, ParamType2 const &Param2);                     \ | ||
| 352 |   template <typename NodeType, typename ParamT1, typename ParamT2>             \ | ||
| 353 |   bool internal::matcher_##DefineMatcher##OverloadId##Matcher<                 \ | ||
| 354 |       NodeType, ParamT1, ParamT2>::                                            \ | ||
| 355 |       matches(const NodeType &Node,                                            \ | ||
| 356 |               ::clang::ast_matchers::internal::ASTMatchFinder *Finder,         \ | ||
| 357 |               ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) \ | ||
| 358 |           const | ||
| 359 | |||
| 360 | // FIXME: add a matcher for TypeLoc derived classes using its custom casting | ||
| 361 | // API (no longer dyn_cast) if/when we need such matching | ||
| 362 | |||
| 363 | #define AST_TYPE_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName,              \ | ||
| 364 |                                        ReturnTypesF)                           \ | ||
| 365 |   namespace internal {                                                         \ | ||
| 366 |   template <typename T> struct TypeMatcher##MatcherName##Getter {              \ | ||
| 367 |     static QualType (T::*value())() const { return &T::FunctionName; }         \ | ||
| 368 |   };                                                                           \ | ||
| 369 |   }                                                                            \ | ||
| 370 |   extern const ::clang::ast_matchers::internal::                               \ | ||
| 371 |       TypeTraversePolymorphicMatcher<                                          \ | ||
| 372 |           QualType,                                                            \ | ||
| 373 |           ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter,   \ | ||
| 374 |           ::clang::ast_matchers::internal::TypeTraverseMatcher,                \ | ||
| 375 |           ReturnTypesF>::Func MatcherName | ||
| 376 | |||
| 377 | #define AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF)               \ | ||
| 378 |   const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher<       \ | ||
| 379 |       QualType,                                                                \ | ||
| 380 |       ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter,       \ | ||
| 381 |       ::clang::ast_matchers::internal::TypeTraverseMatcher,                    \ | ||
| 382 |       ReturnTypesF>::Func MatcherName | ||
| 383 | |||
| 384 | /// AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines | ||
| 385 | /// the matcher \c MatcherName that can be used to traverse from one \c Type | ||
| 386 | /// to another. | ||
| 387 | /// | ||
| 388 | /// For a specific \c SpecificType, the traversal is done using | ||
| 389 | /// \c SpecificType::FunctionName. The existence of such a function determines | ||
| 390 | /// whether a corresponding matcher can be used on \c SpecificType. | ||
| 391 | #define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF)     \ | ||
| 392 |   namespace internal {                                                         \ | ||
| 393 |   template <typename T> struct TypeMatcher##MatcherName##Getter {              \ | ||
| 394 |     static QualType (T::*value())() const { return &T::FunctionName; }         \ | ||
| 395 |   };                                                                           \ | ||
| 396 |   }                                                                            \ | ||
| 397 |   const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher<       \ | ||
| 398 |       QualType,                                                                \ | ||
| 399 |       ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter,       \ | ||
| 400 |       ::clang::ast_matchers::internal::TypeTraverseMatcher,                    \ | ||
| 401 |       ReturnTypesF>::Func MatcherName | ||
| 402 | |||
| 403 | #define AST_TYPELOC_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName,           \ | ||
| 404 |                                           ReturnTypesF)                        \ | ||
| 405 |   namespace internal {                                                         \ | ||
| 406 |   template <typename T> struct TypeLocMatcher##MatcherName##Getter {           \ | ||
| 407 |     static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; }     \ | ||
| 408 |   };                                                                           \ | ||
| 409 |   }                                                                            \ | ||
| 410 |   extern const ::clang::ast_matchers::internal::                               \ | ||
| 411 |       TypeTraversePolymorphicMatcher<                                          \ | ||
| 412 |           TypeLoc,                                                             \ | ||
| 413 |           ::clang::ast_matchers::internal::                                    \ | ||
| 414 |               TypeLocMatcher##MatcherName##Getter,                             \ | ||
| 415 |           ::clang::ast_matchers::internal::TypeLocTraverseMatcher,             \ | ||
| 416 |           ReturnTypesF>::Func MatcherName##Loc;                                \ | ||
| 417 |   AST_TYPE_TRAVERSE_MATCHER_DECL(MatcherName, FunctionName##Type, ReturnTypesF) | ||
| 418 | |||
| 419 | #define AST_TYPELOC_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF)            \ | ||
| 420 |   const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher<       \ | ||
| 421 |       TypeLoc,                                                                 \ | ||
| 422 |       ::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter,    \ | ||
| 423 |       ::clang::ast_matchers::internal::TypeLocTraverseMatcher,                 \ | ||
| 424 |       ReturnTypesF>::Func MatcherName##Loc;                                    \ | ||
| 425 |   AST_TYPE_TRAVERSE_MATCHER_DEF(MatcherName, ReturnTypesF) | ||
| 426 | |||
| 427 | /// AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works | ||
| 428 | /// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs. | ||
| 429 | #define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF)  \ | ||
| 430 |   namespace internal {                                                         \ | ||
| 431 |   template <typename T> struct TypeLocMatcher##MatcherName##Getter {           \ | ||
| 432 |     static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; }     \ | ||
| 433 |   };                                                                           \ | ||
| 434 |   }                                                                            \ | ||
| 435 |   const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher<       \ | ||
| 436 |       TypeLoc,                                                                 \ | ||
| 437 |       ::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter,    \ | ||
| 438 |       ::clang::ast_matchers::internal::TypeLocTraverseMatcher,                 \ | ||
| 439 |       ReturnTypesF>::Func MatcherName##Loc;                                    \ | ||
| 440 |   AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF) | ||
| 441 | |||
| 442 | /// AST_MATCHER_REGEX(Type, DefineMatcher, Param) { ... } | ||
| 443 | /// defines a function named DefineMatcher() that takes a regular expression | ||
| 444 | /// string paramater and an optional RegexFlags parameter and returns a | ||
| 445 | /// Matcher<Type> object. | ||
| 446 | /// | ||
| 447 | /// The code between the curly braces has access to the following variables: | ||
| 448 | /// | ||
| 449 | ///   Node:                  the AST node being matched; its type is Type. | ||
| 450 | ///   Param:                 a pointer to an \ref llvm::Regex object | ||
| 451 | ///   Finder:                an ASTMatchFinder*. | ||
| 452 | ///   Builder:               a BoundNodesTreeBuilder*. | ||
| 453 | /// | ||
| 454 | /// The code should return true if 'Node' matches. | ||
| 455 | #define AST_MATCHER_REGEX(Type, DefineMatcher, Param)                          \ | ||
| 456 |   AST_MATCHER_REGEX_OVERLOAD(Type, DefineMatcher, Param, 0) | ||
| 457 | |||
| 458 | #define AST_MATCHER_REGEX_OVERLOAD(Type, DefineMatcher, Param, OverloadId)     \ | ||
| 459 |   namespace internal {                                                         \ | ||
| 460 |   class matcher_##DefineMatcher##OverloadId##Matcher                           \ | ||
| 461 |       : public ::clang::ast_matchers::internal::MatcherInterface<Type> {       \ | ||
| 462 |   public:                                                                      \ | ||
| 463 |     explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \ | ||
| 464 |         std::shared_ptr<llvm::Regex> RE)                                       \ | ||
| 465 |         : Param(std::move(RE)) {}                                              \ | ||
| 466 |     bool matches(const Type &Node,                                             \ | ||
| 467 |                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \ | ||
| 468 |                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \ | ||
| 469 |                      *Builder) const override;                                 \ | ||
| 470 |                                                                                \ | ||
| 471 |   private:                                                                     \ | ||
| 472 |     std::shared_ptr<llvm::Regex> Param;                                        \ | ||
| 473 |   };                                                                           \ | ||
| 474 |   }                                                                            \ | ||
| 475 |   inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher(         \ | ||
| 476 |       llvm::StringRef Param, llvm::Regex::RegexFlags RegexFlags) {             \ | ||
| 477 |     return ::clang::ast_matchers::internal::makeMatcher(                       \ | ||
| 478 |         new internal::matcher_##DefineMatcher##OverloadId##Matcher(            \ | ||
| 479 |             ::clang::ast_matchers::internal::createAndVerifyRegex(             \ | ||
| 480 |                 Param, RegexFlags, #DefineMatcher)));                          \ | ||
| 481 |   }                                                                            \ | ||
| 482 |   inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher(         \ | ||
| 483 |       llvm::StringRef Param) {                                                 \ | ||
| 484 |     return DefineMatcher(Param, llvm::Regex::NoFlags);                         \ | ||
| 485 |   }                                                                            \ | ||
| 486 |                                                                                \ | ||
| 487 |   typedef ::clang::ast_matchers::internal::Matcher<Type> (                     \ | ||
| 488 |       &DefineMatcher##_Type##OverloadId##Flags)(llvm::StringRef,               \ | ||
| 489 |                                                 llvm::Regex::RegexFlags);      \ | ||
| 490 |   typedef ::clang::ast_matchers::internal::Matcher<Type> (                     \ | ||
| 491 |       &DefineMatcher##_Type##OverloadId)(llvm::StringRef);                     \ | ||
| 492 |   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \ | ||
| 493 |       const Type &Node,                                                        \ | ||
| 494 |       ::clang::ast_matchers::internal::ASTMatchFinder *Finder,                 \ | ||
| 495 |       ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const | ||
| 496 | |||
| 497 | /// AST_POLYMORPHIC_MATCHER_REGEX(DefineMatcher, ReturnTypesF, Param) { ... } | ||
| 498 | /// defines a function named DefineMatcher() that takes a regular expression | ||
| 499 | /// string paramater and an optional RegexFlags parameter that is polymorphic in | ||
| 500 | /// the return type. | ||
| 501 | /// | ||
| 502 | /// The variables are the same as for | ||
| 503 | /// AST_MATCHER_REGEX, with the addition of NodeType, which specifies the node | ||
| 504 | /// type of the matcher Matcher<NodeType> returned by the function matcher(). | ||
| 505 | #define AST_POLYMORPHIC_MATCHER_REGEX(DefineMatcher, ReturnTypesF, Param)      \ | ||
| 506 |   AST_POLYMORPHIC_MATCHER_REGEX_OVERLOAD(DefineMatcher, ReturnTypesF, Param, 0) | ||
| 507 | |||
| 508 | #define AST_POLYMORPHIC_MATCHER_REGEX_OVERLOAD(DefineMatcher, ReturnTypesF,    \ | ||
| 509 |                                                Param, OverloadId)              \ | ||
| 510 |   namespace internal {                                                         \ | ||
| 511 |   template <typename NodeType, typename ParamT>                                \ | ||
| 512 |   class matcher_##DefineMatcher##OverloadId##Matcher                           \ | ||
| 513 |       : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> {   \ | ||
| 514 |   public:                                                                      \ | ||
| 515 |     explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \ | ||
| 516 |         std::shared_ptr<llvm::Regex> RE)                                       \ | ||
| 517 |         : Param(std::move(RE)) {}                                              \ | ||
| 518 |     bool matches(const NodeType &Node,                                         \ | ||
| 519 |                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \ | ||
| 520 |                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \ | ||
| 521 |                      *Builder) const override;                                 \ | ||
| 522 |                                                                                \ | ||
| 523 |   private:                                                                     \ | ||
| 524 |     std::shared_ptr<llvm::Regex> Param;                                        \ | ||
| 525 |   };                                                                           \ | ||
| 526 |   }                                                                            \ | ||
| 527 |   inline ::clang::ast_matchers::internal::PolymorphicMatcher<                  \ | ||
| 528 |       internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,    \ | ||
| 529 |       std::shared_ptr<llvm::Regex>>                                            \ | ||
| 530 |   DefineMatcher(llvm::StringRef Param, llvm::Regex::RegexFlags RegexFlags) {   \ | ||
| 531 |     return ::clang::ast_matchers::internal::PolymorphicMatcher<                \ | ||
| 532 |         internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,  \ | ||
| 533 |         std::shared_ptr<llvm::Regex>>(                                         \ | ||
| 534 |         ::clang::ast_matchers::internal::createAndVerifyRegex(                 \ | ||
| 535 |             Param, RegexFlags, #DefineMatcher));                               \ | ||
| 536 |   }                                                                            \ | ||
| 537 |   inline ::clang::ast_matchers::internal::PolymorphicMatcher<                  \ | ||
| 538 |       internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,    \ | ||
| 539 |       std::shared_ptr<llvm::Regex>>                                            \ | ||
| 540 |   DefineMatcher(llvm::StringRef Param) {                                       \ | ||
| 541 |     return DefineMatcher(Param, llvm::Regex::NoFlags);                         \ | ||
| 542 |   }                                                                            \ | ||
| 543 |   typedef ::clang::ast_matchers::internal::PolymorphicMatcher<                 \ | ||
| 544 |       internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,    \ | ||
| 545 |       std::shared_ptr<llvm::Regex>> (                                          \ | ||
| 546 |       &DefineMatcher##_Type##OverloadId##Flags)(                               \ | ||
| 547 |       llvm::StringRef Param, llvm::Regex::RegexFlags RegexFlags);              \ | ||
| 548 |   typedef ::clang::ast_matchers::internal::PolymorphicMatcher<                 \ | ||
| 549 |       internal::matcher_##DefineMatcher##OverloadId##Matcher, ReturnTypesF,    \ | ||
| 550 |       std::shared_ptr<llvm::Regex>> (&DefineMatcher##_Type##OverloadId)(       \ | ||
| 551 |       llvm::StringRef Param);                                                  \ | ||
| 552 |   template <typename NodeType, typename ParamT>                                \ | ||
| 553 |   bool internal::                                                              \ | ||
| 554 |       matcher_##DefineMatcher##OverloadId##Matcher<NodeType, ParamT>::matches( \ | ||
| 555 |           const NodeType &Node,                                                \ | ||
| 556 |           ::clang::ast_matchers::internal::ASTMatchFinder *Finder,             \ | ||
| 557 |           ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder)     \ | ||
| 558 |           const | ||
| 559 | |||
| 560 | #endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H |