Author: Chuanqi Xu
Date: 2026-10-08T08:15:15Z
New Revision: 86a48da46ff54705c77e1d48200e82b040fb30cd

URL: 
https://github.com/llvm/llvm-project/commit/86a48da46ff54705c77e1d48200e82b040fb30cd
DIFF: 
https://github.com/llvm/llvm-project/commit/86a48da46ff54705c77e1d48200e82b040fb30cd.diff

LOG: [clangd] [C++20] [Modules] Don't reuse prebuilt module files on windows 
(#193426)

Fix https://github.com/clangd/clangd/issues/2497

Note that this only works for --experimental-modules-support. Otherwise,
it is a natural fallback by the design clang based tools.

Added: 
    clang-tools-extra/clangd/test/prebuilt_module_file_reuse.test

Modified: 
    clang-tools-extra/clangd/ModulesBuilder.cpp

Removed: 
    


################################################################################
diff  --git a/clang-tools-extra/clangd/ModulesBuilder.cpp 
b/clang-tools-extra/clangd/ModulesBuilder.cpp
index d90afea465155..72bb5b836d201 100644
--- a/clang-tools-extra/clangd/ModulesBuilder.cpp
+++ b/clang-tools-extra/clangd/ModulesBuilder.cpp
@@ -40,6 +40,23 @@ llvm::cl::opt<bool> DebugModulesBuilder(
                    "Remember to remove them later after debugging."),
     llvm::cl::init(false));
 
+// Disable reusing prebuilt module files on windows by default.
+// As clangd may lock these module files on windows to prevent
+// these module files to be updated by build system on windows.
+//
+// See https://github.com/clangd/clangd/issues/2497 for details.
+#ifdef _WIN32
+constexpr bool ReusePrebuiltModuleFileDefault = false;
+#else
+constexpr bool ReusePrebuiltModuleFileDefault = true;
+#endif
+
+llvm::cl::opt<bool> ReusePrebuiltModuleFile(
+    "reuse-prebuilt-module-file",
+    llvm::cl::desc("Whether or not to reuse prebuilt module files from 
existing build "
+                   "artifacts."),
+    llvm::cl::init(ReusePrebuiltModuleFileDefault));
+
 llvm::cl::opt<unsigned> VersionedModuleFileGCThresholdSeconds(
     "modules-builder-versioned-gc-threshold-seconds",
     llvm::cl::desc("Delete versioned copy-on-read module files whose last "
@@ -1174,6 +1191,9 @@ void ModulesBuilder::ModulesBuilderImpl::
 void ModulesBuilder::ModulesBuilderImpl::getPrebuiltModuleFile(
     StringRef ModuleName, PathRef ModuleUnitFileName, const ThreadsafeFS &TFS,
     ReusablePrerequisiteModules &BuiltModuleFiles) {
+  if (!ReusePrebuiltModuleFile)
+    return;
+
   auto Cmd = getCDB().getCompileCommand(ModuleUnitFileName);
   if (!Cmd)
     return;

diff  --git a/clang-tools-extra/clangd/test/prebuilt_module_file_reuse.test 
b/clang-tools-extra/clangd/test/prebuilt_module_file_reuse.test
new file mode 100644
index 0000000000000..2d0e4af188aa8
--- /dev/null
+++ b/clang-tools-extra/clangd/test/prebuilt_module_file_reuse.test
@@ -0,0 +1,57 @@
+# Check that clangd can optionally avoid reusing prebuilt module files.
+#
+# Windows uses a 
diff erent default for this flag and has 
diff erent escaping
+# modes, so keep this test non-Windows for now.
+# 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: clang -std=c++20 %t/M.cppm --precompile -o %t/M.pcm
+# RUN: clangd -enable-config=0 -experimental-modules-support -log=verbose \
+# RUN:   -compile-commands-dir=%t -check=%t/Use.cpp 2>&1 \
+# RUN:   | FileCheck %s --check-prefix=REUSE
+# RUN: clangd -enable-config=0 -experimental-modules-support -log=verbose \
+# RUN:   -compile-commands-dir=%t -check=%t/Use.cpp \
+# RUN:   --reuse-prebuilt-module-file=false 2>&1 \
+# RUN:   | FileCheck %s --check-prefix=NOREUSE
+
+// REUSE: Reusing prebuilt module file
+// REUSE: All checks completed, 0 errors
+
+// NOREUSE-NOT: Reusing prebuilt module file
+// NOREUSE: All checks completed, 0 errors
+
+#--- M.cppm
+export module M;
+export int value() { return 42; }
+
+#--- A.cppm
+export module A;
+import M;
+export int useM() { return value(); }
+
+#--- Use.cpp
+import A;
+int use() { return useM(); }
+
+#--- compile_commands.json.tmpl
+[
+  {
+    "directory": "DIR",
+    "command": "CLANG_CC -std=c++20 DIR/M.cppm --precompile -o 
DIR/M-from-cdb.pcm",
+    "file": "DIR/M.cppm"
+  },
+  {
+    "directory": "DIR",
+    "command": "CLANG_CC -std=c++20 -fmodule-file=M=DIR/M.pcm DIR/A.cppm 
--precompile -o DIR/A-from-cdb.pcm",
+    "file": "DIR/A.cppm"
+  },
+  {
+    "directory": "DIR",
+    "command": "CLANG_CC -std=c++20 -fprebuilt-module-path=DIR -c DIR/Use.cpp 
-o DIR/Use.o",
+    "file": "DIR/Use.cpp"
+  }
+]


        
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to