[clang] [clang-tools-extra] [clangd] Add missing SymbolKind cases to YAML serialization (PR #222070)
Andre Sun via cfe-commits
cfe-commits at lists.llvm.org
Fri Sep 11 06:50:13 PDT 2026
https://github.com/and2049 updated https://github.com/llvm/llvm-project/pull/222070
>From 924d1761f09cf6b9c76218140111c4435b5c8847 Mon Sep 17 00:00:00 2001
From: andre sun <andsun9999 at gmail.com>
Date: Tue, 8 Sep 2026 13:06:28 -0400
Subject: [PATCH 1/3] [clangd] Add missing SymbolKind cases to YAML
serialization
Add missing enum spellings, remove the duplicate Function entry, and
test round-tripping all symbol kinds. This fixes invalid YAML output
when indexing C++20 concepts.
Fixes #206875
---
.../clangd/index/YAMLSerialization.cpp | 6 +++-
.../clangd/unittests/SerializationTests.cpp | 28 +++++++++++++++++++
clang-tools-extra/docs/ReleaseNotes.md | 4 +++
3 files changed, 37 insertions(+), 1 deletion(-)
diff --git a/clang-tools-extra/clangd/index/YAMLSerialization.cpp b/clang-tools-extra/clangd/index/YAMLSerialization.cpp
index 4d6b5822ece72..e042877a469c6 100644
--- a/clang-tools-extra/clangd/index/YAMLSerialization.cpp
+++ b/clang-tools-extra/clangd/index/YAMLSerialization.cpp
@@ -265,11 +265,11 @@ template <> struct ScalarEnumerationTraits<SymbolKind> {
#define DEFINE_ENUM(name) IO.enumCase(Value, #name, SymbolKind::name)
DEFINE_ENUM(Unknown);
- DEFINE_ENUM(Function);
DEFINE_ENUM(Module);
DEFINE_ENUM(Namespace);
DEFINE_ENUM(NamespaceAlias);
DEFINE_ENUM(Macro);
+ DEFINE_ENUM(IncludeDirective);
DEFINE_ENUM(Enum);
DEFINE_ENUM(Struct);
DEFINE_ENUM(Class);
@@ -292,6 +292,10 @@ template <> struct ScalarEnumerationTraits<SymbolKind> {
DEFINE_ENUM(ConversionFunction);
DEFINE_ENUM(Parameter);
DEFINE_ENUM(Using);
+ DEFINE_ENUM(TemplateTypeParm);
+ DEFINE_ENUM(TemplateTemplateParm);
+ DEFINE_ENUM(NonTypeTemplateParm);
+ DEFINE_ENUM(Concept);
#undef DEFINE_ENUM
}
diff --git a/clang-tools-extra/clangd/unittests/SerializationTests.cpp b/clang-tools-extra/clangd/unittests/SerializationTests.cpp
index 5108e653c36a0..1215e897aab61 100644
--- a/clang-tools-extra/clangd/unittests/SerializationTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SerializationTests.cpp
@@ -9,6 +9,7 @@
#include "FindSymbols.h"
#include "Headers.h"
#include "RIFF.h"
+#include "TestIndex.h"
#include "index/Serialization.h"
#include "support/Logger.h"
#include "clang/Tooling/CompilationDatabase.h"
@@ -260,6 +261,33 @@ TEST(SerializationTest, BinaryConversions) {
UnorderedElementsAreArray(yamlFromRelations(*In->Relations)));
}
+// Every SymbolKind must have a YAML spelling, otherwise writing the index
+// produces invalid YAML (or aborts with assertions enabled).
+TEST(SerializationTest, YAMLSymbolKindRoundTrip) {
+ SymbolSlab::Builder Builder;
+ for (unsigned K = 0; K <= static_cast<unsigned>(index::SymbolKind::Concept);
+ ++K) {
+ std::string Name = "Sym" + std::to_string(K);
+ Symbol Sym = symbol(Name);
+ Sym.SymInfo.Kind = static_cast<index::SymbolKind>(K);
+ Builder.insert(Sym);
+ }
+ SymbolSlab Symbols = std::move(Builder).build();
+
+ IndexFileOut Out;
+ Out.Symbols = &Symbols;
+ Out.Format = IndexFileFormat::YAML;
+
+ auto In = readIndexFile(llvm::to_string(Out));
+ ASSERT_TRUE(bool(In)) << In.takeError();
+ ASSERT_TRUE(In->Symbols);
+ for (const Symbol &Sym : Symbols) {
+ auto It = In->Symbols->find(Sym.ID);
+ ASSERT_NE(It, In->Symbols->end()) << Sym.Name;
+ EXPECT_EQ(It->SymInfo.Kind, Sym.SymInfo.Kind) << Sym.Name;
+ }
+}
+
TEST(SerializationTest, SrcsTest) {
auto In = readIndexFile(YAML);
EXPECT_TRUE(bool(In)) << In.takeError();
diff --git a/clang-tools-extra/docs/ReleaseNotes.md b/clang-tools-extra/docs/ReleaseNotes.md
index 4523e0f78035b..b5d1e4ecd389d 100644
--- a/clang-tools-extra/docs/ReleaseNotes.md
+++ b/clang-tools-extra/docs/ReleaseNotes.md
@@ -90,6 +90,10 @@ infrastructure are described first, followed by tool-specific sections.
#### Miscellaneous
+- Fixed `clangd-indexer --format=yaml` emitting invalid YAML when indexing
+ C++20 concepts.
+ ([#206875](https://github.com/llvm/llvm-project/issues/206875))
+
### Improvements to clang-doc
### Improvements to clang-query
>From 8cdb409e499db512680e51cf2cb3b1268bcb69c4 Mon Sep 17 00:00:00 2001
From: andre sun <andsun9999 at gmail.com>
Date: Wed, 9 Sep 2026 17:42:01 -0400
Subject: [PATCH 2/3] [clangd] Use a SymbolKind end marker in the YAML
round-trip test
Add SymbolKind::Count so the test covers future kinds automatically.
---
clang-tools-extra/clangd/CodeComplete.cpp | 2 ++
clang-tools-extra/clangd/Protocol.cpp | 2 ++
clang-tools-extra/clangd/Quality.cpp | 2 ++
clang-tools-extra/clangd/unittests/SerializationTests.cpp | 4 ++--
clang/include/clang/Index/IndexSymbol.h | 3 +++
clang/lib/Index/IndexSymbol.cpp | 2 ++
clang/tools/libclang/CXIndexDataConsumer.cpp | 2 ++
7 files changed, 15 insertions(+), 2 deletions(-)
diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp
index 80091d3a48b33..71a5d2beb9afa 100644
--- a/clang-tools-extra/clangd/CodeComplete.cpp
+++ b/clang-tools-extra/clangd/CodeComplete.cpp
@@ -158,6 +158,8 @@ toCompletionItemKind(index::SymbolKind Kind,
return CompletionItemKind::TypeParameter;
case SK::Concept:
return CompletionItemKind::Interface;
+ case SK::Count:
+ break;
}
llvm_unreachable("Unhandled clang::index::SymbolKind.");
}
diff --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp
index c22ada45d44cf..74b5932330a55 100644
--- a/clang-tools-extra/clangd/Protocol.cpp
+++ b/clang-tools-extra/clangd/Protocol.cpp
@@ -371,6 +371,8 @@ SymbolKind indexSymbolKindToSymbolKind(const index::SymbolInfo &Info) {
return SymbolKind::TypeParameter;
case index::SymbolKind::Concept:
return SymbolKind::Interface;
+ case index::SymbolKind::Count:
+ break;
}
llvm_unreachable("invalid symbol kind");
}
diff --git a/clang-tools-extra/clangd/Quality.cpp b/clang-tools-extra/clangd/Quality.cpp
index dc4afe18cb354..9ff99a3269e63 100644
--- a/clang-tools-extra/clangd/Quality.cpp
+++ b/clang-tools-extra/clangd/Quality.cpp
@@ -150,6 +150,8 @@ categorize(const index::SymbolInfo &D) {
case index::SymbolKind::Module:
case index::SymbolKind::Unknown:
return SymbolQualitySignals::Unknown;
+ case index::SymbolKind::Count:
+ break;
}
llvm_unreachable("Unknown index::SymbolKind");
}
diff --git a/clang-tools-extra/clangd/unittests/SerializationTests.cpp b/clang-tools-extra/clangd/unittests/SerializationTests.cpp
index 1215e897aab61..be91bbdca3a53 100644
--- a/clang-tools-extra/clangd/unittests/SerializationTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SerializationTests.cpp
@@ -265,8 +265,8 @@ TEST(SerializationTest, BinaryConversions) {
// produces invalid YAML (or aborts with assertions enabled).
TEST(SerializationTest, YAMLSymbolKindRoundTrip) {
SymbolSlab::Builder Builder;
- for (unsigned K = 0; K <= static_cast<unsigned>(index::SymbolKind::Concept);
- ++K) {
+ for (auto K = static_cast<unsigned>(index::SymbolKind::Unknown);
+ K < static_cast<unsigned>(index::SymbolKind::Count); ++K) {
std::string Name = "Sym" + std::to_string(K);
Symbol Sym = symbol(Name);
Sym.SymInfo.Kind = static_cast<index::SymbolKind>(K);
diff --git a/clang/include/clang/Index/IndexSymbol.h b/clang/include/clang/Index/IndexSymbol.h
index 4a7f523b885fc..011a1cbb8b954 100644
--- a/clang/include/clang/Index/IndexSymbol.h
+++ b/clang/include/clang/Index/IndexSymbol.h
@@ -60,6 +60,9 @@ enum class SymbolKind : uint8_t {
NonTypeTemplateParm,
Concept, /// C++20 concept.
+
+ /// One past the last valid kind. Must remain the last enumerator.
+ Count,
};
enum class SymbolLanguage : uint8_t {
diff --git a/clang/lib/Index/IndexSymbol.cpp b/clang/lib/Index/IndexSymbol.cpp
index 5131b321dedb2..154934ac1d412 100644
--- a/clang/lib/Index/IndexSymbol.cpp
+++ b/clang/lib/Index/IndexSymbol.cpp
@@ -570,6 +570,8 @@ StringRef index::getSymbolKindString(SymbolKind K) {
case SymbolKind::NonTypeTemplateParm: return "non-type-template-param";
case SymbolKind::Concept:
return "concept";
+ case SymbolKind::Count:
+ break;
}
llvm_unreachable("invalid symbol kind");
}
diff --git a/clang/tools/libclang/CXIndexDataConsumer.cpp b/clang/tools/libclang/CXIndexDataConsumer.cpp
index 8babcccf38c51..19ccec45ad2e5 100644
--- a/clang/tools/libclang/CXIndexDataConsumer.cpp
+++ b/clang/tools/libclang/CXIndexDataConsumer.cpp
@@ -1288,6 +1288,8 @@ static CXIdxEntityKind getEntityKindFromSymbolKind(SymbolKind K, SymbolLanguage
case SymbolKind::Parameter: return CXIdxEntity_Variable;
case SymbolKind::Concept:
return CXIdxEntity_CXXConcept;
+ case SymbolKind::Count:
+ break;
}
llvm_unreachable("invalid symbol kind");
}
>From 458a85199340b3d8f6d41a861ac4380addb54545 Mon Sep 17 00:00:00 2001
From: andre sun <andsun9999 at gmail.com>
Date: Fri, 11 Sep 2026 09:49:51 -0400
Subject: [PATCH 3/3] [clangd] Remove SymbolKind end marker and bound YAML test
by Concept
---
clang-tools-extra/clangd/CodeComplete.cpp | 2 --
clang-tools-extra/clangd/Protocol.cpp | 2 --
clang-tools-extra/clangd/Quality.cpp | 2 --
clang-tools-extra/clangd/unittests/SerializationTests.cpp | 4 ++--
clang/include/clang/Index/IndexSymbol.h | 3 ---
clang/lib/Index/IndexSymbol.cpp | 2 --
clang/tools/libclang/CXIndexDataConsumer.cpp | 2 --
7 files changed, 2 insertions(+), 15 deletions(-)
diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp
index 71a5d2beb9afa..80091d3a48b33 100644
--- a/clang-tools-extra/clangd/CodeComplete.cpp
+++ b/clang-tools-extra/clangd/CodeComplete.cpp
@@ -158,8 +158,6 @@ toCompletionItemKind(index::SymbolKind Kind,
return CompletionItemKind::TypeParameter;
case SK::Concept:
return CompletionItemKind::Interface;
- case SK::Count:
- break;
}
llvm_unreachable("Unhandled clang::index::SymbolKind.");
}
diff --git a/clang-tools-extra/clangd/Protocol.cpp b/clang-tools-extra/clangd/Protocol.cpp
index 74b5932330a55..c22ada45d44cf 100644
--- a/clang-tools-extra/clangd/Protocol.cpp
+++ b/clang-tools-extra/clangd/Protocol.cpp
@@ -371,8 +371,6 @@ SymbolKind indexSymbolKindToSymbolKind(const index::SymbolInfo &Info) {
return SymbolKind::TypeParameter;
case index::SymbolKind::Concept:
return SymbolKind::Interface;
- case index::SymbolKind::Count:
- break;
}
llvm_unreachable("invalid symbol kind");
}
diff --git a/clang-tools-extra/clangd/Quality.cpp b/clang-tools-extra/clangd/Quality.cpp
index 9ff99a3269e63..dc4afe18cb354 100644
--- a/clang-tools-extra/clangd/Quality.cpp
+++ b/clang-tools-extra/clangd/Quality.cpp
@@ -150,8 +150,6 @@ categorize(const index::SymbolInfo &D) {
case index::SymbolKind::Module:
case index::SymbolKind::Unknown:
return SymbolQualitySignals::Unknown;
- case index::SymbolKind::Count:
- break;
}
llvm_unreachable("Unknown index::SymbolKind");
}
diff --git a/clang-tools-extra/clangd/unittests/SerializationTests.cpp b/clang-tools-extra/clangd/unittests/SerializationTests.cpp
index be91bbdca3a53..cbe2a9726f865 100644
--- a/clang-tools-extra/clangd/unittests/SerializationTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SerializationTests.cpp
@@ -265,8 +265,8 @@ TEST(SerializationTest, BinaryConversions) {
// produces invalid YAML (or aborts with assertions enabled).
TEST(SerializationTest, YAMLSymbolKindRoundTrip) {
SymbolSlab::Builder Builder;
- for (auto K = static_cast<unsigned>(index::SymbolKind::Unknown);
- K < static_cast<unsigned>(index::SymbolKind::Count); ++K) {
+ for (unsigned K = static_cast<unsigned>(index::SymbolKind::Unknown);
+ K <= static_cast<unsigned>(index::SymbolKind::Concept); ++K) {
std::string Name = "Sym" + std::to_string(K);
Symbol Sym = symbol(Name);
Sym.SymInfo.Kind = static_cast<index::SymbolKind>(K);
diff --git a/clang/include/clang/Index/IndexSymbol.h b/clang/include/clang/Index/IndexSymbol.h
index 011a1cbb8b954..4a7f523b885fc 100644
--- a/clang/include/clang/Index/IndexSymbol.h
+++ b/clang/include/clang/Index/IndexSymbol.h
@@ -60,9 +60,6 @@ enum class SymbolKind : uint8_t {
NonTypeTemplateParm,
Concept, /// C++20 concept.
-
- /// One past the last valid kind. Must remain the last enumerator.
- Count,
};
enum class SymbolLanguage : uint8_t {
diff --git a/clang/lib/Index/IndexSymbol.cpp b/clang/lib/Index/IndexSymbol.cpp
index 154934ac1d412..5131b321dedb2 100644
--- a/clang/lib/Index/IndexSymbol.cpp
+++ b/clang/lib/Index/IndexSymbol.cpp
@@ -570,8 +570,6 @@ StringRef index::getSymbolKindString(SymbolKind K) {
case SymbolKind::NonTypeTemplateParm: return "non-type-template-param";
case SymbolKind::Concept:
return "concept";
- case SymbolKind::Count:
- break;
}
llvm_unreachable("invalid symbol kind");
}
diff --git a/clang/tools/libclang/CXIndexDataConsumer.cpp b/clang/tools/libclang/CXIndexDataConsumer.cpp
index 19ccec45ad2e5..8babcccf38c51 100644
--- a/clang/tools/libclang/CXIndexDataConsumer.cpp
+++ b/clang/tools/libclang/CXIndexDataConsumer.cpp
@@ -1288,8 +1288,6 @@ static CXIdxEntityKind getEntityKindFromSymbolKind(SymbolKind K, SymbolLanguage
case SymbolKind::Parameter: return CXIdxEntity_Variable;
case SymbolKind::Concept:
return CXIdxEntity_CXXConcept;
- case SymbolKind::Count:
- break;
}
llvm_unreachable("invalid symbol kind");
}
More information about the cfe-commits
mailing list