summaryrefslogtreecommitdiffstats
path: root/include/clang
diff options
context:
space:
mode:
authorClement Courbet <courbet@google.com>2016-07-05 07:49:31 +0000
committerClement Courbet <courbet@google.com>2016-07-05 07:49:31 +0000
commit7154466fc457c1b7153419f3ad45c4d80bbc6b4a (patch)
tree59e0740e3288c9b09f49ef0561732e3cd4d3a59d /include/clang
parent5889a98a460b6e96bc5db3f32450d1d14d654573 (diff)
[ASTMatchers] New forEachOverriden matcher.
Matches methods overridden by the given method. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@274531 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang')
-rw-r--r--include/clang/AST/ASTContext.h3
-rw-r--r--include/clang/AST/DeclCXX.h3
-rw-r--r--include/clang/ASTMatchers/ASTMatchers.h41
3 files changed, 47 insertions, 0 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 93a0b48133..2efef57c4f 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -825,6 +825,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.
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index a8f00cb327..66acfee60d 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -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"
@@ -1829,6 +1830,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.
diff --git a/include/clang/ASTMatchers/ASTMatchers.h b/include/clang/ASTMatchers/ASTMatchers.h
index 23d2f84f67..5ba154d335 100644
--- a/include/clang/ASTMatchers/ASTMatchers.h
+++ b/include/clang/ASTMatchers/ASTMatchers.h
@@ -3809,6 +3809,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