diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html index 5ab3556890728eef17146d404f1df52eb42783b0..3606367d2fde457f6e9bf9e0e96100741ad2331b 100644 --- a/docs/LibASTMatchersReference.html +++ b/docs/LibASTMatchersReference.html @@ -3968,30 +3968,6 @@ matcher, or is a pointer to a type that matches the InnerMatcher. </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. diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index e3fc4643445538b93088ce9e388c511e95c9da1d..47f89c6361308a240c78261f92a29bc0515d045e 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -821,9 +821,6 @@ 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. diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index e540f072e133755419b6a1af063131e547025600..755542c04a170732569a4483e1a6901e17e7307b 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -16,7 +16,6 @@ #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" @@ -1829,8 +1828,6 @@ 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. diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h index 778b993bc83b5b70af4214fe6baf6d8871cceb7c..712eef0d3ca9943cb14bc6f17ff6d115fa3abe45 100644 --- a/include/clang/ASTMatchers/ASTMatchers.h +++ b/include/clang/ASTMatchers/ASTMatchers.h @@ -3770,47 +3770,6 @@ 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 diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 67024e7c3910b8957a091e258467b5545c44dc08..fa46b24e57c9dff36a1eccc760e0d68f79caa4be 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -1254,35 +1254,32 @@ void ASTContext::setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, 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)); + return Pos->second.size(); } void ASTContext::addOverriddenMethod(const CXXMethodDecl *Method, diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp index 83c7db88f4d9fc2bfc8ad57fb9707df1c9a9e6a9..2a1fac8509eb5881c87e09f941c49175dd557d05 100644 --- a/lib/AST/DeclCXX.cpp +++ b/lib/AST/DeclCXX.cpp @@ -1635,13 +1635,6 @@ unsigned CXXMethodDecl::size_overridden_methods() const { 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*, diff --git a/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp index aa861f4e4da0f75c3965de9f4334fd6f9fa6f740..cc5cf715a706f71d0172a45e31f05f7ff4fbc389 100644 --- a/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp +++ b/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp @@ -1997,49 +1997,5 @@ 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