[clang-tools-extra] Add clangd-index-server support for cross platform indexes (PR #207202)
Bartosz Wiklak via cfe-commits
cfe-commits at lists.llvm.org
Fri Jul 10 01:04:27 PDT 2026
https://github.com/bwiklak updated https://github.com/llvm/llvm-project/pull/207202
>From 18a9088c5bb7c272a8d36a8014e2dae3950f79d6 Mon Sep 17 00:00:00 2001
From: Bartosz Wiklak <bwiklak at opera.com>
Date: Thu, 2 Jul 2026 16:31:37 +0200
Subject: [PATCH 1/3] Add clangd-index-server support for cross platform
indexes
The main use case is to serve windows index on linux server.
Without this change server wasn't able to check if project_root path
is absolute and was closed with error: "Index root should be an absolute path."
---
.../index/remote/marshalling/Marshalling.cpp | 6 ++--
.../clangd/index/remote/server/Server.cpp | 3 +-
.../remote-index/cross-platform-root.test | 9 +++++
.../unittests/remote/MarshallingTests.cpp | 33 +++++++++++++++++++
4 files changed, 48 insertions(+), 3 deletions(-)
create mode 100644 clang-tools-extra/clangd/test/remote-index/cross-platform-root.test
diff --git a/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp b/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp
index aa607926a6d51..903583414dd43 100644
--- a/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp
+++ b/clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp
@@ -59,14 +59,16 @@ Marshaller::Marshaller(llvm::StringRef RemoteIndexRoot,
: Strings(Arena) {
llvm::StringRef PosixSeparator = get_separator(Style::posix);
if (!RemoteIndexRoot.empty()) {
- assert(is_absolute(RemoteIndexRoot));
+ assert(is_absolute(RemoteIndexRoot, Style::posix) ||
+ is_absolute(RemoteIndexRoot, Style::windows));
this->RemoteIndexRoot = convert_to_slash(RemoteIndexRoot, Style::windows);
llvm::StringRef Path(this->RemoteIndexRoot);
if (!is_separator(this->RemoteIndexRoot.back(), Style::posix))
this->RemoteIndexRoot += PosixSeparator;
}
if (!LocalIndexRoot.empty()) {
- assert(is_absolute(LocalIndexRoot));
+ assert(is_absolute(LocalIndexRoot, Style::posix) ||
+ is_absolute(LocalIndexRoot, Style::windows));
this->LocalIndexRoot = convert_to_slash(LocalIndexRoot, Style::windows);
llvm::StringRef Path(this->LocalIndexRoot);
if (!is_separator(this->LocalIndexRoot.back(), Style::posix))
diff --git a/clang-tools-extra/clangd/index/remote/server/Server.cpp b/clang-tools-extra/clangd/index/remote/server/Server.cpp
index 87e4c2d938e63..f3602515691ce 100644
--- a/clang-tools-extra/clangd/index/remote/server/Server.cpp
+++ b/clang-tools-extra/clangd/index/remote/server/Server.cpp
@@ -589,7 +589,8 @@ int main(int argc, char *argv[]) {
llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
llvm::sys::SetInterruptFunction(&clang::clangd::requestShutdown);
- if (!llvm::sys::path::is_absolute(IndexRoot)) {
+ if (!llvm::sys::path::is_absolute(IndexRoot, llvm::sys::path::Style::posix) &&
+ !llvm::sys::path::is_absolute(IndexRoot, llvm::sys::path::Style::windows)) {
llvm::errs() << "Index root should be an absolute path.\n";
return -1;
}
diff --git a/clang-tools-extra/clangd/test/remote-index/cross-platform-root.test b/clang-tools-extra/clangd/test/remote-index/cross-platform-root.test
new file mode 100644
index 0000000000000..04148283b7c15
--- /dev/null
+++ b/clang-tools-extra/clangd/test/remote-index/cross-platform-root.test
@@ -0,0 +1,9 @@
+# Verify that clangd-index-server accepts Windows-style absolute paths as
+# project root, allowing the server to run on Linux with a Windows-built index.
+# "C:/project" is absolute in Windows style but not POSIX style.
+# REQUIRES: clangd-remote-index
+# RUN: rm -f %t.idx
+# RUN: not clangd-index-server --server-address=localhost:0 %t.idx "C:/project" 2>&1 | FileCheck %s
+# The server should pass the path validation and fail later on missing index.
+# CHECK-NOT: Index root should be an absolute path
+# CHECK: does not exist
diff --git a/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp b/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp
index 85e79eae331bc..b4f5c7d89341b 100644
--- a/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp
+++ b/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp
@@ -449,6 +449,39 @@ TEST(RemoteMarshallingTest, URIToRelativePathTranslation) {
llvm::consumeError(RelativePath.takeError());
}
+TEST(RemoteMarshallingTest, CrossPlatformPathsRoundTrip) {
+ llvm::BumpPtrAllocator Arena;
+ llvm::UniqueStringSaver Strings(Arena);
+
+ // Simulate a Windows-built index
+ Marshaller ProtobufMarshaller("C:/remote/project/",
+ testPath("local/project/"));
+
+ clangd::Ref Ref;
+ Ref.Kind = clangd::RefKind::Declaration;
+ clangd::SymbolLocation Location;
+ Location.Start.setLine(1);
+ Location.Start.setColumn(2);
+ Location.End.setLine(3);
+ Location.End.setColumn(4);
+ // Construct the URI as a Windows machine would have serialized it into the
+ // index: file:///C:/remote/project/lib/File.cpp.
+ Location.FileURI =
+ Strings.save("file:///C:/remote/project/lib/File.cpp").begin();
+ Ref.Location = Location;
+
+ auto Serialized = ProtobufMarshaller.toProtobuf(Ref);
+ ASSERT_TRUE(bool(Serialized));
+ // Wire path should be relative with forward slashes.
+ EXPECT_EQ(Serialized->location().file_path(), "lib/File.cpp");
+
+ auto Deserialized = ProtobufMarshaller.fromProtobuf(*Serialized);
+ ASSERT_TRUE(bool(Deserialized));
+ // Deserialized URI should be under the local root.
+ EXPECT_STREQ(Deserialized->Location.FileURI,
+ testPathURI("local/project/lib/File.cpp", Strings));
+}
+
} // namespace
} // namespace remote
} // namespace clangd
>From 81f805a88a1c3daae92df8e22bebb13c52eb9e3b Mon Sep 17 00:00:00 2001
From: Bartosz Wiklak <bwiklak at gmail.com>
Date: Fri, 10 Jul 2026 09:22:22 +0200
Subject: [PATCH 2/3] fixup! Add clangd-index-server support for cross platform
indexes
---
.../clangd/index/remote/server/Server.cpp | 3 ++-
.../test/remote-index/cross-platform-root.test | 3 +--
.../clangd/unittests/remote/MarshallingTests.cpp | 14 ++++++++++----
3 files changed, 13 insertions(+), 7 deletions(-)
diff --git a/clang-tools-extra/clangd/index/remote/server/Server.cpp b/clang-tools-extra/clangd/index/remote/server/Server.cpp
index f3602515691ce..f24e21ef0fdae 100644
--- a/clang-tools-extra/clangd/index/remote/server/Server.cpp
+++ b/clang-tools-extra/clangd/index/remote/server/Server.cpp
@@ -590,7 +590,8 @@ int main(int argc, char *argv[]) {
llvm::sys::SetInterruptFunction(&clang::clangd::requestShutdown);
if (!llvm::sys::path::is_absolute(IndexRoot, llvm::sys::path::Style::posix) &&
- !llvm::sys::path::is_absolute(IndexRoot, llvm::sys::path::Style::windows)) {
+ !llvm::sys::path::is_absolute(IndexRoot,
+ llvm::sys::path::Style::windows)) {
llvm::errs() << "Index root should be an absolute path.\n";
return -1;
}
diff --git a/clang-tools-extra/clangd/test/remote-index/cross-platform-root.test b/clang-tools-extra/clangd/test/remote-index/cross-platform-root.test
index 04148283b7c15..08fa237f576fe 100644
--- a/clang-tools-extra/clangd/test/remote-index/cross-platform-root.test
+++ b/clang-tools-extra/clangd/test/remote-index/cross-platform-root.test
@@ -2,8 +2,7 @@
# project root, allowing the server to run on Linux with a Windows-built index.
# "C:/project" is absolute in Windows style but not POSIX style.
# REQUIRES: clangd-remote-index
-# RUN: rm -f %t.idx
-# RUN: not clangd-index-server --server-address=localhost:0 %t.idx "C:/project" 2>&1 | FileCheck %s
+# RUN: not clangd-index-server --server-address=localhost:0 %t.idx "C:\\project" 2>&1 | FileCheck %s
# The server should pass the path validation and fail later on missing index.
# CHECK-NOT: Index root should be an absolute path
# CHECK: does not exist
diff --git a/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp b/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp
index b4f5c7d89341b..06d0e28c0e865 100644
--- a/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp
+++ b/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp
@@ -453,8 +453,9 @@ TEST(RemoteMarshallingTest, CrossPlatformPathsRoundTrip) {
llvm::BumpPtrAllocator Arena;
llvm::UniqueStringSaver Strings(Arena);
- // Simulate a Windows-built index
- Marshaller ProtobufMarshaller("C:/remote/project/",
+ // Simulate a Windows-built index.
+ std::string RemoteIndexRoot = "C:\\remote\\project\\";
+ Marshaller ProtobufMarshaller(RemoteIndexRoot,
testPath("local/project/"));
clangd::Ref Ref;
@@ -466,8 +467,13 @@ TEST(RemoteMarshallingTest, CrossPlatformPathsRoundTrip) {
Location.End.setColumn(4);
// Construct the URI as a Windows machine would have serialized it into the
// index: file:///C:/remote/project/lib/File.cpp.
- Location.FileURI =
- Strings.save("file:///C:/remote/project/lib/File.cpp").begin();
+ Location.FileURI =
+ Strings
+ .save("file:///" +
+ convert_to_slash(RemoteIndexRoot,
+ llvm::sys::path::Style::windows) +
+ "lib/File.cpp")
+ .begin();
Ref.Location = Location;
auto Serialized = ProtobufMarshaller.toProtobuf(Ref);
>From 85e15a36af3a198dd1d80f7e1399d30e2412257f Mon Sep 17 00:00:00 2001
From: Bartosz Wiklak <bwiklak at gmail.com>
Date: Fri, 10 Jul 2026 10:03:52 +0200
Subject: [PATCH 3/3] fixup! Add clangd-index-server support for cross platform
indexes
---
clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp b/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp
index 06d0e28c0e865..e1ab4244ccfc3 100644
--- a/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp
+++ b/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp
@@ -455,8 +455,7 @@ TEST(RemoteMarshallingTest, CrossPlatformPathsRoundTrip) {
// Simulate a Windows-built index.
std::string RemoteIndexRoot = "C:\\remote\\project\\";
- Marshaller ProtobufMarshaller(RemoteIndexRoot,
- testPath("local/project/"));
+ Marshaller ProtobufMarshaller(RemoteIndexRoot, testPath("local/project/"));
clangd::Ref Ref;
Ref.Kind = clangd::RefKind::Declaration;
More information about the cfe-commits
mailing list