[clang-tools-extra] ed3b1f9 - [clangd] go-to-implementation on a base class jumps to all subclasses.
Haojian Wu via cfe-commits
cfe-commits at lists.llvm.org
Fri Jan 8 04:51:23 PST 2021
Author: Haojian Wu
Date: 2021-01-08T13:50:57+01:00
New Revision: ed3b1f906115a0dcd2542fa294d0382a42eb177d
URL: https://github.com/llvm/llvm-project/commit/ed3b1f906115a0dcd2542fa294d0382a42eb177d
DIFF: https://github.com/llvm/llvm-project/commit/ed3b1f906115a0dcd2542fa294d0382a42eb177d.diff
LOG: [clangd] go-to-implementation on a base class jumps to all subclasses.
Differential Revision: https://reviews.llvm.org/D92749
Added:
Modified:
clang-tools-extra/clangd/XRefs.cpp
clang-tools-extra/clangd/XRefs.h
clang-tools-extra/clangd/unittests/XRefsTests.cpp
Removed:
################################################################################
diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp
index c7ec401c6479..ebe03e74a4a7 100644
--- a/clang-tools-extra/clangd/XRefs.cpp
+++ b/clang-tools-extra/clangd/XRefs.cpp
@@ -292,13 +292,14 @@ const NamedDecl *getPreferredDecl(const NamedDecl *D) {
return D;
}
-std::vector<LocatedSymbol> findOverrides(llvm::DenseSet<SymbolID> IDs,
- const SymbolIndex *Index,
- llvm::StringRef MainFilePath) {
+std::vector<LocatedSymbol> findImplementors(llvm::DenseSet<SymbolID> IDs,
+ RelationKind Predicate,
+ const SymbolIndex *Index,
+ llvm::StringRef MainFilePath) {
if (IDs.empty())
return {};
RelationsRequest Req;
- Req.Predicate = RelationKind::OverriddenBy;
+ Req.Predicate = Predicate;
Req.Subjects = std::move(IDs);
std::vector<LocatedSymbol> Results;
Index->relations(Req, [&](const SymbolID &Subject, const Symbol &Object) {
@@ -458,7 +459,8 @@ locateASTReferent(SourceLocation CurLoc, const syntax::Token *TouchedIdentifier,
});
}
- auto Overrides = findOverrides(VirtualMethods, Index, MainFilePath);
+ auto Overrides = findImplementors(VirtualMethods, RelationKind::OverriddenBy,
+ Index, MainFilePath);
Result.insert(Result.end(), Overrides.begin(), Overrides.end());
return Result;
}
@@ -1239,12 +1241,20 @@ std::vector<LocatedSymbol> findImplementations(ParsedAST &AST, Position Pos,
}
DeclRelationSet Relations =
DeclRelation::TemplatePattern | DeclRelation::Alias;
- llvm::DenseSet<SymbolID> VirtualMethods;
- for (const NamedDecl *ND : getDeclAtPosition(AST, *CurLoc, Relations))
- if (const CXXMethodDecl *CXXMD = llvm::dyn_cast<CXXMethodDecl>(ND))
- if (CXXMD->isVirtual())
- VirtualMethods.insert(getSymbolID(ND));
- return findOverrides(std::move(VirtualMethods), Index, *MainFilePath);
+ llvm::DenseSet<SymbolID> IDs;
+ RelationKind QueryKind;
+ for (const NamedDecl *ND : getDeclAtPosition(AST, *CurLoc, Relations)) {
+ if (const auto *CXXMD = llvm::dyn_cast<CXXMethodDecl>(ND)) {
+ if (CXXMD->isVirtual()) {
+ IDs.insert(getSymbolID(ND));
+ QueryKind = RelationKind::OverriddenBy;
+ }
+ } else if (const auto *RD = dyn_cast<CXXRecordDecl>(ND)) {
+ IDs.insert(getSymbolID(RD));
+ QueryKind = RelationKind::BaseOf;
+ }
+ }
+ return findImplementors(std::move(IDs), QueryKind, Index, *MainFilePath);
}
ReferencesResult findReferences(ParsedAST &AST, Position Pos, uint32_t Limit,
diff --git a/clang-tools-extra/clangd/XRefs.h b/clang-tools-extra/clangd/XRefs.h
index eca174f59096..4c745eb9bc51 100644
--- a/clang-tools-extra/clangd/XRefs.h
+++ b/clang-tools-extra/clangd/XRefs.h
@@ -83,7 +83,9 @@ struct ReferencesResult {
bool HasMore = false;
};
-/// Returns implementations of the virtual function at a specified \p Pos.
+/// Returns implementations at a specified \p Pos:
+/// - overrides for a virtual method;
+/// - subclasses for a base class;
std::vector<LocatedSymbol> findImplementations(ParsedAST &AST, Position Pos,
const SymbolIndex *Index);
diff --git a/clang-tools-extra/clangd/unittests/XRefsTests.cpp b/clang-tools-extra/clangd/unittests/XRefsTests.cpp
index 26e06dad9250..508634ec908a 100644
--- a/clang-tools-extra/clangd/unittests/XRefsTests.cpp
+++ b/clang-tools-extra/clangd/unittests/XRefsTests.cpp
@@ -1611,11 +1611,11 @@ TEST(LocateSymbol, NearbyIdentifier) {
TEST(FindImplementations, Inheritance) {
llvm::StringRef Test = R"cpp(
- struct Base {
+ struct $0^Base {
virtual void F$1^oo();
void C$4^oncrete();
};
- struct Child1 : Base {
+ struct $0[[Child1]] : Base {
void $1[[Fo$3^o]]() override;
virtual void B$2^ar();
void Concrete(); // No implementations for concrete methods.
@@ -1625,7 +1625,7 @@ TEST(FindImplementations, Inheritance) {
void $2[[Bar]]() override;
};
void FromReference() {
- Base* B;
+ $0^Base* B;
B->Fo$1^o();
B->C$4^oncrete();
&Base::Fo$1^o;
@@ -1633,12 +1633,16 @@ TEST(FindImplementations, Inheritance) {
C1->B$2^ar();
C1->Fo$3^o();
}
+ // CRTP should work.
+ template<typename T>
+ struct $5^TemplateBase {};
+ struct $5[[Child3]] : public TemplateBase<Child3> {};
)cpp";
Annotations Code(Test);
auto TU = TestTU::withCode(Code.code());
auto AST = TU.build();
- for (const std::string &Label : {"1", "2", "3", "4"}) {
+ for (StringRef Label : {"0", "1", "2", "3", "4", "5"}) {
for (const auto &Point : Code.points(Label)) {
EXPECT_THAT(findImplementations(AST, Point, TU.index().get()),
UnorderedPointwise(DeclRange(), Code.ranges(Label)))
More information about the cfe-commits
mailing list