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" 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,12 @@ #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/Support/Casting.h" #include "llvm/Support/raw_ostream.h" namespace clang { @@ -72,12 +75,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,16 +351,27 @@ /// 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) { + auto FillInHover = [&HI, Index, &ASTCtx](const Decl *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 (D) { + FillInHover(D); + } else if (const auto *TD = T->getAsTagDecl()) { + FillInHover(TD); + } + + 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; } 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,8 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "class (lambda)"; + // FIXME: Special case lambdas. + HI.Name = "(anonymous class)"; HI.Kind = index::SymbolKind::Class; }}, // auto on template instantiation @@ -373,7 +374,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "class Foo"; + HI.Name = "Foo"; HI.Kind = index::SymbolKind::Class; }}, // auto on specialized template @@ -385,7 +386,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "class Foo"; + HI.Name = "Foo"; HI.Kind = index::SymbolKind::Class; }}, @@ -524,6 +525,25 @@ HI.NamespaceScope = ""; HI.LocalScope = "boom::"; }}, + { + R"cpp(// Should not print inline or anon namespaces. + namespace ns { + inline namespace in_ns { + namespace { + inline namespace in_ns2 { + class Foo {}; + } // in_ns2 + } // anon + } // in_ns + } // ns + void foo() { + [[au^to]] x = ns::Foo(); + } + )cpp", + [](HoverInfo &HI) { + HI.Name = "Foo"; + HI.Kind = index::SymbolKind::Class; + }}, }; for (const auto &Case : Cases) { SCOPED_TRACE(Case.Code); @@ -895,7 +915,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 +1193,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 +1252,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "struct Bar"; + HI.Name = "Bar"; HI.Kind = index::SymbolKind::Struct; }}, { @@ -1242,7 +1263,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "struct Bar"; + HI.Name = "Bar"; HI.Kind = index::SymbolKind::Struct; }}, { @@ -1253,7 +1274,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "struct Bar"; + HI.Name = "Bar"; HI.Kind = index::SymbolKind::Struct; }}, { @@ -1265,7 +1286,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "struct Bar"; + HI.Name = "Bar"; HI.Kind = index::SymbolKind::Struct; }}, { @@ -1277,7 +1298,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "struct Bar"; + HI.Name = "Bar"; HI.Kind = index::SymbolKind::Struct; }}, { @@ -1289,7 +1310,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "struct Bar"; + HI.Name = "Bar"; HI.Kind = index::SymbolKind::Struct; }}, { @@ -1300,7 +1321,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "struct Bar"; + HI.Name = "Bar"; HI.Kind = index::SymbolKind::Struct; }}, { @@ -1364,7 +1385,7 @@ } )cpp", [](HoverInfo &HI) { - HI.Name = "struct Bar"; + HI.Name = "Bar"; HI.Kind = index::SymbolKind::Struct; }}, {