From 953de1f092f5af5f0a1d399bd5c3f51a84804609 Mon Sep 17 00:00:00 2001 From: Samuel Benzaquen Date: Thu, 20 Nov 2014 15:45:53 +0000 Subject: [PATCH] Replace variadic operator function pointer with an enum value. Summary: Replace variadic operator function pointer with an enum value. Hiding the implementation of the variadic matcher will allow to specialize them for the operation performed. In particular, it will allow for a more efficient allOf() matcher. Reviewers: klimek Subscribers: klimek, cfe-commits Differential Revision: http://reviews.llvm.org/D6293 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@222432 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/ASTMatchers/ASTMatchers.h | 8 +- .../clang/ASTMatchers/ASTMatchersInternal.h | 85 ++++++++----------- .../clang/ASTMatchers/Dynamic/VariantValue.h | 4 +- lib/ASTMatchers/ASTMatchersInternal.cpp | 50 +++++++++-- lib/ASTMatchers/Dynamic/Marshallers.h | 12 +-- lib/ASTMatchers/Dynamic/VariantValue.cpp | 16 ++-- 6 files changed, 100 insertions(+), 75 deletions(-) diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index 4537c4719c..37c7b16934 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -1512,21 +1512,21 @@ const internal::VariadicAllOfMatcher typeLoc; /// /// Usable as: Any Matcher const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> eachOf = { - internal::EachOfVariadicOperator + internal::DynTypedMatcher::VO_EachOf }; /// \brief Matches if any of the given matchers matches. /// /// Usable as: Any Matcher const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> anyOf = { - internal::AnyOfVariadicOperator + internal::DynTypedMatcher::VO_AnyOf }; /// \brief Matches if all given matchers match. /// /// Usable as: Any Matcher const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> allOf = { - internal::AllOfVariadicOperator + internal::DynTypedMatcher::VO_AllOf }; /// \brief Matches sizeof (C99), alignof (C++11) and vec_step (OpenCL) @@ -1858,7 +1858,7 @@ const internal::ArgumentAdaptingMatcherFunc< /// /// Usable as: Any Matcher const internal::VariadicOperatorMatcherFunc<1, 1> unless = { - internal::NotUnaryOperator + internal::DynTypedMatcher::VO_UnaryNot }; /// \brief Matches a node if the declaration associated with that node diff --git a/include/clang/ASTMatchers/ASTMatchersInternal.h b/include/clang/ASTMatchers/ASTMatchersInternal.h index ba571f0d15..1b8040cf44 100644 --- a/include/clang/ASTMatchers/ASTMatchersInternal.h +++ b/include/clang/ASTMatchers/ASTMatchersInternal.h @@ -263,11 +263,23 @@ public: RestrictKind(SupportedKind), Implementation(Implementation) {} /// \brief Construct from a variadic function. - typedef bool (*VariadicOperatorFunction)( - const ast_type_traits::DynTypedNode DynNode, ASTMatchFinder *Finder, - BoundNodesTreeBuilder *Builder, ArrayRef InnerMatchers); + enum VariadicOperator { + /// \brief Matches nodes for which all provided matchers match. + VO_AllOf, + /// \brief Matches nodes for which at least one of the provided matchers + /// matches. + VO_AnyOf, + /// \brief Matches nodes for which at least one of the provided matchers + /// matches, but doesn't stop at the first match. + VO_EachOf, + /// \brief Matches nodes that do not match the provided matcher. + /// + /// Uses the variadic matcher interface, but fails if + /// InnerMatchers.size() != 1. + VO_UnaryNot + }; static DynTypedMatcher - constructVariadic(VariadicOperatorFunction Func, + constructVariadic(VariadicOperator Op, std::vector InnerMatchers); /// \brief Get a "true" matcher for \p NodeKind. @@ -1125,7 +1137,7 @@ private: struct VariadicOperatorNoArg {}; /// \brief Polymorphic matcher object that uses a \c -/// DynTypedMatcher::VariadicOperatorFunction operator. +/// DynTypedMatcher::VariadicOperator operator. /// /// Input matchers can have any type (including other polymorphic matcher /// types), and the actual Matcher is generated on demand with an implicit @@ -1140,7 +1152,7 @@ template class VariadicOperatorMatcher { public: - VariadicOperatorMatcher(DynTypedMatcher::VariadicOperatorFunction Func, + VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, const P1 &Param1, const P2 &Param2 = VariadicOperatorNoArg(), const P3 &Param3 = VariadicOperatorNoArg(), @@ -1150,7 +1162,7 @@ public: const P7 &Param7 = VariadicOperatorNoArg(), const P8 &Param8 = VariadicOperatorNoArg(), const P9 &Param9 = VariadicOperatorNoArg()) - : Func(Func), Param1(Param1), Param2(Param2), Param3(Param3), + : Op(Op), Param1(Param1), Param2(Param2), Param3(Param3), Param4(Param4), Param5(Param5), Param6(Param6), Param7(Param7), Param8(Param8), Param9(Param9) {} @@ -1165,7 +1177,7 @@ public: addMatcher(Param7, Matchers); addMatcher(Param8, Matchers); addMatcher(Param9, Matchers); - return DynTypedMatcher::constructVariadic(Func, std::move(Matchers)) + return DynTypedMatcher::constructVariadic(Op, std::move(Matchers)) .template unconditionalConvertTo(); } @@ -1181,7 +1193,7 @@ private: static void addMatcher(VariadicOperatorNoArg, std::vector &Matchers) {} - const DynTypedMatcher::VariadicOperatorFunction Func; + const DynTypedMatcher::VariadicOperator Op; const P1 Param1; const P2 Param2; const P3 Param3; @@ -1199,7 +1211,7 @@ private: /// It supports 1-9 argument overloaded operator(). More can be added if needed. template struct VariadicOperatorMatcherFunc { - DynTypedMatcher::VariadicOperatorFunction Func; + DynTypedMatcher::VariadicOperator Op; template struct EnableIfValidArity @@ -1208,30 +1220,29 @@ struct VariadicOperatorMatcherFunc { template typename EnableIfValidArity<1, VariadicOperatorMatcher >::type operator()(const M1 &P1) const { - return VariadicOperatorMatcher(Func, P1); + return VariadicOperatorMatcher(Op, P1); } template typename EnableIfValidArity<2, VariadicOperatorMatcher >::type operator()(const M1 &P1, const M2 &P2) const { - return VariadicOperatorMatcher(Func, P1, P2); + return VariadicOperatorMatcher(Op, P1, P2); } template typename EnableIfValidArity<3, VariadicOperatorMatcher >::type operator()(const M1 &P1, const M2 &P2, const M3 &P3) const { - return VariadicOperatorMatcher(Func, P1, P2, P3); + return VariadicOperatorMatcher(Op, P1, P2, P3); } template typename EnableIfValidArity<4, VariadicOperatorMatcher >::type operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4) const { - return VariadicOperatorMatcher(Func, P1, P2, P3, P4); + return VariadicOperatorMatcher(Op, P1, P2, P3, P4); } template typename EnableIfValidArity< 5, VariadicOperatorMatcher >::type operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, const M5 &P5) const { - return VariadicOperatorMatcher(Func, P1, P2, P3, P4, - P5); + return VariadicOperatorMatcher(Op, P1, P2, P3, P4, P5); } template @@ -1240,7 +1251,7 @@ struct VariadicOperatorMatcherFunc { operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, const M5 &P5, const M6 &P6) const { return VariadicOperatorMatcher( - Func, P1, P2, P3, P4, P5, P6); + Op, P1, P2, P3, P4, P5, P6); } template @@ -1249,7 +1260,7 @@ struct VariadicOperatorMatcherFunc { operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, const M5 &P5, const M6 &P6, const M7 &P7) const { return VariadicOperatorMatcher( - Func, P1, P2, P3, P4, P5, P6, P7); + Op, P1, P2, P3, P4, P5, P6, P7); } template @@ -1258,7 +1269,7 @@ struct VariadicOperatorMatcherFunc { operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4, const M5 &P5, const M6 &P6, const M7 &P7, const M8 &P8) const { return VariadicOperatorMatcher( - Func, P1, P2, P3, P4, P5, P6, P7, P8); + Op, P1, P2, P3, P4, P5, P6, P7, P8); } template @@ -1268,39 +1279,12 @@ struct VariadicOperatorMatcherFunc { const M5 &P5, const M6 &P6, const M7 &P7, const M8 &P8, const M9 &P9) const { return VariadicOperatorMatcher( - Func, P1, P2, P3, P4, P5, P6, P7, P8, P9); + Op, P1, P2, P3, P4, P5, P6, P7, P8, P9); } }; /// @} -/// \brief Matches nodes that do not match the provided matcher. -/// -/// Uses the variadic matcher interface, but fails if InnerMatchers.size()!=1. -bool NotUnaryOperator(const ast_type_traits::DynTypedNode DynNode, - ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder, - ArrayRef InnerMatchers); - -/// \brief Matches nodes for which all provided matchers match. -bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode, - ASTMatchFinder *Finder, - BoundNodesTreeBuilder *Builder, - ArrayRef InnerMatchers); - -/// \brief Matches nodes for which at least one of the provided matchers -/// matches, but doesn't stop at the first match. -bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode, - ASTMatchFinder *Finder, - BoundNodesTreeBuilder *Builder, - ArrayRef InnerMatchers); - -/// \brief Matches nodes for which at least one of the provided matchers -/// matches. -bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode, - ASTMatchFinder *Finder, - BoundNodesTreeBuilder *Builder, - ArrayRef InnerMatchers); - template inline Matcher DynTypedMatcher::unconditionalConvertTo() const { return Matcher(*this); @@ -1325,9 +1309,10 @@ BindableMatcher makeAllOfComposite( for (const auto *InnerMatcher : InnerMatchers) { DynMatchers.push_back(*InnerMatcher); } - return BindableMatcher(DynTypedMatcher::constructVariadic( - AllOfVariadicOperator, std::move(DynMatchers)) - .template unconditionalConvertTo()); + return BindableMatcher( + DynTypedMatcher::constructVariadic(DynTypedMatcher::VO_AllOf, + std::move(DynMatchers)) + .template unconditionalConvertTo()); } /// \brief Creates a Matcher that matches if diff --git a/include/clang/ASTMatchers/Dynamic/VariantValue.h b/include/clang/ASTMatchers/Dynamic/VariantValue.h index e4b5519dff..a9bd3d5011 100644 --- a/include/clang/ASTMatchers/Dynamic/VariantValue.h +++ b/include/clang/ASTMatchers/Dynamic/VariantValue.h @@ -107,7 +107,7 @@ class VariantMatcher { /// Will try to convert each inner matcher to the destination type and /// return llvm::None if it fails to do so. llvm::Optional - constructVariadicOperator(DynTypedMatcher::VariadicOperatorFunction Func, + constructVariadicOperator(DynTypedMatcher::VariadicOperator Op, ArrayRef InnerMatchers) const; protected: @@ -148,7 +148,7 @@ public: /// /// It will bind to the appropriate type on getTypedMatcher(). static VariantMatcher - VariadicOperatorMatcher(DynTypedMatcher::VariadicOperatorFunction Func, + VariadicOperatorMatcher(DynTypedMatcher::VariadicOperator Op, std::vector Args); /// \brief Makes the matcher the "null" matcher. diff --git a/lib/ASTMatchers/ASTMatchersInternal.cpp b/lib/ASTMatchers/ASTMatchersInternal.cpp index af6f0abfb9..c7d98b8a3a 100644 --- a/lib/ASTMatchers/ASTMatchersInternal.cpp +++ b/lib/ASTMatchers/ASTMatchersInternal.cpp @@ -20,6 +20,26 @@ namespace clang { namespace ast_matchers { namespace internal { +bool NotUnaryOperator(const ast_type_traits::DynTypedNode DynNode, + ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder, + ArrayRef InnerMatchers); + +bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder, + ArrayRef InnerMatchers); + +bool EachOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder, + ArrayRef InnerMatchers); + +bool AnyOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode, + ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder, + ArrayRef InnerMatchers); + + void BoundNodesTreeBuilder::visitMatches(Visitor *ResultVisitor) { if (Bindings.empty()) Bindings.push_back(BoundNodesMap()); @@ -31,8 +51,12 @@ void BoundNodesTreeBuilder::visitMatches(Visitor *ResultVisitor) { namespace { class VariadicMatcher : public DynMatcherInterface { - public: - VariadicMatcher(DynTypedMatcher::VariadicOperatorFunction Func, +public: + typedef bool (*VariadicOperatorFunction)( + const ast_type_traits::DynTypedNode DynNode, ASTMatchFinder *Finder, + BoundNodesTreeBuilder *Builder, ArrayRef InnerMatchers); + + VariadicMatcher(VariadicOperatorFunction Func, std::vector InnerMatchers) : Func(Func), InnerMatchers(std::move(InnerMatchers)) {} @@ -42,8 +66,8 @@ class VariadicMatcher : public DynMatcherInterface { return Func(DynNode, Finder, Builder, InnerMatchers); } - private: - DynTypedMatcher::VariadicOperatorFunction Func; +private: + VariadicOperatorFunction Func; std::vector InnerMatchers; }; @@ -86,7 +110,7 @@ static llvm::ManagedStatic TrueMatcherInstance; } // namespace DynTypedMatcher DynTypedMatcher::constructVariadic( - DynTypedMatcher::VariadicOperatorFunction Func, + DynTypedMatcher::VariadicOperator Op, std::vector InnerMatchers) { assert(InnerMatchers.size() > 0 && "Array must not be empty."); assert(std::all_of(InnerMatchers.begin(), InnerMatchers.end(), @@ -100,6 +124,22 @@ DynTypedMatcher DynTypedMatcher::constructVariadic( // Make it the same as SupportedKind, since that is the broadest type we are // allowed to accept. auto SupportedKind = InnerMatchers[0].SupportedKind; + VariadicMatcher::VariadicOperatorFunction Func; + switch (Op) { + case VO_AllOf: + Func = AllOfVariadicOperator; + break; + case VO_AnyOf: + Func = AnyOfVariadicOperator; + break; + case VO_EachOf: + Func = EachOfVariadicOperator; + break; + case VO_UnaryNot: + Func = NotUnaryOperator; + break; + } + return DynTypedMatcher(SupportedKind, SupportedKind, new VariadicMatcher(Func, std::move(InnerMatchers))); } diff --git a/lib/ASTMatchers/Dynamic/Marshallers.h b/lib/ASTMatchers/Dynamic/Marshallers.h index 42c880e80e..b78bc03819 100644 --- a/lib/ASTMatchers/Dynamic/Marshallers.h +++ b/lib/ASTMatchers/Dynamic/Marshallers.h @@ -556,10 +556,10 @@ private: /// \brief Variadic operator marshaller function. class VariadicOperatorMatcherDescriptor : public MatcherDescriptor { public: - typedef DynTypedMatcher::VariadicOperatorFunction VarFunc; + typedef DynTypedMatcher::VariadicOperator VarOp; VariadicOperatorMatcherDescriptor(unsigned MinCount, unsigned MaxCount, - VarFunc Func, StringRef MatcherName) - : MinCount(MinCount), MaxCount(MaxCount), Func(Func), + VarOp Op, StringRef MatcherName) + : MinCount(MinCount), MaxCount(MaxCount), Op(Op), MatcherName(MatcherName) {} virtual VariantMatcher create(const SourceRange &NameRange, @@ -584,7 +584,7 @@ public: } InnerArgs.push_back(Value.getMatcher()); } - return VariantMatcher::VariadicOperatorMatcher(Func, std::move(InnerArgs)); + return VariantMatcher::VariadicOperatorMatcher(Op, std::move(InnerArgs)); } bool isVariadic() const override { return true; } @@ -606,7 +606,7 @@ public: private: const unsigned MinCount; const unsigned MaxCount; - const VarFunc Func; + const VarOp Op; const StringRef MatcherName; }; @@ -699,7 +699,7 @@ MatcherDescriptor * makeMatcherAutoMarshall(ast_matchers::internal::VariadicOperatorMatcherFunc< MinCount, MaxCount> Func, StringRef MatcherName) { - return new VariadicOperatorMatcherDescriptor(MinCount, MaxCount, Func.Func, + return new VariadicOperatorMatcherDescriptor(MinCount, MaxCount, Func.Op, MatcherName); } diff --git a/lib/ASTMatchers/Dynamic/VariantValue.cpp b/lib/ASTMatchers/Dynamic/VariantValue.cpp index 08b3b1d3f3..a88b707012 100644 --- a/lib/ASTMatchers/Dynamic/VariantValue.cpp +++ b/lib/ASTMatchers/Dynamic/VariantValue.cpp @@ -58,7 +58,7 @@ VariantMatcher::MatcherOps::canConstructFrom(const DynTypedMatcher &Matcher, llvm::Optional VariantMatcher::MatcherOps::constructVariadicOperator( - DynTypedMatcher::VariadicOperatorFunction Func, + DynTypedMatcher::VariadicOperator Op, ArrayRef InnerMatchers) const { std::vector DynMatchers; for (const auto &InnerMatcher : InnerMatchers) { @@ -72,7 +72,7 @@ VariantMatcher::MatcherOps::constructVariadicOperator( return llvm::None; DynMatchers.push_back(*Inner); } - return DynTypedMatcher::constructVariadic(Func, DynMatchers); + return DynTypedMatcher::constructVariadic(Op, DynMatchers); } VariantMatcher::Payload::~Payload() {} @@ -176,9 +176,9 @@ public: class VariantMatcher::VariadicOpPayload : public VariantMatcher::Payload { public: - VariadicOpPayload(DynTypedMatcher::VariadicOperatorFunction Func, + VariadicOpPayload(DynTypedMatcher::VariadicOperator Op, std::vector Args) - : Func(Func), Args(std::move(Args)) {} + : Op(Op), Args(std::move(Args)) {} llvm::Optional getSingleMatcher() const override { return llvm::Optional(); @@ -196,7 +196,7 @@ public: llvm::Optional getTypedMatcher(const MatcherOps &Ops) const override { - return Ops.constructVariadicOperator(Func, Args); + return Ops.constructVariadicOperator(Op, Args); } bool isConvertibleTo(ast_type_traits::ASTNodeKind Kind, @@ -209,7 +209,7 @@ public: } private: - const DynTypedMatcher::VariadicOperatorFunction Func; + const DynTypedMatcher::VariadicOperator Op; const std::vector Args; }; @@ -225,9 +225,9 @@ VariantMatcher::PolymorphicMatcher(std::vector Matchers) { } VariantMatcher VariantMatcher::VariadicOperatorMatcher( - DynTypedMatcher::VariadicOperatorFunction Func, + DynTypedMatcher::VariadicOperator Op, std::vector Args) { - return VariantMatcher(new VariadicOpPayload(Func, std::move(Args))); + return VariantMatcher(new VariadicOpPayload(Op, std::move(Args))); } llvm::Optional VariantMatcher::getSingleMatcher() const { -- 2.40.0