diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp --- a/clang-tools-extra/clangd/Hover.cpp +++ b/clang-tools-extra/clangd/Hover.cpp @@ -24,6 +24,7 @@ #include "clang/AST/DeclTemplate.h" #include "clang/AST/PrettyPrinter.h" #include "clang/Index/IndexSymbol.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/Support/Casting.h" #include "llvm/Support/raw_ostream.h" @@ -416,11 +417,22 @@ if (auto Deduced = getDeducedType(AST.getASTContext(), SourceLocationBeg)) { // Find the corresponding decl to populate kind and fetch documentation. - DeclRelationSet Rel = DeclRelation::TemplatePattern | DeclRelation::Alias; + DeclRelationSet Rel = DeclRelation::TemplateInstantiation | + DeclRelation::TemplatePattern | DeclRelation::Alias; auto Decls = targetDecl(ast_type_traits::DynTypedNode::create(*Deduced), Rel); - HI = getHoverContents(*Deduced, Decls.empty() ? nullptr : Decls.front(), - AST.getASTContext(), Index); + // Select the target decl, biased towards instantiations. + auto *D = [&Decls]() -> const Decl * { + if (Decls.empty()) + return nullptr; + auto *Spec = llvm::find_if(Decls, [](const Decl *D) { + return llvm::isa(D); + }); + if (Spec != Decls.end()) + return *Spec; + return Decls.front(); + }(); + HI = getHoverContents(*Deduced, D, AST.getASTContext(), Index); } else if (auto M = locateMacroAt(SourceLocationBeg, AST.getPreprocessor())) { HI = getHoverContents(*M, AST); } else { diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp --- a/clang-tools-extra/clangd/unittests/HoverTests.cpp +++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp @@ -373,7 +373,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "Foo"; + HI.Name = "Foo"; HI.Kind = index::SymbolKind::Class; }}, // auto on specialized template @@ -543,6 +543,19 @@ HI.Name = "Foo"; HI.Kind = index::SymbolKind::Class; }}, + { + R"cpp( + template class Foo {}; + class X; + void foo() { + [[^auto]] x = Foo(); + } + )cpp", + [](HoverInfo &HI) { + // FIXME: Drop default arguments. + HI.Name = "Foo"; + HI.Kind = index::SymbolKind::Class; + }}, }; for (const auto &Case : Cases) { SCOPED_TRACE(Case.Code); @@ -1193,7 +1206,7 @@ )cpp", [](HoverInfo &HI) { // FIXME: Print template instantiation parameters. - HI.Name = "initializer_list"; + HI.Name = "initializer_list"; HI.Kind = index::SymbolKind::Class; }}, {