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