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