diff options
Diffstat (limited to 'include/clang/ASTMatchers/ASTMatchersMacros.h')
-rw-r--r-- | include/clang/ASTMatchers/ASTMatchersMacros.h | 189 |
1 files changed, 90 insertions, 99 deletions
diff --git a/include/clang/ASTMatchers/ASTMatchersMacros.h b/include/clang/ASTMatchers/ASTMatchersMacros.h index f5ca26b..b5d5303 100644 --- a/include/clang/ASTMatchers/ASTMatchersMacros.h +++ b/include/clang/ASTMatchers/ASTMatchersMacros.h @@ -49,23 +49,19 @@ /// /// The code should return true if 'Node' matches. #define AST_MATCHER(Type, DefineMatcher) \ - AST_MATCHER_OVERLOAD(Type, DefineMatcher, 0) - -#define AST_MATCHER_OVERLOAD(Type, DefineMatcher, OverloadId) \ namespace internal { \ - class matcher_##DefineMatcher##OverloadId##Matcher \ - : public MatcherInterface<Type> { \ + class matcher_##DefineMatcher##Matcher : public MatcherInterface<Type> { \ public: \ - explicit matcher_##DefineMatcher##OverloadId##Matcher() {} \ + explicit matcher_##DefineMatcher##Matcher() {} \ virtual bool matches(const Type &Node, ASTMatchFinder *Finder, \ BoundNodesTreeBuilder *Builder) const; \ }; \ } \ inline internal::Matcher<Type> DefineMatcher() { \ return internal::makeMatcher( \ - new internal::matcher_##DefineMatcher##OverloadId##Matcher()); \ + new internal::matcher_##DefineMatcher##Matcher()); \ } \ - inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \ + inline bool internal::matcher_##DefineMatcher##Matcher::matches( \ const Type &Node, ASTMatchFinder *Finder, \ BoundNodesTreeBuilder *Builder) const @@ -93,10 +89,10 @@ public: \ explicit matcher_##DefineMatcher##OverloadId##Matcher( \ const ParamType &A##Param) \ - : Param(A##Param) { \ - } \ + : Param(A##Param) {} \ virtual bool matches(const Type &Node, ASTMatchFinder *Finder, \ BoundNodesTreeBuilder *Builder) const; \ + \ private: \ const ParamType Param; \ }; \ @@ -105,6 +101,8 @@ return internal::makeMatcher( \ new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param)); \ } \ + typedef internal::Matcher<Type>(&DefineMatcher##_Type##OverloadId)( \ + const ParamType &Param); \ inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \ const Type &Node, ASTMatchFinder *Finder, \ BoundNodesTreeBuilder *Builder) const @@ -136,53 +134,70 @@ public: \ matcher_##DefineMatcher##OverloadId##Matcher(const ParamType1 &A##Param1, \ const ParamType2 &A##Param2) \ - : Param1(A##Param1), Param2(A##Param2) { \ - } \ + : Param1(A##Param1), Param2(A##Param2) {} \ virtual bool matches(const Type &Node, ASTMatchFinder *Finder, \ BoundNodesTreeBuilder *Builder) const; \ + \ private: \ const ParamType1 Param1; \ const ParamType2 Param2; \ }; \ } \ - inline internal::Matcher<Type> \ - DefineMatcher(const ParamType1 &Param1, const ParamType2 &Param2) { \ + inline internal::Matcher<Type> DefineMatcher(const ParamType1 &Param1, \ + const ParamType2 &Param2) { \ return internal::makeMatcher( \ new internal::matcher_##DefineMatcher##OverloadId##Matcher(Param1, \ Param2)); \ } \ + typedef internal::Matcher<Type>(&DefineMatcher##_Type##OverloadId)( \ + const ParamType1 &Param1, const ParamType2 &Param2); \ inline bool internal::matcher_##DefineMatcher##OverloadId##Matcher::matches( \ const Type &Node, ASTMatchFinder *Finder, \ BoundNodesTreeBuilder *Builder) const +/// \brief Construct a type-list to be passed to the AST_POLYMORPHIC_MATCHER* +/// macros. +/// +/// You can't pass something like \c TypeList<Foo, Bar> to a macro, because it +/// will look at that as two arguments. However, you can pass +/// \c void(TypeList<Foo, Bar>), which works thanks to the parenthesis. +/// The \c PolymorphicMatcherWithParam* classes will unpack the function type to +/// extract the TypeList object. +#define AST_POLYMORPHIC_SUPPORTED_TYPES_1(t1) void(internal::TypeList<t1>) +#define AST_POLYMORPHIC_SUPPORTED_TYPES_2(t1, t2) \ + void(internal::TypeList<t1, t2>) +#define AST_POLYMORPHIC_SUPPORTED_TYPES_3(t1, t2, t3) \ + void(internal::TypeList<t1, t2, t3>) +#define AST_POLYMORPHIC_SUPPORTED_TYPES_4(t1, t2, t3, t4) \ + void(internal::TypeList<t1, t2, t3, t4>) +#define AST_POLYMORPHIC_SUPPORTED_TYPES_5(t1, t2, t3, t4, t5) \ + void(internal::TypeList<t1, t2, t3, internal::TypeList<t4, t5> >) + /// \brief AST_POLYMORPHIC_MATCHER(DefineMatcher) { ... } /// defines a single-parameter function named DefineMatcher() that is /// polymorphic in the return type. /// /// The variables are the same as for AST_MATCHER, but NodeType will be deduced /// from the calling context. -#define AST_POLYMORPHIC_MATCHER(DefineMatcher) \ - AST_POLYMORPHIC_MATCHER_OVERLOAD(DefineMatcher, 0) - -#define AST_POLYMORPHIC_MATCHER_OVERLOAD(DefineMatcher, OverloadId) \ +#define AST_POLYMORPHIC_MATCHER(DefineMatcher, ReturnTypesF) \ namespace internal { \ template <typename NodeType> \ - class matcher_##DefineMatcher##OverloadId##Matcher \ - : public MatcherInterface<NodeType> { \ + class matcher_##DefineMatcher##Matcher : public MatcherInterface<NodeType> { \ public: \ virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder, \ BoundNodesTreeBuilder *Builder) const; \ }; \ } \ inline internal::PolymorphicMatcherWithParam0< \ - internal::matcher_##DefineMatcher##OverloadId##Matcher> DefineMatcher() {\ + internal::matcher_##DefineMatcher##Matcher, ReturnTypesF> \ + DefineMatcher() { \ return internal::PolymorphicMatcherWithParam0< \ - internal::matcher_##DefineMatcher##OverloadId##Matcher>(); \ + internal::matcher_##DefineMatcher##Matcher, ReturnTypesF>(); \ } \ template <typename NodeType> \ - bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \ - NodeType>::matches(const NodeType &Node, ASTMatchFinder *Finder, \ - BoundNodesTreeBuilder *Builder) const + bool internal::matcher_##DefineMatcher##Matcher<NodeType>::matches( \ + const NodeType &Node, ASTMatchFinder *Finder, \ + BoundNodesTreeBuilder *Builder) const /// \brief AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) { ... } /// defines a single-parameter function named DefineMatcher() that is @@ -193,11 +208,13 @@ /// of the matcher Matcher<NodeType> returned by the function matcher(). /// /// FIXME: Pull out common code with above macro? -#define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ParamType, Param) \ - AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ParamType, Param, 0) +#define AST_POLYMORPHIC_MATCHER_P(DefineMatcher, ReturnTypesF, ParamType, \ + Param) \ + AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType, \ + Param, 0) -#define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ParamType, Param, \ - OverloadId) \ +#define AST_POLYMORPHIC_MATCHER_P_OVERLOAD(DefineMatcher, ReturnTypesF, \ + ParamType, Param, OverloadId) \ namespace internal { \ template <typename NodeType, typename ParamT> \ class matcher_##DefineMatcher##OverloadId##Matcher \ @@ -205,21 +222,25 @@ public: \ explicit matcher_##DefineMatcher##OverloadId##Matcher( \ const ParamType &A##Param) \ - : Param(A##Param) { \ - } \ + : Param(A##Param) {} \ virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder, \ BoundNodesTreeBuilder *Builder) const; \ + \ private: \ const ParamType Param; \ }; \ } \ inline internal::PolymorphicMatcherWithParam1< \ - internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType> \ - DefineMatcher(const ParamType &Param) { \ + internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \ + ReturnTypesF> DefineMatcher(const ParamType &Param) { \ return internal::PolymorphicMatcherWithParam1< \ - internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType>( \ - Param); \ + internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \ + ReturnTypesF>(Param); \ } \ + typedef internal::PolymorphicMatcherWithParam1< \ + internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType, \ + ReturnTypesF>(&DefineMatcher##_Type##OverloadId)( \ + const ParamType &Param); \ template <typename NodeType, typename ParamT> \ bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \ NodeType, ParamT>::matches(const NodeType &Node, ASTMatchFinder *Finder, \ @@ -233,13 +254,14 @@ /// The variables are the same as for AST_MATCHER_P2, with the /// addition of NodeType, which specifies the node type of the matcher /// Matcher<NodeType> returned by the function DefineMatcher(). -#define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ParamType1, Param1, \ - ParamType2, Param2) \ - AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ParamType1, Param1, \ - ParamType2, Param2, 0) +#define AST_POLYMORPHIC_MATCHER_P2(DefineMatcher, ReturnTypesF, ParamType1, \ + Param1, ParamType2, Param2) \ + AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, ParamType1, \ + Param1, ParamType2, Param2, 0) -#define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ParamType1, Param1, \ - ParamType2, Param2, OverloadId) \ +#define AST_POLYMORPHIC_MATCHER_P2_OVERLOAD(DefineMatcher, ReturnTypesF, \ + ParamType1, Param1, ParamType2, \ + Param2, OverloadId) \ namespace internal { \ template <typename NodeType, typename ParamT1, typename ParamT2> \ class matcher_##DefineMatcher##OverloadId##Matcher \ @@ -247,10 +269,10 @@ public: \ matcher_##DefineMatcher##OverloadId##Matcher(const ParamType1 &A##Param1, \ const ParamType2 &A##Param2) \ - : Param1(A##Param1), Param2(A##Param2) { \ - } \ + : Param1(A##Param1), Param2(A##Param2) {} \ virtual bool matches(const NodeType &Node, ASTMatchFinder *Finder, \ BoundNodesTreeBuilder *Builder) const; \ + \ private: \ const ParamType1 Param1; \ const ParamType2 Param2; \ @@ -258,12 +280,16 @@ } \ inline internal::PolymorphicMatcherWithParam2< \ internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \ - ParamType2> \ - DefineMatcher(const ParamType1 &Param1, const ParamType2 &Param2) { \ + ParamType2, ReturnTypesF> DefineMatcher(const ParamType1 &Param1, \ + const ParamType2 &Param2) { \ return internal::PolymorphicMatcherWithParam2< \ internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \ - ParamType2>(Param1, Param2); \ + ParamType2, ReturnTypesF>(Param1, Param2); \ } \ + typedef internal::PolymorphicMatcherWithParam2< \ + internal::matcher_##DefineMatcher##OverloadId##Matcher, ParamType1, \ + ParamType2, ReturnTypesF>(&DefineMatcher##_Type##OverloadId)( \ + const ParamType1 &Param1, const ParamType2 &Param2); \ template <typename NodeType, typename ParamT1, typename ParamT2> \ bool internal::matcher_##DefineMatcher##OverloadId##Matcher< \ NodeType, ParamT1, ParamT2>::matches( \ @@ -282,64 +308,29 @@ /// to another. /// /// For a specific \c SpecificType, the traversal is done using -/// \c SpecificType::FunctionName. The existance of such a function determines +/// \c SpecificType::FunctionName. The existence of such a function determines /// whether a corresponding matcher can be used on \c SpecificType. -#define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName) \ - class Polymorphic##MatcherName##TypeMatcher { \ - public: \ - Polymorphic##MatcherName##TypeMatcher( \ - const internal::Matcher<QualType> &InnerMatcher) \ - : InnerMatcher(InnerMatcher) { \ - } \ - template <typename T> operator internal:: Matcher< T>() { \ - return internal::Matcher<T>(new internal::TypeTraverseMatcher<T>( \ - InnerMatcher, &T::FunctionName)); \ - } \ - private: \ - const internal::Matcher<QualType> InnerMatcher; \ - } \ - ; \ - class Variadic##MatcherName##TypeTraverseMatcher \ - : public llvm::VariadicFunction< \ - Polymorphic##MatcherName##TypeMatcher, internal::Matcher<QualType>, \ - internal::makeTypeAllOfComposite< \ - Polymorphic##MatcherName##TypeMatcher, QualType> > { \ - public: \ - Variadic##MatcherName##TypeTraverseMatcher() { \ - } \ +#define AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \ + namespace internal { \ + template <typename T> struct TypeMatcher##MatcherName##Getter { \ + static QualType (T::*value())() const { return &T::FunctionName; } \ + }; \ } \ - ; \ - const Variadic##MatcherName##TypeTraverseMatcher MatcherName + const internal::TypeTraversePolymorphicMatcher< \ + QualType, internal::TypeMatcher##MatcherName##Getter, \ + internal::TypeTraverseMatcher, ReturnTypesF>::Func MatcherName /// \brief AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) works /// identical to \c AST_TYPE_TRAVERSE_MATCHER but operates on \c TypeLocs. -#define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName) \ - class Polymorphic##MatcherName##TypeLocMatcher { \ - public: \ - Polymorphic##MatcherName##TypeLocMatcher( \ - const internal::Matcher<TypeLoc> &InnerMatcher) \ - : InnerMatcher(InnerMatcher) { \ - } \ - template <typename T> operator internal:: Matcher< T>() { \ - return internal::Matcher<T>( \ - new internal::TypeLocTraverseMatcher<T>(InnerMatcher, \ - &T::FunctionName##Loc)); \ - } \ - private: \ - const internal::Matcher<TypeLoc> InnerMatcher; \ - } \ - ; \ - class Variadic##MatcherName##TypeLocTraverseMatcher \ - : public llvm::VariadicFunction< \ - Polymorphic##MatcherName##TypeLocMatcher, internal::Matcher<TypeLoc>,\ - internal::makeTypeAllOfComposite< \ - Polymorphic##MatcherName##TypeLocMatcher, TypeLoc> > { \ - public: \ - Variadic##MatcherName##TypeLocTraverseMatcher() { \ - } \ +#define AST_TYPELOC_TRAVERSE_MATCHER(MatcherName, FunctionName, ReturnTypesF) \ + namespace internal { \ + template <typename T> struct TypeLocMatcher##MatcherName##Getter { \ + static TypeLoc (T::*value())() const { return &T::FunctionName##Loc; } \ + }; \ } \ - ; \ - const Variadic##MatcherName##TypeLocTraverseMatcher MatcherName##Loc; \ - AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type) + const internal::TypeTraversePolymorphicMatcher< \ + TypeLoc, internal::TypeLocMatcher##MatcherName##Getter, \ + internal::TypeLocTraverseMatcher, ReturnTypesF>::Func MatcherName##Loc; \ + AST_TYPE_TRAVERSE_MATCHER(MatcherName, FunctionName##Type, ReturnTypesF) #endif // LLVM_CLANG_AST_MATCHERS_AST_MATCHERS_MACROS_H |