[Index] Compute correct symbol kind for variable templates

Summary:
The index library itself seems to never pass variable templates as
input, however clangd does.

Reviewers: kadircet

Reviewed By: kadircet

Subscribers: jkorous, arphaman, cfe-commits

Tags: #clang

Differential Revision: https://reviews.llvm.org/D62579

llvm-svn: 361996
This commit is contained in:
Ilya Biryukov 2019-05-29 17:49:30 +00:00
parent 5a0e13c4d6
commit f6faa382f3
2 changed files with 49 additions and 0 deletions

View File

@ -463,6 +463,31 @@ TEST(CompletionTest, Kinds) {
EXPECT_THAT( EXPECT_THAT(
Results.Completions, Results.Completions,
UnorderedElementsAre(AllOf(Named("a"), Kind(CompletionItemKind::Field)))); UnorderedElementsAre(AllOf(Named("a"), Kind(CompletionItemKind::Field))));
// Completion kinds for templates should not be unknown.
Results = completions(
R"cpp(
template <class T> struct complete_class {};
template <class T> void complete_function();
template <class T> using complete_type_alias = int;
template <class T> int complete_variable = 10;
struct X {
template <class T> static int complete_static_member = 10;
static auto x = complete_^
}
)cpp");
EXPECT_THAT(
Results.Completions,
UnorderedElementsAre(
AllOf(Named("complete_class"), Kind(CompletionItemKind::Class)),
AllOf(Named("complete_function"), Kind(CompletionItemKind::Function)),
AllOf(Named("complete_type_alias"),
Kind(CompletionItemKind::Interface)),
AllOf(Named("complete_variable"), Kind(CompletionItemKind::Variable)),
AllOf(Named("complete_static_member"),
Kind(CompletionItemKind::Property))));
} }
TEST(CompletionTest, NoDuplicates) { TEST(CompletionTest, NoDuplicates) {

View File

@ -96,6 +96,13 @@ SymbolInfo index::getSymbolInfo(const Decl *D) {
Info.Properties |= (SymbolPropertySet)SymbolProperty::ProtocolInterface; Info.Properties |= (SymbolPropertySet)SymbolProperty::ProtocolInterface;
} }
if (auto *VT = dyn_cast<VarTemplateDecl>(D)) {
Info.Properties |= (SymbolPropertySet)SymbolProperty::Generic;
Info.Lang = SymbolLanguage::CXX;
// All other fields are filled from the templated decl.
D = VT->getTemplatedDecl();
}
if (const TagDecl *TD = dyn_cast<TagDecl>(D)) { if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
switch (TD->getTagKind()) { switch (TD->getTagKind()) {
case TTK_Struct: case TTK_Struct:
@ -333,6 +340,23 @@ SymbolInfo index::getSymbolInfo(const Decl *D) {
Info.Lang = SymbolLanguage::CXX; Info.Lang = SymbolLanguage::CXX;
} }
break; break;
case Decl::ClassTemplatePartialSpecialization:
case Decl::ClassScopeFunctionSpecialization:
case Decl::ClassTemplateSpecialization:
case Decl::CXXRecord:
case Decl::Enum:
case Decl::Record:
llvm_unreachable("records handled before");
break;
case Decl::VarTemplateSpecialization:
case Decl::VarTemplatePartialSpecialization:
case Decl::ImplicitParam:
case Decl::ParmVar:
case Decl::Var:
case Decl::VarTemplate:
llvm_unreachable("variables handled before");
break;
// Other decls get the 'unknown' kind.
default: default:
break; break;
} }