Author: David Zbarsky Date: 2026-07-17T08:38:19+03:00 New Revision: 15ae01dd24261bd70947aab884098e5dcd4096dd
URL: https://github.com/llvm/llvm-project/commit/15ae01dd24261bd70947aab884098e5dcd4096dd DIFF: https://github.com/llvm/llvm-project/commit/15ae01dd24261bd70947aab884098e5dcd4096dd.diff LOG: [clangd][Support] Outline LSP payload decode errors (#203121) Move failed payload handling from `clangd::LSPBinder::parse<T>` and `llvm::lsp::MessageHandler::parse<T>` into their non-inline `handleParseError` functions, while keeping successful payload conversion specialized in each `parse<T>` instantiation. For a Darwin arm64 build, stripped clangd decreased by 32,848 bytes and `__TEXT,__text` decreased by 25,180 bytes. `ClangdTests --gtest_filter=LSPBinderTest.*` passes, and `llvm/lib/Support/LSP/Transport.cpp` passes a standalone syntax compile. Work towards #202616 AI tool disclosure: Co-authored with OpenAI Codex. Co-authored-by: OpenAI Codex <[email protected]> Added: clang-tools-extra/clangd/LSPBinder.cpp Modified: clang-tools-extra/clangd/CMakeLists.txt clang-tools-extra/clangd/LSPBinder.h llvm/include/llvm/Support/LSP/Transport.h llvm/lib/Support/LSP/Transport.cpp llvm/utils/gn/secondary/clang-tools-extra/clangd/BUILD.gn utils/bazel/llvm-project-overlay/clang-tools-extra/clangd/BUILD.bazel Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/CMakeLists.txt b/clang-tools-extra/clangd/CMakeLists.txt index 890562dde1792..9fa7d92d8374c 100644 --- a/clang-tools-extra/clangd/CMakeLists.txt +++ b/clang-tools-extra/clangd/CMakeLists.txt @@ -96,6 +96,7 @@ add_clang_library(clangDaemon STATIC IncludeFixer.cpp InlayHints.cpp JSONTransport.cpp + LSPBinder.cpp ModulesBuilder.cpp PathMapping.cpp ProjectModules.cpp diff --git a/clang-tools-extra/clangd/LSPBinder.cpp b/clang-tools-extra/clangd/LSPBinder.cpp new file mode 100644 index 0000000000000..8e997776f3763 --- /dev/null +++ b/clang-tools-extra/clangd/LSPBinder.cpp @@ -0,0 +1,36 @@ +//===--- LSPBinder.cpp - Tables of LSP handlers --------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "LSPBinder.h" +#include "llvm/Support/Compiler.h" +#include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/raw_ostream.h" + +namespace clang { +namespace clangd { + +// Keep handleParseError out of every parse<T> instantiation. +LLVM_ATTRIBUTE_NOINLINE llvm::Error LSPBinder::handleParseError( + const llvm::json::Value &Raw, llvm::StringRef PayloadName, + llvm::StringRef PayloadKind, const llvm::json::Path::Root &Root) { + elog("Failed to decode {0} {1}: {2}", PayloadName, PayloadKind, + Root.getError()); + // Dump the relevant parts of the broken message. + std::string Context; + llvm::raw_string_ostream OS(Context); + Root.printErrorContext(Raw, OS); + vlog("{0}", OS.str()); + // Report the error (e.g. to the client). + return llvm::make_error<LSPError>( + llvm::formatv("failed to decode {0} {1}: {2}", PayloadName, PayloadKind, + fmt_consume(Root.getError())), + ErrorCode::InvalidParams); +} + +} // namespace clangd +} // namespace clang diff --git a/clang-tools-extra/clangd/LSPBinder.h b/clang-tools-extra/clangd/LSPBinder.h index 8542112681375..74b4bd0f708ff 100644 --- a/clang-tools-extra/clangd/LSPBinder.h +++ b/clang-tools-extra/clangd/LSPBinder.h @@ -101,6 +101,10 @@ class LSPBinder { static llvm::Expected<T> parse(const llvm::json::Value &Raw, llvm::StringRef PayloadName, llvm::StringRef PayloadKind); + static llvm::Error handleParseError(const llvm::json::Value &Raw, + llvm::StringRef PayloadName, + llvm::StringRef PayloadKind, + const llvm::json::Path::Root &Root); RawHandlers &Raw; RawOutgoing &Out; @@ -112,20 +116,8 @@ llvm::Expected<T> LSPBinder::parse(const llvm::json::Value &Raw, llvm::StringRef PayloadKind) { T Result; llvm::json::Path::Root Root; - if (!fromJSON(Raw, Result, Root)) { - elog("Failed to decode {0} {1}: {2}", PayloadName, PayloadKind, - Root.getError()); - // Dump the relevant parts of the broken message. - std::string Context; - llvm::raw_string_ostream OS(Context); - Root.printErrorContext(Raw, OS); - vlog("{0}", OS.str()); - // Report the error (e.g. to the client). - return llvm::make_error<LSPError>( - llvm::formatv("failed to decode {0} {1}: {2}", PayloadName, PayloadKind, - fmt_consume(Root.getError())), - ErrorCode::InvalidParams); - } + if (!fromJSON(Raw, Result, Root)) + return handleParseError(Raw, PayloadName, PayloadKind, Root); return std::move(Result); } diff --git a/llvm/include/llvm/Support/LSP/Transport.h b/llvm/include/llvm/Support/LSP/Transport.h index 6a0dd51d946bd..eee4a4e525fde 100644 --- a/llvm/include/llvm/Support/LSP/Transport.h +++ b/llvm/include/llvm/Support/LSP/Transport.h @@ -172,19 +172,9 @@ class MessageHandler { StringRef PayloadName, StringRef PayloadKind) { T Result; llvm::json::Path::Root Root; - if (fromJSON(Raw, Result, Root)) - return std::move(Result); - - // Dump the relevant parts of the broken message. - std::string Context; - llvm::raw_string_ostream Os(Context); - Root.printErrorContext(Raw, Os); - - // Report the error (e.g. to the client). - return llvm::make_error<LSPError>( - llvm::formatv("failed to decode {0} {1}: {2}", PayloadName, PayloadKind, - fmt_consume(Root.getError())), - ErrorCode::InvalidParams); + if (!fromJSON(Raw, Result, Root)) + return handleParseError(Raw, PayloadName, PayloadKind, Root); + return std::move(Result); } template <typename Param, typename Result, typename ThisT> @@ -266,6 +256,10 @@ class MessageHandler { } private: + LLVM_ABI static llvm::Error + handleParseError(const llvm::json::Value &Raw, StringRef PayloadName, + StringRef PayloadKind, const llvm::json::Path::Root &Root); + template <typename HandlerT> using HandlerMap = llvm::StringMap<llvm::unique_function<HandlerT>>; diff --git a/llvm/lib/Support/LSP/Transport.cpp b/llvm/lib/Support/LSP/Transport.cpp index 31b5a89f9b5e0..e79ca679878d0 100644 --- a/llvm/lib/Support/LSP/Transport.cpp +++ b/llvm/lib/Support/LSP/Transport.cpp @@ -83,6 +83,23 @@ void Reply::operator()(llvm::Expected<llvm::json::Value> Reply) { // MessageHandler //===----------------------------------------------------------------------===// +// Keep handleParseError out of every parse<T> instantiation. +LLVM_ATTRIBUTE_NOINLINE llvm::Error +MessageHandler::handleParseError(const llvm::json::Value &Raw, + StringRef PayloadName, StringRef PayloadKind, + const llvm::json::Path::Root &Root) { + // Dump the relevant parts of the broken message. + std::string Context; + llvm::raw_string_ostream Os(Context); + Root.printErrorContext(Raw, Os); + + // Report the error (e.g. to the client). + return llvm::make_error<LSPError>( + llvm::formatv("failed to decode {0} {1}: {2}", PayloadName, PayloadKind, + fmt_consume(Root.getError())), + ErrorCode::InvalidParams); +} + bool MessageHandler::onNotify(llvm::StringRef Method, llvm::json::Value Value) { Logger::info("--> {0}", Method); diff --git a/llvm/utils/gn/secondary/clang-tools-extra/clangd/BUILD.gn b/llvm/utils/gn/secondary/clang-tools-extra/clangd/BUILD.gn index 86f959816f958..f30aac6add176 100644 --- a/llvm/utils/gn/secondary/clang-tools-extra/clangd/BUILD.gn +++ b/llvm/utils/gn/secondary/clang-tools-extra/clangd/BUILD.gn @@ -112,6 +112,7 @@ static_library("clangd") { "IncludeFixer.cpp", "InlayHints.cpp", "JSONTransport.cpp", + "LSPBinder.cpp", "ModulesBuilder.cpp", "ParsedAST.cpp", "PathMapping.cpp", diff --git a/utils/bazel/llvm-project-overlay/clang-tools-extra/clangd/BUILD.bazel b/utils/bazel/llvm-project-overlay/clang-tools-extra/clangd/BUILD.bazel index 4151e55a938d9..34d44e8f63512 100644 --- a/utils/bazel/llvm-project-overlay/clang-tools-extra/clangd/BUILD.bazel +++ b/utils/bazel/llvm-project-overlay/clang-tools-extra/clangd/BUILD.bazel @@ -36,6 +36,7 @@ cc_library( "Feature.cpp", "Features.inc", "JSONTransport.cpp", + "LSPBinder.cpp", "Protocol.cpp", "URI.cpp", "index/SymbolID.cpp", _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
