diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp --- a/clang/lib/Serialization/ASTWriter.cpp +++ b/clang/lib/Serialization/ASTWriter.cpp @@ -2641,16 +2641,33 @@ if (!Mod) return 0; + // Is there already an ID assigned to this module? auto Known = SubmoduleIDs.find(Mod); if (Known != SubmoduleIDs.end()) return Known->second; - auto *Top = Mod->getTopLevelModule(); - if (Top != WritingModule && - (getLangOpts().CompilingPCH || - !Top->fullModuleNameIs(StringRef(getLangOpts().CurrentModule)))) - return 0; + // If Mod is part of a loaded module, its ID is assigned in the ModuleRead + // callback. Otherwise we must assign an ID. + bool IDAssignedOnImport = [&]{ + // If we're simulating modules (e.g. -fmodule-map-file without -fmodules) + // then no reading happens. + if (!getLangOpts().Modules) + return false; + // If this is a submodule of the module we're building, it's not loaded. + auto *Top = Mod->getTopLevelModule(); + if (Top == WritingModule) + return false; + // FIXME: This name-based check is similar to above, why is it needed? + // When building a module PCH, #includes of same-module headers are textual. + if (!getLangOpts().CompilingPCH && + Top->fullModuleNameIs(StringRef(getLangOpts().CurrentModule))) + return false; + // Unrelated module that must be loaded. + return true; + }(); + if (IDAssignedOnImport) + return 0; return SubmoduleIDs[Mod] = NextSubmoduleID++; } diff --git a/clang/test/PCH/preamble-modules.cpp b/clang/test/PCH/preamble-modules.cpp --- a/clang/test/PCH/preamble-modules.cpp +++ b/clang/test/PCH/preamble-modules.cpp @@ -5,6 +5,9 @@ // RUN: %clang_cc1 -emit-pch -o %t.pch %s -fmodules -fmodule-map-file=%S/Inputs/modules/module.modulemap -fmodules-local-submodule-visibility -fmodules-cache-path=%t.mcp // RUN: %clang_cc1 -include-pch %t.pch %s -fmodules -fmodule-map-file=%S/Inputs/modules/module.modulemap -fmodules-local-submodule-visibility -fmodules-cache-path=%t.mcp +// Check we can build a PCH with modular includes but no -fmodules. (https://github.com/llvm/llvm-project/issues/59027) +// RUN: %clang_cc1 -emit-pch -o %t.pch %s -fmodule-map-file=%S/Inputs/modules/module.modulemap + #ifndef MAIN_FILE #define MAIN_FILE // Premable section.