r195466 - Add support for the 'unless' matcher in the dynamic layer.
Aaron Ballman
aaron at aaronballman.com
Fri Nov 22 14:49:07 PST 2013
This commit is causing failures for me on Windows 7 with MSVC 2013.
74> FAIL: Clang-Unit ::
ASTMatchers/Dynamic/Debug/DynamicASTMatchersTests.exe/RegistryTest.VariadicOp
(6433 of 6775)
74> ******************** TEST 'Clang-Unit ::
ASTMatchers/Dynamic/Debug/DynamicASTMatchersTests.exe/RegistryTest.VariadicOp'
FAILED ********************
74> Note: Google Test filter = RegistryTest.VariadicOp
74>
74> [==========] Running 1 test from 1 test case.
74>
74> [----------] Global test environment set-up.
74>
74> [----------] 1 test from RegistryTest
74>
74> [ RUN ] RegistryTest.VariadicOp
74>
74>E:\llvm\llvm\tools\clang\unittests\ASTMatchers\Dynamic\RegistryTest.cpp(307):
error : Value of: matches("class Bar{};", D)
74>
74> Actual: true
74>
74> Expected: false
74>
74> [ FAILED ] RegistryTest.VariadicOp (173 ms)
74>
74> [----------] 1 test from RegistryTest (173 ms total)
74>
74>
74>
74> [----------] Global test environment tear-down
74>
74> [==========] 1 test from 1 test case ran. (173 ms total)
74>
74> [ PASSED ] 0 tests.
74>
74> [ FAILED ] 1 test, listed below:
74>
74> [ FAILED ] RegistryTest.VariadicOp
74>
74>
74>
74> 1 FAILED TEST
74>
74>
74> ********************
74>
74> Testing Time: 78.98s
74> ********************
74> Failing Tests (1):
74> Clang-Unit ::
ASTMatchers/Dynamic/Debug/DynamicASTMatchersTests.exe/RegistryTest.VariadicOp
74>
74> Expected Passes : 6709
74> Expected Failures : 27
74> Unsupported Tests : 38
74> Unexpected Failures: 1
~Aaron
On Fri, Nov 22, 2013 at 9:41 AM, Samuel Benzaquen <sbenza at google.com> wrote:
> Author: sbenza
> Date: Fri Nov 22 08:41:48 2013
> New Revision: 195466
>
> URL: http://llvm.org/viewvc/llvm-project?rev=195466&view=rev
> Log:
> Add support for the 'unless' matcher in the dynamic layer.
>
> Summary: Add support for the 'unless' matcher in the dynamic layer.
>
> Reviewers: klimek
>
> CC: cfe-commits, revane, klimek
>
> Differential Revision: http://llvm-reviews.chandlerc.com/D2247
>
> Modified:
> cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
> cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h
> cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
> cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h
> cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
> cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
>
> Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=195466&r1=195465&r2=195466&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
> +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Fri Nov 22 08:41:48 2013
> @@ -1317,21 +1317,21 @@ const internal::VariadicAllOfMatcher<Typ
> /// \c b.
> ///
> /// Usable as: Any Matcher
> -const internal::VariadicOperatorMatcherFunc eachOf = {
> +const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> eachOf = {
> internal::EachOfVariadicOperator
> };
>
> /// \brief Matches if any of the given matchers matches.
> ///
> /// Usable as: Any Matcher
> -const internal::VariadicOperatorMatcherFunc anyOf = {
> +const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> anyOf = {
> internal::AnyOfVariadicOperator
> };
>
> /// \brief Matches if all given matchers match.
> ///
> /// Usable as: Any Matcher
> -const internal::VariadicOperatorMatcherFunc allOf = {
> +const internal::VariadicOperatorMatcherFunc<2, UINT_MAX> allOf = {
> internal::AllOfVariadicOperator
> };
>
> @@ -1671,12 +1671,9 @@ const internal::ArgumentAdaptingMatcherF
> /// \endcode
> ///
> /// Usable as: Any Matcher
> -template <typename M>
> -internal::PolymorphicMatcherWithParam1<internal::NotMatcher, M>
> -unless(const M &InnerMatcher) {
> - return internal::PolymorphicMatcherWithParam1<
> - internal::NotMatcher, M>(InnerMatcher);
> -}
> +const internal::VariadicOperatorMatcherFunc<1, 1> unless = {
> + internal::NotUnaryOperator
> +};
>
> /// \brief Matches a node if the declaration associated with that node
> /// matches the given matcher.
>
> Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h?rev=195466&r1=195465&r2=195466&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h (original)
> +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchersInternal.h Fri Nov 22 08:41:48 2013
> @@ -1098,38 +1098,6 @@ private:
> const Matcher<ChildT> ChildMatcher;
> };
>
> -/// \brief Matches nodes of type T if the given Matcher<T> does not match.
> -///
> -/// Type argument MatcherT is required by PolymorphicMatcherWithParam1
> -/// but not actually used. It will always be instantiated with a type
> -/// convertible to Matcher<T>.
> -template <typename T, typename MatcherT>
> -class NotMatcher : public MatcherInterface<T> {
> -public:
> - explicit NotMatcher(const Matcher<T> &InnerMatcher)
> - : InnerMatcher(InnerMatcher) {}
> -
> - virtual bool matches(const T &Node,
> - ASTMatchFinder *Finder,
> - BoundNodesTreeBuilder *Builder) const {
> - // The 'unless' matcher will always discard the result:
> - // If the inner matcher doesn't match, unless returns true,
> - // but the inner matcher cannot have bound anything.
> - // If the inner matcher matches, the result is false, and
> - // any possible binding will be discarded.
> - // We still need to hand in all the bound nodes up to this
> - // point so the inner matcher can depend on bound nodes,
> - // and we need to actively discard the bound nodes, otherwise
> - // the inner matcher will reset the bound nodes if it doesn't
> - // match, but this would be inversed by 'unless'.
> - BoundNodesTreeBuilder Discard(*Builder);
> - return !InnerMatcher.matches(Node, Finder, &Discard);
> - }
> -
> -private:
> - const Matcher<T> InnerMatcher;
> -};
> -
> /// \brief VariadicOperatorMatcher related types.
> /// @{
>
> @@ -1167,14 +1135,14 @@ struct VariadicOperatorNoArg {};
> /// Input matchers can have any type (including other polymorphic matcher
> /// types), and the actual Matcher<T> is generated on demand with an implicit
> /// coversion operator.
> -template <typename P1, typename P2,
> +template <typename P1, typename P2 = VariadicOperatorNoArg,
> typename P3 = VariadicOperatorNoArg,
> typename P4 = VariadicOperatorNoArg,
> typename P5 = VariadicOperatorNoArg>
> class VariadicOperatorMatcher {
> public:
> VariadicOperatorMatcher(VariadicOperatorFunction Func, const P1 &Param1,
> - const P2 &Param2,
> + const P2 &Param2 = VariadicOperatorNoArg(),
> const P3 &Param3 = VariadicOperatorNoArg(),
> const P4 &Param4 = VariadicOperatorNoArg(),
> const P5 &Param5 = VariadicOperatorNoArg())
> @@ -1183,7 +1151,6 @@ public:
>
> template <typename T> operator Matcher<T>() const {
> std::vector<DynTypedMatcher> Matchers;
> -
> addMatcher<T>(Param1, Matchers);
> addMatcher<T>(Param2, Matchers);
> addMatcher<T>(Param3, Matchers);
> @@ -1215,26 +1182,38 @@ private:
> /// \brief Overloaded function object to generate VariadicOperatorMatcher
> /// objects from arbitrary matchers.
> ///
> -/// It supports 2-5 argument overloaded operator(). More can be added if needed.
> +/// It supports 1-5 argument overloaded operator(). More can be added if needed.
> +template <unsigned MinCount, unsigned MaxCount>
> struct VariadicOperatorMatcherFunc {
> VariadicOperatorFunction Func;
>
> + template <unsigned Count, typename T>
> + struct EnableIfValidArity
> + : public llvm::enable_if_c<MinCount <= Count &&Count <= MaxCount, T> {};
> +
> + template <typename M1>
> + typename EnableIfValidArity<1, VariadicOperatorMatcher<M1> >::type
> + operator()(const M1 &P1) const {
> + return VariadicOperatorMatcher<M1>(Func, P1);
> + }
> template <typename M1, typename M2>
> - VariadicOperatorMatcher<M1, M2> operator()(const M1 &P1, const M2 &P2) const {
> + typename EnableIfValidArity<2, VariadicOperatorMatcher<M1, M2> >::type
> + operator()(const M1 &P1, const M2 &P2) const {
> return VariadicOperatorMatcher<M1, M2>(Func, P1, P2);
> }
> template <typename M1, typename M2, typename M3>
> - VariadicOperatorMatcher<M1, M2, M3> operator()(const M1 &P1, const M2 &P2,
> - const M3 &P3) const {
> + typename EnableIfValidArity<3, VariadicOperatorMatcher<M1, M2, M3> >::type
> + operator()(const M1 &P1, const M2 &P2, const M3 &P3) const {
> return VariadicOperatorMatcher<M1, M2, M3>(Func, P1, P2, P3);
> }
> template <typename M1, typename M2, typename M3, typename M4>
> - VariadicOperatorMatcher<M1, M2, M3, M4>
> + typename EnableIfValidArity<4, VariadicOperatorMatcher<M1, M2, M3, M4> >::type
> operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4) const {
> return VariadicOperatorMatcher<M1, M2, M3, M4>(Func, P1, P2, P3, P4);
> }
> template <typename M1, typename M2, typename M3, typename M4, typename M5>
> - VariadicOperatorMatcher<M1, M2, M3, M4, M5>
> + typename EnableIfValidArity<
> + 5, VariadicOperatorMatcher<M1, M2, M3, M4, M5> >::type
> operator()(const M1 &P1, const M2 &P2, const M3 &P3, const M4 &P4,
> const M5 &P5) const {
> return VariadicOperatorMatcher<M1, M2, M3, M4, M5>(Func, P1, P2, P3, P4,
> @@ -1244,6 +1223,13 @@ struct VariadicOperatorMatcherFunc {
>
> /// @}
>
> +/// \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<DynTypedMatcher> InnerMatchers);
> +
> /// \brief Matches nodes for which all provided matchers match.
> bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
> ASTMatchFinder *Finder,
>
> Modified: cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp?rev=195466&r1=195465&r2=195466&view=diff
> ==============================================================================
> --- cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp (original)
> +++ cfe/trunk/lib/ASTMatchers/ASTMatchersInternal.cpp Fri Nov 22 08:41:48 2013
> @@ -34,6 +34,26 @@ void BoundNodesTreeBuilder::addMatch(con
> }
> }
>
> +bool NotUnaryOperator(const ast_type_traits::DynTypedNode DynNode,
> + ASTMatchFinder *Finder, BoundNodesTreeBuilder *Builder,
> + ArrayRef<DynTypedMatcher> InnerMatchers) {
> + if (InnerMatchers.size() != 1)
> + return false;
> +
> + // The 'unless' matcher will always discard the result:
> + // If the inner matcher doesn't match, unless returns true,
> + // but the inner matcher cannot have bound anything.
> + // If the inner matcher matches, the result is false, and
> + // any possible binding will be discarded.
> + // We still need to hand in all the bound nodes up to this
> + // point so the inner matcher can depend on bound nodes,
> + // and we need to actively discard the bound nodes, otherwise
> + // the inner matcher will reset the bound nodes if it doesn't
> + // match, but this would be inversed by 'unless'.
> + BoundNodesTreeBuilder Discard(*Builder);
> + return !InnerMatchers[0].matches(DynNode, Finder, &Discard);
> +}
> +
> bool AllOfVariadicOperator(const ast_type_traits::DynTypedNode DynNode,
> ASTMatchFinder *Finder,
> BoundNodesTreeBuilder *Builder,
>
> Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h?rev=195466&r1=195465&r2=195466&view=diff
> ==============================================================================
> --- cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h (original)
> +++ cfe/trunk/lib/ASTMatchers/Dynamic/Marshallers.h Fri Nov 22 08:41:48 2013
> @@ -347,12 +347,22 @@ private:
> class VariadicOperatorMatcherCreateCallback : public MatcherCreateCallback {
> public:
> typedef ast_matchers::internal::VariadicOperatorFunction VarFunc;
> - VariadicOperatorMatcherCreateCallback(VarFunc Func, StringRef MatcherName)
> - : Func(Func), MatcherName(MatcherName) {}
> + VariadicOperatorMatcherCreateCallback(unsigned MinCount, unsigned MaxCount,
> + VarFunc Func, StringRef MatcherName)
> + : MinCount(MinCount), MaxCount(MaxCount), Func(Func),
> + MatcherName(MatcherName) {}
>
> virtual VariantMatcher run(const SourceRange &NameRange,
> ArrayRef<ParserValue> Args,
> Diagnostics *Error) const {
> + if (Args.size() < MinCount || MaxCount < Args.size()) {
> + const std::string MaxStr =
> + (MaxCount == UINT_MAX ? "" : Twine(MaxCount)).str();
> + Error->addError(NameRange, Error->ET_RegistryWrongArgCount)
> + << ("(" + Twine(MinCount) + ", " + MaxStr + ")") << Args.size();
> + return VariantMatcher();
> + }
> +
> std::vector<VariantMatcher> InnerArgs;
> for (size_t i = 0, e = Args.size(); i != e; ++i) {
> const ParserValue &Arg = Args[i];
> @@ -368,6 +378,8 @@ public:
> }
>
> private:
> + const unsigned MinCount;
> + const unsigned MaxCount;
> const VarFunc Func;
> const StringRef MatcherName;
> };
> @@ -439,10 +451,13 @@ AdaptativeOverloadCollector<ArgumentAdap
> }
>
> /// \brief Variadic operator overload.
> -MatcherCreateCallback *makeMatcherAutoMarshall(
> - ast_matchers::internal::VariadicOperatorMatcherFunc Func,
> - StringRef MatcherName) {
> - return new VariadicOperatorMatcherCreateCallback(Func.Func, MatcherName);
> +template <unsigned MinCount, unsigned MaxCount>
> +MatcherCreateCallback *
> +makeMatcherAutoMarshall(ast_matchers::internal::VariadicOperatorMatcherFunc<
> + MinCount, MaxCount> Func,
> + StringRef MatcherName) {
> + return new VariadicOperatorMatcherCreateCallback(MinCount, MaxCount,
> + Func.Func, MatcherName);
> }
>
> } // namespace internal
>
> Modified: cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp?rev=195466&r1=195465&r2=195466&view=diff
> ==============================================================================
> --- cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp (original)
> +++ cfe/trunk/lib/ASTMatchers/Dynamic/Registry.cpp Fri Nov 22 08:41:48 2013
> @@ -76,7 +76,6 @@ RegistryMaps::RegistryMaps() {
> // ofKind
> //
> // Polymorphic + argument overload:
> - // unless
> // findAll
> //
> // Other:
> @@ -285,6 +284,7 @@ RegistryMaps::RegistryMaps() {
> REGISTER_MATCHER(typedefType);
> REGISTER_MATCHER(unaryExprOrTypeTraitExpr);
> REGISTER_MATCHER(unaryOperator);
> + REGISTER_MATCHER(unless);
> REGISTER_MATCHER(userDefinedLiteral);
> REGISTER_MATCHER(usingDecl);
> REGISTER_MATCHER(varDecl);
>
> Modified: cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp?rev=195466&r1=195465&r2=195466&view=diff
> ==============================================================================
> --- cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp (original)
> +++ cfe/trunk/unittests/ASTMatchers/Dynamic/RegistryTest.cpp Fri Nov 22 08:41:48 2013
> @@ -295,6 +295,17 @@ TEST_F(RegistryTest, VariadicOp) {
> EXPECT_FALSE(matches("int i = 0;", D));
> EXPECT_TRUE(matches("class Bar{};", D));
> EXPECT_FALSE(matches("class OtherBar{};", D));
> +
> + D = constructMatcher(
> + "recordDecl",
> + constructMatcher(
> + "unless",
> + constructMatcher("namedDecl",
> + constructMatcher("hasName", std::string("Bar")))))
> + .getTypedMatcher<Decl>();
> +
> + EXPECT_FALSE(matches("class Bar{};", D));
> + EXPECT_TRUE(matches("class OtherBar{};", D));
> }
>
> TEST_F(RegistryTest, Errors) {
> @@ -307,6 +318,15 @@ TEST_F(RegistryTest, Errors) {
> EXPECT_TRUE(constructMatcher("isArrow", std::string(), Error.get()).isNull());
> EXPECT_EQ("Incorrect argument count. (Expected = 0) != (Actual = 1)",
> Error->toString());
> + Error.reset(new Diagnostics());
> + EXPECT_TRUE(constructMatcher("anyOf", Error.get()).isNull());
> + EXPECT_EQ("Incorrect argument count. (Expected = (2, )) != (Actual = 0)",
> + Error->toString());
> + Error.reset(new Diagnostics());
> + EXPECT_TRUE(constructMatcher("unless", std::string(), std::string(),
> + Error.get()).isNull());
> + EXPECT_EQ("Incorrect argument count. (Expected = (1, 1)) != (Actual = 2)",
> + Error->toString());
>
> // Bad argument type
> Error.reset(new Diagnostics());
> @@ -324,7 +344,8 @@ TEST_F(RegistryTest, Errors) {
>
> // Bad argument type with variadic.
> Error.reset(new Diagnostics());
> - EXPECT_TRUE(constructMatcher("anyOf", std::string(), Error.get()).isNull());
> + EXPECT_TRUE(constructMatcher("anyOf", std::string(), std::string(),
> + Error.get()).isNull());
> EXPECT_EQ(
> "Incorrect type for arg 1. (Expected = Matcher<>) != (Actual = String)",
> Error->toString());
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
More information about the cfe-commits
mailing list