diff options
Diffstat (limited to 'clang/lib/Sema/SemaModule.cpp')
-rw-r--r-- | clang/lib/Sema/SemaModule.cpp | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/clang/lib/Sema/SemaModule.cpp b/clang/lib/Sema/SemaModule.cpp index 9de95e2..a115834 100644 --- a/clang/lib/Sema/SemaModule.cpp +++ b/clang/lib/Sema/SemaModule.cpp @@ -97,6 +97,38 @@ Sema::ActOnGlobalModuleFragmentDecl(SourceLocation ModuleLoc) { return nullptr; } +void Sema::HandleStartOfHeaderUnit() { + assert(getLangOpts().CPlusPlusModules && + "Header units are only valid for C++20 modules"); + SourceLocation StartOfTU = + SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()); + + StringRef HUName = getLangOpts().CurrentModule; + if (HUName.empty()) { + HUName = SourceMgr.getFileEntryForID(SourceMgr.getMainFileID())->getName(); + const_cast<LangOptions &>(getLangOpts()).CurrentModule = HUName.str(); + } + + auto &Map = PP.getHeaderSearchInfo().getModuleMap(); + // TODO: Make the C++20 header lookup independent. + Module::Header H{getLangOpts().CurrentModule, getLangOpts().CurrentModule, + SourceMgr.getFileEntryForID(SourceMgr.getMainFileID())}; + Module *Mod = Map.createHeaderUnit(StartOfTU, HUName, H); + assert(Mod && "module creation should not fail"); + ModuleScopes.push_back({}); // No GMF + ModuleScopes.back().BeginLoc = StartOfTU; + ModuleScopes.back().Module = Mod; + ModuleScopes.back().ModuleInterface = true; + ModuleScopes.back().IsPartition = false; + VisibleModules.setVisible(Mod, StartOfTU); + + // From now on, we have an owning module for all declarations we see. + // All of these are implicitly exported. + auto *TU = Context.getTranslationUnitDecl(); + TU->setModuleOwnershipKind(Decl::ModuleOwnershipKind::Visible); + TU->setLocalOwningModule(Mod); +} + Sema::DeclGroupPtrTy Sema::ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc, ModuleDeclKind MDK, ModuleIdPath Path, @@ -149,6 +181,7 @@ Sema::ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc, return nullptr; case LangOptions::CMK_HeaderModule: + case LangOptions::CMK_HeaderUnit: Diag(ModuleLoc, diag::err_module_decl_in_header_module); return nullptr; } @@ -310,6 +343,7 @@ Sema::ActOnPrivateModuleFragmentDecl(SourceLocation ModuleLoc, case Module::GlobalModuleFragment: case Module::ModulePartitionImplementation: case Module::ModulePartitionInterface: + case Module::ModuleHeaderUnit: Diag(PrivateLoc, diag::err_private_module_fragment_not_module); return nullptr; @@ -480,7 +514,13 @@ DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc, Mod->Kind == Module::ModuleKind::ModulePartitionImplementation) { Diag(ExportLoc, diag::err_export_partition_impl) << SourceRange(ExportLoc, Path.back().second); - } else if (!ModuleScopes.empty() && ModuleScopes.back().ModuleInterface) { + } else if (!ModuleScopes.empty() && + (ModuleScopes.back().ModuleInterface || + (getLangOpts().CPlusPlusModules && + ModuleScopes.back().Module->isGlobalModule()))) { + assert((!ModuleScopes.back().Module->isGlobalModule() || + Mod->Kind == Module::ModuleKind::ModuleHeaderUnit) && + "should only be importing a header unit into the GMF"); // 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. |