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 @@ -16,13 +16,13 @@ #include "Selection.h" #include "SourceCode.h" #include "index/SymbolCollector.h" - #include "clang/AST/ASTContext.h" #include "clang/AST/ASTTypeTraits.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/PrettyPrinter.h" +#include "clang/AST/Type.h" #include "clang/Index/IndexSymbol.h" #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/SmallVector.h" @@ -101,6 +101,7 @@ printingPolicyForDecls(D->getASTContext().getPrintingPolicy()); Policy.IncludeTagDefinition = false; Policy.SuppressTemplateArgsInCXXConstructors = true; + Policy.SuppressTagKeyword = true; D->print(OS, Policy); OS.flush(); return Definition; @@ -233,9 +234,7 @@ HI.Parameters->emplace_back(); auto &P = HI.Parameters->back(); if (!PVD->getType().isNull()) { - P.Type.emplace(); - llvm::raw_string_ostream OS(*P.Type); - PVD->getType().print(OS, Policy); + P.Type = PVD->getType().getAsString(Policy); } else { std::string Param; llvm::raw_string_ostream OS(Param); @@ -344,13 +343,10 @@ } // Fill in types and params. - if (const FunctionDecl *FD = getUnderlyingFunction(D)) { + if (const FunctionDecl *FD = getUnderlyingFunction(D)) fillFunctionTypeAndParams(HI, D, FD, Policy); - } else if (const auto *VD = dyn_cast(D)) { - HI.Type.emplace(); - llvm::raw_string_ostream OS(*HI.Type); - VD->getType().print(OS, Policy); - } + else if (const auto *VD = dyn_cast(D)) + HI.Type = VD->getType().getAsString(Policy); // Fill in value with evaluated initializer if possible. if (const auto *Var = dyn_cast(D)) { @@ -380,9 +376,9 @@ enhanceFromIndex(HI, *CommentD, Index); } else { // Builtin types - llvm::raw_string_ostream OS(HI.Name); - PrintingPolicy Policy = printingPolicyForDecls(ASTCtx.getPrintingPolicy()); - T.print(OS, Policy); + auto Policy = printingPolicyForDecls(ASTCtx.getPrintingPolicy()); + Policy.SuppressTagKeyword = true; + HI.Name = T.getAsString(Policy); } return HI; } 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 @@ -446,7 +446,7 @@ [](HoverInfo &HI) { HI.Name = "x"; HI.NamespaceScope = ""; - HI.Definition = "enum Color x = GREEN"; + HI.Definition = "Color x = GREEN"; HI.Kind = index::SymbolKind::Variable; HI.Type = "enum Color"; HI.Value = "GREEN (1)"; // Symbolic when hovering on an expression. @@ -1427,7 +1427,7 @@ HI.NamespaceScope = ""; HI.LocalScope = "test::"; HI.Type = "struct Test &&"; - HI.Definition = "struct Test &&test = {}"; + HI.Definition = "Test &&test = {}"; HI.Value = "{}"; }}, { @@ -1476,6 +1476,31 @@ HI.ReturnType = "int"; HI.Type = "int ()"; }}, + { + R"cpp(// type of nested templates. + template struct cls {}; + cls>> [[fo^o]]; + )cpp", + [](HoverInfo &HI) { + HI.Definition = "cls>> foo"; + HI.Kind = index::SymbolKind::Variable; + HI.NamespaceScope = ""; + HI.Name = "foo"; + HI.Type = "cls > >"; + HI.Value = "{}"; + }}, + { + R"cpp(// type of nested templates. + template struct cls {}; + [[cl^s]]>> foo; + )cpp", + [](HoverInfo &HI) { + HI.Definition = "template <> struct cls>> {}"; + HI.Kind = index::SymbolKind::Struct; + HI.NamespaceScope = ""; + HI.Name = "cls > >"; + HI.Documentation = "type of nested templates."; + }}, }; // Create a tiny index, so tests above can verify documentation is fetched.