summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp25
-rw-r--r--clang/lib/Index/IndexSymbol.cpp24
2 files changed, 49 insertions, 0 deletions
diff --git a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
index b9ca702ee0f..202757aff41 100644
--- a/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
+++ b/clang-tools-extra/clangd/unittests/CodeCompleteTests.cpp
@@ -463,6 +463,31 @@ TEST(CompletionTest, Kinds) {
EXPECT_THAT(
Results.Completions,
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) {
diff --git a/clang/lib/Index/IndexSymbol.cpp b/clang/lib/Index/IndexSymbol.cpp
index db397b98561..064f3ae32f9 100644
--- a/clang/lib/Index/IndexSymbol.cpp
+++ b/clang/lib/Index/IndexSymbol.cpp
@@ -96,6 +96,13 @@ SymbolInfo index::getSymbolInfo(const Decl *D) {
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)) {
switch (TD->getTagKind()) {
case TTK_Struct:
@@ -333,6 +340,23 @@ SymbolInfo index::getSymbolInfo(const Decl *D) {
Info.Lang = SymbolLanguage::CXX;
}
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:
break;
}
OpenPOWER on IntegriCloud