[clang] a6e5242 - [Modules] Add merged Files to UsedModuleFiles

Chuanqi Xu via cfe-commits cfe-commits at lists.llvm.org
Wed Jun 25 22:40:14 PDT 2025


Author: Chuanqi Xu
Date: 2025-06-26T13:39:45+08:00
New Revision: a6e524276e2c0596162a9635e0aa87a5ba145409

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

LOG: [Modules] Add merged Files to UsedModuleFiles

This is needed by no casacading chanegs feature. A BMI of a module
interface needs to merge the hash value of all the module files that
the users can touched actually.

Added: 
    clang/test/Modules/no-transitive-decl-change-4.cppm

Modified: 
    clang/include/clang/Serialization/ASTWriter.h
    clang/lib/Serialization/ASTWriter.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Serialization/ASTWriter.h b/clang/include/clang/Serialization/ASTWriter.h
index 162be84bbda19..c86019f01d9f3 100644
--- a/clang/include/clang/Serialization/ASTWriter.h
+++ b/clang/include/clang/Serialization/ASTWriter.h
@@ -376,6 +376,7 @@ class ASTWriter : public ASTDeserializationListener,
   /// Only meaningful for standard C++ named modules. See the comments in
   /// createSignatureForNamedModule() for details.
   llvm::SetVector<Module *> TouchedTopLevelModules;
+  llvm::SetVector<serialization::ModuleFile *> TouchedModuleFiles;
 
   /// An update to a Decl.
   class DeclUpdate {
@@ -913,6 +914,8 @@ class ASTWriter : public ASTDeserializationListener,
 
   void handleVTable(CXXRecordDecl *RD);
 
+  void addTouchedModuleFile(serialization::ModuleFile *);
+
 private:
   // ASTDeserializationListener implementation
   void ReaderInitialized(ASTReader *Reader) override;

diff  --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 04cbd1ca552b7..06cd6c7305114 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -4062,6 +4062,10 @@ void ASTWriter::handleVTable(CXXRecordDecl *RD) {
   PendingEmittingVTables.push_back(RD);
 }
 
+void ASTWriter::addTouchedModuleFile(serialization::ModuleFile *MF) {
+  TouchedModuleFiles.insert(MF);
+}
+
 //===----------------------------------------------------------------------===//
 // DeclContext's Name Lookup Table Serialization
 //===----------------------------------------------------------------------===//
@@ -4106,7 +4110,7 @@ class ASTDeclContextNameLookupTraitBase {
            "have reference to loaded module file but no chain?");
 
     using namespace llvm::support;
-
+    Writer.addTouchedModuleFile(F);
     endian::write<uint32_t>(Out, Writer.getChain()->getModuleFileID(F),
                             llvm::endianness::little);
   }
@@ -4473,6 +4477,7 @@ class LazySpecializationInfoLookupTrait {
            "have reference to loaded module file but no chain?");
 
     using namespace llvm::support;
+    Writer.addTouchedModuleFile(F);
     endian::write<uint32_t>(Out, Writer.getChain()->getModuleFileID(F),
                             llvm::endianness::little);
   }

diff  --git a/clang/test/Modules/no-transitive-decl-change-4.cppm b/clang/test/Modules/no-transitive-decl-change-4.cppm
new file mode 100644
index 0000000000000..944878be8df63
--- /dev/null
+++ b/clang/test/Modules/no-transitive-decl-change-4.cppm
@@ -0,0 +1,81 @@
+// Test that adding a new unused decl within reduced BMI may not produce a transitive change.
+//
+// RUN: rm -rf %t
+// RUN: split-file %s %t
+//
+// RUN: %clang_cc1 -std=c++20 -emit-reduced-module-interface %t/T.cppm -o %t/T.pcm   \
+// RUN:     -fmodule-file=T=%t/T.pcm
+// RUN: %clang_cc1 -std=c++20 -emit-reduced-module-interface %t/T1.cppm -o %t/T1.pcm \
+// RUN:     -fmodule-file=T=%t/T.pcm
+// RUN: %clang_cc1 -std=c++20 -emit-reduced-module-interface %t/T2.cppm -o %t/T2.pcm \
+// RUN:     -fmodule-file=T=%t/T.pcm
+// RUN: %clang_cc1 -std=c++20 -emit-reduced-module-interface %t/T3.cppm -o %t/T3.pcm \
+// RUN:     -fmodule-file=T=%t/T.pcm
+// RUN: %clang_cc1 -std=c++20 -emit-reduced-module-interface %t/T4.cppm -o %t/T4.pcm \
+// RUN:     -fmodule-file=T=%t/T.pcm
+// RUN: %clang_cc1 -std=c++20 -emit-reduced-module-interface %t/A.cppm -o %t/A.pcm \
+// RUN:     -fmodule-file=T=%t/T.pcm
+// RUN: %clang_cc1 -std=c++20 -emit-reduced-module-interface %t/AWrapper.cppm -o %t/AWrapper.pcm \
+// RUN:      -fprebuilt-module-path=%t
+// RUN: %clang_cc1 -std=c++20 -emit-reduced-module-interface %t/B.cppm -o %t/B.pcm \
+// RUN:     -fprebuilt-module-path=%t
+//
+// RUN: %clang_cc1 -std=c++20 -emit-reduced-module-interface %t/A.v1.cppm -o %t/A.v1.pcm \
+// RUN:     -fmodule-file=T=%t/T.pcm
+// RUN: %clang_cc1 -std=c++20 -emit-reduced-module-interface %t/AWrapper.cppm -o %t/AWrapper.v1.pcm \
+// RUN:      -fprebuilt-module-path=%t -fmodule-file=A=%t/A.v1.pcm
+// RUN: %clang_cc1 -std=c++20 -emit-reduced-module-interface %t/B.cppm -o %t/B.v1.pcm \
+// RUN:     -fprebuilt-module-path=%t -fmodule-file=AWrapper=%t/AWrapper.v1.pcm -fmodule-file=A=%t/A.v1.pcm
+//
+// RUN: not 
diff  %t/B.pcm %t/B.v1.pcm &> /dev/null
+
+//--- T.cppm
+export module T;
+export template <class T>
+struct Templ {};
+
+//--- T1.cppm
+export module T1;
+import T;
+export using Tunsigned = Templ<unsigned>;
+
+//--- T2.cppm
+export module T2;
+import T;
+export using Tfloat = Templ<float>;
+
+//--- T3.cppm
+export module T3;
+import T;
+export using Tlong = Templ<long long>;
+
+//--- T4.cppm
+export module T4;
+import T;
+export using Tshort = Templ<short>;
+
+//--- A.cppm
+export module A;
+import T;
+export using Tint = Templ<int>;
+
+//--- A.v1.cppm
+export module A;
+import T;
+export using Tint = Templ<int>;
+void __unused__() {}
+
+//--- AWrapper.cppm
+export module AWrapper;
+import A;
+
+//--- B.cppm
+export module B;
+import AWrapper;
+import T;
+import T1;
+import T2;
+import T3;
+import T4;
+
+export using Tdouble = Templ<double>;


        


More information about the cfe-commits mailing list