usaxena95 updated this revision to Diff 305835.
usaxena95 edited the summary of this revision.
usaxena95 added a comment.
Minor fixes.
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D91626/new/
https://reviews.llvm.org/D91626
Files:
clang-tools-extra/clangd/ClangdLSPServer.cpp
clang-tools-extra/clangd/ClangdLSPServer.h
clang-tools-extra/clangd/ClangdServer.cpp
clang-tools-extra/clangd/ClangdServer.h
clang-tools-extra/clangd/Protocol.cpp
clang-tools-extra/clangd/Protocol.h
clang-tools-extra/clangd/XRefs.cpp
clang-tools-extra/clangd/XRefs.h
clang-tools-extra/clangd/test/initialize-params.test
clang-tools-extra/clangd/unittests/XRefsTests.cpp
Index: clang-tools-extra/clangd/unittests/XRefsTests.cpp
===================================================================
--- clang-tools-extra/clangd/unittests/XRefsTests.cpp
+++ clang-tools-extra/clangd/unittests/XRefsTests.cpp
@@ -1464,6 +1464,44 @@
}
}
+TEST(FindImplementations, Inheritance) {
+ llvm::StringRef Test = R"cpp(
+ struct Base {
+ virtual void F$1^oo();
+ };
+ struct Child1 : Base {
+ void $1[[Fo$3^o]]() override;
+ virtual void B$2^ar();
+ };
+ struct Child2 : Child1 {
+ void $3[[Foo]]() override;
+ void $2[[Bar]]() override;
+ };
+ void FromReference() {
+ Base* B;
+ B->Fo$1^o();
+ &Base::Fo$1^o;
+ Child1 * C1;
+ C1->B$2^ar();
+ C1->Fo$3^o();
+ }
+ )cpp";
+
+ Annotations Code(Test);
+ auto TU = TestTU::withCode(Code.code());
+ auto AST = TU.build();
+ for (const std::string &Label : {"1", "2", "3"}) {
+ std::vector<Matcher<Location>> ExpectedLocations;
+ for (const auto &R : Code.ranges(Label))
+ ExpectedLocations.push_back(RangeIs(R));
+ for (const auto &Point : Code.points(Label)) {
+ EXPECT_THAT(findImplementations(AST, Point, TU.index().get()).References,
+ UnorderedElementsAreArray(ExpectedLocations))
+ << Code.code() << " at " << Point;
+ }
+ }
+}
+
TEST(FindReferences, WithinAST) {
const char *Tests[] = {
R"cpp(// Local variable
Index: clang-tools-extra/clangd/test/initialize-params.test
===================================================================
--- clang-tools-extra/clangd/test/initialize-params.test
+++ clang-tools-extra/clangd/test/initialize-params.test
@@ -66,7 +66,8 @@
# CHECK-NEXT: ]
# CHECK-NEXT: },
# CHECK-NEXT: "hoverProvider": true,
-# CHECK-NEXT: "memoryUsageProvider": true
+# CHECK-NEXT: "implementationProvider": true,
+# CHECK-NEXT: "memoryUsageProvider": true,
# CHECK-NEXT: "referencesProvider": true,
# CHECK-NEXT: "renameProvider": true,
# CHECK-NEXT: "selectionRangeProvider": true,
Index: clang-tools-extra/clangd/XRefs.h
===================================================================
--- clang-tools-extra/clangd/XRefs.h
+++ clang-tools-extra/clangd/XRefs.h
@@ -82,6 +82,11 @@
std::vector<Location> References;
bool HasMore = false;
};
+
+/// Returns implementations of the virtual function at a specified \p Pos.
+ReferencesResult findImplementations(ParsedAST &AST, Position Pos,
+ const SymbolIndex *Index);
+
/// Returns references of the symbol at a specified \p Pos.
/// \p Limit limits the number of results returned (0 means no limit).
ReferencesResult findReferences(ParsedAST &AST, Position Pos, uint32_t Limit,
Index: clang-tools-extra/clangd/XRefs.cpp
===================================================================
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -1124,6 +1124,38 @@
return Result;
}
+ReferencesResult findImplementations(ParsedAST &AST, Position Pos,
+ const SymbolIndex *Index) {
+ ReferencesResult Results;
+ // We rely on index to find the implementations in subclasses.
+ if (!Index)
+ return Results;
+ const SourceManager &SM = AST.getSourceManager();
+ auto MainFilePath =
+ getCanonicalPath(SM.getFileEntryForID(SM.getMainFileID()), SM);
+ if (!MainFilePath) {
+ elog("Failed to get a path for the main file, so no implementations.");
+ return Results;
+ }
+ auto CurLoc = sourceLocationInMainFile(SM, Pos);
+
+ DeclRelationSet Relations =
+ DeclRelation::TemplatePattern | DeclRelation::Alias;
+ RelationsRequest Req;
+ Req.Predicate = RelationKind::OverriddenBy;
+ for (const NamedDecl *ND : getDeclAtPosition(AST, *CurLoc, Relations))
+ if (llvm::isa<CXXMethodDecl>(ND))
+ Req.Subjects.insert(getSymbolID(ND));
+
+ if (Req.Subjects.empty())
+ return Results;
+ Index->relations(Req, [&](const SymbolID &Subject, const Symbol &Object) {
+ if (auto Loc = symbolToLocation(Object, *MainFilePath))
+ Results.References.push_back(*Loc);
+ });
+ return Results;
+}
+
ReferencesResult findReferences(ParsedAST &AST, Position Pos, uint32_t Limit,
const SymbolIndex *Index) {
if (!Limit)
Index: clang-tools-extra/clangd/Protocol.h
===================================================================
--- clang-tools-extra/clangd/Protocol.h
+++ clang-tools-extra/clangd/Protocol.h
@@ -1402,6 +1402,10 @@
};
bool fromJSON(const llvm::json::Value &, ReferenceParams &, llvm::json::Path);
+struct ImplementationParams : public TextDocumentPositionParams {};
+bool fromJSON(const llvm::json::Value &, ImplementationParams &,
+ llvm::json::Path);
+
/// Clangd extension: indicates the current state of the file in clangd,
/// sent from server via the `textDocument/clangd.fileStatus` notification.
struct FileStatus {
Index: clang-tools-extra/clangd/Protocol.cpp
===================================================================
--- clang-tools-extra/clangd/Protocol.cpp
+++ clang-tools-extra/clangd/Protocol.cpp
@@ -1209,6 +1209,12 @@
return fromJSON(Params, Base, P);
}
+bool fromJSON(const llvm::json::Value &Params, ImplementationParams &R,
+ llvm::json::Path P) {
+ TextDocumentPositionParams &Base = R;
+ return fromJSON(Params, Base, P);
+}
+
static const char *toString(OffsetEncoding OE) {
switch (OE) {
case OffsetEncoding::UTF8:
Index: clang-tools-extra/clangd/ClangdServer.h
===================================================================
--- clang-tools-extra/clangd/ClangdServer.h
+++ clang-tools-extra/clangd/ClangdServer.h
@@ -253,6 +253,10 @@
/// Retrieve ranges that can be used to fold code within the specified file.
void foldingRanges(StringRef File, Callback<std::vector<FoldingRange>> CB);
+ /// Retrieve implementations for virtual method.
+ void findImplementations(PathRef File, Position Pos,
+ Callback<ReferencesResult> CB);
+
/// Retrieve locations for symbol references.
void findReferences(PathRef File, Position Pos, uint32_t Limit,
Callback<ReferencesResult> CB);
Index: clang-tools-extra/clangd/ClangdServer.cpp
===================================================================
--- clang-tools-extra/clangd/ClangdServer.cpp
+++ clang-tools-extra/clangd/ClangdServer.cpp
@@ -717,6 +717,18 @@
TUScheduler::InvalidateOnUpdate);
}
+void ClangdServer::findImplementations(PathRef File, Position Pos,
+ Callback<ReferencesResult> CB) {
+ auto Action = [Pos, CB = std::move(CB),
+ this](llvm::Expected<InputsAndAST> InpAST) mutable {
+ if (!InpAST)
+ return CB(InpAST.takeError());
+ CB(clangd::findImplementations(InpAST->AST, Pos, Index));
+ };
+
+ WorkScheduler.runWithAST("Implementations", File, std::move(Action));
+}
+
void ClangdServer::findReferences(PathRef File, Position Pos, uint32_t Limit,
Callback<ReferencesResult> CB) {
auto Action = [Pos, Limit, CB = std::move(CB),
Index: clang-tools-extra/clangd/ClangdLSPServer.h
===================================================================
--- clang-tools-extra/clangd/ClangdLSPServer.h
+++ clang-tools-extra/clangd/ClangdLSPServer.h
@@ -114,6 +114,8 @@
Callback<std::vector<Location>>);
void onGoToDefinition(const TextDocumentPositionParams &,
Callback<std::vector<Location>>);
+ void onImplementation(const ImplementationParams &,
+ Callback<std::vector<Location>>);
void onReference(const ReferenceParams &, Callback<std::vector<Location>>);
void onSwitchSourceHeader(const TextDocumentIdentifier &,
Callback<llvm::Optional<URIForFile>>);
Index: clang-tools-extra/clangd/ClangdLSPServer.cpp
===================================================================
--- clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -612,6 +612,7 @@
{"selectionRangeProvider", true},
{"documentSymbolProvider", true},
{"workspaceSymbolProvider", true},
+ {"implementationProvider", true},
{"referencesProvider", true},
{"executeCommandProvider",
llvm::json::Object{
@@ -1288,6 +1289,18 @@
});
}
+void ClangdLSPServer::onImplementation(const ImplementationParams &Params,
+ Callback<std::vector<Location>> Reply) {
+ Server->findImplementations(
+ Params.textDocument.uri.file(), Params.position,
+ [Reply =
+ std::move(Reply)](llvm::Expected<ReferencesResult> Impls) mutable {
+ if (!Impls)
+ return Reply(Impls.takeError());
+ return Reply(std::move(Impls->References));
+ });
+}
+
void ClangdLSPServer::onSymbolInfo(const TextDocumentPositionParams &Params,
Callback<std::vector<SymbolDetails>> Reply) {
Server->symbolInfo(Params.textDocument.uri.file(), Params.position,
@@ -1424,6 +1437,7 @@
MsgHandler->bind("textDocument/definition", &ClangdLSPServer::onGoToDefinition);
MsgHandler->bind("textDocument/declaration", &ClangdLSPServer::onGoToDeclaration);
MsgHandler->bind("textDocument/references", &ClangdLSPServer::onReference);
+ MsgHandler->bind("textDocument/implementation", &ClangdLSPServer::onImplementation);
MsgHandler->bind("textDocument/switchSourceHeader", &ClangdLSPServer::onSwitchSourceHeader);
MsgHandler->bind("textDocument/prepareRename", &ClangdLSPServer::onPrepareRename);
MsgHandler->bind("textDocument/rename", &ClangdLSPServer::onRename);
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits