diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h --- a/clang/include/clang/Sema/Sema.h +++ b/clang/include/clang/Sema/Sema.h @@ -2218,6 +2218,8 @@ }; /// The modules we're currently parsing. llvm::SmallVector ModuleScopes; + /// The global module fragment of the current translation unit. + clang::Module *GlobalModuleFragment = nullptr; /// Namespace definitions that we will export when they finish. llvm::SmallPtrSet DeferredExportedNamespaces; diff --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp --- a/clang/lib/Sema/SemaModule.cpp +++ b/clang/lib/Sema/SemaModule.cpp @@ -720,19 +720,24 @@ Module *Sema::PushGlobalModuleFragment(SourceLocation BeginLoc, bool IsImplicit) { - ModuleMap &Map = PP.getHeaderSearchInfo().getModuleMap(); - Module *GlobalModule = - Map.createGlobalModuleFragmentForModuleUnit(BeginLoc, getCurrentModule()); - assert(GlobalModule && "module creation should not fail"); + // We shouldn't create new global module fragment if there is already + // one. + if (!GlobalModuleFragment) { + ModuleMap &Map = PP.getHeaderSearchInfo().getModuleMap(); + GlobalModuleFragment = Map.createGlobalModuleFragmentForModuleUnit( + BeginLoc, getCurrentModule()); + } + + assert(GlobalModuleFragment && "module creation should not fail"); // Enter the scope of the global module. - ModuleScopes.push_back({BeginLoc, GlobalModule, + ModuleScopes.push_back({BeginLoc, GlobalModuleFragment, /*ModuleInterface=*/false, /*ImplicitGlobalModuleFragment=*/IsImplicit, - /*VisibleModuleSet*/{}}); - VisibleModules.setVisible(GlobalModule, BeginLoc); + /*VisibleModuleSet*/ {}}); + VisibleModules.setVisible(GlobalModuleFragment, BeginLoc); - return GlobalModule; + return GlobalModuleFragment; } void Sema::PopGlobalModuleFragment() { diff --git a/clang/test/CXX/module/module.unit/p7/Inputs/h8.h b/clang/test/CXX/module/module.unit/p7/Inputs/h8.h new file mode 100644 --- /dev/null +++ b/clang/test/CXX/module/module.unit/p7/Inputs/h8.h @@ -0,0 +1,4 @@ +#ifndef H8 +#define H8 +void foo(); +#endif diff --git a/clang/test/CXX/module/module.unit/p7/Inputs/m8.cppm b/clang/test/CXX/module/module.unit/p7/Inputs/m8.cppm new file mode 100644 --- /dev/null +++ b/clang/test/CXX/module/module.unit/p7/Inputs/m8.cppm @@ -0,0 +1,7 @@ +module; +#include "h8.h" +export module m8; + +extern "C++" { +void bar(); +} diff --git a/clang/test/CXX/module/module.unit/p7/t8.cpp b/clang/test/CXX/module/module.unit/p7/t8.cpp new file mode 100644 --- /dev/null +++ b/clang/test/CXX/module/module.unit/p7/t8.cpp @@ -0,0 +1,7 @@ +// RUN: rm -fr %t +// RUN: mkdir %t +// RUN: %clang_cc1 -std=c++20 -emit-module-interface %S/Inputs/m8.cppm -I%S/Inputs -o %t/m8.pcm +// RUN: %clang_cc1 -std=c++20 -I%S/Inputs/ -fprebuilt-module-path=%t %s -verify -fsyntax-only +// expected-no-diagnostics +export module t8; +import m8;