Home | History | Annotate | Download | only in ASTMatchers
      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, put it into your own namespace. This would
     24 //  help to prevent ODR violations in case a matcher with the same name is
     25 //  defined in multiple translation units:
     26 //
     27 //  namespace my_matchers {
     28 //  AST_MATCHER_P(clang::MemberExpr, Member,
     29 //                clang::ast_matchers::internal::Matcher<clang::ValueDecl>,
     30 //                InnerMatcher) {
     31 //    return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
     32 //  }
     33 //  } // namespace my_matchers
     34 //
     35 //  Alternatively, an unnamed namespace may be used:
     36 //
     37 //  namespace clang {
     38 //  namespace ast_matchers {
     39 //  namespace {
     40 //  AST_MATCHER_P(MemberExpr, Member,
     41 //                internal::Matcher<ValueDecl>, InnerMatcher) {
     42 //    return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
     43 //  }
     44 //  } // namespace
     45 //  } // namespace ast_matchers
     46 //  } // namespace clang
     47 //
     48 //===----------------------------------------------------------------------===//
     49 
     50 #ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
     51 #define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
     52 
     53 /// \brief AST_MATCHER_FUNCTION(ReturnType, DefineMatcher) { ... }
     54 /// defines a zero parameter function named DefineMatcher() that returns a
     55 /// ReturnType object.
     56 #define AST_MATCHER_FUNCTION(ReturnType, DefineMatcher)                        \
     57   inline ReturnType DefineMatcher##_getInstance();                             \
     58   inline ReturnType DefineMatcher() {                                          \
     59     return ::clang::ast_matchers::internal::MemoizedMatcher<                   \
     60         ReturnType, DefineMatcher##_getInstance>::getInstance();               \
     61   }                                                                            \
     62   inline ReturnType DefineMatcher##_getInstance()
     63 
     64 /// \brief AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) {
     65 /// ... }
     66 /// defines a single-parameter function named DefineMatcher() that returns a
     67 /// ReturnType object.
     68 ///
     69 /// The code between the curly braces has access to the following variables:
     70 ///
     71 ///   Param:                 the parameter passed to the function; its type
     72 ///                          is ParamType.
     73 ///
     74 /// The code should return an instance of ReturnType.
     75 #define AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param)    \
     76   AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, Param, \
     77                                   0)
     78 #define AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType,  \
     79                                         Param, OverloadId)                     \
     80   inline ReturnType DefineMatcher(ParamType const &Param);                     \
     81   typedef ReturnType (&DefineMatcher##_Type##OverloadId)(ParamType const &);   \
     82   inline ReturnType DefineMatcher(ParamType const &Param)
     83 
     84 /// \brief AST_MATCHER(Type, DefineMatcher) { ... }
     85 /// defines a zero parameter function named DefineMatcher() that returns a
     86 /// Matcher<Type> object.
     87 ///
     88 /// The code between the curly braces has access to the following variables:
     89 ///
     90 ///   Node:                  the AST node being matched; its type is Type.
     91 ///   Finder:                an ASTMatchFinder*.
     92 ///   Builder:               a BoundNodesTreeBuilder*.
     93 ///
     94 /// The code should return true if 'Node' matches.
     95 #define AST_MATCHER(Type, DefineMatcher)                                       \
     96   namespace internal {                                                         \
     97   class matcher_##DefineMatcher##Matcher                                       \
     98       : public ::clang::ast_matchers::internal::MatcherInterface<Type> {       \
     99   public:                                                                      \
    100     explicit matcher_##DefineMatcher##Matcher() = default;                     \
    101     bool matches(const Type &Node,                                             \
    102                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \
    103                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \
    104                      *Builder) const override;                                 \
    105   };                                                                           \
    106   }                                                                            \
    107   inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher() {      \
    108     return ::clang::ast_matchers::internal::makeMatcher(                       \
    109         new internal::matcher_##DefineMatcher##Matcher());                     \
    110   }                                                                            \
    111   inline bool internal::matcher_##DefineMatcher##Matcher::matches(             \
    112       const Type &Node,                                                        \
    113       ::clang::ast_matchers::internal::ASTMatchFinder *Finder,                 \
    114       ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
    115 
    116 /// \brief AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... }
    117 /// defines a single-parameter function named DefineMatcher() that returns a
    118 /// Matcher<Type> object.
    119 ///
    120 /// The code between the curly braces has access to the following variables:
    121 ///
    122 ///   Node:                  the AST node being matched; its type is Type.
    123 ///   Param:                 the parameter passed to the function; its type
    124 ///                          is ParamType.
    125 ///   Finder:                an ASTMatchFinder*.
    126 ///   Builder:               a BoundNodesTreeBuilder*.
    127 ///
    128 /// The code should return true if 'Node' matches.
    129 #define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param)                   \
    130   AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, 0)
    131 
    132 #define AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param,          \
    133                                OverloadId)                                     \
    134   namespace internal {                                                         \
    135   class matcher_##DefineMatcher##OverloadId##Matcher                           \
    136       : public ::clang::ast_matchers::internal::MatcherInterface<Type> {       \
    137   public:                                                                      \
    138     explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
    139         ParamType const &A##Param)                                             \
    140         : Param(A##Param) {}                                                   \
    141     bool matches(const Type &Node,                                             \
    142                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \
    143                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \
    144                      *Builder) const override;                                 \
    145                                                                                \
    146   private:                                                                     \
    147     ParamType const Param;                                                     \
    148   };                                                                           \
    149   }                                                                            \
    150   inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher(         \
    151       ParamType const &Param) {                                                \
    152     return ::clang::ast_matchers::internal::makeMatcher(                       \
    153         new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param));    \
    154   }                                                                            \
    155   typedef ::clang::ast_matchers::internal::Matcher<Type>(                      \
    156       &DefineMatcher##_Type##OverloadId)(ParamType const &Param);              \
    157   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
    158       const Type &Node,                                                        \
    159       ::clang::ast_matchers::internal::ASTMatchFinder *Finder,                 \
    160       ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
    161 
    162 /// \brief AST_MATCHER_P2(
    163 ///     Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
    164 /// defines a two-parameter function named DefineMatcher() that returns a
    165 /// Matcher<Type> object.
    166 ///
    167 /// The code between the curly braces has access to the following variables:
    168 ///
    169 ///   Node:                  the AST node being matched; its type is Type.
    170 ///   Param1, Param2:        the parameters passed to the function; their types
    171 ///                          are ParamType1 and ParamType2.
    172 ///   Finder:                an ASTMatchFinder*.
    173 ///   Builder:               a BoundNodesTreeBuilder*.
    174 ///
    175 /// The code should return true if 'Node' matches.
    176 #define AST_MATCHER_P2(Type, DefineMatcher, ParamType1, Param1, ParamType2,    \
    177                        Param2)                                                 \
    178   AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
    179                           Param2, 0)
    180 
    181 #define AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1,       \
    182                                 ParamType2, Param2, OverloadId)                \
    183   namespace internal {                                                         \
    184   class matcher_##DefineMatcher##OverloadId##Matcher                           \
    185       : public ::clang::ast_matchers::internal::MatcherInterface<Type> {       \
    186   public:                                                                      \
    187     matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1,  \
    188                                                  ParamType2 const &A##Param2)  \
    189         : Param1(A##Param1), Param2(A##Param2) {}                              \
    190     bool matches(const Type &Node,                                             \
    191                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \
    192                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \
    193                      *Builder) const override;                                 \
    194                                                                                \
    195   private:                                                                     \
    196     ParamType1 const Param1;                                                   \
    197     ParamType2 const Param2;                                                   \
    198   };                                                                           \
    199   }                                                                            \
    200   inline ::clang::ast_matchers::internal::Matcher<Type> DefineMatcher(         \
    201       ParamType1 const &Param1, ParamType2 const &Param2) {                    \
    202     return ::clang::ast_matchers::internal::makeMatcher(                       \
    203         new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1,     \
    204                                                                    Param2));   \
    205   }                                                                            \
    206   typedef ::clang::ast_matchers::internal::Matcher<Type>(                      \
    207       &DefineMatcher##_Type##OverloadId)(ParamType1 const &Param1,             \
    208                                          ParamType2 const &Param2);            \
    209   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
    210       const Type &Node,                                                        \
    211       ::clang::ast_matchers::internal::ASTMatchFinder *Finder,                 \
    212       ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
    213 
    214 /// \brief Construct a type-list to be passed to the AST_POLYMORPHIC_MATCHER*
    215 ///   macros.
    216 ///
    217 /// You can't pass something like \c TypeList<Foo, Bar> to a macro, because it
    218 /// will look at that as two arguments. However, you can pass
    219 /// \c void(TypeList<Foo, Bar>), which works thanks to the parenthesis.
    220 /// The \c PolymorphicMatcherWithParam* classes will unpack the function type to
    221 /// extract the TypeList object.
    222 #define AST_POLYMORPHIC_SUPPORTED_TYPES(...)                                   \
    223   void(::clang::ast_matchers::internal::TypeList<__VA_ARGS__>)
    224 
    225 /// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... }
    226 /// defines a single-parameter function named DefineMatcher() that is
    227 /// polymorphic in the return type.
    228 ///
    229 /// The variables are the same as for AST_MATCHER, but NodeType will be deduced
    230 /// from the calling context.
    231 #define AST_POLYMORPHIC_MATCHER(DefineMatcher, ReturnTypesF)                   \
    232   namespace internal {                                                         \
    233   template <typename NodeType>                                                 \
    234   class matcher_##DefineMatcher##Matcher                                       \
    235       : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> {   \
    236   public:                                                                      \
    237     bool matches(const NodeType &Node,                                         \
    238                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \
    239                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \
    240                      *Builder) const override;                                 \
    241   };                                                                           \
    242   }                                                                            \
    243   inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam0<        \
    244       internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>                \
    245   DefineMatcher() {                                                            \
    246     return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam0<      \
    247         internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>();           \
    248   }                                                                            \
    249   template <typename NodeType>                                                 \
    250   bool internal::matcher_##DefineMatcher##Matcher<NodeType>::matches(          \
    251       const NodeType &Node,                                                    \
    252       ::clang::ast_matchers::internal::ASTMatchFinder *Finder,                 \
    253       ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) const
    254 
    255 /// \brief AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... }
    256 /// defines a single-parameter function named DefineMatcher() that is
    257 /// polymorphic in the return type.
    258 ///
    259 /// The variables are the same as for
    260 /// AST_MATCHER_P, with the addition of NodeType, which specifies the node type
    261 /// of the matcher Matcher<NodeType> returned by the function matcher().
    262 ///
    263 /// FIXME: Pull out common code with above macro?
    264 #define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ReturnTypesF, ParamType,      \
    265                                   Param)                                       \
    266   AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType,   \
    267                                      Param, 0)
    268 
    269 #define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF,        \
    270                                            ParamType, Param, OverloadId)       \
    271   namespace internal {                                                         \
    272   template <typename NodeType, typename ParamT>                                \
    273   class matcher_##DefineMatcher##OverloadId##Matcher                           \
    274       : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> {   \
    275   public:                                                                      \
    276     explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
    277         ParamType const &A##Param)                                             \
    278         : Param(A##Param) {}                                                   \
    279     bool matches(const NodeType &Node,                                         \
    280                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \
    281                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \
    282                      *Builder) const override;                                 \
    283                                                                                \
    284   private:                                                                     \
    285     ParamType const Param;                                                     \
    286   };                                                                           \
    287   }                                                                            \
    288   inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1<        \
    289       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,       \
    290       ReturnTypesF>                                                            \
    291   DefineMatcher(ParamType const &Param) {                                      \
    292     return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1<      \
    293         internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,     \
    294         ReturnTypesF>(Param);                                                  \
    295   }                                                                            \
    296   typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam1<       \
    297       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,       \
    298       ReturnTypesF>(&DefineMatcher##_Type##OverloadId)(                        \
    299       ParamType const &Param);                                                 \
    300   template <typename NodeType, typename ParamT>                                \
    301   bool internal::                                                              \
    302       matcher_##DefineMatcher##OverloadId##Matcher<NodeType, ParamT>::matches( \
    303           const NodeType &Node,                                                \
    304           ::clang::ast_matchers::internal::ASTMatchFinder *Finder,             \
    305           ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder)     \
    306           const
    307 
    308 /// \brief AST_POLYMORPHIC_MATCHER_P2(
    309 ///     DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
    310 /// defines a two-parameter function named matcher() that is polymorphic in
    311 /// the return type.
    312 ///
    313 /// The variables are the same as for AST_MATCHER_P2, with the
    314 /// addition of NodeType, which specifies the node type of the matcher
    315 /// Matcher<NodeType> returned by the function DefineMatcher().
    316 #define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ReturnTypesF, ParamType1,    \
    317                                    Param1, ParamType2, Param2)                 \
    318   AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType1, \
    319                                       Param1, ParamType2, Param2, 0)
    320 
    321 #define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF,       \
    322                                             ParamType1, Param1, ParamType2,    \
    323                                             Param2, OverloadId)                \
    324   namespace internal {                                                         \
    325   template <typename NodeType, typename ParamT1, typename ParamT2>             \
    326   class matcher_##DefineMatcher##OverloadId##Matcher                           \
    327       : public ::clang::ast_matchers::internal::MatcherInterface<NodeType> {   \
    328   public:                                                                      \
    329     matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1,  \
    330                                                  ParamType2 const &A##Param2)  \
    331         : Param1(A##Param1), Param2(A##Param2) {}                              \
    332     bool matches(const NodeType &Node,                                         \
    333                  ::clang::ast_matchers::internal::ASTMatchFinder *Finder,      \
    334                  ::clang::ast_matchers::internal::BoundNodesTreeBuilder        \
    335                      *Builder) const override;                                 \
    336                                                                                \
    337   private:                                                                     \
    338     ParamType1 const Param1;                                                   \
    339     ParamType2 const Param2;                                                   \
    340   };                                                                           \
    341   }                                                                            \
    342   inline ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2<        \
    343       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,      \
    344       ParamType2, ReturnTypesF>                                                \
    345   DefineMatcher(ParamType1 const &Param1, ParamType2 const &Param2) {          \
    346     return ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2<      \
    347         internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,    \
    348         ParamType2, ReturnTypesF>(Param1, Param2);                             \
    349   }                                                                            \
    350   typedef ::clang::ast_matchers::internal::PolymorphicMatcherWithParam2<       \
    351       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,      \
    352       ParamType2, ReturnTypesF>(&DefineMatcher##_Type##OverloadId)(            \
    353       ParamType1 const &Param1, ParamType2 const &Param2);                     \
    354   template <typename NodeType, typename ParamT1, typename ParamT2>             \
    355   bool internal::matcher_##DefineMatcher##OverloadId##Matcher<                 \
    356       NodeType, ParamT1, ParamT2>::                                            \
    357       matches(const NodeType &Node,                                            \
    358               ::clang::ast_matchers::internal::ASTMatchFinder *Finder,         \
    359               ::clang::ast_matchers::internal::BoundNodesTreeBuilder *Builder) \
    360           const
    361 
    362 /// \brief Creates a variadic matcher for both a specific \c Type as well as
    363 /// the corresponding \c TypeLoc.
    364 #define AST_TYPE_MATCHER(NodeType, MatcherName)                                \
    365   const ::clang::ast_matchers::internal::VariadicDynCastAllOfMatcher<          \
    366       Type, NodeType> MatcherName
    367 // FIXME: add a matcher for TypeLoc derived classes using its custom casting
    368 // API (no longer dyn_cast) if/when we need such matching
    369 
    370 /// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
    371 /// the matcher \c MatcherName that can be used to traverse from one \c Type
    372 /// to another.
    373 ///
    374 /// For a specific \c SpecificType, the traversal is done using
    375 /// \c SpecificType::FunctionName. The existence of such a function determines
    376 /// whether a corresponding matcher can be used on \c SpecificType.
    377 #define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF)     \
    378   namespace internal {                                                         \
    379   template <typename T> struct TypeMatcher##MatcherName##Getter {              \
    380     static QualType (T::*value())() const { return &T::FunctionName; }         \
    381   };                                                                           \
    382   }                                                                            \
    383   const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher<       \
    384       QualType,                                                                \
    385       ::clang::ast_matchers::internal::TypeMatcher##MatcherName##Getter,       \
    386       ::clang::ast_matchers::internal::TypeTraverseMatcher,                    \
    387       ReturnTypesF>::Func MatcherName
    388 
    389 /// \brief AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works
    390 /// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs.
    391 #define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF)  \
    392   namespace internal {                                                         \
    393   template <typename T> struct TypeLocMatcher##MatcherName##Getter {           \
    394     static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; }     \
    395   };                                                                           \
    396   }                                                                            \
    397   const ::clang::ast_matchers::internal::TypeTraversePolymorphicMatcher<       \
    398       TypeLoc,                                                                 \
    399       ::clang::ast_matchers::internal::TypeLocMatcher##MatcherName##Getter,    \
    400       ::clang::ast_matchers::internal::TypeLocTraverseMatcher,                 \
    401       ReturnTypesF>::Func MatcherName##Loc;                                    \
    402   AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF)
    403 
    404 #endif // LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
    405