Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 15 additions & 8 deletions clang/lib/Serialization/ASTReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4087,10 +4087,14 @@ llvm::Error ASTReader::ReadASTBlock(ModuleFile &F,
std::errc::illegal_byte_sequence,
"Invalid PENDING_IMPLICIT_INSTANTIATIONS block");

for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
PendingInstantiations.push_back(
{ReadDeclID(F, Record, I),
ReadSourceLocation(F, Record, I).getRawEncoding()});
// For standard C++20 module, we will only reads the instantiations
// if it is the main file.
if (!F.StandardCXXModule || F.Kind == MK_MainFile) {
for (unsigned I = 0, N = Record.size(); I != N; /* in loop */) {
PendingInstantiations.push_back(
{ReadDeclID(F, Record, I),
ReadSourceLocation(F, Record, I).getRawEncoding()});
}
}
break;

Expand Down Expand Up @@ -6438,10 +6442,13 @@ llvm::Error ASTReader::ReadSubmoduleBlock(ModuleFile &F,
case SUBMODULE_INITIALIZERS: {
if (!ContextObj)
break;
SmallVector<GlobalDeclID, 16> Inits;
for (unsigned I = 0; I < Record.size(); /*in loop*/)
Inits.push_back(ReadDeclID(F, Record, I));
ContextObj->addLazyModuleInitializers(CurrentModule, Inits);
// Standard C++ module has its own way to initialize variables.
if (!F.StandardCXXModule || F.Kind == MK_MainFile) {
SmallVector<GlobalDeclID, 16> Inits;
for (unsigned I = 0; I < Record.size(); /*in loop*/)
Inits.push_back(ReadDeclID(F, Record, I));
ContextObj->addLazyModuleInitializers(CurrentModule, Inits);
}
break;
}

Expand Down
22 changes: 12 additions & 10 deletions clang/lib/Serialization/ASTWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3247,7 +3247,7 @@ void ASTWriter::WriteSubmodules(Module *WritingModule, ASTContext *Context) {

// Emit the reachable initializers.
// The initializer may only be unreachable in reduced BMI.
if (Context) {
if (Context && !GeneratingReducedBMI) {
RecordData Inits;
for (Decl *D : Context->getModuleInitializers(Mod))
if (wasDeclEmitted(D))
Expand Down Expand Up @@ -5827,17 +5827,19 @@ void ASTWriter::WriteSpecialDeclRecords(Sema &SemaRef) {
Stream.EmitRecord(UNUSED_LOCAL_TYPEDEF_NAME_CANDIDATES,
UnusedLocalTypedefNameCandidates);

// Write the record containing pending implicit instantiations.
RecordData PendingInstantiations;
for (const auto &I : SemaRef.PendingInstantiations) {
if (!wasDeclEmitted(I.first))
continue;
if (!GeneratingReducedBMI) {
// Write the record containing pending implicit instantiations.
RecordData PendingInstantiations;
for (const auto &I : SemaRef.PendingInstantiations) {
if (!wasDeclEmitted(I.first))
continue;

AddDeclRef(I.first, PendingInstantiations);
AddSourceLocation(I.second, PendingInstantiations);
AddDeclRef(I.first, PendingInstantiations);
AddSourceLocation(I.second, PendingInstantiations);
}
if (!PendingInstantiations.empty())
Stream.EmitRecord(PENDING_IMPLICIT_INSTANTIATIONS, PendingInstantiations);
}
if (!PendingInstantiations.empty())
Stream.EmitRecord(PENDING_IMPLICIT_INSTANTIATIONS, PendingInstantiations);

// Write the record containing declaration references of Sema.
RecordData SemaDeclRefs;
Expand Down
38 changes: 38 additions & 0 deletions clang/test/Modules/pr166068.cppm
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// RUN: rm -rf %t
// RUN: mkdir -p %t
// RUN: split-file %s %t
//
// RUN: %clang_cc1 -std=c++20 %t/flyweight.cppm -emit-reduced-module-interface -o %t/flyweight.pcm
// RUN: %clang_cc1 -std=c++20 %t/account.cppm -emit-reduced-module-interface -o %t/account.pcm -fprebuilt-module-path=%t
// RUN: %clang_cc1 -std=c++20 %t/core.cppm -emit-reduced-module-interface -o %t/core.pcm -fprebuilt-module-path=%t
// RUN: %clang_cc1 -std=c++20 %t/core.cppm -fprebuilt-module-path=%t -emit-llvm -disable-llvm-passes -o - | FileCheck %t/core.cppm

//--- flyweight.cppm
module;
template <typename> struct flyweight_core {
static bool init() { (void)__builtin_operator_new(2); return true; }
static bool static_initializer;
};
template <typename T> bool flyweight_core<T>::static_initializer = init();
export module flyweight;
export template <class> void flyweight() {
(void)flyweight_core<int>::static_initializer;
}

//--- account.cppm
export module account;
import flyweight;
export void account() {
(void)::flyweight<int>;
}

//--- core.cppm
export module core;
import account;

extern "C" void core() {}

// Fine enough to check it won't crash.
// CHECK-NOT: init
// CHECK-NOT: static_initializer
// CHECK: define {{.*}}@core(
Loading