kadircet updated this revision to Diff 198630.
kadircet marked 23 inline comments as done.
kadircet added a comment.
- Address comments
- Make little modifications to existing tests
Repository:
rG LLVM Github Monorepo
CHANGES SINCE LAST ACTION
https://reviews.llvm.org/D61497/new/
https://reviews.llvm.org/D61497
Files:
clang-tools-extra/clangd/ClangdLSPServer.cpp
clang-tools-extra/clangd/ClangdServer.cpp
clang-tools-extra/clangd/ClangdServer.h
clang-tools-extra/clangd/XRefs.cpp
clang-tools-extra/clangd/XRefs.h
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
@@ -937,7 +937,7 @@
^auto i = {1,2};
}
)cpp",
- "class std::initializer_list<int>",
+ "template<> class initializer_list<int> {}",
},
{
R"cpp(// User defined conversion to auto
@@ -1012,7 +1012,7 @@
return Bar();
}
)cpp",
- "struct Bar",
+ "struct Bar {}",
},
{
R"cpp(// trailing return type
@@ -1021,7 +1021,7 @@
return Bar();
}
)cpp",
- "struct Bar",
+ "struct Bar {}",
},
{
R"cpp(// auto in function return
@@ -1030,7 +1030,7 @@
return Bar();
}
)cpp",
- "struct Bar",
+ "struct Bar {}",
},
{
R"cpp(// auto& in function return
@@ -1039,7 +1039,7 @@
return Bar();
}
)cpp",
- "struct Bar",
+ "struct Bar {}",
},
{
R"cpp(// auto* in function return
@@ -1049,7 +1049,7 @@
return bar;
}
)cpp",
- "struct Bar",
+ "struct Bar {}",
},
{
R"cpp(// const auto& in function return
@@ -1058,7 +1058,7 @@
return Bar();
}
)cpp",
- "struct Bar",
+ "struct Bar {}",
},
{
R"cpp(// decltype(auto) in function return
@@ -1067,7 +1067,7 @@
return Bar();
}
)cpp",
- "struct Bar",
+ "struct Bar {}",
},
{
R"cpp(// decltype(auto) reference in function return
@@ -1136,7 +1136,7 @@
^decltype(test()) i = test();
}
)cpp",
- "struct Bar",
+ "struct Bar {}",
},
{
R"cpp(// decltype of var with decltype.
@@ -1185,7 +1185,8 @@
auto AST = TU.build();
if (auto H = getHover(AST, T.point())) {
EXPECT_NE("", Test.ExpectedHover) << Test.Input;
- EXPECT_EQ(H->contents.value, Test.ExpectedHover.str()) << Test.Input;
+ EXPECT_EQ(H->render().contents.value, Test.ExpectedHover.str())
+ << Test.Input;
} else
EXPECT_EQ("", Test.ExpectedHover.str()) << Test.Input;
}
Index: clang-tools-extra/clangd/XRefs.h
===================================================================
--- clang-tools-extra/clangd/XRefs.h
+++ clang-tools-extra/clangd/XRefs.h
@@ -16,7 +16,10 @@
#include "ClangdUnit.h"
#include "Protocol.h"
#include "index/Index.h"
+#include "index/SymbolLocation.h"
+#include "clang/Index/IndexSymbol.h"
#include "llvm/ADT/Optional.h"
+#include "llvm/Support/raw_ostream.h"
#include <vector>
namespace clang {
@@ -46,8 +49,53 @@
std::vector<DocumentHighlight> findDocumentHighlights(ParsedAST &AST,
Position Pos);
+/// Contains detailed information about a Symbol. Especially useful when
+/// generating hover responses. It is not serialized so that embedding clients
+/// can choose to serialize it w.r.t their UI capabilities.
+struct HoverInfo {
+ /// Represents parameters of a function, a template or a macro.
+ /// For example:
+ /// - void foo(ParamType Name = DefaultValue)
+ /// - #define FOO(Name)
+ /// - template <ParamType Name = DefaultType> class Foo {};
+ struct Param {
+ /// The pretty-printed parameter type, e.g. "int", or "typename" (in
+ /// TemplateParameters)
+ llvm::Optional<std::string> Type;
+ /// None for unnamed parameters.
+ llvm::Optional<std::string> Name;
+ /// None if no default is provided.
+ llvm::Optional<std::string> Default;
+ };
+
+ std::string Name;
+ std::string Scope;
+ llvm::Optional<Range> SymRange;
+ /// Scope containing the symbol. e.g, "global namespace", "function x::Y"
+ /// - None for deduced types, e.g "auto", "decltype" keywords.
+ llvm::Optional<std::string> ContainedIn;
+ SymbolKind Kind;
+ std::string Documentation;
+ /// Source code containing the definition of the symbol.
+ std::string Definition;
+
+ /// Pretty-printed variable type.
+ /// Set only for variables.
+ llvm::Optional<std::string> Type;
+ /// Set for functions and lambadas.
+ llvm::Optional<std::string> ReturnType;
+ /// Set for functions, lambdas and macros with parameters.
+ llvm::Optional<std::vector<Param>> Parameters;
+ /// Set for all template declarations(function, class, variable).
+ llvm::Optional<std::vector<Param>> TemplateParameters;
+
+ /// Lower to LSP struct.
+ Hover render() const;
+};
+llvm::raw_ostream &operator<<(llvm::raw_ostream &, const HoverInfo::Param &);
+
/// Get the hover information when hovering at \p Pos.
-llvm::Optional<Hover> getHover(ParsedAST &AST, Position Pos);
+llvm::Optional<HoverInfo> getHover(ParsedAST &AST, Position Pos);
/// Returns reference locations of the symbol at a specified \p Pos.
/// \p Limit limits the number of results returned (0 means no limit).
Index: clang-tools-extra/clangd/XRefs.cpp
===================================================================
--- clang-tools-extra/clangd/XRefs.cpp
+++ clang-tools-extra/clangd/XRefs.cpp
@@ -7,21 +7,33 @@
//===----------------------------------------------------------------------===//
#include "XRefs.h"
#include "AST.h"
+#include "CodeCompletionStrings.h"
#include "FindSymbols.h"
#include "Logger.h"
+#include "Protocol.h"
#include "SourceCode.h"
#include "URI.h"
#include "index/Merge.h"
#include "index/SymbolCollector.h"
#include "index/SymbolLocation.h"
+#include "clang/AST/ASTContext.h"
+#include "clang/AST/Decl.h"
#include "clang/AST/DeclTemplate.h"
+#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/AST/Type.h"
+#include "clang/Basic/LLVM.h"
+#include "clang/Basic/SourceLocation.h"
#include "clang/Index/IndexDataConsumer.h"
#include "clang/Index/IndexSymbol.h"
#include "clang/Index/IndexingAction.h"
#include "clang/Index/USRGeneration.h"
+#include "llvm/ADT/None.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Casting.h"
+#include "llvm/Support/FormatVariadic.h"
#include "llvm/Support/Path.h"
+#include "llvm/Support/raw_ostream.h"
namespace clang {
namespace clangd {
@@ -241,17 +253,17 @@
return {DeclMacrosFinder.getFoundDecls(), DeclMacrosFinder.takeMacroInfos()};
}
-Range getTokenRange(ParsedAST &AST, SourceLocation TokLoc) {
- const SourceManager &SourceMgr = AST.getASTContext().getSourceManager();
- SourceLocation LocEnd = Lexer::getLocForEndOfToken(
- TokLoc, 0, SourceMgr, AST.getASTContext().getLangOpts());
+Range getTokenRange(ASTContext &AST, SourceLocation TokLoc) {
+ const SourceManager &SourceMgr = AST.getSourceManager();
+ SourceLocation LocEnd =
+ Lexer::getLocForEndOfToken(TokLoc, 0, SourceMgr, AST.getLangOpts());
return {sourceLocToPosition(SourceMgr, TokLoc),
sourceLocToPosition(SourceMgr, LocEnd)};
}
-llvm::Optional<Location> makeLocation(ParsedAST &AST, SourceLocation TokLoc,
+llvm::Optional<Location> makeLocation(ASTContext &AST, SourceLocation TokLoc,
llvm::StringRef TUPath) {
- const SourceManager &SourceMgr = AST.getASTContext().getSourceManager();
+ const SourceManager &SourceMgr = AST.getSourceManager();
const FileEntry *F = SourceMgr.getFileEntryForID(SourceMgr.getFileID(TokLoc));
if (!F)
return None;
@@ -299,8 +311,8 @@
// As a consequence, there's no need to look them up in the index either.
std::vector<LocatedSymbol> Result;
for (auto M : Symbols.Macros) {
- if (auto Loc =
- makeLocation(AST, M.Info->getDefinitionLoc(), *MainFilePath)) {
+ if (auto Loc = makeLocation(AST.getASTContext(), M.Info->getDefinitionLoc(),
+ *MainFilePath)) {
LocatedSymbol Macro;
Macro.Name = M.Name;
Macro.PreferredDeclaration = *Loc;
@@ -320,7 +332,7 @@
// Emit all symbol locations (declaration or definition) from AST.
for (const Decl *D : Symbols.Decls) {
- auto Loc = makeLocation(AST, findNameLoc(D), *MainFilePath);
+ auto Loc = makeLocation(AST.getASTContext(), findNameLoc(D), *MainFilePath);
if (!Loc)
continue;
@@ -441,6 +453,73 @@
return std::move(RefFinder).take();
}
+// FIXME: Expose in AST/Decl ?
+void printSpecifiers(llvm::raw_ostream &Out, const FunctionDecl *D) {
+ switch (D->getStorageClass()) {
+ case SC_None:
+ break;
+ case SC_Extern:
+ Out << "extern ";
+ break;
+ case SC_Static:
+ Out << "static ";
+ break;
+ case SC_PrivateExtern:
+ Out << "__private_extern__ ";
+ break;
+ case SC_Auto:
+ case SC_Register:
+ llvm_unreachable("invalid for functions");
+ }
+
+ if (D->isInlineSpecified())
+ Out << "inline ";
+ if (D->isVirtualAsWritten())
+ Out << "virtual ";
+ if (D->isModulePrivate())
+ Out << "__module_private__ ";
+ if (D->isConstexpr() && !D->isExplicitlyDefaulted())
+ Out << "constexpr ";
+
+ const CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D);
+ const CXXConversionDecl *ConversionDecl = dyn_cast<CXXConversionDecl>(D);
+ const CXXDeductionGuideDecl *GuideDecl = dyn_cast<CXXDeductionGuideDecl>(D);
+ if ((CDecl && CDecl->isExplicitSpecified()) ||
+ (ConversionDecl && ConversionDecl->isExplicitSpecified()) ||
+ (GuideDecl && GuideDecl->isExplicitSpecified()))
+ Out << "explicit ";
+}
+
+void printSpecifiers(llvm::raw_ostream &Out, const DeclaratorDecl *DD) {
+ const VarDecl *D = dyn_cast<VarDecl>(DD);
+ if (!D)
+ return;
+
+ StorageClass SC = D->getStorageClass();
+ if (SC != SC_None)
+ Out << VarDecl::getStorageClassSpecifierString(SC) << " ";
+
+ switch (D->getTSCSpec()) {
+ case TSCS_unspecified:
+ break;
+ case TSCS___thread:
+ Out << "__thread ";
+ break;
+ case TSCS__Thread_local:
+ Out << "_Thread_local ";
+ break;
+ case TSCS_thread_local:
+ Out << "thread_local ";
+ break;
+ }
+
+ if (D->isModulePrivate())
+ Out << "__module_private__ ";
+
+ if (D->isConstexpr())
+ Out << "constexpr ";
+}
+
} // namespace
std::vector<DocumentHighlight> findDocumentHighlights(ParsedAST &AST,
@@ -453,7 +532,7 @@
std::vector<DocumentHighlight> Result;
for (const auto &Ref : References) {
DocumentHighlight DH;
- DH.range = getTokenRange(AST, Ref.Loc);
+ DH.range = getTokenRange(AST.getASTContext(), Ref.Loc);
if (Ref.Role & index::SymbolRoleSet(index::SymbolRole::Write))
DH.kind = DocumentHighlightKind::Write;
else if (Ref.Role & index::SymbolRoleSet(index::SymbolRole::Read))
@@ -525,54 +604,175 @@
return None;
}
-/// Generate a \p Hover object given the declaration \p D.
-static Hover getHoverContents(const Decl *D) {
- Hover H;
- llvm::Optional<std::string> NamedScope = getScopeName(D);
+static std::string printDefinition(const Decl *D) {
+ std::string Definition;
+ {
+ llvm::raw_string_ostream OS(Definition);
+ PrintingPolicy Policy =
+ printingPolicyForDecls(D->getASTContext().getPrintingPolicy());
+ D->print(OS, Policy);
+ }
+ return Definition;
+}
- // Generate the "Declared in" section.
- if (NamedScope) {
- assert(!NamedScope->empty());
+static void printParams(llvm::raw_ostream &OS,
+ const std::vector<HoverInfo::Param> &Params) {
+ for (size_t I = 0, E = Params.size(); I != E; ++I) {
+ if (I)
+ OS << ", ";
+ OS << Params.at(I);
+ }
+}
- H.contents.value += "Declared in ";
- H.contents.value += *NamedScope;
- H.contents.value += "\n\n";
+static std::vector<HoverInfo::Param>
+fetchTemplateParameters(const TemplateParameterList *Params,
+ const PrintingPolicy &PP) {
+ assert(Params);
+ std::vector<HoverInfo::Param> TempParameters;
+
+ for (const Decl *Param : *Params) {
+ HoverInfo::Param P;
+ P.Type.emplace();
+ if (const auto TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
+ P.Type = TTP->wasDeclaredWithTypename() ? "typename" : "class";
+ if (TTP->isParameterPack())
+ *P.Type += "...";
+
+ P.Name.emplace();
+ llvm::raw_string_ostream Out(*P.Name);
+ Out << *TTP;
+ if (TTP->hasDefaultArgument())
+ P.Default = TTP->getDefaultArgument().getAsString(PP);
+ } else if (const auto NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
+ if (IdentifierInfo *II = NTTP->getIdentifier())
+ P.Name = II->getName().str();
+
+ llvm::raw_string_ostream Out(*P.Type);
+ NTTP->getType().print(Out, PP);
+ if (NTTP->isParameterPack())
+ Out << "...";
+
+ if (NTTP->hasDefaultArgument()) {
+ P.Default.emplace();
+ llvm::raw_string_ostream Out(*P.Default);
+ NTTP->getDefaultArgument()->printPretty(Out, nullptr, PP);
+ }
+ } else if (const auto TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) {
+ llvm::raw_string_ostream OS(*P.Type);
+ OS << "template <";
+ printParams(
+ OS, fetchTemplateParameters(
+ TTPD->getDescribedTemplate()->getTemplateParameters(), PP));
+ OS << "> class"; // FIXME: TemplateTemplateParameter doesn't store the
+ // info on whether this param was a "typename" or
+ // "class".
+ if (TTPD->hasDefaultArgument()) {
+ P.Default.emplace();
+ llvm::raw_string_ostream Out(*P.Default);
+ TTPD->getDefaultArgument().getArgument().print(PP, Out);
+ }
+ }
+ TempParameters.push_back(std::move(P));
}
- // We want to include the template in the Hover.
- if (TemplateDecl *TD = D->getDescribedTemplate())
- D = TD;
+ return TempParameters;
+}
- std::string DeclText;
- llvm::raw_string_ostream OS(DeclText);
+/// Generate a \p Hover object given the declaration \p D.
+static HoverInfo getHoverContents(const Decl *D) {
+ HoverInfo HI;
PrintingPolicy Policy =
printingPolicyForDecls(D->getASTContext().getPrintingPolicy());
+ if (const NamedDecl *ND = llvm::dyn_cast<NamedDecl>(D)) {
+ HI.Documentation = getDeclComment(ND->getASTContext(), *ND);
+ HI.Name = printName(D->getASTContext(), *ND);
+ HI.Scope = splitQualifiedName(printQualifiedName(*ND)).first.str();
+ }
- D->print(OS, Policy);
+ if (llvm::Optional<std::string> NamedScope = getScopeName(D)) {
+ assert(!NamedScope->empty());
+ HI.ContainedIn = std::move(*NamedScope);
+ }
+ HI.Kind = indexSymbolKindToSymbolKind(index::getSymbolInfo(D).Kind);
+
+ // Fill in template params.
+ if (const TemplateDecl *TD = D->getDescribedTemplate()) {
+ HI.TemplateParameters =
+ fetchTemplateParameters(TD->getTemplateParameters(), Policy);
+ D = TD;
+ } else if (const FunctionDecl *FD = D->getAsFunction()) {
+ if (const auto FTD = FD->getDescribedTemplate()) {
+ HI.TemplateParameters =
+ fetchTemplateParameters(FTD->getTemplateParameters(), Policy);
+ D = FTD;
+ }
+ }
- OS.flush();
+ // Fill in types and params.
+ if (const FunctionDecl *FD = D->getAsFunction()) {
+ HI.ReturnType.emplace();
+ llvm::raw_string_ostream OS(*HI.ReturnType);
+ printSpecifiers(OS, FD);
+ FD->getReturnType().print(OS, Policy);
+
+ HI.Parameters.emplace();
+ for (const ParmVarDecl *PVD : FD->parameters()) {
+ HI.Parameters->emplace_back();
+ auto &P = HI.Parameters->back();
+ if (!PVD->getType().isNull()) {
+ P.Type.emplace();
+ llvm::raw_string_ostream OS(*P.Type);
+ printSpecifiers(OS, PVD);
+ PVD->getType().print(OS, Policy);
+ }
+ if (!PVD->getName().empty())
+ P.Name = PVD->getNameAsString();
+ if (PVD->hasDefaultArg()) {
+ P.Default.emplace();
+ llvm::raw_string_ostream Out(*P.Default);
+ PVD->getDefaultArg()->printPretty(Out, nullptr, Policy);
+ }
+ }
+ if (FD->isVariadic()) {
+ HI.Parameters->emplace_back();
+ HI.Parameters->back().Type = "...";
+ }
+ } else if (const auto *DD = dyn_cast<DeclaratorDecl>(D)) {
+ HI.Type.emplace();
+ llvm::raw_string_ostream OS(*HI.Type);
+ printSpecifiers(OS, DD);
+ DD->getType().print(OS, Policy);
+ }
- H.contents.value += DeclText;
- return H;
+ HI.Definition = printDefinition(D);
+ return HI;
}
/// Generate a \p Hover object given the type \p T.
-static Hover getHoverContents(QualType T, ASTContext &ASTCtx) {
- Hover H;
- std::string TypeText;
- llvm::raw_string_ostream OS(TypeText);
+static HoverInfo getHoverContents(QualType T, ASTContext &ASTCtx) {
+ HoverInfo HI;
+ llvm::raw_string_ostream OS(HI.Name);
PrintingPolicy Policy = printingPolicyForDecls(ASTCtx.getPrintingPolicy());
T.print(OS, Policy);
- OS.flush();
- H.contents.value += TypeText;
- return H;
+
+ if (const TagDecl *TD = T.getTypePtr()->getAsTagDecl()) {
+ HI.Scope = printQualifiedName(*TD);
+ HI.Kind = indexSymbolKindToSymbolKind(index::getSymbolInfo(TD).Kind);
+ HI.Definition = printDefinition(TD);
+ // FIXME: Populate documentation
+ }
+ return HI;
}
/// Generate a \p Hover object given the macro \p MacroDecl.
-static Hover getHoverContents(MacroDecl Decl, ParsedAST &AST) {
+static HoverInfo getHoverContents(MacroDecl Decl, ParsedAST &AST) {
+ HoverInfo HI;
SourceManager &SM = AST.getASTContext().getSourceManager();
- std::string Definition = Decl.Name;
+ HI.Name = Decl.Name;
+ HI.Kind = indexSymbolKindToSymbolKind(
+ index::getSymbolInfoForMacro(*Decl.Info).Kind);
+ // FIXME: Populate documentation
// Try to get the full definition, not just the name
SourceLocation StartLoc = Decl.Info->getDefinitionLoc();
@@ -586,14 +786,12 @@
unsigned StartOffset = SM.getFileOffset(StartLoc);
unsigned EndOffset = SM.getFileOffset(EndLoc);
if (EndOffset <= Buffer.size() && StartOffset < EndOffset)
- Definition = Buffer.substr(StartOffset, EndOffset - StartOffset).str();
+ HI.Definition =
+ ("#define " + Buffer.substr(StartOffset, EndOffset - StartOffset))
+ .str();
}
}
-
- Hover H;
- H.contents.kind = MarkupKind::PlainText;
- H.contents.value = "#define " + Definition;
- return H;
+ return HI;
}
namespace {
@@ -708,7 +906,7 @@
return V.getDeducedType();
}
-llvm::Optional<Hover> getHover(ParsedAST &AST, Position Pos) {
+llvm::Optional<HoverInfo> getHover(ParsedAST &AST, Position Pos) {
const SourceManager &SourceMgr = AST.getASTContext().getSourceManager();
SourceLocation SourceLocationBeg =
getBeginningOfIdentifier(AST, Pos, SourceMgr.getMainFileID());
@@ -748,7 +946,7 @@
auto MainFileRefs = findRefs(Symbols.Decls, AST);
for (const auto &Ref : MainFileRefs) {
Location Result;
- Result.range = getTokenRange(AST, Ref.Loc);
+ Result.range = getTokenRange(AST.getASTContext(), Ref.Loc);
Result.uri = URIForFile::canonicalize(*MainFilePath, *MainFilePath);
Results.push_back(std::move(Result));
}
@@ -991,5 +1189,69 @@
return Result;
}
+Hover HoverInfo::render() const {
+ Hover H;
+ H.range = SymRange;
+ H.contents.kind = MarkupKind::PlainText;
+ std::vector<std::string> Output;
+
+ if (ContainedIn)
+ H.contents.value = llvm::formatv("Declared in {0}\n\n", *ContainedIn);
+
+ if (Kind == SymbolKind::String) {
+ // We use SymbolKind::String for macro kinds
+ Output.push_back(Definition);
+ } else if (Type || ReturnType) {
+ // Variables or Functions
+ if (!Definition.empty())
+ Output.push_back(Definition);
+ else {
+ if (TemplateParameters) {
+ Output.emplace_back();
+ llvm::raw_string_ostream OS(Output.back());
+ OS << "template <";
+ printParams(OS, *TemplateParameters);
+ OS << '>';
+ }
+ if (Type)
+ Output.push_back(*Type);
+ else if (ReturnType)
+ Output.push_back(*ReturnType);
+
+ if (!Name.empty())
+ Output.push_back(Name);
+
+ if (Parameters) {
+ // We don't want space before parameters.
+ llvm::raw_string_ostream OS(Output.back());
+ OS << '(';
+ printParams(OS, *Parameters);
+ OS << ')';
+ }
+ }
+ } else {
+ // Types and namespaces
+ if (!Definition.empty())
+ Output.push_back(Definition);
+ else
+ Output.push_back(Name);
+ }
+ H.contents.value += llvm::join(Output, " ");
+ return H;
+}
+
+llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+ const HoverInfo::Param &P) {
+ std::vector<llvm::StringRef> Output;
+ if (P.Type)
+ Output.push_back(*P.Type);
+ if (P.Name)
+ Output.push_back(*P.Name);
+ OS << llvm::join(Output, " ");
+ if (P.Default)
+ OS << " = " << P.Default;
+ return OS;
+}
+
} // namespace clangd
} // namespace clang
Index: clang-tools-extra/clangd/ClangdServer.h
===================================================================
--- clang-tools-extra/clangd/ClangdServer.h
+++ clang-tools-extra/clangd/ClangdServer.h
@@ -180,7 +180,7 @@
/// Get code hover for a given position.
void findHover(PathRef File, Position Pos,
- Callback<llvm::Optional<Hover>> CB);
+ Callback<llvm::Optional<HoverInfo>> CB);
/// Get information about type hierarchy for a given position.
void typeHierarchy(PathRef File, Position Pos, int Resolve,
Index: clang-tools-extra/clangd/ClangdServer.cpp
===================================================================
--- clang-tools-extra/clangd/ClangdServer.cpp
+++ clang-tools-extra/clangd/ClangdServer.cpp
@@ -523,8 +523,8 @@
}
void ClangdServer::findHover(PathRef File, Position Pos,
- Callback<llvm::Optional<Hover>> CB) {
- auto Action = [Pos](Callback<llvm::Optional<Hover>> CB,
+ Callback<llvm::Optional<HoverInfo>> CB) {
+ auto Action = [Pos](Callback<llvm::Optional<HoverInfo>> CB,
llvm::Expected<InputsAndAST> InpAST) {
if (!InpAST)
return CB(InpAST.takeError());
Index: clang-tools-extra/clangd/ClangdLSPServer.cpp
===================================================================
--- clang-tools-extra/clangd/ClangdLSPServer.cpp
+++ clang-tools-extra/clangd/ClangdLSPServer.cpp
@@ -839,7 +839,17 @@
void ClangdLSPServer::onHover(const TextDocumentPositionParams &Params,
Callback<llvm::Optional<Hover>> Reply) {
Server->findHover(Params.textDocument.uri.file(), Params.position,
- std::move(Reply));
+ Bind(
+ [](decltype(Reply) Reply,
+ llvm::Expected<llvm::Optional<HoverInfo>> HIorErr) {
+ if (!HIorErr)
+ return Reply(HIorErr.takeError());
+ const auto &HI = HIorErr.get();
+ if (!HI)
+ return Reply(llvm::None);
+ return Reply(HI->render());
+ },
+ std::move(Reply)));
}
void ClangdLSPServer::onTypeHierarchy(
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits