[clang] [C++20] [Modules] Don't update MarkAsUsed information for decls from named modules (PR #174687)
via cfe-commits
cfe-commits at lists.llvm.org
Tue Jan 6 18:55:47 PST 2026
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-modules
Author: Chuanqi Xu (ChuanqiXu9)
<details>
<summary>Changes</summary>
Declarations from named modules are used naturally. Thet are declarations in other TU. We don't need to record the information for updating them.
---
Full diff: https://github.com/llvm/llvm-project/pull/174687.diff
2 Files Affected:
- (modified) clang/lib/Serialization/ASTWriter.cpp (+4)
- (added) clang/test/Modules/class-instantiate-no-change.cppm (+50)
``````````diff
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();
+};
``````````
</details>
https://github.com/llvm/llvm-project/pull/174687
More information about the cfe-commits
mailing list