Author: Bartosz Wiklak Date: 2026-07-10T17:34:56+03:00 New Revision: ff5363bf29ba9f426b241abb9e72d12d9b785221
URL: https://github.com/llvm/llvm-project/commit/ff5363bf29ba9f426b241abb9e72d12d9b785221 DIFF: https://github.com/llvm/llvm-project/commit/ff5363bf29ba9f426b241abb9e72d12d9b785221.diff LOG: [clangd][remote] Add clangd-index-server support for cross platform indexes (#207202) 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." This change is meant to solve issue: https://github.com/clangd/clangd/issues/2646 Added: clang-tools-extra/clangd/test/remote-index/cross-platform-root.test Modified: clang-tools-extra/clangd/index/remote/marshalling/Marshalling.cpp clang-tools-extra/clangd/index/remote/server/Server.cpp clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp Removed: ################################################################################ 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..f24e21ef0fdae 100644 --- a/clang-tools-extra/clangd/index/remote/server/Server.cpp +++ b/clang-tools-extra/clangd/index/remote/server/Server.cpp @@ -589,7 +589,9 @@ 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..08fa237f576fe --- /dev/null +++ b/clang-tools-extra/clangd/test/remote-index/cross-platform-root.test @@ -0,0 +1,8 @@ +# 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: 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..fe0dc4a67622c 100644 --- a/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp +++ b/clang-tools-extra/clangd/unittests/remote/MarshallingTests.cpp @@ -449,6 +449,44 @@ TEST(RemoteMarshallingTest, URIToRelativePathTranslation) { llvm::consumeError(RelativePath.takeError()); } +TEST(RemoteMarshallingTest, CrossPlatformPathsRoundTrip) { + llvm::BumpPtrAllocator Arena; + llvm::UniqueStringSaver Strings(Arena); + + // Simulate a Windows-built index. + llvm::StringRef RemoteIndexRoot = "C:\\remote\\project\\"; + Marshaller ProtobufMarshaller(RemoteIndexRoot, 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:///" + + convert_to_slash(RemoteIndexRoot, + llvm::sys::path::Style::windows) + + "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 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
