Author: Aleksandr Platonov Date: 2026-06-05T09:47:24+03:00 New Revision: e3260943a9bf6f14b9f92cb30de40ac6cc4ae406
URL: https://github.com/llvm/llvm-project/commit/e3260943a9bf6f14b9f92cb30de40ac6cc4ae406 DIFF: https://github.com/llvm/llvm-project/commit/e3260943a9bf6f14b9f92cb30de40ac6cc4ae406.diff LOG: [clangd][modules] Provide correct context to ModulesBuilder::hasRequiredModules() call (#201419) To make command mangler to use compile command edits from the configuration, we need to provide the correct context to it. Without this patch compile command edits declared in .clangd file are not used during required modules check, which can lead to compile errors appearing and false negative `ModulesBuilder::hadRequiredModules()` return result. This PR addresses problem described here https://github.com/llvm/llvm-project/pull/200001#issuecomment-4590514342 Added: clang-tools-extra/clangd/test/modules_config_remove_flags.test Modified: clang-tools-extra/clangd/ClangdServer.cpp clang-tools-extra/clangd/ClangdServer.h Removed: ################################################################################ diff --git a/clang-tools-extra/clangd/ClangdServer.cpp b/clang-tools-extra/clangd/ClangdServer.cpp index 9c9290b8b6b1b..37eb82116f3a9 100644 --- a/clang-tools-extra/clangd/ClangdServer.cpp +++ b/clang-tools-extra/clangd/ClangdServer.cpp @@ -229,7 +229,8 @@ ClangdServer::ClangdServer(const GlobalCompilationDatabase &CDB, WorkspaceRoot(Opts.WorkspaceRoot), Transient(Opts.ImplicitCancellation ? TUScheduler::InvalidateOnUpdate : TUScheduler::NoInvalidation), - DirtyFS(std::make_unique<DraftStoreFS>(TFS, DraftMgr)) { + DirtyFS(std::make_unique<DraftStoreFS>(TFS, DraftMgr)), + ContextProvider(Opts.ContextProvider) { if (Opts.AsyncThreadsCount != 0) IndexTasks.emplace(); // Pass a callback into `WorkScheduler` to extract symbols from a newly @@ -1198,9 +1199,18 @@ void ClangdServer::adjustParseInputs(ParseInputs &Inputs, PathRef File) const { // named modules. Mixing PCH and modules may cause diff erent issues (incorrect // diagnostics, crashes) due to instability of such scenario support in the // clang. - Inputs.Opts.SkipPreambleBuild = - SkipPreambleBuild || - (ModulesManager && ModulesManager->hasRequiredModules(File)); + auto HasRequiredModules = [this, File]() { + if (!ModulesManager) + return false; + // Required modules check uses compile commands extracted from the + // compilation database. + // We use context provider here to make command mangler to use compile + // command adjustments from the config. + WithContext Ctx(ContextProvider ? ContextProvider(File) + : Context::current().clone()); + return ModulesManager->hasRequiredModules(File); + }; + Inputs.Opts.SkipPreambleBuild = SkipPreambleBuild || HasRequiredModules(); } } // namespace clangd diff --git a/clang-tools-extra/clangd/ClangdServer.h b/clang-tools-extra/clangd/ClangdServer.h index 36d320af2f8a1..264ab7437c248 100644 --- a/clang-tools-extra/clangd/ClangdServer.h +++ b/clang-tools-extra/clangd/ClangdServer.h @@ -535,6 +535,7 @@ class ClangdServer { DraftStore DraftMgr; std::unique_ptr<ThreadsafeFS> DirtyFS; + std::function<Context(PathRef)> ContextProvider; }; } // namespace clangd diff --git a/clang-tools-extra/clangd/test/modules_config_remove_flags.test b/clang-tools-extra/clangd/test/modules_config_remove_flags.test new file mode 100644 index 0000000000000..eef5052ac50b1 --- /dev/null +++ b/clang-tools-extra/clangd/test/modules_config_remove_flags.test @@ -0,0 +1,58 @@ +# Test that compile command edits from .clangd config are used during +# the required modules check. + +# FIXME: Excepted to fail on Windows like module_dependencies.test. +# UNSUPPORTED: system-windows + +# RUN: rm -fr %t +# RUN: mkdir -p %t +# RUN: split-file %s %t + +# RUN: sed -e "s|DIR|%/t|g" %t/compile_commands.json.tmpl > %t/compile_commands.json.tmp +# RUN: sed -e "s|CLANG_CC|%clang|g" %t/compile_commands.json.tmp > %t/compile_commands.json +# RUN: sed -e "s|DIR|%/t|g" %t/didOpen.jsonrpc.tmpl > %t/didOpen.jsonrpc + +# RUN: clangd -experimental-modules-support -enable-config -lit-test < %t/didOpen.jsonrpc 2>&1 \ +# RUN: | FileCheck -strict-whitespace --check-prefix=CHECK %t/didOpen.jsonrpc + +#--- .clangd +CompileFlags: + Remove: [-fmodule-mapper=*] + +#--- A.cppm +export module A; +export void printA() {} + +#--- Use.cpp +import A; +void foo() { + print +} + +#--- compile_commands.json.tmpl +[ + { + "directory": "DIR", + "command": "CLANG_CC -fprebuilt-module-path=DIR -std=c++20 -fmodule-mapper=test.modmap -o DIR/Use.cpp.o -c DIR/Use.cpp", + "file": "DIR/Use.cpp" + }, + { + "directory": "DIR", + "command": "CLANG_CC -std=c++20 DIR/A.cppm --precompile -o DIR/A.pcm", + "file": "DIR/A.cppm" + } +] + +#--- didOpen.jsonrpc.tmpl +{"jsonrpc":"2.0","id":0,"method":"initialize","params":{"processId":123,"rootPath":"clangd","capabilities":{},"trace":"off"}} +--- +{"jsonrpc":"2.0","method":"textDocument/didOpen","params":{"textDocument":{"uri":"file://DIR/Use.cpp","languageId":"cpp","version":1,"text":"import A;\nvoid foo() {\n print\n}\n"}}} + +# Verify no log errors from module scanning (stderr captured via 2>&1). +# CHECK-NOT: unknown argument +# CHECK: "message"{{.*}}printA{{.*}}(fix available) + +--- +{"jsonrpc":"2.0","id":1,"method":"shutdown"} +--- +{"jsonrpc":"2.0","method":"exit"} _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
