10b57cec5SDimitry Andric //===--- SemaModule.cpp - Semantic Analysis for Modules -------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file implements semantic analysis for modules (C++ modules syntax, 100b57cec5SDimitry Andric // Objective-C modules syntax, and Clang header modules). 110b57cec5SDimitry Andric // 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric 140b57cec5SDimitry Andric #include "clang/AST/ASTConsumer.h" 15*0fca6ea1SDimitry Andric #include "clang/AST/ASTMutationListener.h" 160b57cec5SDimitry Andric #include "clang/Lex/HeaderSearch.h" 170b57cec5SDimitry Andric #include "clang/Lex/Preprocessor.h" 180b57cec5SDimitry Andric #include "clang/Sema/SemaInternal.h" 1906c3fb27SDimitry Andric #include "llvm/ADT/StringExtras.h" 20bdd1243dSDimitry Andric #include <optional> 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric using namespace clang; 230b57cec5SDimitry Andric using namespace sema; 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric static void checkModuleImportContext(Sema &S, Module *M, 260b57cec5SDimitry Andric SourceLocation ImportLoc, DeclContext *DC, 270b57cec5SDimitry Andric bool FromInclude = false) { 280b57cec5SDimitry Andric SourceLocation ExternCLoc; 290b57cec5SDimitry Andric 300b57cec5SDimitry Andric if (auto *LSD = dyn_cast<LinkageSpecDecl>(DC)) { 310b57cec5SDimitry Andric switch (LSD->getLanguage()) { 325f757f3fSDimitry Andric case LinkageSpecLanguageIDs::C: 330b57cec5SDimitry Andric if (ExternCLoc.isInvalid()) 340b57cec5SDimitry Andric ExternCLoc = LSD->getBeginLoc(); 350b57cec5SDimitry Andric break; 365f757f3fSDimitry Andric case LinkageSpecLanguageIDs::CXX: 370b57cec5SDimitry Andric break; 380b57cec5SDimitry Andric } 390b57cec5SDimitry Andric DC = LSD->getParent(); 400b57cec5SDimitry Andric } 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric while (isa<LinkageSpecDecl>(DC) || isa<ExportDecl>(DC)) 430b57cec5SDimitry Andric DC = DC->getParent(); 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric if (!isa<TranslationUnitDecl>(DC)) { 460b57cec5SDimitry Andric S.Diag(ImportLoc, (FromInclude && S.isModuleVisible(M)) 470b57cec5SDimitry Andric ? diag::ext_module_import_not_at_top_level_noop 480b57cec5SDimitry Andric : diag::err_module_import_not_at_top_level_fatal) 490b57cec5SDimitry Andric << M->getFullModuleName() << DC; 500b57cec5SDimitry Andric S.Diag(cast<Decl>(DC)->getBeginLoc(), 510b57cec5SDimitry Andric diag::note_module_import_not_at_top_level) 520b57cec5SDimitry Andric << DC; 530b57cec5SDimitry Andric } else if (!M->IsExternC && ExternCLoc.isValid()) { 540b57cec5SDimitry Andric S.Diag(ImportLoc, diag::ext_module_import_in_extern_c) 550b57cec5SDimitry Andric << M->getFullModuleName(); 560b57cec5SDimitry Andric S.Diag(ExternCLoc, diag::note_extern_c_begins_here); 570b57cec5SDimitry Andric } 580b57cec5SDimitry Andric } 590b57cec5SDimitry Andric 6081ad6265SDimitry Andric // We represent the primary and partition names as 'Paths' which are sections 6181ad6265SDimitry Andric // of the hierarchical access path for a clang module. However for C++20 6281ad6265SDimitry Andric // the periods in a name are just another character, and we will need to 6381ad6265SDimitry Andric // flatten them into a string. 6481ad6265SDimitry Andric static std::string stringFromPath(ModuleIdPath Path) { 6581ad6265SDimitry Andric std::string Name; 6681ad6265SDimitry Andric if (Path.empty()) 6781ad6265SDimitry Andric return Name; 6881ad6265SDimitry Andric 6981ad6265SDimitry Andric for (auto &Piece : Path) { 7081ad6265SDimitry Andric if (!Name.empty()) 7181ad6265SDimitry Andric Name += "."; 7281ad6265SDimitry Andric Name += Piece.first->getName(); 7381ad6265SDimitry Andric } 7481ad6265SDimitry Andric return Name; 7581ad6265SDimitry Andric } 7681ad6265SDimitry Andric 77*0fca6ea1SDimitry Andric /// Helper function for makeTransitiveImportsVisible to decide whether 78*0fca6ea1SDimitry Andric /// the \param Imported module unit is in the same module with the \param 79*0fca6ea1SDimitry Andric /// CurrentModule. 80*0fca6ea1SDimitry Andric /// \param FoundPrimaryModuleInterface is a helper parameter to record the 81*0fca6ea1SDimitry Andric /// primary module interface unit corresponding to the module \param 82*0fca6ea1SDimitry Andric /// CurrentModule. Since currently it is expensive to decide whether two module 83*0fca6ea1SDimitry Andric /// units come from the same module by comparing the module name. 84*0fca6ea1SDimitry Andric static bool 85*0fca6ea1SDimitry Andric isImportingModuleUnitFromSameModule(ASTContext &Ctx, Module *Imported, 86*0fca6ea1SDimitry Andric Module *CurrentModule, 87*0fca6ea1SDimitry Andric Module *&FoundPrimaryModuleInterface) { 88*0fca6ea1SDimitry Andric if (!Imported->isNamedModule()) 89*0fca6ea1SDimitry Andric return false; 90*0fca6ea1SDimitry Andric 91*0fca6ea1SDimitry Andric // The a partition unit we're importing must be in the same module of the 92*0fca6ea1SDimitry Andric // current module. 93*0fca6ea1SDimitry Andric if (Imported->isModulePartition()) 94*0fca6ea1SDimitry Andric return true; 95*0fca6ea1SDimitry Andric 96*0fca6ea1SDimitry Andric // If we found the primary module interface during the search process, we can 97*0fca6ea1SDimitry Andric // return quickly to avoid expensive string comparison. 98*0fca6ea1SDimitry Andric if (FoundPrimaryModuleInterface) 99*0fca6ea1SDimitry Andric return Imported == FoundPrimaryModuleInterface; 100*0fca6ea1SDimitry Andric 101*0fca6ea1SDimitry Andric if (!CurrentModule) 102*0fca6ea1SDimitry Andric return false; 103*0fca6ea1SDimitry Andric 104*0fca6ea1SDimitry Andric // Then the imported module must be a primary module interface unit. It 105*0fca6ea1SDimitry Andric // is only allowed to import the primary module interface unit from the same 106*0fca6ea1SDimitry Andric // module in the implementation unit and the implementation partition unit. 107*0fca6ea1SDimitry Andric 108*0fca6ea1SDimitry Andric // Since we'll handle implementation unit above. We can only care 109*0fca6ea1SDimitry Andric // about the implementation partition unit here. 110*0fca6ea1SDimitry Andric if (!CurrentModule->isModulePartitionImplementation()) 111*0fca6ea1SDimitry Andric return false; 112*0fca6ea1SDimitry Andric 113*0fca6ea1SDimitry Andric if (Ctx.isInSameModule(Imported, CurrentModule)) { 114*0fca6ea1SDimitry Andric assert(!FoundPrimaryModuleInterface || 115*0fca6ea1SDimitry Andric FoundPrimaryModuleInterface == Imported); 116*0fca6ea1SDimitry Andric FoundPrimaryModuleInterface = Imported; 117*0fca6ea1SDimitry Andric return true; 118*0fca6ea1SDimitry Andric } 119*0fca6ea1SDimitry Andric 120*0fca6ea1SDimitry Andric return false; 121*0fca6ea1SDimitry Andric } 122*0fca6ea1SDimitry Andric 123*0fca6ea1SDimitry Andric /// [module.import]p7: 124*0fca6ea1SDimitry Andric /// Additionally, when a module-import-declaration in a module unit of some 125*0fca6ea1SDimitry Andric /// module M imports another module unit U of M, it also imports all 126*0fca6ea1SDimitry Andric /// translation units imported by non-exported module-import-declarations in 127*0fca6ea1SDimitry Andric /// the module unit purview of U. These rules can in turn lead to the 128*0fca6ea1SDimitry Andric /// importation of yet more translation units. 129*0fca6ea1SDimitry Andric static void 130*0fca6ea1SDimitry Andric makeTransitiveImportsVisible(ASTContext &Ctx, VisibleModuleSet &VisibleModules, 131*0fca6ea1SDimitry Andric Module *Imported, Module *CurrentModule, 132*0fca6ea1SDimitry Andric SourceLocation ImportLoc, 133*0fca6ea1SDimitry Andric bool IsImportingPrimaryModuleInterface = false) { 134*0fca6ea1SDimitry Andric assert(Imported->isNamedModule() && 135*0fca6ea1SDimitry Andric "'makeTransitiveImportsVisible()' is intended for standard C++ named " 136*0fca6ea1SDimitry Andric "modules only."); 137*0fca6ea1SDimitry Andric 138*0fca6ea1SDimitry Andric llvm::SmallVector<Module *, 4> Worklist; 139*0fca6ea1SDimitry Andric Worklist.push_back(Imported); 140*0fca6ea1SDimitry Andric 141*0fca6ea1SDimitry Andric Module *FoundPrimaryModuleInterface = 142*0fca6ea1SDimitry Andric IsImportingPrimaryModuleInterface ? Imported : nullptr; 143*0fca6ea1SDimitry Andric 144*0fca6ea1SDimitry Andric while (!Worklist.empty()) { 145*0fca6ea1SDimitry Andric Module *Importing = Worklist.pop_back_val(); 146*0fca6ea1SDimitry Andric 147*0fca6ea1SDimitry Andric if (VisibleModules.isVisible(Importing)) 148*0fca6ea1SDimitry Andric continue; 149*0fca6ea1SDimitry Andric 150*0fca6ea1SDimitry Andric // FIXME: The ImportLoc here is not meaningful. It may be problematic if we 151*0fca6ea1SDimitry Andric // use the sourcelocation loaded from the visible modules. 152*0fca6ea1SDimitry Andric VisibleModules.setVisible(Importing, ImportLoc); 153*0fca6ea1SDimitry Andric 154*0fca6ea1SDimitry Andric if (isImportingModuleUnitFromSameModule(Ctx, Importing, CurrentModule, 155*0fca6ea1SDimitry Andric FoundPrimaryModuleInterface)) 156*0fca6ea1SDimitry Andric for (Module *TransImported : Importing->Imports) 157*0fca6ea1SDimitry Andric if (!VisibleModules.isVisible(TransImported)) 158*0fca6ea1SDimitry Andric Worklist.push_back(TransImported); 159*0fca6ea1SDimitry Andric } 160*0fca6ea1SDimitry Andric } 161*0fca6ea1SDimitry Andric 1620b57cec5SDimitry Andric Sema::DeclGroupPtrTy 1630b57cec5SDimitry Andric Sema::ActOnGlobalModuleFragmentDecl(SourceLocation ModuleLoc) { 16406c3fb27SDimitry Andric // We start in the global module; 1650eae32dcSDimitry Andric Module *GlobalModule = 16606c3fb27SDimitry Andric PushGlobalModuleFragment(ModuleLoc); 1670b57cec5SDimitry Andric 1680b57cec5SDimitry Andric // All declarations created from now on are owned by the global module. 1690b57cec5SDimitry Andric auto *TU = Context.getTranslationUnitDecl(); 17081ad6265SDimitry Andric // [module.global.frag]p2 17181ad6265SDimitry Andric // A global-module-fragment specifies the contents of the global module 17281ad6265SDimitry Andric // fragment for a module unit. The global module fragment can be used to 17381ad6265SDimitry Andric // provide declarations that are attached to the global module and usable 17481ad6265SDimitry Andric // within the module unit. 17581ad6265SDimitry Andric // 17681ad6265SDimitry Andric // So the declations in the global module shouldn't be visible by default. 17781ad6265SDimitry Andric TU->setModuleOwnershipKind(Decl::ModuleOwnershipKind::ReachableWhenImported); 1780b57cec5SDimitry Andric TU->setLocalOwningModule(GlobalModule); 1790b57cec5SDimitry Andric 1800b57cec5SDimitry Andric // FIXME: Consider creating an explicit representation of this declaration. 1810b57cec5SDimitry Andric return nullptr; 1820b57cec5SDimitry Andric } 1830b57cec5SDimitry Andric 18481ad6265SDimitry Andric void Sema::HandleStartOfHeaderUnit() { 18581ad6265SDimitry Andric assert(getLangOpts().CPlusPlusModules && 18681ad6265SDimitry Andric "Header units are only valid for C++20 modules"); 18781ad6265SDimitry Andric SourceLocation StartOfTU = 18881ad6265SDimitry Andric SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()); 18981ad6265SDimitry Andric 19081ad6265SDimitry Andric StringRef HUName = getLangOpts().CurrentModule; 19181ad6265SDimitry Andric if (HUName.empty()) { 1925f757f3fSDimitry Andric HUName = 1935f757f3fSDimitry Andric SourceMgr.getFileEntryRefForID(SourceMgr.getMainFileID())->getName(); 19481ad6265SDimitry Andric const_cast<LangOptions &>(getLangOpts()).CurrentModule = HUName.str(); 19581ad6265SDimitry Andric } 19681ad6265SDimitry Andric 19781ad6265SDimitry Andric // TODO: Make the C++20 header lookup independent. 19881ad6265SDimitry Andric // When the input is pre-processed source, we need a file ref to the original 19981ad6265SDimitry Andric // file for the header map. 200bdd1243dSDimitry Andric auto F = SourceMgr.getFileManager().getOptionalFileRef(HUName); 20181ad6265SDimitry Andric // For the sake of error recovery (if someone has moved the original header 20281ad6265SDimitry Andric // after creating the pre-processed output) fall back to obtaining the file 20381ad6265SDimitry Andric // ref for the input file, which must be present. 20481ad6265SDimitry Andric if (!F) 205bdd1243dSDimitry Andric F = SourceMgr.getFileEntryRefForID(SourceMgr.getMainFileID()); 20681ad6265SDimitry Andric assert(F && "failed to find the header unit source?"); 20781ad6265SDimitry Andric Module::Header H{HUName.str(), HUName.str(), *F}; 20881ad6265SDimitry Andric auto &Map = PP.getHeaderSearchInfo().getModuleMap(); 20981ad6265SDimitry Andric Module *Mod = Map.createHeaderUnit(StartOfTU, HUName, H); 21081ad6265SDimitry Andric assert(Mod && "module creation should not fail"); 21181ad6265SDimitry Andric ModuleScopes.push_back({}); // No GMF 21281ad6265SDimitry Andric ModuleScopes.back().BeginLoc = StartOfTU; 21381ad6265SDimitry Andric ModuleScopes.back().Module = Mod; 21481ad6265SDimitry Andric VisibleModules.setVisible(Mod, StartOfTU); 21581ad6265SDimitry Andric 21681ad6265SDimitry Andric // From now on, we have an owning module for all declarations we see. 21781ad6265SDimitry Andric // All of these are implicitly exported. 21881ad6265SDimitry Andric auto *TU = Context.getTranslationUnitDecl(); 21981ad6265SDimitry Andric TU->setModuleOwnershipKind(Decl::ModuleOwnershipKind::Visible); 22081ad6265SDimitry Andric TU->setLocalOwningModule(Mod); 22181ad6265SDimitry Andric } 22281ad6265SDimitry Andric 223bdd1243dSDimitry Andric /// Tests whether the given identifier is reserved as a module name and 224bdd1243dSDimitry Andric /// diagnoses if it is. Returns true if a diagnostic is emitted and false 225bdd1243dSDimitry Andric /// otherwise. 226bdd1243dSDimitry Andric static bool DiagReservedModuleName(Sema &S, const IdentifierInfo *II, 227bdd1243dSDimitry Andric SourceLocation Loc) { 228bdd1243dSDimitry Andric enum { 229bdd1243dSDimitry Andric Valid = -1, 230bdd1243dSDimitry Andric Invalid = 0, 231bdd1243dSDimitry Andric Reserved = 1, 232bdd1243dSDimitry Andric } Reason = Valid; 233bdd1243dSDimitry Andric 234bdd1243dSDimitry Andric if (II->isStr("module") || II->isStr("import")) 235bdd1243dSDimitry Andric Reason = Invalid; 236bdd1243dSDimitry Andric else if (II->isReserved(S.getLangOpts()) != 237bdd1243dSDimitry Andric ReservedIdentifierStatus::NotReserved) 238bdd1243dSDimitry Andric Reason = Reserved; 239bdd1243dSDimitry Andric 240bdd1243dSDimitry Andric // If the identifier is reserved (not invalid) but is in a system header, 241bdd1243dSDimitry Andric // we do not diagnose (because we expect system headers to use reserved 242bdd1243dSDimitry Andric // identifiers). 243bdd1243dSDimitry Andric if (Reason == Reserved && S.getSourceManager().isInSystemHeader(Loc)) 244bdd1243dSDimitry Andric Reason = Valid; 245bdd1243dSDimitry Andric 24606c3fb27SDimitry Andric switch (Reason) { 24706c3fb27SDimitry Andric case Valid: 248bdd1243dSDimitry Andric return false; 24906c3fb27SDimitry Andric case Invalid: 25006c3fb27SDimitry Andric return S.Diag(Loc, diag::err_invalid_module_name) << II; 25106c3fb27SDimitry Andric case Reserved: 25206c3fb27SDimitry Andric S.Diag(Loc, diag::warn_reserved_module_name) << II; 25306c3fb27SDimitry Andric return false; 25406c3fb27SDimitry Andric } 25506c3fb27SDimitry Andric llvm_unreachable("fell off a fully covered switch"); 256bdd1243dSDimitry Andric } 257bdd1243dSDimitry Andric 2580b57cec5SDimitry Andric Sema::DeclGroupPtrTy 2590b57cec5SDimitry Andric Sema::ActOnModuleDecl(SourceLocation StartLoc, SourceLocation ModuleLoc, 26081ad6265SDimitry Andric ModuleDeclKind MDK, ModuleIdPath Path, 26181ad6265SDimitry Andric ModuleIdPath Partition, ModuleImportState &ImportState) { 26206c3fb27SDimitry Andric assert(getLangOpts().CPlusPlusModules && 26306c3fb27SDimitry Andric "should only have module decl in standard C++ modules"); 2640b57cec5SDimitry Andric 26581ad6265SDimitry Andric bool IsFirstDecl = ImportState == ModuleImportState::FirstDecl; 26681ad6265SDimitry Andric bool SeenGMF = ImportState == ModuleImportState::GlobalFragment; 26781ad6265SDimitry Andric // If any of the steps here fail, we count that as invalidating C++20 26881ad6265SDimitry Andric // module state; 26981ad6265SDimitry Andric ImportState = ModuleImportState::NotACXX20Module; 27081ad6265SDimitry Andric 27181ad6265SDimitry Andric bool IsPartition = !Partition.empty(); 27281ad6265SDimitry Andric if (IsPartition) 27381ad6265SDimitry Andric switch (MDK) { 27481ad6265SDimitry Andric case ModuleDeclKind::Implementation: 27581ad6265SDimitry Andric MDK = ModuleDeclKind::PartitionImplementation; 27681ad6265SDimitry Andric break; 27781ad6265SDimitry Andric case ModuleDeclKind::Interface: 27881ad6265SDimitry Andric MDK = ModuleDeclKind::PartitionInterface; 27981ad6265SDimitry Andric break; 28081ad6265SDimitry Andric default: 28181ad6265SDimitry Andric llvm_unreachable("how did we get a partition type set?"); 28281ad6265SDimitry Andric } 28381ad6265SDimitry Andric 28481ad6265SDimitry Andric // A (non-partition) module implementation unit requires that we are not 28581ad6265SDimitry Andric // compiling a module of any kind. A partition implementation emits an 28681ad6265SDimitry Andric // interface (and the AST for the implementation), which will subsequently 28781ad6265SDimitry Andric // be consumed to emit a binary. 28881ad6265SDimitry Andric // A module interface unit requires that we are not compiling a module map. 2890b57cec5SDimitry Andric switch (getLangOpts().getCompilingModule()) { 2900b57cec5SDimitry Andric case LangOptions::CMK_None: 2910b57cec5SDimitry Andric // It's OK to compile a module interface as a normal translation unit. 2920b57cec5SDimitry Andric break; 2930b57cec5SDimitry Andric 2940b57cec5SDimitry Andric case LangOptions::CMK_ModuleInterface: 2950b57cec5SDimitry Andric if (MDK != ModuleDeclKind::Implementation) 2960b57cec5SDimitry Andric break; 2970b57cec5SDimitry Andric 2980b57cec5SDimitry Andric // We were asked to compile a module interface unit but this is a module 29981ad6265SDimitry Andric // implementation unit. 3000b57cec5SDimitry Andric Diag(ModuleLoc, diag::err_module_interface_implementation_mismatch) 3010b57cec5SDimitry Andric << FixItHint::CreateInsertion(ModuleLoc, "export "); 3020b57cec5SDimitry Andric MDK = ModuleDeclKind::Interface; 3030b57cec5SDimitry Andric break; 3040b57cec5SDimitry Andric 3050b57cec5SDimitry Andric case LangOptions::CMK_ModuleMap: 3060b57cec5SDimitry Andric Diag(ModuleLoc, diag::err_module_decl_in_module_map_module); 3070b57cec5SDimitry Andric return nullptr; 3080b57cec5SDimitry Andric 30981ad6265SDimitry Andric case LangOptions::CMK_HeaderUnit: 310bdd1243dSDimitry Andric Diag(ModuleLoc, diag::err_module_decl_in_header_unit); 3110b57cec5SDimitry Andric return nullptr; 3120b57cec5SDimitry Andric } 3130b57cec5SDimitry Andric 3140b57cec5SDimitry Andric assert(ModuleScopes.size() <= 1 && "expected to be at global module scope"); 3150b57cec5SDimitry Andric 3160b57cec5SDimitry Andric // FIXME: Most of this work should be done by the preprocessor rather than 3170b57cec5SDimitry Andric // here, in order to support macro import. 3180b57cec5SDimitry Andric 3190b57cec5SDimitry Andric // Only one module-declaration is permitted per source file. 320bdd1243dSDimitry Andric if (isCurrentModulePurview()) { 3210b57cec5SDimitry Andric Diag(ModuleLoc, diag::err_module_redeclaration); 3220b57cec5SDimitry Andric Diag(VisibleModules.getImportLoc(ModuleScopes.back().Module), 3230b57cec5SDimitry Andric diag::note_prev_module_declaration); 3240b57cec5SDimitry Andric return nullptr; 3250b57cec5SDimitry Andric } 3260b57cec5SDimitry Andric 32706c3fb27SDimitry Andric assert((!getLangOpts().CPlusPlusModules || 32806c3fb27SDimitry Andric SeenGMF == (bool)this->TheGlobalModuleFragment) && 32981ad6265SDimitry Andric "mismatched global module state"); 33081ad6265SDimitry Andric 3310b57cec5SDimitry Andric // In C++20, the module-declaration must be the first declaration if there 3320b57cec5SDimitry Andric // is no global module fragment. 33381ad6265SDimitry Andric if (getLangOpts().CPlusPlusModules && !IsFirstDecl && !SeenGMF) { 3340b57cec5SDimitry Andric Diag(ModuleLoc, diag::err_module_decl_not_at_start); 3350b57cec5SDimitry Andric SourceLocation BeginLoc = 3360b57cec5SDimitry Andric ModuleScopes.empty() 3370b57cec5SDimitry Andric ? SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID()) 3380b57cec5SDimitry Andric : ModuleScopes.back().BeginLoc; 3390b57cec5SDimitry Andric if (BeginLoc.isValid()) { 3400b57cec5SDimitry Andric Diag(BeginLoc, diag::note_global_module_introducer_missing) 3410b57cec5SDimitry Andric << FixItHint::CreateInsertion(BeginLoc, "module;\n"); 3420b57cec5SDimitry Andric } 3430b57cec5SDimitry Andric } 3440b57cec5SDimitry Andric 34506c3fb27SDimitry Andric // C++23 [module.unit]p1: ... The identifiers module and import shall not 346bdd1243dSDimitry Andric // appear as identifiers in a module-name or module-partition. All 347bdd1243dSDimitry Andric // module-names either beginning with an identifier consisting of std 348bdd1243dSDimitry Andric // followed by zero or more digits or containing a reserved identifier 349bdd1243dSDimitry Andric // ([lex.name]) are reserved and shall not be specified in a 350bdd1243dSDimitry Andric // module-declaration; no diagnostic is required. 351bdd1243dSDimitry Andric 352bdd1243dSDimitry Andric // Test the first part of the path to see if it's std[0-9]+ but allow the 353bdd1243dSDimitry Andric // name in a system header. 354bdd1243dSDimitry Andric StringRef FirstComponentName = Path[0].first->getName(); 355bdd1243dSDimitry Andric if (!getSourceManager().isInSystemHeader(Path[0].second) && 356bdd1243dSDimitry Andric (FirstComponentName == "std" || 3575f757f3fSDimitry Andric (FirstComponentName.starts_with("std") && 35806c3fb27SDimitry Andric llvm::all_of(FirstComponentName.drop_front(3), &llvm::isDigit)))) 35906c3fb27SDimitry Andric Diag(Path[0].second, diag::warn_reserved_module_name) << Path[0].first; 360bdd1243dSDimitry Andric 361bdd1243dSDimitry Andric // Then test all of the components in the path to see if any of them are 362bdd1243dSDimitry Andric // using another kind of reserved or invalid identifier. 363bdd1243dSDimitry Andric for (auto Part : Path) { 364bdd1243dSDimitry Andric if (DiagReservedModuleName(*this, Part.first, Part.second)) 365bdd1243dSDimitry Andric return nullptr; 366bdd1243dSDimitry Andric } 367bdd1243dSDimitry Andric 3680b57cec5SDimitry Andric // Flatten the dots in a module name. Unlike Clang's hierarchical module map 3690b57cec5SDimitry Andric // modules, the dots here are just another character that can appear in a 3700b57cec5SDimitry Andric // module name. 37181ad6265SDimitry Andric std::string ModuleName = stringFromPath(Path); 37281ad6265SDimitry Andric if (IsPartition) { 37381ad6265SDimitry Andric ModuleName += ":"; 37481ad6265SDimitry Andric ModuleName += stringFromPath(Partition); 3750b57cec5SDimitry Andric } 3760b57cec5SDimitry Andric // If a module name was explicitly specified on the command line, it must be 3770b57cec5SDimitry Andric // correct. 3780b57cec5SDimitry Andric if (!getLangOpts().CurrentModule.empty() && 3790b57cec5SDimitry Andric getLangOpts().CurrentModule != ModuleName) { 3800b57cec5SDimitry Andric Diag(Path.front().second, diag::err_current_module_name_mismatch) 38181ad6265SDimitry Andric << SourceRange(Path.front().second, IsPartition 38281ad6265SDimitry Andric ? Partition.back().second 38381ad6265SDimitry Andric : Path.back().second) 3840b57cec5SDimitry Andric << getLangOpts().CurrentModule; 3850b57cec5SDimitry Andric return nullptr; 3860b57cec5SDimitry Andric } 3870b57cec5SDimitry Andric const_cast<LangOptions&>(getLangOpts()).CurrentModule = ModuleName; 3880b57cec5SDimitry Andric 3890b57cec5SDimitry Andric auto &Map = PP.getHeaderSearchInfo().getModuleMap(); 39006c3fb27SDimitry Andric Module *Mod; // The module we are creating. 39106c3fb27SDimitry Andric Module *Interface = nullptr; // The interface for an implementation. 3920b57cec5SDimitry Andric switch (MDK) { 39381ad6265SDimitry Andric case ModuleDeclKind::Interface: 39481ad6265SDimitry Andric case ModuleDeclKind::PartitionInterface: { 3950b57cec5SDimitry Andric // We can't have parsed or imported a definition of this module or parsed a 3960b57cec5SDimitry Andric // module map defining it already. 3970b57cec5SDimitry Andric if (auto *M = Map.findModule(ModuleName)) { 3980b57cec5SDimitry Andric Diag(Path[0].second, diag::err_module_redefinition) << ModuleName; 3990b57cec5SDimitry Andric if (M->DefinitionLoc.isValid()) 4000b57cec5SDimitry Andric Diag(M->DefinitionLoc, diag::note_prev_module_definition); 401bdd1243dSDimitry Andric else if (OptionalFileEntryRef FE = M->getASTFile()) 4020b57cec5SDimitry Andric Diag(M->DefinitionLoc, diag::note_prev_module_definition_from_ast_file) 4030b57cec5SDimitry Andric << FE->getName(); 4040b57cec5SDimitry Andric Mod = M; 4050b57cec5SDimitry Andric break; 4060b57cec5SDimitry Andric } 4070b57cec5SDimitry Andric 4080b57cec5SDimitry Andric // Create a Module for the module that we're defining. 409bdd1243dSDimitry Andric Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName); 41081ad6265SDimitry Andric if (MDK == ModuleDeclKind::PartitionInterface) 41181ad6265SDimitry Andric Mod->Kind = Module::ModulePartitionInterface; 4120b57cec5SDimitry Andric assert(Mod && "module creation should not fail"); 4130b57cec5SDimitry Andric break; 4140b57cec5SDimitry Andric } 4150b57cec5SDimitry Andric 41681ad6265SDimitry Andric case ModuleDeclKind::Implementation: { 41781ad6265SDimitry Andric // C++20 A module-declaration that contains neither an export- 41881ad6265SDimitry Andric // keyword nor a module-partition implicitly imports the primary 41981ad6265SDimitry Andric // module interface unit of the module as if by a module-import- 42081ad6265SDimitry Andric // declaration. 4211ac55f4cSDimitry Andric std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc( 4221ac55f4cSDimitry Andric PP.getIdentifierInfo(ModuleName), Path[0].second); 4231ac55f4cSDimitry Andric 4241ac55f4cSDimitry Andric // The module loader will assume we're trying to import the module that 4251ac55f4cSDimitry Andric // we're building if `LangOpts.CurrentModule` equals to 'ModuleName'. 4261ac55f4cSDimitry Andric // Change the value for `LangOpts.CurrentModule` temporarily to make the 4271ac55f4cSDimitry Andric // module loader work properly. 4281ac55f4cSDimitry Andric const_cast<LangOptions &>(getLangOpts()).CurrentModule = ""; 42906c3fb27SDimitry Andric Interface = getModuleLoader().loadModule(ModuleLoc, {ModuleNameLoc}, 4300b57cec5SDimitry Andric Module::AllVisible, 4310b57cec5SDimitry Andric /*IsInclusionDirective=*/false); 4321ac55f4cSDimitry Andric const_cast<LangOptions&>(getLangOpts()).CurrentModule = ModuleName; 4331ac55f4cSDimitry Andric 43406c3fb27SDimitry Andric if (!Interface) { 4350b57cec5SDimitry Andric Diag(ModuleLoc, diag::err_module_not_defined) << ModuleName; 4360b57cec5SDimitry Andric // Create an empty module interface unit for error recovery. 437bdd1243dSDimitry Andric Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName); 43806c3fb27SDimitry Andric } else { 43906c3fb27SDimitry Andric Mod = Map.createModuleForImplementationUnit(ModuleLoc, ModuleName); 4400b57cec5SDimitry Andric } 44181ad6265SDimitry Andric } break; 44281ad6265SDimitry Andric 44381ad6265SDimitry Andric case ModuleDeclKind::PartitionImplementation: 44481ad6265SDimitry Andric // Create an interface, but note that it is an implementation 44581ad6265SDimitry Andric // unit. 446bdd1243dSDimitry Andric Mod = Map.createModuleForInterfaceUnit(ModuleLoc, ModuleName); 44781ad6265SDimitry Andric Mod->Kind = Module::ModulePartitionImplementation; 4480b57cec5SDimitry Andric break; 4490b57cec5SDimitry Andric } 4500b57cec5SDimitry Andric 45106c3fb27SDimitry Andric if (!this->TheGlobalModuleFragment) { 4520b57cec5SDimitry Andric ModuleScopes.push_back({}); 4530b57cec5SDimitry Andric if (getLangOpts().ModulesLocalVisibility) 4540b57cec5SDimitry Andric ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules); 4550b57cec5SDimitry Andric } else { 4560b57cec5SDimitry Andric // We're done with the global module fragment now. 4570b57cec5SDimitry Andric ActOnEndOfTranslationUnitFragment(TUFragmentKind::Global); 4580b57cec5SDimitry Andric } 4590b57cec5SDimitry Andric 4600b57cec5SDimitry Andric // Switch from the global module fragment (if any) to the named module. 4610b57cec5SDimitry Andric ModuleScopes.back().BeginLoc = StartLoc; 4620b57cec5SDimitry Andric ModuleScopes.back().Module = Mod; 4630b57cec5SDimitry Andric VisibleModules.setVisible(Mod, ModuleLoc); 4640b57cec5SDimitry Andric 4650b57cec5SDimitry Andric // From now on, we have an owning module for all declarations we see. 46681ad6265SDimitry Andric // In C++20 modules, those declaration would be reachable when imported 46781ad6265SDimitry Andric // unless explicitily exported. 46881ad6265SDimitry Andric // Otherwise, those declarations are module-private unless explicitly 4690b57cec5SDimitry Andric // exported. 4700b57cec5SDimitry Andric auto *TU = Context.getTranslationUnitDecl(); 47181ad6265SDimitry Andric TU->setModuleOwnershipKind(Decl::ModuleOwnershipKind::ReachableWhenImported); 4720b57cec5SDimitry Andric TU->setLocalOwningModule(Mod); 4730b57cec5SDimitry Andric 47481ad6265SDimitry Andric // We are in the module purview, but before any other (non import) 47581ad6265SDimitry Andric // statements, so imports are allowed. 47681ad6265SDimitry Andric ImportState = ModuleImportState::ImportAllowed; 47781ad6265SDimitry Andric 47806c3fb27SDimitry Andric getASTContext().setCurrentNamedModule(Mod); 47906c3fb27SDimitry Andric 480*0fca6ea1SDimitry Andric if (auto *Listener = getASTMutationListener()) 481*0fca6ea1SDimitry Andric Listener->EnteringModulePurview(); 482*0fca6ea1SDimitry Andric 48306c3fb27SDimitry Andric // We already potentially made an implicit import (in the case of a module 48406c3fb27SDimitry Andric // implementation unit importing its interface). Make this module visible 48506c3fb27SDimitry Andric // and return the import decl to be added to the current TU. 48606c3fb27SDimitry Andric if (Interface) { 48706c3fb27SDimitry Andric 488*0fca6ea1SDimitry Andric makeTransitiveImportsVisible(getASTContext(), VisibleModules, Interface, 489*0fca6ea1SDimitry Andric Mod, ModuleLoc, 490*0fca6ea1SDimitry Andric /*IsImportingPrimaryModuleInterface=*/true); 49106c3fb27SDimitry Andric 49206c3fb27SDimitry Andric // Make the import decl for the interface in the impl module. 49306c3fb27SDimitry Andric ImportDecl *Import = ImportDecl::Create(Context, CurContext, ModuleLoc, 49406c3fb27SDimitry Andric Interface, Path[0].second); 49506c3fb27SDimitry Andric CurContext->addDecl(Import); 49606c3fb27SDimitry Andric 49706c3fb27SDimitry Andric // Sequence initialization of the imported module before that of the current 49806c3fb27SDimitry Andric // module, if any. 49906c3fb27SDimitry Andric Context.addModuleInitializer(ModuleScopes.back().Module, Import); 50006c3fb27SDimitry Andric Mod->Imports.insert(Interface); // As if we imported it. 50106c3fb27SDimitry Andric // Also save this as a shortcut to checking for decls in the interface 50206c3fb27SDimitry Andric ThePrimaryInterface = Interface; 50306c3fb27SDimitry Andric // If we made an implicit import of the module interface, then return the 50406c3fb27SDimitry Andric // imported module decl. 505fcaf7f86SDimitry Andric return ConvertDeclToDeclGroup(Import); 506fcaf7f86SDimitry Andric } 507fcaf7f86SDimitry Andric 5080b57cec5SDimitry Andric return nullptr; 5090b57cec5SDimitry Andric } 5100b57cec5SDimitry Andric 5110b57cec5SDimitry Andric Sema::DeclGroupPtrTy 5120b57cec5SDimitry Andric Sema::ActOnPrivateModuleFragmentDecl(SourceLocation ModuleLoc, 5130b57cec5SDimitry Andric SourceLocation PrivateLoc) { 5140b57cec5SDimitry Andric // C++20 [basic.link]/2: 5150b57cec5SDimitry Andric // A private-module-fragment shall appear only in a primary module 5160b57cec5SDimitry Andric // interface unit. 51706c3fb27SDimitry Andric switch (ModuleScopes.empty() ? Module::ExplicitGlobalModuleFragment 5180b57cec5SDimitry Andric : ModuleScopes.back().Module->Kind) { 5190b57cec5SDimitry Andric case Module::ModuleMapModule: 52006c3fb27SDimitry Andric case Module::ExplicitGlobalModuleFragment: 52106c3fb27SDimitry Andric case Module::ImplicitGlobalModuleFragment: 52281ad6265SDimitry Andric case Module::ModulePartitionImplementation: 52381ad6265SDimitry Andric case Module::ModulePartitionInterface: 52481ad6265SDimitry Andric case Module::ModuleHeaderUnit: 5250b57cec5SDimitry Andric Diag(PrivateLoc, diag::err_private_module_fragment_not_module); 5260b57cec5SDimitry Andric return nullptr; 5270b57cec5SDimitry Andric 5280b57cec5SDimitry Andric case Module::PrivateModuleFragment: 5290b57cec5SDimitry Andric Diag(PrivateLoc, diag::err_private_module_fragment_redefined); 5300b57cec5SDimitry Andric Diag(ModuleScopes.back().BeginLoc, diag::note_previous_definition); 5310b57cec5SDimitry Andric return nullptr; 5320b57cec5SDimitry Andric 53306c3fb27SDimitry Andric case Module::ModuleImplementationUnit: 5340b57cec5SDimitry Andric Diag(PrivateLoc, diag::err_private_module_fragment_not_module_interface); 5350b57cec5SDimitry Andric Diag(ModuleScopes.back().BeginLoc, 5360b57cec5SDimitry Andric diag::note_not_module_interface_add_export) 5370b57cec5SDimitry Andric << FixItHint::CreateInsertion(ModuleScopes.back().BeginLoc, "export "); 5380b57cec5SDimitry Andric return nullptr; 53906c3fb27SDimitry Andric 54006c3fb27SDimitry Andric case Module::ModuleInterfaceUnit: 54106c3fb27SDimitry Andric break; 5420b57cec5SDimitry Andric } 5430b57cec5SDimitry Andric 5440b57cec5SDimitry Andric // FIXME: Check that this translation unit does not import any partitions; 5450b57cec5SDimitry Andric // such imports would violate [basic.link]/2's "shall be the only module unit" 5460b57cec5SDimitry Andric // restriction. 5470b57cec5SDimitry Andric 5480b57cec5SDimitry Andric // We've finished the public fragment of the translation unit. 5490b57cec5SDimitry Andric ActOnEndOfTranslationUnitFragment(TUFragmentKind::Normal); 5500b57cec5SDimitry Andric 5510b57cec5SDimitry Andric auto &Map = PP.getHeaderSearchInfo().getModuleMap(); 5520b57cec5SDimitry Andric Module *PrivateModuleFragment = 5530b57cec5SDimitry Andric Map.createPrivateModuleFragmentForInterfaceUnit( 5540b57cec5SDimitry Andric ModuleScopes.back().Module, PrivateLoc); 5550b57cec5SDimitry Andric assert(PrivateModuleFragment && "module creation should not fail"); 5560b57cec5SDimitry Andric 5570b57cec5SDimitry Andric // Enter the scope of the private module fragment. 5580b57cec5SDimitry Andric ModuleScopes.push_back({}); 5590b57cec5SDimitry Andric ModuleScopes.back().BeginLoc = ModuleLoc; 5600b57cec5SDimitry Andric ModuleScopes.back().Module = PrivateModuleFragment; 5610b57cec5SDimitry Andric VisibleModules.setVisible(PrivateModuleFragment, ModuleLoc); 5620b57cec5SDimitry Andric 5630b57cec5SDimitry Andric // All declarations created from now on are scoped to the private module 5640b57cec5SDimitry Andric // fragment (and are neither visible nor reachable in importers of the module 5650b57cec5SDimitry Andric // interface). 5660b57cec5SDimitry Andric auto *TU = Context.getTranslationUnitDecl(); 5670b57cec5SDimitry Andric TU->setModuleOwnershipKind(Decl::ModuleOwnershipKind::ModulePrivate); 5680b57cec5SDimitry Andric TU->setLocalOwningModule(PrivateModuleFragment); 5690b57cec5SDimitry Andric 5700b57cec5SDimitry Andric // FIXME: Consider creating an explicit representation of this declaration. 5710b57cec5SDimitry Andric return nullptr; 5720b57cec5SDimitry Andric } 5730b57cec5SDimitry Andric 5740b57cec5SDimitry Andric DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc, 5750b57cec5SDimitry Andric SourceLocation ExportLoc, 57681ad6265SDimitry Andric SourceLocation ImportLoc, ModuleIdPath Path, 57781ad6265SDimitry Andric bool IsPartition) { 57806c3fb27SDimitry Andric assert((!IsPartition || getLangOpts().CPlusPlusModules) && 57906c3fb27SDimitry Andric "partition seen in non-C++20 code?"); 58081ad6265SDimitry Andric 58181ad6265SDimitry Andric // For a C++20 module name, flatten into a single identifier with the source 58281ad6265SDimitry Andric // location of the first component. 5830b57cec5SDimitry Andric std::pair<IdentifierInfo *, SourceLocation> ModuleNameLoc; 58481ad6265SDimitry Andric 5850b57cec5SDimitry Andric std::string ModuleName; 58681ad6265SDimitry Andric if (IsPartition) { 58781ad6265SDimitry Andric // We already checked that we are in a module purview in the parser. 58881ad6265SDimitry Andric assert(!ModuleScopes.empty() && "in a module purview, but no module?"); 58981ad6265SDimitry Andric Module *NamedMod = ModuleScopes.back().Module; 59081ad6265SDimitry Andric // If we are importing into a partition, find the owning named module, 59181ad6265SDimitry Andric // otherwise, the name of the importing named module. 59281ad6265SDimitry Andric ModuleName = NamedMod->getPrimaryModuleInterfaceName().str(); 59381ad6265SDimitry Andric ModuleName += ":"; 59481ad6265SDimitry Andric ModuleName += stringFromPath(Path); 59581ad6265SDimitry Andric ModuleNameLoc = {PP.getIdentifierInfo(ModuleName), Path[0].second}; 59681ad6265SDimitry Andric Path = ModuleIdPath(ModuleNameLoc); 59706c3fb27SDimitry Andric } else if (getLangOpts().CPlusPlusModules) { 59881ad6265SDimitry Andric ModuleName = stringFromPath(Path); 5990b57cec5SDimitry Andric ModuleNameLoc = {PP.getIdentifierInfo(ModuleName), Path[0].second}; 6000b57cec5SDimitry Andric Path = ModuleIdPath(ModuleNameLoc); 6010b57cec5SDimitry Andric } 6020b57cec5SDimitry Andric 60381ad6265SDimitry Andric // Diagnose self-import before attempting a load. 60481ad6265SDimitry Andric // [module.import]/9 60581ad6265SDimitry Andric // A module implementation unit of a module M that is not a module partition 60681ad6265SDimitry Andric // shall not contain a module-import-declaration nominating M. 60781ad6265SDimitry Andric // (for an implementation, the module interface is imported implicitly, 60881ad6265SDimitry Andric // but that's handled in the module decl code). 60981ad6265SDimitry Andric 61081ad6265SDimitry Andric if (getLangOpts().CPlusPlusModules && isCurrentModulePurview() && 61181ad6265SDimitry Andric getCurrentModule()->Name == ModuleName) { 61281ad6265SDimitry Andric Diag(ImportLoc, diag::err_module_self_import_cxx20) 6135f757f3fSDimitry Andric << ModuleName << currentModuleIsImplementation(); 61481ad6265SDimitry Andric return true; 61581ad6265SDimitry Andric } 61681ad6265SDimitry Andric 61781ad6265SDimitry Andric Module *Mod = getModuleLoader().loadModule( 61881ad6265SDimitry Andric ImportLoc, Path, Module::AllVisible, /*IsInclusionDirective=*/false); 6190b57cec5SDimitry Andric if (!Mod) 6200b57cec5SDimitry Andric return true; 6210b57cec5SDimitry Andric 622647cbc5dSDimitry Andric if (!Mod->isInterfaceOrPartition() && !ModuleName.empty() && 623647cbc5dSDimitry Andric !getLangOpts().ObjC) { 6245f757f3fSDimitry Andric Diag(ImportLoc, diag::err_module_import_non_interface_nor_parition) 6255f757f3fSDimitry Andric << ModuleName; 6265f757f3fSDimitry Andric return true; 6275f757f3fSDimitry Andric } 6285f757f3fSDimitry Andric 6290b57cec5SDimitry Andric return ActOnModuleImport(StartLoc, ExportLoc, ImportLoc, Mod, Path); 6300b57cec5SDimitry Andric } 6310b57cec5SDimitry Andric 6320b57cec5SDimitry Andric /// Determine whether \p D is lexically within an export-declaration. 6330b57cec5SDimitry Andric static const ExportDecl *getEnclosingExportDecl(const Decl *D) { 6340b57cec5SDimitry Andric for (auto *DC = D->getLexicalDeclContext(); DC; DC = DC->getLexicalParent()) 6350b57cec5SDimitry Andric if (auto *ED = dyn_cast<ExportDecl>(DC)) 6360b57cec5SDimitry Andric return ED; 6370b57cec5SDimitry Andric return nullptr; 6380b57cec5SDimitry Andric } 6390b57cec5SDimitry Andric 6400b57cec5SDimitry Andric DeclResult Sema::ActOnModuleImport(SourceLocation StartLoc, 6410b57cec5SDimitry Andric SourceLocation ExportLoc, 64281ad6265SDimitry Andric SourceLocation ImportLoc, Module *Mod, 64381ad6265SDimitry Andric ModuleIdPath Path) { 64406c3fb27SDimitry Andric if (Mod->isHeaderUnit()) 64506c3fb27SDimitry Andric Diag(ImportLoc, diag::warn_experimental_header_unit); 64606c3fb27SDimitry Andric 647*0fca6ea1SDimitry Andric if (Mod->isNamedModule()) 648*0fca6ea1SDimitry Andric makeTransitiveImportsVisible(getASTContext(), VisibleModules, Mod, 649*0fca6ea1SDimitry Andric getCurrentModule(), ImportLoc); 650*0fca6ea1SDimitry Andric else 6510b57cec5SDimitry Andric VisibleModules.setVisible(Mod, ImportLoc); 6520b57cec5SDimitry Andric 6530b57cec5SDimitry Andric checkModuleImportContext(*this, Mod, ImportLoc, CurContext); 6540b57cec5SDimitry Andric 6550b57cec5SDimitry Andric // FIXME: we should support importing a submodule within a different submodule 6560b57cec5SDimitry Andric // of the same top-level module. Until we do, make it an error rather than 6570b57cec5SDimitry Andric // silently ignoring the import. 65881ad6265SDimitry Andric // FIXME: Should we warn on a redundant import of the current module? 65906c3fb27SDimitry Andric if (Mod->isForBuilding(getLangOpts())) { 6600b57cec5SDimitry Andric Diag(ImportLoc, getLangOpts().isCompilingModule() 6610b57cec5SDimitry Andric ? diag::err_module_self_import 6620b57cec5SDimitry Andric : diag::err_module_import_in_implementation) 6630b57cec5SDimitry Andric << Mod->getFullModuleName() << getLangOpts().CurrentModule; 6640b57cec5SDimitry Andric } 6650b57cec5SDimitry Andric 6660b57cec5SDimitry Andric SmallVector<SourceLocation, 2> IdentifierLocs; 66781ad6265SDimitry Andric 66881ad6265SDimitry Andric if (Path.empty()) { 66981ad6265SDimitry Andric // If this was a header import, pad out with dummy locations. 67081ad6265SDimitry Andric // FIXME: Pass in and use the location of the header-name token in this 67181ad6265SDimitry Andric // case. 67281ad6265SDimitry Andric for (Module *ModCheck = Mod; ModCheck; ModCheck = ModCheck->Parent) 67381ad6265SDimitry Andric IdentifierLocs.push_back(SourceLocation()); 67481ad6265SDimitry Andric } else if (getLangOpts().CPlusPlusModules && !Mod->Parent) { 67581ad6265SDimitry Andric // A single identifier for the whole name. 67681ad6265SDimitry Andric IdentifierLocs.push_back(Path[0].second); 67781ad6265SDimitry Andric } else { 6780b57cec5SDimitry Andric Module *ModCheck = Mod; 6790b57cec5SDimitry Andric for (unsigned I = 0, N = Path.size(); I != N; ++I) { 68081ad6265SDimitry Andric // If we've run out of module parents, just drop the remaining 68181ad6265SDimitry Andric // identifiers. We need the length to be consistent. 6820b57cec5SDimitry Andric if (!ModCheck) 6830b57cec5SDimitry Andric break; 6840b57cec5SDimitry Andric ModCheck = ModCheck->Parent; 6850b57cec5SDimitry Andric 6860b57cec5SDimitry Andric IdentifierLocs.push_back(Path[I].second); 6870b57cec5SDimitry Andric } 6880b57cec5SDimitry Andric } 6890b57cec5SDimitry Andric 6900b57cec5SDimitry Andric ImportDecl *Import = ImportDecl::Create(Context, CurContext, StartLoc, 6910b57cec5SDimitry Andric Mod, IdentifierLocs); 6920b57cec5SDimitry Andric CurContext->addDecl(Import); 6930b57cec5SDimitry Andric 6940b57cec5SDimitry Andric // Sequence initialization of the imported module before that of the current 6950b57cec5SDimitry Andric // module, if any. 6960b57cec5SDimitry Andric if (!ModuleScopes.empty()) 6970b57cec5SDimitry Andric Context.addModuleInitializer(ModuleScopes.back().Module, Import); 6980b57cec5SDimitry Andric 69981ad6265SDimitry Andric // A module (partition) implementation unit shall not be exported. 70081ad6265SDimitry Andric if (getLangOpts().CPlusPlusModules && ExportLoc.isValid() && 70181ad6265SDimitry Andric Mod->Kind == Module::ModuleKind::ModulePartitionImplementation) { 70281ad6265SDimitry Andric Diag(ExportLoc, diag::err_export_partition_impl) 70381ad6265SDimitry Andric << SourceRange(ExportLoc, Path.back().second); 7045f757f3fSDimitry Andric } else if (!ModuleScopes.empty() && !currentModuleIsImplementation()) { 7050eae32dcSDimitry Andric // Re-export the module if the imported module is exported. 7060eae32dcSDimitry Andric // Note that we don't need to add re-exported module to Imports field 7070eae32dcSDimitry Andric // since `Exports` implies the module is imported already. 7080b57cec5SDimitry Andric if (ExportLoc.isValid() || getEnclosingExportDecl(Import)) 7090b57cec5SDimitry Andric getCurrentModule()->Exports.emplace_back(Mod, false); 7100eae32dcSDimitry Andric else 7110eae32dcSDimitry Andric getCurrentModule()->Imports.insert(Mod); 7120b57cec5SDimitry Andric } else if (ExportLoc.isValid()) { 7130eae32dcSDimitry Andric // [module.interface]p1: 7140eae32dcSDimitry Andric // An export-declaration shall inhabit a namespace scope and appear in the 7150eae32dcSDimitry Andric // purview of a module interface unit. 71606c3fb27SDimitry Andric Diag(ExportLoc, diag::err_export_not_in_module_interface); 7170b57cec5SDimitry Andric } 7180b57cec5SDimitry Andric 7190b57cec5SDimitry Andric return Import; 7200b57cec5SDimitry Andric } 7210b57cec5SDimitry Andric 722*0fca6ea1SDimitry Andric void Sema::ActOnAnnotModuleInclude(SourceLocation DirectiveLoc, Module *Mod) { 7230b57cec5SDimitry Andric checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext, true); 7240b57cec5SDimitry Andric BuildModuleInclude(DirectiveLoc, Mod); 7250b57cec5SDimitry Andric } 7260b57cec5SDimitry Andric 7270b57cec5SDimitry Andric void Sema::BuildModuleInclude(SourceLocation DirectiveLoc, Module *Mod) { 7280b57cec5SDimitry Andric // Determine whether we're in the #include buffer for a module. The #includes 7290b57cec5SDimitry Andric // in that buffer do not qualify as module imports; they're just an 7300b57cec5SDimitry Andric // implementation detail of us building the module. 7310b57cec5SDimitry Andric // 732*0fca6ea1SDimitry Andric // FIXME: Should we even get ActOnAnnotModuleInclude calls for those? 7330b57cec5SDimitry Andric bool IsInModuleIncludes = 734*0fca6ea1SDimitry Andric TUKind == TU_ClangModule && 7350b57cec5SDimitry Andric getSourceManager().isWrittenInMainFile(DirectiveLoc); 7360b57cec5SDimitry Andric 73706c3fb27SDimitry Andric // If we are really importing a module (not just checking layering) due to an 73806c3fb27SDimitry Andric // #include in the main file, synthesize an ImportDecl. 73906c3fb27SDimitry Andric if (getLangOpts().Modules && !IsInModuleIncludes) { 7400b57cec5SDimitry Andric TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl(); 7410b57cec5SDimitry Andric ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU, 7420b57cec5SDimitry Andric DirectiveLoc, Mod, 7430b57cec5SDimitry Andric DirectiveLoc); 7440b57cec5SDimitry Andric if (!ModuleScopes.empty()) 7450b57cec5SDimitry Andric Context.addModuleInitializer(ModuleScopes.back().Module, ImportD); 7460b57cec5SDimitry Andric TU->addDecl(ImportD); 7470b57cec5SDimitry Andric Consumer.HandleImplicitImportDecl(ImportD); 7480b57cec5SDimitry Andric } 7490b57cec5SDimitry Andric 7500b57cec5SDimitry Andric getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, DirectiveLoc); 7510b57cec5SDimitry Andric VisibleModules.setVisible(Mod, DirectiveLoc); 75281ad6265SDimitry Andric 75381ad6265SDimitry Andric if (getLangOpts().isCompilingModule()) { 75481ad6265SDimitry Andric Module *ThisModule = PP.getHeaderSearchInfo().lookupModule( 75581ad6265SDimitry Andric getLangOpts().CurrentModule, DirectiveLoc, false, false); 75681ad6265SDimitry Andric (void)ThisModule; 75781ad6265SDimitry Andric assert(ThisModule && "was expecting a module if building one"); 75881ad6265SDimitry Andric } 7590b57cec5SDimitry Andric } 7600b57cec5SDimitry Andric 761*0fca6ea1SDimitry Andric void Sema::ActOnAnnotModuleBegin(SourceLocation DirectiveLoc, Module *Mod) { 7620b57cec5SDimitry Andric checkModuleImportContext(*this, Mod, DirectiveLoc, CurContext, true); 7630b57cec5SDimitry Andric 7640b57cec5SDimitry Andric ModuleScopes.push_back({}); 7650b57cec5SDimitry Andric ModuleScopes.back().Module = Mod; 7660b57cec5SDimitry Andric if (getLangOpts().ModulesLocalVisibility) 7670b57cec5SDimitry Andric ModuleScopes.back().OuterVisibleModules = std::move(VisibleModules); 7680b57cec5SDimitry Andric 7690b57cec5SDimitry Andric VisibleModules.setVisible(Mod, DirectiveLoc); 7700b57cec5SDimitry Andric 7710b57cec5SDimitry Andric // The enclosing context is now part of this module. 7720b57cec5SDimitry Andric // FIXME: Consider creating a child DeclContext to hold the entities 7730b57cec5SDimitry Andric // lexically within the module. 7740b57cec5SDimitry Andric if (getLangOpts().trackLocalOwningModule()) { 7750b57cec5SDimitry Andric for (auto *DC = CurContext; DC; DC = DC->getLexicalParent()) { 7760b57cec5SDimitry Andric cast<Decl>(DC)->setModuleOwnershipKind( 7770b57cec5SDimitry Andric getLangOpts().ModulesLocalVisibility 7780b57cec5SDimitry Andric ? Decl::ModuleOwnershipKind::VisibleWhenImported 7790b57cec5SDimitry Andric : Decl::ModuleOwnershipKind::Visible); 7800b57cec5SDimitry Andric cast<Decl>(DC)->setLocalOwningModule(Mod); 7810b57cec5SDimitry Andric } 7820b57cec5SDimitry Andric } 7830b57cec5SDimitry Andric } 7840b57cec5SDimitry Andric 785*0fca6ea1SDimitry Andric void Sema::ActOnAnnotModuleEnd(SourceLocation EomLoc, Module *Mod) { 7860b57cec5SDimitry Andric if (getLangOpts().ModulesLocalVisibility) { 7870b57cec5SDimitry Andric VisibleModules = std::move(ModuleScopes.back().OuterVisibleModules); 7880b57cec5SDimitry Andric // Leaving a module hides namespace names, so our visible namespace cache 7890b57cec5SDimitry Andric // is now out of date. 7900b57cec5SDimitry Andric VisibleNamespaceCache.clear(); 7910b57cec5SDimitry Andric } 7920b57cec5SDimitry Andric 7930b57cec5SDimitry Andric assert(!ModuleScopes.empty() && ModuleScopes.back().Module == Mod && 7940b57cec5SDimitry Andric "left the wrong module scope"); 7950b57cec5SDimitry Andric ModuleScopes.pop_back(); 7960b57cec5SDimitry Andric 7970b57cec5SDimitry Andric // We got to the end of processing a local module. Create an 7980b57cec5SDimitry Andric // ImportDecl as we would for an imported module. 7990b57cec5SDimitry Andric FileID File = getSourceManager().getFileID(EomLoc); 8000b57cec5SDimitry Andric SourceLocation DirectiveLoc; 8010b57cec5SDimitry Andric if (EomLoc == getSourceManager().getLocForEndOfFile(File)) { 8020b57cec5SDimitry Andric // We reached the end of a #included module header. Use the #include loc. 8030b57cec5SDimitry Andric assert(File != getSourceManager().getMainFileID() && 8040b57cec5SDimitry Andric "end of submodule in main source file"); 8050b57cec5SDimitry Andric DirectiveLoc = getSourceManager().getIncludeLoc(File); 8060b57cec5SDimitry Andric } else { 8070b57cec5SDimitry Andric // We reached an EOM pragma. Use the pragma location. 8080b57cec5SDimitry Andric DirectiveLoc = EomLoc; 8090b57cec5SDimitry Andric } 8100b57cec5SDimitry Andric BuildModuleInclude(DirectiveLoc, Mod); 8110b57cec5SDimitry Andric 8120b57cec5SDimitry Andric // Any further declarations are in whatever module we returned to. 8130b57cec5SDimitry Andric if (getLangOpts().trackLocalOwningModule()) { 8140b57cec5SDimitry Andric // The parser guarantees that this is the same context that we entered 8150b57cec5SDimitry Andric // the module within. 8160b57cec5SDimitry Andric for (auto *DC = CurContext; DC; DC = DC->getLexicalParent()) { 8170b57cec5SDimitry Andric cast<Decl>(DC)->setLocalOwningModule(getCurrentModule()); 8180b57cec5SDimitry Andric if (!getCurrentModule()) 8190b57cec5SDimitry Andric cast<Decl>(DC)->setModuleOwnershipKind( 8200b57cec5SDimitry Andric Decl::ModuleOwnershipKind::Unowned); 8210b57cec5SDimitry Andric } 8220b57cec5SDimitry Andric } 8230b57cec5SDimitry Andric } 8240b57cec5SDimitry Andric 8250b57cec5SDimitry Andric void Sema::createImplicitModuleImportForErrorRecovery(SourceLocation Loc, 8260b57cec5SDimitry Andric Module *Mod) { 8270b57cec5SDimitry Andric // Bail if we're not allowed to implicitly import a module here. 8280b57cec5SDimitry Andric if (isSFINAEContext() || !getLangOpts().ModulesErrorRecovery || 8290b57cec5SDimitry Andric VisibleModules.isVisible(Mod)) 8300b57cec5SDimitry Andric return; 8310b57cec5SDimitry Andric 8320b57cec5SDimitry Andric // Create the implicit import declaration. 8330b57cec5SDimitry Andric TranslationUnitDecl *TU = getASTContext().getTranslationUnitDecl(); 8340b57cec5SDimitry Andric ImportDecl *ImportD = ImportDecl::CreateImplicit(getASTContext(), TU, 8350b57cec5SDimitry Andric Loc, Mod, Loc); 8360b57cec5SDimitry Andric TU->addDecl(ImportD); 8370b57cec5SDimitry Andric Consumer.HandleImplicitImportDecl(ImportD); 8380b57cec5SDimitry Andric 8390b57cec5SDimitry Andric // Make the module visible. 8400b57cec5SDimitry Andric getModuleLoader().makeModuleVisible(Mod, Module::AllVisible, Loc); 8410b57cec5SDimitry Andric VisibleModules.setVisible(Mod, Loc); 8420b57cec5SDimitry Andric } 8430b57cec5SDimitry Andric 8440b57cec5SDimitry Andric Decl *Sema::ActOnStartExportDecl(Scope *S, SourceLocation ExportLoc, 8450b57cec5SDimitry Andric SourceLocation LBraceLoc) { 8460b57cec5SDimitry Andric ExportDecl *D = ExportDecl::Create(Context, CurContext, ExportLoc); 8470b57cec5SDimitry Andric 8480b57cec5SDimitry Andric // Set this temporarily so we know the export-declaration was braced. 8490b57cec5SDimitry Andric D->setRBraceLoc(LBraceLoc); 8500b57cec5SDimitry Andric 85104eeddc0SDimitry Andric CurContext->addDecl(D); 85204eeddc0SDimitry Andric PushDeclContext(S, D); 85304eeddc0SDimitry Andric 8540b57cec5SDimitry Andric // C++2a [module.interface]p1: 8550b57cec5SDimitry Andric // An export-declaration shall appear only [...] in the purview of a module 8560b57cec5SDimitry Andric // interface unit. An export-declaration shall not appear directly or 8570b57cec5SDimitry Andric // indirectly within [...] a private-module-fragment. 858*0fca6ea1SDimitry Andric if (!getLangOpts().HLSL) { 859bdd1243dSDimitry Andric if (!isCurrentModulePurview()) { 8600b57cec5SDimitry Andric Diag(ExportLoc, diag::err_export_not_in_module_interface) << 0; 86104eeddc0SDimitry Andric D->setInvalidDecl(); 86204eeddc0SDimitry Andric return D; 8635f757f3fSDimitry Andric } else if (currentModuleIsImplementation()) { 8640b57cec5SDimitry Andric Diag(ExportLoc, diag::err_export_not_in_module_interface) << 1; 8650b57cec5SDimitry Andric Diag(ModuleScopes.back().BeginLoc, 8660b57cec5SDimitry Andric diag::note_not_module_interface_add_export) 8670b57cec5SDimitry Andric << FixItHint::CreateInsertion(ModuleScopes.back().BeginLoc, "export "); 86804eeddc0SDimitry Andric D->setInvalidDecl(); 86904eeddc0SDimitry Andric return D; 8700b57cec5SDimitry Andric } else if (ModuleScopes.back().Module->Kind == 8710b57cec5SDimitry Andric Module::PrivateModuleFragment) { 8720b57cec5SDimitry Andric Diag(ExportLoc, diag::err_export_in_private_module_fragment); 8730b57cec5SDimitry Andric Diag(ModuleScopes.back().BeginLoc, diag::note_private_module_fragment); 87404eeddc0SDimitry Andric D->setInvalidDecl(); 87504eeddc0SDimitry Andric return D; 8760b57cec5SDimitry Andric } 877*0fca6ea1SDimitry Andric } 8780b57cec5SDimitry Andric 8790b57cec5SDimitry Andric for (const DeclContext *DC = CurContext; DC; DC = DC->getLexicalParent()) { 8800b57cec5SDimitry Andric if (const auto *ND = dyn_cast<NamespaceDecl>(DC)) { 8810b57cec5SDimitry Andric // An export-declaration shall not appear directly or indirectly within 8820b57cec5SDimitry Andric // an unnamed namespace [...] 8830b57cec5SDimitry Andric if (ND->isAnonymousNamespace()) { 8840b57cec5SDimitry Andric Diag(ExportLoc, diag::err_export_within_anonymous_namespace); 8850b57cec5SDimitry Andric Diag(ND->getLocation(), diag::note_anonymous_namespace); 8860b57cec5SDimitry Andric // Don't diagnose internal-linkage declarations in this region. 8870b57cec5SDimitry Andric D->setInvalidDecl(); 88804eeddc0SDimitry Andric return D; 8890b57cec5SDimitry Andric } 8900b57cec5SDimitry Andric 8910b57cec5SDimitry Andric // A declaration is exported if it is [...] a namespace-definition 8920b57cec5SDimitry Andric // that contains an exported declaration. 8930b57cec5SDimitry Andric // 8940b57cec5SDimitry Andric // Defer exporting the namespace until after we leave it, in order to 8950b57cec5SDimitry Andric // avoid marking all subsequent declarations in the namespace as exported. 896*0fca6ea1SDimitry Andric if (!getLangOpts().HLSL && !DeferredExportedNamespaces.insert(ND).second) 8970b57cec5SDimitry Andric break; 8980b57cec5SDimitry Andric } 8990b57cec5SDimitry Andric } 9000b57cec5SDimitry Andric 9010b57cec5SDimitry Andric // [...] its declaration or declaration-seq shall not contain an 9020b57cec5SDimitry Andric // export-declaration. 9030b57cec5SDimitry Andric if (auto *ED = getEnclosingExportDecl(D)) { 9040b57cec5SDimitry Andric Diag(ExportLoc, diag::err_export_within_export); 9050b57cec5SDimitry Andric if (ED->hasBraces()) 9060b57cec5SDimitry Andric Diag(ED->getLocation(), diag::note_export); 90704eeddc0SDimitry Andric D->setInvalidDecl(); 90804eeddc0SDimitry Andric return D; 9090b57cec5SDimitry Andric } 9100b57cec5SDimitry Andric 911*0fca6ea1SDimitry Andric if (!getLangOpts().HLSL) 9120b57cec5SDimitry Andric D->setModuleOwnershipKind(Decl::ModuleOwnershipKind::VisibleWhenImported); 913*0fca6ea1SDimitry Andric 9140b57cec5SDimitry Andric return D; 9150b57cec5SDimitry Andric } 9160b57cec5SDimitry Andric 91706c3fb27SDimitry Andric static bool checkExportedDecl(Sema &, Decl *, SourceLocation); 91806c3fb27SDimitry Andric 91906c3fb27SDimitry Andric /// Check that it's valid to export all the declarations in \p DC. 9200b57cec5SDimitry Andric static bool checkExportedDeclContext(Sema &S, DeclContext *DC, 9210b57cec5SDimitry Andric SourceLocation BlockStart) { 92206c3fb27SDimitry Andric bool AllUnnamed = true; 92306c3fb27SDimitry Andric for (auto *D : DC->decls()) 92406c3fb27SDimitry Andric AllUnnamed &= checkExportedDecl(S, D, BlockStart); 92506c3fb27SDimitry Andric return AllUnnamed; 9260b57cec5SDimitry Andric } 9270b57cec5SDimitry Andric 9280b57cec5SDimitry Andric /// Check that it's valid to export \p D. 9290b57cec5SDimitry Andric static bool checkExportedDecl(Sema &S, Decl *D, SourceLocation BlockStart) { 9300b57cec5SDimitry Andric 931*0fca6ea1SDimitry Andric // HLSL: export declaration is valid only on functions 932*0fca6ea1SDimitry Andric if (S.getLangOpts().HLSL) { 933*0fca6ea1SDimitry Andric // Export-within-export was already diagnosed in ActOnStartExportDecl 934*0fca6ea1SDimitry Andric if (!dyn_cast<FunctionDecl>(D) && !dyn_cast<ExportDecl>(D)) { 935*0fca6ea1SDimitry Andric S.Diag(D->getBeginLoc(), diag::err_hlsl_export_not_on_function); 936*0fca6ea1SDimitry Andric D->setInvalidDecl(); 937*0fca6ea1SDimitry Andric return false; 938*0fca6ea1SDimitry Andric } 939*0fca6ea1SDimitry Andric } 940*0fca6ea1SDimitry Andric 94106c3fb27SDimitry Andric // C++20 [module.interface]p3: 94206c3fb27SDimitry Andric // [...] it shall not declare a name with internal linkage. 94381ad6265SDimitry Andric bool HasName = false; 9440b57cec5SDimitry Andric if (auto *ND = dyn_cast<NamedDecl>(D)) { 9450b57cec5SDimitry Andric // Don't diagnose anonymous union objects; we'll diagnose their members 9460b57cec5SDimitry Andric // instead. 94781ad6265SDimitry Andric HasName = (bool)ND->getDeclName(); 9485f757f3fSDimitry Andric if (HasName && ND->getFormalLinkage() == Linkage::Internal) { 9490b57cec5SDimitry Andric S.Diag(ND->getLocation(), diag::err_export_internal) << ND; 9500b57cec5SDimitry Andric if (BlockStart.isValid()) 9510b57cec5SDimitry Andric S.Diag(BlockStart, diag::note_export); 95206c3fb27SDimitry Andric return false; 9530b57cec5SDimitry Andric } 9540b57cec5SDimitry Andric } 9550b57cec5SDimitry Andric 9560b57cec5SDimitry Andric // C++2a [module.interface]p5: 9570b57cec5SDimitry Andric // all entities to which all of the using-declarators ultimately refer 9580b57cec5SDimitry Andric // shall have been introduced with a name having external linkage 9590b57cec5SDimitry Andric if (auto *USD = dyn_cast<UsingShadowDecl>(D)) { 9600b57cec5SDimitry Andric NamedDecl *Target = USD->getUnderlyingDecl(); 96181ad6265SDimitry Andric Linkage Lk = Target->getFormalLinkage(); 9625f757f3fSDimitry Andric if (Lk == Linkage::Internal || Lk == Linkage::Module) { 96381ad6265SDimitry Andric S.Diag(USD->getLocation(), diag::err_export_using_internal) 9645f757f3fSDimitry Andric << (Lk == Linkage::Internal ? 0 : 1) << Target; 9650b57cec5SDimitry Andric S.Diag(Target->getLocation(), diag::note_using_decl_target); 9660b57cec5SDimitry Andric if (BlockStart.isValid()) 9670b57cec5SDimitry Andric S.Diag(BlockStart, diag::note_export); 96806c3fb27SDimitry Andric return false; 9690b57cec5SDimitry Andric } 9700b57cec5SDimitry Andric } 9710b57cec5SDimitry Andric 9720b57cec5SDimitry Andric // Recurse into namespace-scope DeclContexts. (Only namespace-scope 97306c3fb27SDimitry Andric // declarations are exported). 97481ad6265SDimitry Andric if (auto *DC = dyn_cast<DeclContext>(D)) { 97506c3fb27SDimitry Andric if (!isa<NamespaceDecl>(D)) 97606c3fb27SDimitry Andric return true; 97706c3fb27SDimitry Andric 97806c3fb27SDimitry Andric if (auto *ND = dyn_cast<NamedDecl>(D)) { 97906c3fb27SDimitry Andric if (!ND->getDeclName()) { 98006c3fb27SDimitry Andric S.Diag(ND->getLocation(), diag::err_export_anon_ns_internal); 98106c3fb27SDimitry Andric if (BlockStart.isValid()) 98206c3fb27SDimitry Andric S.Diag(BlockStart, diag::note_export); 98306c3fb27SDimitry Andric return false; 98406c3fb27SDimitry Andric } else if (!DC->decls().empty() && 98506c3fb27SDimitry Andric DC->getRedeclContext()->isFileContext()) { 9860b57cec5SDimitry Andric return checkExportedDeclContext(S, DC, BlockStart); 98781ad6265SDimitry Andric } 9880b57cec5SDimitry Andric } 98906c3fb27SDimitry Andric } 99006c3fb27SDimitry Andric return true; 9910b57cec5SDimitry Andric } 9920b57cec5SDimitry Andric 9930b57cec5SDimitry Andric Decl *Sema::ActOnFinishExportDecl(Scope *S, Decl *D, SourceLocation RBraceLoc) { 9940b57cec5SDimitry Andric auto *ED = cast<ExportDecl>(D); 9950b57cec5SDimitry Andric if (RBraceLoc.isValid()) 9960b57cec5SDimitry Andric ED->setRBraceLoc(RBraceLoc); 9970b57cec5SDimitry Andric 9980b57cec5SDimitry Andric PopDeclContext(); 9990b57cec5SDimitry Andric 10000b57cec5SDimitry Andric if (!D->isInvalidDecl()) { 10010b57cec5SDimitry Andric SourceLocation BlockStart = 10020b57cec5SDimitry Andric ED->hasBraces() ? ED->getBeginLoc() : SourceLocation(); 10030b57cec5SDimitry Andric for (auto *Child : ED->decls()) { 100406c3fb27SDimitry Andric checkExportedDecl(*this, Child, BlockStart); 1005bdd1243dSDimitry Andric if (auto *FD = dyn_cast<FunctionDecl>(Child)) { 1006bdd1243dSDimitry Andric // [dcl.inline]/7 1007bdd1243dSDimitry Andric // If an inline function or variable that is attached to a named module 1008bdd1243dSDimitry Andric // is declared in a definition domain, it shall be defined in that 1009bdd1243dSDimitry Andric // domain. 1010bdd1243dSDimitry Andric // So, if the current declaration does not have a definition, we must 1011bdd1243dSDimitry Andric // check at the end of the TU (or when the PMF starts) to see that we 1012bdd1243dSDimitry Andric // have a definition at that point. 1013bdd1243dSDimitry Andric if (FD->isInlineSpecified() && !FD->isDefined()) 1014bdd1243dSDimitry Andric PendingInlineFuncDecls.insert(FD); 1015bdd1243dSDimitry Andric } 10160b57cec5SDimitry Andric } 10170b57cec5SDimitry Andric } 10180b57cec5SDimitry Andric 1019*0fca6ea1SDimitry Andric // Anything exported from a module should never be considered unused. 1020*0fca6ea1SDimitry Andric for (auto *Exported : ED->decls()) 1021*0fca6ea1SDimitry Andric Exported->markUsed(getASTContext()); 1022*0fca6ea1SDimitry Andric 10230b57cec5SDimitry Andric return D; 10240b57cec5SDimitry Andric } 10250eae32dcSDimitry Andric 102606c3fb27SDimitry Andric Module *Sema::PushGlobalModuleFragment(SourceLocation BeginLoc) { 102781ad6265SDimitry Andric // We shouldn't create new global module fragment if there is already 102881ad6265SDimitry Andric // one. 102906c3fb27SDimitry Andric if (!TheGlobalModuleFragment) { 10300eae32dcSDimitry Andric ModuleMap &Map = PP.getHeaderSearchInfo().getModuleMap(); 103106c3fb27SDimitry Andric TheGlobalModuleFragment = Map.createGlobalModuleFragmentForModuleUnit( 103281ad6265SDimitry Andric BeginLoc, getCurrentModule()); 103381ad6265SDimitry Andric } 103481ad6265SDimitry Andric 103506c3fb27SDimitry Andric assert(TheGlobalModuleFragment && "module creation should not fail"); 10360eae32dcSDimitry Andric 10370eae32dcSDimitry Andric // Enter the scope of the global module. 103806c3fb27SDimitry Andric ModuleScopes.push_back({BeginLoc, TheGlobalModuleFragment, 103981ad6265SDimitry Andric /*OuterVisibleModules=*/{}}); 104006c3fb27SDimitry Andric VisibleModules.setVisible(TheGlobalModuleFragment, BeginLoc); 10410eae32dcSDimitry Andric 104206c3fb27SDimitry Andric return TheGlobalModuleFragment; 10430eae32dcSDimitry Andric } 10440eae32dcSDimitry Andric 10450eae32dcSDimitry Andric void Sema::PopGlobalModuleFragment() { 104606c3fb27SDimitry Andric assert(!ModuleScopes.empty() && 104706c3fb27SDimitry Andric getCurrentModule()->isExplicitGlobalModule() && 10480eae32dcSDimitry Andric "left the wrong module scope, which is not global module fragment"); 10490eae32dcSDimitry Andric ModuleScopes.pop_back(); 10500eae32dcSDimitry Andric } 1051753f127fSDimitry Andric 10525f757f3fSDimitry Andric Module *Sema::PushImplicitGlobalModuleFragment(SourceLocation BeginLoc) { 10535f757f3fSDimitry Andric if (!TheImplicitGlobalModuleFragment) { 105406c3fb27SDimitry Andric ModuleMap &Map = PP.getHeaderSearchInfo().getModuleMap(); 10555f757f3fSDimitry Andric TheImplicitGlobalModuleFragment = 10565f757f3fSDimitry Andric Map.createImplicitGlobalModuleFragmentForModuleUnit(BeginLoc, 10575f757f3fSDimitry Andric getCurrentModule()); 105806c3fb27SDimitry Andric } 10595f757f3fSDimitry Andric assert(TheImplicitGlobalModuleFragment && "module creation should not fail"); 1060753f127fSDimitry Andric 106106c3fb27SDimitry Andric // Enter the scope of the global module. 10625f757f3fSDimitry Andric ModuleScopes.push_back({BeginLoc, TheImplicitGlobalModuleFragment, 106306c3fb27SDimitry Andric /*OuterVisibleModules=*/{}}); 10645f757f3fSDimitry Andric VisibleModules.setVisible(TheImplicitGlobalModuleFragment, BeginLoc); 10655f757f3fSDimitry Andric return TheImplicitGlobalModuleFragment; 106606c3fb27SDimitry Andric } 1067753f127fSDimitry Andric 106806c3fb27SDimitry Andric void Sema::PopImplicitGlobalModuleFragment() { 106906c3fb27SDimitry Andric assert(!ModuleScopes.empty() && 107006c3fb27SDimitry Andric getCurrentModule()->isImplicitGlobalModule() && 107106c3fb27SDimitry Andric "left the wrong module scope, which is not global module fragment"); 107206c3fb27SDimitry Andric ModuleScopes.pop_back(); 1073753f127fSDimitry Andric } 10745f757f3fSDimitry Andric 10755f757f3fSDimitry Andric bool Sema::isCurrentModulePurview() const { 10765f757f3fSDimitry Andric if (!getCurrentModule()) 10775f757f3fSDimitry Andric return false; 10785f757f3fSDimitry Andric 10795f757f3fSDimitry Andric /// Does this Module scope describe part of the purview of a standard named 10805f757f3fSDimitry Andric /// C++ module? 10815f757f3fSDimitry Andric switch (getCurrentModule()->Kind) { 10825f757f3fSDimitry Andric case Module::ModuleInterfaceUnit: 10835f757f3fSDimitry Andric case Module::ModuleImplementationUnit: 10845f757f3fSDimitry Andric case Module::ModulePartitionInterface: 10855f757f3fSDimitry Andric case Module::ModulePartitionImplementation: 10865f757f3fSDimitry Andric case Module::PrivateModuleFragment: 10875f757f3fSDimitry Andric case Module::ImplicitGlobalModuleFragment: 10885f757f3fSDimitry Andric return true; 10895f757f3fSDimitry Andric default: 10905f757f3fSDimitry Andric return false; 10915f757f3fSDimitry Andric } 10925f757f3fSDimitry Andric } 1093