aboutsummaryrefslogtreecommitdiff
path: root/contrib/llvm-project/clang/lib/Sema/SemaModule.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/llvm-project/clang/lib/Sema/SemaModule.cpp')
-rw-r--r--contrib/llvm-project/clang/lib/Sema/SemaModule.cpp43
1 files changed, 33 insertions, 10 deletions
diff --git a/contrib/llvm-project/clang/lib/Sema/SemaModule.cpp b/contrib/llvm-project/clang/lib/Sema/SemaModule.cpp
index af95b1a93cc4..a4b9f3c242c1 100644
--- a/contrib/llvm-project/clang/lib/Sema/SemaModule.cpp
+++ b/contrib/llvm-project/clang/lib/Sema/SemaModule.cpp
@@ -68,15 +68,8 @@ Sema::ActOnGlobalModuleFragmentDecl(SourceLocation ModuleLoc) {
// We start in the global module; all those declarations are implicitly
// module-private (though they do not have module linkage).
- auto &Map = PP.getHeaderSearchInfo().getModuleMap();
- auto *GlobalModule = Map.createGlobalModuleFragmentForModuleUnit(ModuleLoc);
- assert(GlobalModule && "module creation should not fail");
-
- // Enter the scope of the global module.
- ModuleScopes.push_back({});
- ModuleScopes.back().BeginLoc = ModuleLoc;
- ModuleScopes.back().Module = GlobalModule;
- VisibleModules.setVisible(GlobalModule, ModuleLoc);
+ Module *GlobalModule =
+ PushGlobalModuleFragment(ModuleLoc, /*IsImplicit=*/false);
// All declarations created from now on are owned by the global module.
auto *TU = Context.getTranslationUnitDecl();
@@ -390,11 +383,18 @@ DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc,
if (!ModuleScopes.empty())
Context.addModuleInitializer(ModuleScopes.back().Module, Import);
- // Re-export the module if needed.
if (!ModuleScopes.empty() && ModuleScopes.back().ModuleInterface) {
+ // Re-export the module if the imported module is exported.
+ // Note that we don't need to add re-exported module to Imports field
+ // since `Exports` implies the module is imported already.
if (ExportLoc.isValid() || getEnclosingExportDecl(Import))
getCurrentModule()->Exports.emplace_back(Mod, false);
+ else
+ getCurrentModule()->Imports.insert(Mod);
} else if (ExportLoc.isValid()) {
+ // [module.interface]p1:
+ // An export-declaration shall inhabit a namespace scope and appear in the
+ // purview of a module interface unit.
Diag(ExportLoc, diag::err_export_not_in_module_interface);
}
@@ -708,3 +708,26 @@ Decl *Sema::ActOnFinishExportDecl(Scope *S, Decl *D, SourceLocation RBraceLoc) {
return D;
}
+
+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");
+
+ // Enter the scope of the global module.
+ ModuleScopes.push_back({BeginLoc, GlobalModule,
+ /*ModuleInterface=*/false,
+ /*ImplicitGlobalModuleFragment=*/IsImplicit,
+ /*VisibleModuleSet*/{}});
+ VisibleModules.setVisible(GlobalModule, BeginLoc);
+
+ return GlobalModule;
+}
+
+void Sema::PopGlobalModuleFragment() {
+ assert(!ModuleScopes.empty() && getCurrentModule()->isGlobalModule() &&
+ "left the wrong module scope, which is not global module fragment");
+ ModuleScopes.pop_back();
+}