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
