r272386 - [ASTMatchers] New forEachOverriden matcher.

Chandler Carruth via cfe-commits cfe-commits at lists.llvm.org
Fri Jun 10 21:52:38 PDT 2016


This has broken Windows build bots all day. Here are some recent examples:
http://lab.llvm.org:8011/builders/clang-x86-win2008-selfhost/builds/8506/steps/ninja%20check%201/logs/stdio
http://lab.llvm.org:8011/builders/clang-x64-ninja-win7/builds/12981/steps/ninja%20check%201/logs/stdio

Please pay attention to the bots when you are committing changes. I've
reverted it in r272453.

On Fri, Jun 10, 2016 at 5:01 AM Clement Courbet via cfe-commits <
cfe-commits at lists.llvm.org> wrote:

> Author: courbet
> Date: Fri Jun 10 06:54:43 2016
> New Revision: 272386
>
> URL: http://llvm.org/viewvc/llvm-project?rev=272386&view=rev
> Log:
> [ASTMatchers] New forEachOverriden matcher.
>
> Matches methods overridden by the given method.
>
> Modified:
>     cfe/trunk/docs/LibASTMatchersReference.html
>     cfe/trunk/include/clang/AST/ASTContext.h
>     cfe/trunk/include/clang/AST/DeclCXX.h
>     cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
>     cfe/trunk/lib/AST/ASTContext.cpp
>     cfe/trunk/lib/AST/DeclCXX.cpp
>     cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
>
> Modified: cfe/trunk/docs/LibASTMatchersReference.html
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/LibASTMatchersReference.html?rev=272386&r1=272385&r2=272386&view=diff
>
> ==============================================================================
> --- cfe/trunk/docs/LibASTMatchersReference.html (original)
> +++ cfe/trunk/docs/LibASTMatchersReference.html Fri Jun 10 06:54:43 2016
> @@ -3968,6 +3968,30 @@ matcher, or is a pointer to a type that
>  </pre></td></tr>
>
>
> +<tr><td>Matcher<<a href="
> http://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>></td><td
> class="name" onclick="toggle('forEachOverridden0')"><a
> name="forEachOverridden0Anchor">forEachOverridden</a></td><td>Matcher<<a
> href="http://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>>
> InnerMatcher</td></tr>
> +<tr><td colspan="4" class="doc" id="forEachOverridden0"><pre>Matches each
> method overriden by the given method. This matcher may
> +produce multiple matches.
> +
> +Given
> +  class A { virtual void f(); };
> +  class B : public A { void f(); };
> +  class C : public B { void f(); };
> +cxxMethodDecl(ofClass(hasName("C")),
> +              forEachOverridden(cxxMethodDecl().bind("b"))).bind("d")
> +  matches once, with "b" binding "A::f" and "d" binding "C::f" (Note
> +  that B::f is not overridden by C::f).
> +
> +The check can produce multiple matches in case of multiple inheritance,
> e.g.
> +  class A1 { virtual void f(); };
> +  class A2 { virtual void f(); };
> +  class C : public A1, public A2 { void f(); };
> +cxxMethodDecl(ofClass(hasName("C")),
> +              forEachOverridden(cxxMethodDecl().bind("b"))).bind("d")
> +  matches twice, once with "b" binding "A1::f" and "d" binding "C::f", and
> +  once with "b" binding "A2::f" and "d" binding "C::f".
> +</pre></td></tr>
> +
> +
>  <tr><td>Matcher<<a href="
> http://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>></td><td
> class="name" onclick="toggle('ofClass0')"><a
> name="ofClass0Anchor">ofClass</a></td><td>Matcher<<a href="
> http://clang.llvm.org/doxygen/classclang_1_1CXXRecordDecl.html">CXXRecordDecl</a>>
> InnerMatcher</td></tr>
>  <tr><td colspan="4" class="doc" id="ofClass0"><pre>Matches the class
> declaration that the given method declaration
>  belongs to.
>
> Modified: cfe/trunk/include/clang/AST/ASTContext.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=272386&r1=272385&r2=272386&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/AST/ASTContext.h (original)
> +++ cfe/trunk/include/clang/AST/ASTContext.h Fri Jun 10 06:54:43 2016
> @@ -821,6 +821,9 @@ public:
>    overridden_methods_end(const CXXMethodDecl *Method) const;
>
>    unsigned overridden_methods_size(const CXXMethodDecl *Method) const;
> +  typedef llvm::iterator_range<overridden_cxx_method_iterator>
> +      overridden_method_range;
> +  overridden_method_range overridden_methods(const CXXMethodDecl *Method)
> const;
>
>    /// \brief Note that the given C++ \p Method overrides the given \p
>    /// Overridden method.
>
> Modified: cfe/trunk/include/clang/AST/DeclCXX.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/DeclCXX.h?rev=272386&r1=272385&r2=272386&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/AST/DeclCXX.h (original)
> +++ cfe/trunk/include/clang/AST/DeclCXX.h Fri Jun 10 06:54:43 2016
> @@ -16,6 +16,7 @@
>  #ifndef LLVM_CLANG_AST_DECLCXX_H
>  #define LLVM_CLANG_AST_DECLCXX_H
>
> +#include "clang/AST/ASTContext.h"
>  #include "clang/AST/ASTUnresolvedSet.h"
>  #include "clang/AST/Attr.h"
>  #include "clang/AST/Decl.h"
> @@ -1828,6 +1829,8 @@ public:
>    method_iterator begin_overridden_methods() const;
>    method_iterator end_overridden_methods() const;
>    unsigned size_overridden_methods() const;
> +  typedef ASTContext::overridden_method_range overridden_method_range;
> +  overridden_method_range overridden_methods() const;
>
>    /// Returns the parent of this method declaration, which
>    /// is the class in which this method is defined.
>
> Modified: cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h?rev=272386&r1=272385&r2=272386&view=diff
>
> ==============================================================================
> --- cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h (original)
> +++ cfe/trunk/include/clang/ASTMatchers/ASTMatchers.h Fri Jun 10 06:54:43
> 2016
> @@ -3770,6 +3770,47 @@ AST_MATCHER_P(CXXMethodDecl, ofClass,
>            InnerMatcher.matches(*Parent, Finder, Builder));
>  }
>
> +/// \brief Matches each method overriden by the given method. This
> matcher may
> +/// produce multiple matches.
> +///
> +/// Given
> +/// \code
> +///   class A { virtual void f(); };
> +///   class B : public A { void f(); };
> +///   class C : public B { void f(); };
> +/// \endcode
> +/// cxxMethodDecl(ofClass(hasName("C")),
> +///               forEachOverridden(cxxMethodDecl().bind("b"))).bind("d")
> +///   matches once, with "b" binding "A::f" and "d" binding "C::f" (Note
> +///   that B::f is not overridden by C::f).
> +///
> +/// The check can produce multiple matches in case of multiple
> inheritance, e.g.
> +/// \code
> +///   class A1 { virtual void f(); };
> +///   class A2 { virtual void f(); };
> +///   class C : public A1, public A2 { void f(); };
> +/// \endcode
> +/// cxxMethodDecl(ofClass(hasName("C")),
> +///               forEachOverridden(cxxMethodDecl().bind("b"))).bind("d")
> +///   matches twice, once with "b" binding "A1::f" and "d" binding
> "C::f", and
> +///   once with "b" binding "A2::f" and "d" binding "C::f".
> +AST_MATCHER_P(CXXMethodDecl, forEachOverridden,
> +              internal::Matcher<CXXMethodDecl>, InnerMatcher) {
> +  BoundNodesTreeBuilder Result;
> +  bool Matched = false;
> +  for (const auto *Overridden : Node.overridden_methods()) {
> +    BoundNodesTreeBuilder OverriddenBuilder(*Builder);
> +    const bool OverriddenMatched =
> +        InnerMatcher.matches(*Overridden, Finder, &OverriddenBuilder);
> +    if (OverriddenMatched) {
> +      Matched = true;
> +      Result.addMatch(OverriddenBuilder);
> +    }
> +  }
> +  *Builder = std::move(Result);
> +  return Matched;
> +}
> +
>  /// \brief Matches if the given method declaration is virtual.
>  ///
>  /// Given
>
> Modified: cfe/trunk/lib/AST/ASTContext.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=272386&r1=272385&r2=272386&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/ASTContext.cpp (original)
> +++ cfe/trunk/lib/AST/ASTContext.cpp Fri Jun 10 06:54:43 2016
> @@ -1254,34 +1254,37 @@ void ASTContext::setInstantiatedFromUnna
>
>  ASTContext::overridden_cxx_method_iterator
>  ASTContext::overridden_methods_begin(const CXXMethodDecl *Method) const {
> -  llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator
> Pos
> -    = OverriddenMethods.find(Method->getCanonicalDecl());
> +  llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator
> Pos =
> +      OverriddenMethods.find(Method->getCanonicalDecl());
>    if (Pos == OverriddenMethods.end())
>      return nullptr;
> -
>    return Pos->second.begin();
>  }
>
>  ASTContext::overridden_cxx_method_iterator
>  ASTContext::overridden_methods_end(const CXXMethodDecl *Method) const {
> -  llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator
> Pos
> -    = OverriddenMethods.find(Method->getCanonicalDecl());
> +  llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator
> Pos =
> +      OverriddenMethods.find(Method->getCanonicalDecl());
>    if (Pos == OverriddenMethods.end())
>      return nullptr;
> -
>    return Pos->second.end();
>  }
>
>  unsigned
>  ASTContext::overridden_methods_size(const CXXMethodDecl *Method) const {
> -  llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator
> Pos
> -    = OverriddenMethods.find(Method->getCanonicalDecl());
> +  llvm::DenseMap<const CXXMethodDecl *, CXXMethodVector>::const_iterator
> Pos =
> +      OverriddenMethods.find(Method->getCanonicalDecl());
>    if (Pos == OverriddenMethods.end())
>      return 0;
> -
>    return Pos->second.size();
>  }
>
> +ASTContext::overridden_method_range
> +ASTContext::overridden_methods(const CXXMethodDecl *Method) const {
> +  return overridden_method_range(overridden_methods_begin(Method),
> +                                 overridden_methods_end(Method));
> +}
> +
>  void ASTContext::addOverriddenMethod(const CXXMethodDecl *Method,
>                                       const CXXMethodDecl *Overridden) {
>    assert(Method->isCanonicalDecl() && Overridden->isCanonicalDecl());
>
> Modified: cfe/trunk/lib/AST/DeclCXX.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=272386&r1=272385&r2=272386&view=diff
>
> ==============================================================================
> --- cfe/trunk/lib/AST/DeclCXX.cpp (original)
> +++ cfe/trunk/lib/AST/DeclCXX.cpp Fri Jun 10 06:54:43 2016
> @@ -1635,6 +1635,13 @@ unsigned CXXMethodDecl::size_overridden_
>    return getASTContext().overridden_methods_size(this);
>  }
>
> +CXXMethodDecl::overridden_method_range
> +CXXMethodDecl::overridden_methods() const {
> +  if (isa<CXXConstructorDecl>(this))
> +    return overridden_method_range(nullptr, nullptr);
> +  return getASTContext().overridden_methods(this);
> +}
> +
>  QualType CXXMethodDecl::getThisType(ASTContext &C) const {
>    // C++ 9.3.2p1: The type of this in a member function of a class X is
> X*.
>    // If the member function is declared const, the type of this is const
> X*,
>
> Modified: cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
> URL:
> http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp?rev=272386&r1=272385&r2=272386&view=diff
>
> ==============================================================================
> --- cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp (original)
> +++ cfe/trunk/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp Fri Jun
> 10 06:54:43 2016
> @@ -1997,5 +1997,49 @@ TEST(StatementMatcher, ForFunction) {
>    EXPECT_TRUE(notMatches(CppString2,
> returnStmt(forFunction(hasName("F")))));
>  }
>
> +TEST(Matcher, ForEachOverriden) {
> +  const auto ForEachOverriddenInClass = [](const char *ClassName) {
> +    return cxxMethodDecl(ofClass(hasName(ClassName)), isVirtual(),
> +
>  forEachOverridden(cxxMethodDecl().bind("overridden")))
> +        .bind("override");
> +  };
> +  constexpr const char Code1[] = "class A { virtual void f(); };"
> +                                 "class B : public A { void f(); };"
> +                                 "class C : public B { void f(); };";
> +  // C::f overrides A::f.
> +  EXPECT_TRUE(matchAndVerifyResultTrue(
> +      Code1, ForEachOverriddenInClass("C"),
> +      llvm::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("override",
> "f", 1)));
> +  EXPECT_TRUE(matchAndVerifyResultTrue(
> +      Code1, ForEachOverriddenInClass("C"),
> +      llvm::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("overridden",
> "f",
> +                                                          1)));
> +  // B::f overrides A::f.
> +  EXPECT_TRUE(matchAndVerifyResultTrue(
> +      Code1, ForEachOverriddenInClass("B"),
> +      llvm::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("override",
> "f", 1)));
> +  EXPECT_TRUE(matchAndVerifyResultTrue(
> +      Code1, ForEachOverriddenInClass("B"),
> +      llvm::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("overridden",
> "f",
> +                                                          1)));
> +  // A::f overrides nothing.
> +  EXPECT_TRUE(notMatches(Code1, ForEachOverriddenInClass("A")));
> +
> +  constexpr const char Code2[] =
> +      "class A1 { virtual void f(); };"
> +      "class A2 { virtual void f(); };"
> +      "class B : public A1, public A2 { void f(); };";
> +  // B::f overrides A1::f and A2::f. This produces two matches.
> +  EXPECT_TRUE(matchAndVerifyResultTrue(
> +      Code2, ForEachOverriddenInClass("B"),
> +      llvm::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("override",
> "f", 2)));
> +  EXPECT_TRUE(matchAndVerifyResultTrue(
> +      Code2, ForEachOverriddenInClass("B"),
> +      llvm::make_unique<VerifyIdIsBoundTo<CXXMethodDecl>>("overridden",
> "f",
> +                                                          2)));
> +  // A1::f overrides nothing.
> +  EXPECT_TRUE(notMatches(Code2, ForEachOverriddenInClass("A1")));
> +}
> +
>  } // namespace ast_matchers
>  } // namespace clang
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20160611/801d1e6d/attachment-0001.html>


More information about the cfe-commits mailing list