diff options
Diffstat (limited to 'clang/lib/Lex/ModuleMap.cpp')
-rw-r--r-- | clang/lib/Lex/ModuleMap.cpp | 100 |
1 files changed, 68 insertions, 32 deletions
diff --git a/clang/lib/Lex/ModuleMap.cpp b/clang/lib/Lex/ModuleMap.cpp index b3ac10c5c5a..c2ea64fcd12 100644 --- a/clang/lib/Lex/ModuleMap.cpp +++ b/clang/lib/Lex/ModuleMap.cpp @@ -744,14 +744,13 @@ Module *ModuleMap::lookupModuleQualified(StringRef Name, Module *Context) const{ return Context->findSubmodule(Name); } -std::pair<Module *, bool> ModuleMap::findOrCreateModule(StringRef Name, - Module *Parent, - bool IsFramework, - bool IsExplicit) { +std::pair<Module *, bool> +ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, + bool IsExplicit, bool UsesExplicitModuleMapFile) { // Try to find an existing module with this name. if (Module *Sub = lookupModuleQualified(Name, Parent)) return std::make_pair(Sub, false); - + // Create a new module with this name. Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework, IsExplicit, NumCreatedModules++); @@ -759,6 +758,8 @@ std::pair<Module *, bool> ModuleMap::findOrCreateModule(StringRef Name, if (LangOpts.CurrentModule == Name) SourceModule = Result; Modules[Name] = Result; + if (UsesExplicitModuleMapFile) + ExplicitlyProvidedModules.insert(Result); } return std::make_pair(Result, true); } @@ -999,6 +1000,19 @@ Module *ModuleMap::inferFrameworkModule(const DirectoryEntry *FrameworkDir, return Result; } +Module *ModuleMap::createShadowedModule(StringRef Name, bool IsFramework, + Module *ShadowingModule) { + + // Create a new module with this name. + Module *Result = + new Module(Name, SourceLocation(), /*Parent=*/nullptr, IsFramework, + /*IsExplicit=*/false, NumCreatedModules++); + Result->ShadowingModule = ShadowingModule; + Result->IsAvailable = false; + + return Result; +} + void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry *UmbrellaHeader, Twine NameAsWritten) { Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader)); @@ -1116,6 +1130,11 @@ void ModuleMap::excludeHeader(Module *Mod, Module::Header Header) { Mod->Headers[Module::HK_Excluded].push_back(std::move(Header)); } +void ModuleMap::setExplicitlyProvided(Module *Mod) { + assert(Modules[Mod->Name] == Mod && "explicitly provided module is shadowed"); + ExplicitlyProvidedModules.insert(Mod); +} + const FileEntry * ModuleMap::getContainingModuleMapFile(const Module *Module) const { if (Module->DefinitionLoc.isInvalid()) @@ -1319,7 +1338,9 @@ namespace clang { /// \brief Consume the current token and return its location. SourceLocation consumeToken(); - + + bool UsesExplicitModuleMapFile = false; + /// \brief Skip tokens until we reach the a token with the given kind /// (or the end of the file). void skipUntil(MMToken::TokenKind K); @@ -1345,20 +1366,19 @@ namespace clang { bool parseOptionalAttributes(Attributes &Attrs); public: - explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, - const TargetInfo *Target, - DiagnosticsEngine &Diags, - ModuleMap &Map, - const FileEntry *ModuleMapFile, - const DirectoryEntry *Directory, - bool IsSystem) + explicit ModuleMapParser(Lexer &L, SourceManager &SourceMgr, + const TargetInfo *Target, DiagnosticsEngine &Diags, + ModuleMap &Map, const FileEntry *ModuleMapFile, + const DirectoryEntry *Directory, bool IsSystem, + bool UsesExplicitModuleMapFile) : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map), ModuleMapFile(ModuleMapFile), Directory(Directory), - IsSystem(IsSystem) { + IsSystem(IsSystem), + UsesExplicitModuleMapFile(UsesExplicitModuleMapFile) { Tok.clear(); consumeToken(); } - + bool parseModuleMapFile(); bool terminatedByDirective() { return false; } @@ -1787,6 +1807,7 @@ void ModuleMapParser::parseModuleDecl() { SourceLocation LBraceLoc = consumeToken(); // Determine whether this (sub)module has already been defined. + Module *ShadowingModule = nullptr; if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) { // We might see a (re)definition of a module that we already have a // definition for in two cases: @@ -1812,23 +1833,36 @@ void ModuleMapParser::parseModuleDecl() { } return; } - - Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) - << ModuleName; - Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition); - - // Skip the module definition. - skipUntil(MMToken::RBrace); - if (Tok.is(MMToken::RBrace)) - consumeToken(); - - HadError = true; - return; + + if (!Existing->Parent && + Map.mayShadowModuleBeingParsed(Existing, UsesExplicitModuleMapFile)) { + ShadowingModule = Existing; + } else { + // This is not a shawdowed module decl, it is an illegal redefinition. + Diags.Report(ModuleNameLoc, diag::err_mmap_module_redefinition) + << ModuleName; + Diags.Report(Existing->DefinitionLoc, diag::note_mmap_prev_definition); + + // Skip the module definition. + skipUntil(MMToken::RBrace); + if (Tok.is(MMToken::RBrace)) + consumeToken(); + + HadError = true; + return; + } } // Start defining this module. - ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework, - Explicit).first; + if (ShadowingModule) { + ActiveModule = + Map.createShadowedModule(ModuleName, Framework, ShadowingModule); + } else { + ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework, + Explicit, UsesExplicitModuleMapFile) + .first; + } + ActiveModule->DefinitionLoc = ModuleNameLoc; if (Attrs.IsSystem || IsSystem) ActiveModule->IsSystem = true; @@ -2004,7 +2038,7 @@ void ModuleMapParser::parseExternModuleDecl() { Map.HeaderInfo.getHeaderSearchOpts().ModuleMapFileHomeIsCwd ? Directory : File->getDir(), - FileID(), nullptr, ExternLoc); + false /*IsExplicitlyProvided*/, FileID(), nullptr, ExternLoc); } /// Whether to add the requirement \p Feature to the module \p M. @@ -2811,7 +2845,8 @@ bool ModuleMapParser::parseModuleMapFile() { } bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem, - const DirectoryEntry *Dir, FileID ID, + const DirectoryEntry *Dir, + bool IsExplicitlyProvided, FileID ID, unsigned *Offset, SourceLocation ExternModuleLoc) { assert(Target && "Missing target information"); @@ -2841,7 +2876,7 @@ bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem, Buffer->getBufferEnd()); SourceLocation Start = L.getSourceLocation(); ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir, - IsSystem); + IsSystem, IsExplicitlyProvided); bool Result = Parser.parseModuleMapFile(); ParsedModuleMap[File] = Result; @@ -2854,5 +2889,6 @@ bool ModuleMap::parseModuleMapFile(const FileEntry *File, bool IsSystem, // Notify callbacks that we parsed it. for (const auto &Cb : Callbacks) Cb->moduleMapFileRead(Start, *File, IsSystem); + return Result; } |