clang API Documentation

ASTMatchersMacros.h
Go to the documentation of this file.
00001 //===--- ASTMatchersMacros.h - Structural query framework -------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 //  Defines macros that enable us to define new matchers in a single place.
00011 //  Since a matcher is a function which returns a Matcher<T> object, where
00012 //  T is the type of the actual implementation of the matcher, the macros allow
00013 //  us to write matchers like functions and take care of the definition of the
00014 //  class boilerplate.
00015 //
00016 //  Note that when you define a matcher with an AST_MATCHER* macro, only the
00017 //  function which creates the matcher goes into the current namespace - the
00018 //  class that implements the actual matcher, which gets returned by the
00019 //  generator function, is put into the 'internal' namespace. This allows us
00020 //  to only have the functions (which is all the user cares about) in the
00021 //  'ast_matchers' namespace and hide the boilerplate.
00022 //
00023 //  To define a matcher in user code, always put it into the clang::ast_matchers
00024 //  namespace and refer to the internal types via the 'internal::':
00025 //
00026 //  namespace clang {
00027 //  namespace ast_matchers {
00028 //  AST_MATCHER_P(MemberExpr, Member,
00029 //                internal::Matcher<ValueDecl>, InnerMatcher) {
00030 //    return InnerMatcher.matches(*Node.getMemberDecl(), Finder, Builder);
00031 //  }
00032 //  } // end namespace ast_matchers
00033 //  } // end namespace clang
00034 //
00035 //===----------------------------------------------------------------------===//
00036 
00037 #ifndef LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
00038 #define LLVM_CLANG_ASTMATCHERS_ASTMATCHERSMACROS_H
00039 
00040 /// \brief AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param) {
00041 /// defines a single-parameter function named DefineMatcher() that returns a
00042 /// ReturnType object.
00043 ///
00044 /// The code between the curly braces has access to the following variables:
00045 ///
00046 ///   Param:                 the parameter passed to the function; its type
00047 ///                          is ParamType.
00048 ///
00049 /// The code should return an instance of ReturnType.
00050 #define AST_MATCHER_FUNCTION_P(ReturnType, DefineMatcher, ParamType, Param)    \
00051   AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType, Param, \
00052                                   0)
00053 #define AST_MATCHER_FUNCTION_P_OVERLOAD(ReturnType, DefineMatcher, ParamType,  \
00054                                         Param, OverloadId)                     \
00055   inline ReturnType DefineMatcher(ParamType const &Param);                     \
00056   typedef ReturnType (&DefineMatcher##_Type##OverloadId)(ParamType const &);   \
00057   inline ReturnType DefineMatcher(ParamType const &Param)
00058 
00059 /// \brief AST_MATCHER(Type, DefineMatcher) { ... }
00060 /// defines a zero parameter function named DefineMatcher() that returns a
00061 /// Matcher<Type> object.
00062 ///
00063 /// The code between the curly braces has access to the following variables:
00064 ///
00065 ///   Node:                  the AST node being matched; its type is Type.
00066 ///   Finder:                an ASTMatchFinder*.
00067 ///   Builder:               a BoundNodesTreeBuilder*.
00068 ///
00069 /// The code should return true if 'Node' matches.
00070 #define AST_MATCHER(Type, DefineMatcher)                                       \
00071   namespace internal {                                                         \
00072   class matcher_##DefineMatcher##Matcher : public MatcherInterface<Type> {     \
00073   public:                                                                      \
00074     explicit matcher_##DefineMatcher##Matcher() {}                             \
00075     bool matches(const Type &Node, ASTMatchFinder *Finder,                     \
00076                  BoundNodesTreeBuilder *Builder) const override;               \
00077   };                                                                           \
00078   }                                                                            \
00079   inline internal::Matcher<Type> DefineMatcher() {                             \
00080     return internal::makeMatcher(                                              \
00081         new internal::matcher_##DefineMatcher##Matcher());                     \
00082   }                                                                            \
00083   inline bool internal::matcher_##DefineMatcher##Matcher::matches(             \
00084       const Type &Node, ASTMatchFinder *Finder,                                \
00085       BoundNodesTreeBuilder *Builder) const
00086 
00087 /// \brief AST_MATCHER_P(Type, DefineMatcher, ParamType, Param) { ... }
00088 /// defines a single-parameter function named DefineMatcher() that returns a
00089 /// Matcher<Type> object.
00090 ///
00091 /// The code between the curly braces has access to the following variables:
00092 ///
00093 ///   Node:                  the AST node being matched; its type is Type.
00094 ///   Param:                 the parameter passed to the function; its type
00095 ///                          is ParamType.
00096 ///   Finder:                an ASTMatchFinder*.
00097 ///   Builder:               a BoundNodesTreeBuilder*.
00098 ///
00099 /// The code should return true if 'Node' matches.
00100 #define AST_MATCHER_P(Type, DefineMatcher, ParamType, Param)                   \
00101   AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param, 0)
00102 
00103 #define AST_MATCHER_P_OVERLOAD(Type, DefineMatcher, ParamType, Param,          \
00104                                OverloadId)                                     \
00105   namespace internal {                                                         \
00106   class matcher_##DefineMatcher##OverloadId##Matcher                           \
00107       : public MatcherInterface<Type> {                                        \
00108   public:                                                                      \
00109     explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
00110         ParamType const &A##Param)                                             \
00111         : Param(A##Param) {}                                                   \
00112     bool matches(const Type &Node, ASTMatchFinder *Finder,                     \
00113                  BoundNodesTreeBuilder *Builder) const override;               \
00114                                                                                \
00115   private:                                                                     \
00116     ParamType const Param;                                                     \
00117   };                                                                           \
00118   }                                                                            \
00119   inline internal::Matcher<Type> DefineMatcher(ParamType const &Param) {       \
00120     return internal::makeMatcher(                                              \
00121         new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param));    \
00122   }                                                                            \
00123   typedef internal::Matcher<Type>(&DefineMatcher##_Type##OverloadId)(          \
00124       ParamType const &Param);                                                 \
00125   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
00126       const Type &Node, ASTMatchFinder *Finder,                                \
00127       BoundNodesTreeBuilder *Builder) const
00128 
00129 /// \brief AST_MATCHER_P2(
00130 ///     Type, DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
00131 /// defines a two-parameter function named DefineMatcher() that returns a
00132 /// Matcher<Type> object.
00133 ///
00134 /// The code between the curly braces has access to the following variables:
00135 ///
00136 ///   Node:                  the AST node being matched; its type is Type.
00137 ///   Param1, Param2:        the parameters passed to the function; their types
00138 ///                          are ParamType1 and ParamType2.
00139 ///   Finder:                an ASTMatchFinder*.
00140 ///   Builder:               a BoundNodesTreeBuilder*.
00141 ///
00142 /// The code should return true if 'Node' matches.
00143 #define AST_MATCHER_P2(Type, DefineMatcher, ParamType1, Param1, ParamType2,    \
00144                        Param2)                                                 \
00145   AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1, ParamType2, \
00146                           Param2, 0)
00147 
00148 #define AST_MATCHER_P2_OVERLOAD(Type, DefineMatcher, ParamType1, Param1,       \
00149                                 ParamType2, Param2, OverloadId)                \
00150   namespace internal {                                                         \
00151   class matcher_##DefineMatcher##OverloadId##Matcher                           \
00152       : public MatcherInterface<Type> {                                        \
00153   public:                                                                      \
00154     matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1,  \
00155                                                  ParamType2 const &A##Param2)  \
00156         : Param1(A##Param1), Param2(A##Param2) {}                              \
00157     bool matches(const Type &Node, ASTMatchFinder *Finder,                     \
00158                  BoundNodesTreeBuilder *Builder) const override;               \
00159                                                                                \
00160   private:                                                                     \
00161     ParamType1 const Param1;                                                   \
00162     ParamType2 const Param2;                                                   \
00163   };                                                                           \
00164   }                                                                            \
00165   inline internal::Matcher<Type> DefineMatcher(ParamType1 const &Param1,       \
00166                                                ParamType2 const &Param2) {     \
00167     return internal::makeMatcher(                                              \
00168         new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1,     \
00169                                                                    Param2));   \
00170   }                                                                            \
00171   typedef internal::Matcher<Type>(&DefineMatcher##_Type##OverloadId)(          \
00172       ParamType1 const &Param1, ParamType2 const &Param2);                     \
00173   inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \
00174       const Type &Node, ASTMatchFinder *Finder,                                \
00175       BoundNodesTreeBuilder *Builder) const
00176 
00177 /// \brief Construct a type-list to be passed to the AST_POLYMORPHIC_MATCHER*
00178 ///   macros.
00179 ///
00180 /// You can't pass something like \c TypeList<Foo, Bar> to a macro, because it
00181 /// will look at that as two arguments. However, you can pass
00182 /// \c void(TypeList<Foo, Bar>), which works thanks to the parenthesis.
00183 /// The \c PolymorphicMatcherWithParam* classes will unpack the function type to
00184 /// extract the TypeList object.
00185 #define AST_POLYMORPHIC_SUPPORTED_TYPES_1(t1) void(internal::TypeList<t1>)
00186 #define AST_POLYMORPHIC_SUPPORTED_TYPES_2(t1, t2)                              \
00187   void(internal::TypeList<t1, t2>)
00188 #define AST_POLYMORPHIC_SUPPORTED_TYPES_3(t1, t2, t3)                          \
00189   void(internal::TypeList<t1, t2, t3>)
00190 #define AST_POLYMORPHIC_SUPPORTED_TYPES_4(t1, t2, t3, t4)                      \
00191   void(internal::TypeList<t1, t2, t3, t4>)
00192 #define AST_POLYMORPHIC_SUPPORTED_TYPES_5(t1, t2, t3, t4, t5)                  \
00193   void(internal::TypeList<t1, t2, t3, internal::TypeList<t4, t5> >)
00194 
00195 /// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... }
00196 /// defines a single-parameter function named DefineMatcher() that is
00197 /// polymorphic in the return type.
00198 ///
00199 /// The variables are the same as for AST_MATCHER, but NodeType will be deduced
00200 /// from the calling context.
00201 #define AST_POLYMORPHIC_MATCHER(DefineMatcher, ReturnTypesF)                   \
00202   namespace internal {                                                         \
00203   template <typename NodeType>                                                 \
00204   class matcher_##DefineMatcher##Matcher : public MatcherInterface<NodeType> { \
00205   public:                                                                      \
00206     bool matches(const NodeType &Node, ASTMatchFinder *Finder,                 \
00207                  BoundNodesTreeBuilder *Builder) const override;               \
00208   };                                                                           \
00209   }                                                                            \
00210   inline internal::PolymorphicMatcherWithParam0<                               \
00211       internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>                \
00212   DefineMatcher() {                                                            \
00213     return internal::PolymorphicMatcherWithParam0<                             \
00214         internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>();           \
00215   }                                                                            \
00216   template <typename NodeType>                                                 \
00217   bool internal::matcher_##DefineMatcher##Matcher<NodeType>::matches(          \
00218       const NodeType &Node, ASTMatchFinder *Finder,                            \
00219       BoundNodesTreeBuilder *Builder) const
00220 
00221 /// \brief AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... }
00222 /// defines a single-parameter function named DefineMatcher() that is
00223 /// polymorphic in the return type.
00224 ///
00225 /// The variables are the same as for
00226 /// AST_MATCHER_P, with the addition of NodeType, which specifies the node type
00227 /// of the matcher Matcher<NodeType> returned by the function matcher().
00228 ///
00229 /// FIXME: Pull out common code with above macro?
00230 #define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ReturnTypesF, ParamType,      \
00231                                   Param)                                       \
00232   AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType,   \
00233                                      Param, 0)
00234 
00235 #define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF,        \
00236                                            ParamType, Param, OverloadId)       \
00237   namespace internal {                                                         \
00238   template <typename NodeType, typename ParamT>                                \
00239   class matcher_##DefineMatcher##OverloadId##Matcher                           \
00240       : public MatcherInterface<NodeType> {                                    \
00241   public:                                                                      \
00242     explicit matcher_##DefineMatcher##OverloadId##Matcher(                     \
00243         ParamType const &A##Param)                                             \
00244         : Param(A##Param) {}                                                   \
00245     bool matches(const NodeType &Node, ASTMatchFinder *Finder,                 \
00246                  BoundNodesTreeBuilder *Builder) const override;               \
00247                                                                                \
00248   private:                                                                     \
00249     ParamType const Param;                                                     \
00250   };                                                                           \
00251   }                                                                            \
00252   inline internal::PolymorphicMatcherWithParam1<                               \
00253       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,       \
00254       ReturnTypesF> DefineMatcher(ParamType const &Param) {                    \
00255     return internal::PolymorphicMatcherWithParam1<                             \
00256         internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,     \
00257         ReturnTypesF>(Param);                                                  \
00258   }                                                                            \
00259   typedef internal::PolymorphicMatcherWithParam1<                              \
00260       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType,       \
00261       ReturnTypesF>(&DefineMatcher##_Type##OverloadId)(                        \
00262       ParamType const &Param);                                                 \
00263   template <typename NodeType, typename ParamT>                                \
00264   bool internal::matcher_##DefineMatcher##OverloadId##Matcher<                 \
00265       NodeType, ParamT>::matches(const NodeType &Node, ASTMatchFinder *Finder, \
00266                                  BoundNodesTreeBuilder *Builder) const
00267 
00268 /// \brief AST_POLYMORPHIC_MATCHER_P2(
00269 ///     DefineMatcher, ParamType1, Param1, ParamType2, Param2) { ... }
00270 /// defines a two-parameter function named matcher() that is polymorphic in
00271 /// the return type.
00272 ///
00273 /// The variables are the same as for AST_MATCHER_P2, with the
00274 /// addition of NodeType, which specifies the node type of the matcher
00275 /// Matcher<NodeType> returned by the function DefineMatcher().
00276 #define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ReturnTypesF, ParamType1,    \
00277                                    Param1, ParamType2, Param2)                 \
00278   AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType1, \
00279                                       Param1, ParamType2, Param2, 0)
00280 
00281 #define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF,       \
00282                                             ParamType1, Param1, ParamType2,    \
00283                                             Param2, OverloadId)                \
00284   namespace internal {                                                         \
00285   template <typename NodeType, typename ParamT1, typename ParamT2>             \
00286   class matcher_##DefineMatcher##OverloadId##Matcher                           \
00287       : public MatcherInterface<NodeType> {                                    \
00288   public:                                                                      \
00289     matcher_##DefineMatcher##OverloadId##Matcher(ParamType1 const &A##Param1,  \
00290                                                  ParamType2 const &A##Param2)  \
00291         : Param1(A##Param1), Param2(A##Param2) {}                              \
00292      bool matches(const NodeType &Node, ASTMatchFinder *Finder,                \
00293                   BoundNodesTreeBuilder *Builder) const override;              \
00294                                                                                \
00295   private:                                                                     \
00296     ParamType1 const Param1;                                                   \
00297     ParamType2 const Param2;                                                   \
00298   };                                                                           \
00299   }                                                                            \
00300   inline internal::PolymorphicMatcherWithParam2<                               \
00301       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,      \
00302       ParamType2, ReturnTypesF> DefineMatcher(ParamType1 const &Param1,        \
00303                                               ParamType2 const &Param2) {      \
00304     return internal::PolymorphicMatcherWithParam2<                             \
00305         internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,    \
00306         ParamType2, ReturnTypesF>(Param1, Param2);                             \
00307   }                                                                            \
00308   typedef internal::PolymorphicMatcherWithParam2<                              \
00309       internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1,      \
00310       ParamType2, ReturnTypesF>(&DefineMatcher##_Type##OverloadId)(            \
00311       ParamType1 const &Param1, ParamType2 const &Param2);                     \
00312   template <typename NodeType, typename ParamT1, typename ParamT2>             \
00313   bool internal::matcher_##DefineMatcher##OverloadId##Matcher<                 \
00314       NodeType, ParamT1, ParamT2>::matches(                                    \
00315       const NodeType &Node, ASTMatchFinder *Finder,                            \
00316       BoundNodesTreeBuilder *Builder) const
00317 
00318 /// \brief Creates a variadic matcher for both a specific \c Type as well as
00319 /// the corresponding \c TypeLoc.
00320 #define AST_TYPE_MATCHER(NodeType, MatcherName)                                \
00321   const internal::VariadicDynCastAllOfMatcher<Type, NodeType> MatcherName
00322 // FIXME: add a matcher for TypeLoc derived classes using its custom casting
00323 // API (no longer dyn_cast) if/when we need such matching
00324 
00325 /// \brief AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) defines
00326 /// the matcher \c MatcherName that can be used to traverse from one \c Type
00327 /// to another.
00328 ///
00329 /// For a specific \c SpecificType, the traversal is done using 
00330 /// \c SpecificType::FunctionName. The existence of such a function determines
00331 /// whether a corresponding matcher can be used on \c SpecificType.
00332 #define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF)     \
00333   namespace internal {                                                         \
00334   template <typename T> struct TypeMatcher##MatcherName##Getter {              \
00335     static QualType (T::*value())() const { return &T::FunctionName; }         \
00336   };                                                                           \
00337   }                                                                            \
00338   const internal::TypeTraversePolymorphicMatcher<                              \
00339       QualType, internal::TypeMatcher##MatcherName##Getter,                    \
00340       internal::TypeTraverseMatcher, ReturnTypesF>::Func MatcherName
00341 
00342 /// \brief AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works
00343 /// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs.
00344 #define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF)  \
00345   namespace internal {                                                         \
00346   template <typename T> struct TypeLocMatcher##MatcherName##Getter {           \
00347     static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; }     \
00348   };                                                                           \
00349   }                                                                            \
00350   const internal::TypeTraversePolymorphicMatcher<                              \
00351       TypeLoc, internal::TypeLocMatcher##MatcherName##Getter,                  \
00352       internal::TypeLocTraverseMatcher, ReturnTypesF>::Func MatcherName##Loc;  \
00353   AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF)
00354 
00355 #endif