diff --git a/clang-tools-extra/clangd/AST.cpp b/clang-tools-extra/clangd/AST.cpp --- a/clang-tools-extra/clangd/AST.cpp +++ b/clang-tools-extra/clangd/AST.cpp @@ -12,6 +12,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclBase.h" +#include "clang/AST/DeclCXX.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/NestedNameSpecifier.h" @@ -222,8 +223,11 @@ // Come up with a presentation for an anonymous entity. if (isa(ND)) return "(anonymous namespace)"; - if (auto *Cls = llvm::dyn_cast(&ND)) + if (auto *Cls = llvm::dyn_cast(&ND)) { + if (Cls->isLambda()) + return "(lambda)"; return ("(anonymous " + Cls->getKindName() + ")").str(); + } if (isa(ND)) return "(anonymous enum)"; return "(anonymous)"; 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 @@ -19,9 +19,13 @@ #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/Index/IndexSymbol.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/raw_ostream.h" namespace clang { @@ -72,12 +76,17 @@ std::string getNamespaceScope(const Decl *D) { const DeclContext *DC = D->getDeclContext(); - if (const TypeDecl *TD = dyn_cast(DC)) + if (const TagDecl *TD = dyn_cast(DC)) return getNamespaceScope(TD); if (const FunctionDecl *FD = dyn_cast(DC)) return getNamespaceScope(FD); + if (const NamespaceDecl *NSD = dyn_cast(DC)) { + // Skip inline/anon namespaces. + if (NSD->isInline() || NSD->isAnonymousNamespace()) + return getNamespaceScope(NSD); + } if (const NamedDecl *ND = dyn_cast(DC)) - return ND->getQualifiedNameAsString(); + return printQualifiedName(*ND); return ""; } @@ -343,17 +352,25 @@ /// Generate a \p Hover object given the type \p T. HoverInfo getHoverContents(QualType T, const Decl *D, ASTContext &ASTCtx, - const SymbolIndex *Index) { + const SymbolIndex *Index) { HoverInfo HI; - llvm::raw_string_ostream OS(HI.Name); - PrintingPolicy Policy = printingPolicyForDecls(ASTCtx.getPrintingPolicy()); - T.print(OS, Policy); - OS.flush(); + if (!D) + D = T->getAsTagDecl(); if (D) { + if (const auto *ND = llvm::dyn_cast(D)) + HI.Name = printName(ASTCtx, *ND); HI.Kind = index::getSymbolInfo(D).Kind; enhanceFromIndex(HI, D, Index); } + + if (HI.Name.empty()) { + // Builtin types + llvm::raw_string_ostream OS(HI.Name); + PrintingPolicy Policy = printingPolicyForDecls(ASTCtx.getPrintingPolicy()); + T.print(OS, Policy); + OS.flush(); + } return HI; } @@ -397,11 +414,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 @@ -104,7 +104,7 @@ }} )cpp", [](HoverInfo &HI) { - HI.NamespaceScope = "ns1::(anonymous)::"; + HI.NamespaceScope = "ns1::"; HI.LocalScope = "(anonymous struct)::"; HI.Name = "bar"; HI.Kind = index::SymbolKind::Field; @@ -362,7 +362,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "class (lambda)"; + HI.Name = "(lambda)"; HI.Kind = index::SymbolKind::Class; }}, // auto on template instantiation @@ -373,7 +373,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "class Foo"; + HI.Name = "Foo"; HI.Kind = index::SymbolKind::Class; }}, // auto on specialized template @@ -385,7 +385,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "class Foo"; + HI.Name = "Foo"; HI.Kind = index::SymbolKind::Class; }}, @@ -524,6 +524,44 @@ HI.NamespaceScope = ""; HI.LocalScope = "boom::"; }}, + { + R"cpp(// Should not print inline or anon namespaces. + namespace ns { + inline namespace in_ns { + namespace a { + namespace { + namespace b { + inline namespace in_ns2 { + class Foo {}; + } // in_ns2 + } // b + } // anon + } // a + } // in_ns + } // ns + void foo() { + ns::a::b::[[F^oo]] x; + (void)x; + } + )cpp", + [](HoverInfo &HI) { + HI.Name = "Foo"; + HI.Kind = index::SymbolKind::Class; + HI.NamespaceScope = "ns::a::b::"; + HI.Definition = "class Foo {}"; + }}, + { + R"cpp( + template class Foo {}; + class X; + void foo() { + [[^auto]] x = Foo(); + } + )cpp", + [](HoverInfo &HI) { + HI.Name = "Foo"; + HI.Kind = index::SymbolKind::Class; + }}, }; for (const auto &Case : Cases) { SCOPED_TRACE(Case.Code); @@ -895,7 +933,7 @@ [](HoverInfo &HI) { HI.Name = "foo"; HI.Kind = index::SymbolKind::Variable; - HI.NamespaceScope = "ns::(anonymous)::"; + HI.NamespaceScope = "ns::"; HI.Type = "int"; HI.Definition = "int foo"; }}, @@ -1173,7 +1211,8 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "class std::initializer_list"; + // FIXME: Print template instantiation parameters. + HI.Name = "initializer_list"; HI.Kind = index::SymbolKind::Class; }}, { @@ -1231,7 +1270,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "struct Bar"; + HI.Name = "Bar"; HI.Kind = index::SymbolKind::Struct; }}, { @@ -1242,7 +1281,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "struct Bar"; + HI.Name = "Bar"; HI.Kind = index::SymbolKind::Struct; }}, { @@ -1253,7 +1292,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "struct Bar"; + HI.Name = "Bar"; HI.Kind = index::SymbolKind::Struct; }}, { @@ -1265,7 +1304,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "struct Bar"; + HI.Name = "Bar"; HI.Kind = index::SymbolKind::Struct; }}, { @@ -1277,7 +1316,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "struct Bar"; + HI.Name = "Bar"; HI.Kind = index::SymbolKind::Struct; }}, { @@ -1289,7 +1328,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "struct Bar"; + HI.Name = "Bar"; HI.Kind = index::SymbolKind::Struct; }}, { @@ -1300,7 +1339,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "struct Bar"; + HI.Name = "Bar"; HI.Kind = index::SymbolKind::Struct; }}, { @@ -1364,7 +1403,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "struct Bar"; + HI.Name = "Bar"; HI.Kind = index::SymbolKind::Struct; }}, {