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 ""; } @@ -345,15 +354,19 @@ HoverInfo getHoverContents(QualType T, ASTContext &ASTCtx, const SymbolIndex *Index) { HoverInfo HI; - llvm::raw_string_ostream OS(HI.Name); - PrintingPolicy Policy = printingPolicyForDecls(ASTCtx.getPrintingPolicy()); - T.print(OS, Policy); - OS.flush(); if (const auto *D = T->getAsTagDecl()) { + HI.Name = printName(ASTCtx, *D); 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); + } 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 @@ -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,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "class std::initializer_list"; + HI.Name = "initializer_list"; HI.Kind = index::SymbolKind::Class; }}, { @@ -1231,7 +1269,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "struct Bar"; + HI.Name = "Bar"; HI.Kind = index::SymbolKind::Struct; }}, { @@ -1242,7 +1280,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "struct Bar"; + HI.Name = "Bar"; HI.Kind = index::SymbolKind::Struct; }}, { @@ -1253,7 +1291,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "struct Bar"; + HI.Name = "Bar"; HI.Kind = index::SymbolKind::Struct; }}, { @@ -1265,7 +1303,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "struct Bar"; + HI.Name = "Bar"; HI.Kind = index::SymbolKind::Struct; }}, { @@ -1277,7 +1315,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "struct Bar"; + HI.Name = "Bar"; HI.Kind = index::SymbolKind::Struct; }}, { @@ -1289,7 +1327,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "struct Bar"; + HI.Name = "Bar"; HI.Kind = index::SymbolKind::Struct; }}, { @@ -1300,7 +1338,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "struct Bar"; + HI.Name = "Bar"; HI.Kind = index::SymbolKind::Struct; }}, { @@ -1364,7 +1402,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "struct Bar"; + HI.Name = "Bar"; HI.Kind = index::SymbolKind::Struct; }}, {