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

Reply via email to