https://github.com/ChuanqiXu9 created 
https://github.com/llvm/llvm-project/pull/174687


Declarations from named modules are used naturally. Thet are declarations in 
other TU. We don't need to record the information for updating them.

>From 12768cb8dcf0b1675cf2c0193dd7ee8256ee2ef6 Mon Sep 17 00:00:00 2001
From: Chuanqi Xu <[email protected]>
Date: Wed, 7 Jan 2026 10:53:31 +0800
Subject: [PATCH] [C++20] [Modules] Don't update MarkAsUsed information for
 decls from named modules

Declarations from named modules are used naturally. Thet are
declarations in other TU. We don't need to record the information for
updating them.
---
 clang/lib/Serialization/ASTWriter.cpp         |  4 ++
 .../Modules/class-instantiate-no-change.cppm  | 50 +++++++++++++++++++
 2 files changed, 54 insertions(+)
 create mode 100644 clang/test/Modules/class-instantiate-no-change.cppm

diff --git a/clang/lib/Serialization/ASTWriter.cpp 
b/clang/lib/Serialization/ASTWriter.cpp
index f9176b7e68f73..a211e98667829 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -7769,6 +7769,10 @@ void ASTWriter::DeclarationMarkedUsed(const Decl *D) {
   if (Chain && Chain->isProcessingUpdateRecords()) return;
   assert(!WritingAST && "Already writing the AST!");
 
+  // If the declaration comes from module unit, it is meaningless to mark it 
as used.
+  if (auto *M = D->getOwningModule(); M && 
M->getTopLevelModule()->isNamedModule())
+    return;
+
   // If there is *any* declaration of the entity that's not from an AST file,
   // we can skip writing the update record. We make sure that isUsed() triggers
   // completion of the redeclaration chain of the entity.
diff --git a/clang/test/Modules/class-instantiate-no-change.cppm 
b/clang/test/Modules/class-instantiate-no-change.cppm
new file mode 100644
index 0000000000000..6ea7d24252ab5
--- /dev/null
+++ b/clang/test/Modules/class-instantiate-no-change.cppm
@@ -0,0 +1,50 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: split-file %s %t
+
+// RUN: %clang_cc1 -std=c++20 %t/impl.cppm -emit-reduced-module-interface -o 
%t/impl.pcm
+// RUN: %clang_cc1 -std=c++20 %t/impl.v2.cppm -emit-reduced-module-interface 
-o %t/impl.v2.pcm
+// RUN: %clang_cc1 -std=c++20 %t/m.cppm -emit-reduced-module-interface -o 
%t/m.pcm \
+// RUN:     -fmodule-file=impl=%t/impl.pcm
+// RUN: %clang_cc1 -std=c++20 %t/m.cppm -emit-reduced-module-interface -o 
%t/m.v2.pcm \
+// RUN:     -fmodule-file=impl=%t/impl.v2.pcm
+
+// Since m only uses impl in the definition, the change in impl shouldn't 
affect m.
+// RUN: diff %t/m.pcm %t/m.v2.pcm &> /dev/null
+
+//--- impl.cppm
+export module impl;
+export struct Impl {
+    Impl() {}
+    Impl(const Impl &) {}
+    ~Impl() {}
+    int get() {
+        return 43;
+    }
+};
+
+//--- impl.v2.cppm
+export module impl;
+export struct Impl {
+    Impl() {}
+    Impl(const Impl &) {}
+    ~Impl() {}
+    int get() {
+        return 43;
+    }
+};
+
+export struct ImplV2 {
+    int get() {
+        return 43;
+    }
+};
+
+//--- m.cppm
+export module m;
+import impl;
+
+export int interface() {
+    Impl impl;
+    return impl.get();
+};

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

Reply via email to