forked from OSchip/llvm-project
[clangd] Fix handling of inline/anon namespaces and names of deduced types in hover
Summary: Clangd normally skips inline and anon namespaces while printing nested name specifiers. It also drops any tag specifiers since we make use of `HoverInfo::Kind` instead of some text in `HoverInfo::Name` There was a bug causing us to print innermost inline/anon namespace, this patch fixes that by skipping those. Also changes printing and kind detection of deduced types to be similar to decl case. Also improves printing for lambdas, currently clangd prints lambdas as `(anonymous class)`, we can improve it by at least printing `(lambda)` instead. Subscribers: ilya-biryukov, MaskRay, jkorous, arphaman, usaxena95, cfe-commits Tags: #clang Differential Revision: https://reviews.llvm.org/D71543
This commit is contained in:
parent
3d15605358
commit
9ab15f303e
|
@ -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 @@ std::string printName(const ASTContext &Ctx, const NamedDecl &ND) {
|
|||
// Come up with a presentation for an anonymous entity.
|
||||
if (isa<NamespaceDecl>(ND))
|
||||
return "(anonymous namespace)";
|
||||
if (auto *Cls = llvm::dyn_cast<RecordDecl>(&ND))
|
||||
if (auto *Cls = llvm::dyn_cast<RecordDecl>(&ND)) {
|
||||
if (Cls->isLambda())
|
||||
return "(lambda)";
|
||||
return ("(anonymous " + Cls->getKindName() + ")").str();
|
||||
}
|
||||
if (isa<EnumDecl>(ND))
|
||||
return "(anonymous enum)";
|
||||
return "(anonymous)";
|
||||
|
|
|
@ -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 getLocalScope(const Decl *D) {
|
|||
std::string getNamespaceScope(const Decl *D) {
|
||||
const DeclContext *DC = D->getDeclContext();
|
||||
|
||||
if (const TypeDecl *TD = dyn_cast<TypeDecl>(DC))
|
||||
if (const TagDecl *TD = dyn_cast<TagDecl>(DC))
|
||||
return getNamespaceScope(TD);
|
||||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(DC))
|
||||
return getNamespaceScope(FD);
|
||||
if (const NamespaceDecl *NSD = dyn_cast<NamespaceDecl>(DC)) {
|
||||
// Skip inline/anon namespaces.
|
||||
if (NSD->isInline() || NSD->isAnonymousNamespace())
|
||||
return getNamespaceScope(NSD);
|
||||
}
|
||||
if (const NamedDecl *ND = dyn_cast<NamedDecl>(DC))
|
||||
return ND->getQualifiedNameAsString();
|
||||
return printQualifiedName(*ND);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
@ -345,15 +354,19 @@ HoverInfo getHoverContents(const Decl *D, const SymbolIndex *Index) {
|
|||
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;
|
||||
}
|
||||
|
||||
|
|
|
@ -104,7 +104,7 @@ TEST(Hover, Structured) {
|
|||
}}
|
||||
)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 @@ void foo())cpp";
|
|||
}
|
||||
)cpp",
|
||||
[](HoverInfo &HI) {
|
||||
HI.Name = "class (lambda)";
|
||||
HI.Name = "(lambda)";
|
||||
HI.Kind = index::SymbolKind::Class;
|
||||
}},
|
||||
// auto on template instantiation
|
||||
|
@ -373,7 +373,7 @@ void foo())cpp";
|
|||
}
|
||||
)cpp",
|
||||
[](HoverInfo &HI) {
|
||||
HI.Name = "class Foo<int>";
|
||||
HI.Name = "Foo<int>";
|
||||
HI.Kind = index::SymbolKind::Class;
|
||||
}},
|
||||
// auto on specialized template
|
||||
|
@ -385,7 +385,7 @@ void foo())cpp";
|
|||
}
|
||||
)cpp",
|
||||
[](HoverInfo &HI) {
|
||||
HI.Name = "class Foo<int>";
|
||||
HI.Name = "Foo<int>";
|
||||
HI.Kind = index::SymbolKind::Class;
|
||||
}},
|
||||
|
||||
|
@ -524,6 +524,44 @@ void foo())cpp";
|
|||
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 <typename T> class Foo {};
|
||||
class X;
|
||||
void foo() {
|
||||
[[^auto]] x = Foo<X>();
|
||||
}
|
||||
)cpp",
|
||||
[](HoverInfo &HI) {
|
||||
HI.Name = "Foo<X>";
|
||||
HI.Kind = index::SymbolKind::Class;
|
||||
}},
|
||||
};
|
||||
for (const auto &Case : Cases) {
|
||||
SCOPED_TRACE(Case.Code);
|
||||
|
@ -895,7 +933,7 @@ TEST(Hover, All) {
|
|||
[](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 @@ TEST(Hover, All) {
|
|||
}
|
||||
)cpp",
|
||||
[](HoverInfo &HI) {
|
||||
HI.Name = "class std::initializer_list<int>";
|
||||
HI.Name = "initializer_list<int>";
|
||||
HI.Kind = index::SymbolKind::Class;
|
||||
}},
|
||||
{
|
||||
|
@ -1231,7 +1269,7 @@ TEST(Hover, All) {
|
|||
}
|
||||
)cpp",
|
||||
[](HoverInfo &HI) {
|
||||
HI.Name = "struct Bar";
|
||||
HI.Name = "Bar";
|
||||
HI.Kind = index::SymbolKind::Struct;
|
||||
}},
|
||||
{
|
||||
|
@ -1242,7 +1280,7 @@ TEST(Hover, All) {
|
|||
}
|
||||
)cpp",
|
||||
[](HoverInfo &HI) {
|
||||
HI.Name = "struct Bar";
|
||||
HI.Name = "Bar";
|
||||
HI.Kind = index::SymbolKind::Struct;
|
||||
}},
|
||||
{
|
||||
|
@ -1253,7 +1291,7 @@ TEST(Hover, All) {
|
|||
}
|
||||
)cpp",
|
||||
[](HoverInfo &HI) {
|
||||
HI.Name = "struct Bar";
|
||||
HI.Name = "Bar";
|
||||
HI.Kind = index::SymbolKind::Struct;
|
||||
}},
|
||||
{
|
||||
|
@ -1265,7 +1303,7 @@ TEST(Hover, All) {
|
|||
}
|
||||
)cpp",
|
||||
[](HoverInfo &HI) {
|
||||
HI.Name = "struct Bar";
|
||||
HI.Name = "Bar";
|
||||
HI.Kind = index::SymbolKind::Struct;
|
||||
}},
|
||||
{
|
||||
|
@ -1277,7 +1315,7 @@ TEST(Hover, All) {
|
|||
}
|
||||
)cpp",
|
||||
[](HoverInfo &HI) {
|
||||
HI.Name = "struct Bar";
|
||||
HI.Name = "Bar";
|
||||
HI.Kind = index::SymbolKind::Struct;
|
||||
}},
|
||||
{
|
||||
|
@ -1289,7 +1327,7 @@ TEST(Hover, All) {
|
|||
}
|
||||
)cpp",
|
||||
[](HoverInfo &HI) {
|
||||
HI.Name = "struct Bar";
|
||||
HI.Name = "Bar";
|
||||
HI.Kind = index::SymbolKind::Struct;
|
||||
}},
|
||||
{
|
||||
|
@ -1300,7 +1338,7 @@ TEST(Hover, All) {
|
|||
}
|
||||
)cpp",
|
||||
[](HoverInfo &HI) {
|
||||
HI.Name = "struct Bar";
|
||||
HI.Name = "Bar";
|
||||
HI.Kind = index::SymbolKind::Struct;
|
||||
}},
|
||||
{
|
||||
|
@ -1364,7 +1402,7 @@ TEST(Hover, All) {
|
|||
}
|
||||
)cpp",
|
||||
[](HoverInfo &HI) {
|
||||
HI.Name = "struct Bar";
|
||||
HI.Name = "Bar";
|
||||
HI.Kind = index::SymbolKind::Struct;
|
||||
}},
|
||||
{
|
||||
|
@ -1409,7 +1447,7 @@ TEST(Hover, All) {
|
|||
^[[auto]] y = cls_type();
|
||||
)cpp",
|
||||
[](HoverInfo &HI) {
|
||||
HI.Name = "struct cls";
|
||||
HI.Name = "cls";
|
||||
HI.Kind = index::SymbolKind::Struct;
|
||||
}},
|
||||
{
|
||||
|
@ -1419,7 +1457,7 @@ TEST(Hover, All) {
|
|||
^[[auto]] z = templ<int>();
|
||||
)cpp",
|
||||
[](HoverInfo &HI) {
|
||||
HI.Name = "struct templ<int>";
|
||||
HI.Name = "templ<int>";
|
||||
HI.Kind = index::SymbolKind::Struct;
|
||||
}},
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue