I haven't done a ton of investigation yet, but I suspect this commit is responsible for breaking my LLVM module selfhost build, which uses libc++ as the STL, and builds LLD (No bots appear to test this configuration).
The error message can be found here: https://gist.github.com/EricWF/fb5e1d18eb1069d23788469b5fb15442 I'll investigate further tomorrow, but I wanted to send this your way in case it looks familiar. /Eric On Thu, Jan 4, 2018 at 7:33 PM, Bruno Cardoso Lopes via cfe-commits < cfe-commits@lists.llvm.org> wrote: > Author: bruno > Date: Thu Jan 4 18:33:18 2018 > New Revision: 321855 > > URL: http://llvm.org/viewvc/llvm-project?rev=321855&view=rev > Log: > Reapply r321781: [Modules] Allow modules specified by -fmodule-map-file to > shadow implicitly found ones > > When modules come from module map files explicitly specified by > -fmodule-map-file= arguments, allow those to override/shadow modules > with the same name that are found implicitly by header search. If such a > module is looked up by name (e.g. @import), we will always find the one > from -fmodule-map-file. If we try to use a shadowed module by including > one of its headers report an error. > > This enables developers to force use of a specific copy of their module > to be used if there are multiple copies that would otherwise be visible, > for example if they develop modules that are installed in the default > search paths. > > Patch originally by Ben Langmuir, > http://lists.llvm.org/pipermail/cfe-commits/Week-of- > Mon-20151116/143425.html > > Based on cfe-dev discussion: > http://lists.llvm.org/pipermail/cfe-dev/2015-November/046164.html > > Differential Revision: https://reviews.llvm.org/D31269 > > rdar://problem/23612102 > > Added: > cfe/trunk/test/Modules/Inputs/shadow/A1/A.h > cfe/trunk/test/Modules/Inputs/shadow/A1/module.modulemap > cfe/trunk/test/Modules/Inputs/shadow/A2/A.h > cfe/trunk/test/Modules/Inputs/shadow/A2/module.modulemap > cfe/trunk/test/Modules/Inputs/shadowed-submodule/A1/Foo.h > cfe/trunk/test/Modules/Inputs/shadowed-submodule/A1/module.modulemap > cfe/trunk/test/Modules/Inputs/shadowed-submodule/A1/sys/A.h > cfe/trunk/test/Modules/Inputs/shadowed-submodule/A1/sys/A2.h > cfe/trunk/test/Modules/Inputs/shadowed-submodule/A2/Foo.h > cfe/trunk/test/Modules/Inputs/shadowed-submodule/A2/module.modulemap > cfe/trunk/test/Modules/Inputs/shadowed-submodule/A2/sys/A.h > cfe/trunk/test/Modules/Inputs/shadowed-submodule/A2/sys/A2.h > cfe/trunk/test/Modules/Inputs/shadowed-submodule/Foo/module.modulemap > cfe/trunk/test/Modules/shadow.m > cfe/trunk/test/Modules/shadowed-submodule.m > Modified: > cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td > cfe/trunk/include/clang/Basic/Module.h > cfe/trunk/include/clang/Lex/HeaderSearch.h > cfe/trunk/include/clang/Lex/ModuleMap.h > cfe/trunk/lib/Basic/Module.cpp > cfe/trunk/lib/Lex/HeaderSearch.cpp > cfe/trunk/lib/Lex/ModuleMap.cpp > cfe/trunk/lib/Lex/PPDirectives.cpp > > Modified: cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/ > DiagnosticCommonKinds.td?rev=321855&r1=321854&r2=321855&view=diff > ============================================================ > ================== > --- cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td (original) > +++ cfe/trunk/include/clang/Basic/DiagnosticCommonKinds.td Thu Jan 4 > 18:33:18 2018 > @@ -94,6 +94,9 @@ def remark_module_lock_failure : Remark< > "could not acquire lock file for module '%0': %1">, > InGroup<ModuleBuild>; > def remark_module_lock_timeout : Remark< > "timed out waiting to acquire lock file for module '%0'">, > InGroup<ModuleBuild>; > +def err_module_shadowed : Error<"import of shadowed module '%0'">, > DefaultFatal; > +def err_module_build_shadowed_submodule : Error< > + "build a shadowed submodule '%0'">, DefaultFatal; > def err_module_cycle : Error<"cyclic dependency in module '%0': %1">, > DefaultFatal; > def err_module_prebuilt : Error< > > Modified: cfe/trunk/include/clang/Basic/Module.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/ > clang/Basic/Module.h?rev=321855&r1=321854&r2=321855&view=diff > ============================================================ > ================== > --- cfe/trunk/include/clang/Basic/Module.h (original) > +++ cfe/trunk/include/clang/Basic/Module.h Thu Jan 4 18:33:18 2018 > @@ -197,6 +197,9 @@ public: > /// will be false to indicate that this (sub)module is not available. > SmallVector<Requirement, 2> Requirements; > > + /// \brief A module with the same name that shadows this module. > + Module *ShadowingModule = nullptr; > + > /// \brief Whether this module is missing a feature from \c > Requirements. > unsigned IsMissingRequirement : 1; > > @@ -375,13 +378,20 @@ public: > /// > /// \param Target The target options used for the current translation > unit. > /// > - /// \param Req If this module is unavailable, this parameter > - /// will be set to one of the requirements that is not met for use of > - /// this module. > + /// \param Req If this module is unavailable because of a missing > requirement, > + /// this parameter will be set to one of the requirements that is not > met for > + /// use of this module. > + /// > + /// \param MissingHeader If this module is unavailable because of a > missing > + /// header, this parameter will be set to one of the missing headers. > + /// > + /// \param ShadowingModule If this module is unavailable because it is > + /// shadowed, this parameter will be set to the shadowing module. > bool isAvailable(const LangOptions &LangOpts, > const TargetInfo &Target, > Requirement &Req, > - UnresolvedHeaderDirective &MissingHeader) const; > + UnresolvedHeaderDirective &MissingHeader, > + Module *&ShadowingModule) const; > > /// \brief Determine whether this module is a submodule. > bool isSubModule() const { return Parent != nullptr; } > > Modified: cfe/trunk/include/clang/Lex/HeaderSearch.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/ > clang/Lex/HeaderSearch.h?rev=321855&r1=321854&r2=321855&view=diff > ============================================================ > ================== > --- cfe/trunk/include/clang/Lex/HeaderSearch.h (original) > +++ cfe/trunk/include/clang/Lex/HeaderSearch.h Thu Jan 4 18:33:18 2018 > @@ -726,6 +726,7 @@ private: > LoadModuleMapResult loadModuleMapFileImpl(const FileEntry *File, > bool IsSystem, > const DirectoryEntry *Dir, > + bool IsExplicitlyProvided, > FileID ID = FileID(), > unsigned *Offset = nullptr); > > > Modified: cfe/trunk/include/clang/Lex/ModuleMap.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/ > clang/Lex/ModuleMap.h?rev=321855&r1=321854&r2=321855&view=diff > ============================================================ > ================== > --- cfe/trunk/include/clang/Lex/ModuleMap.h (original) > +++ cfe/trunk/include/clang/Lex/ModuleMap.h Thu Jan 4 18:33:18 2018 > @@ -98,6 +98,9 @@ class ModuleMap { > /// \brief The top-level modules that are known. > llvm::StringMap<Module *> Modules; > > + /// Shadow modules created while building this module map. > + llvm::SmallVector<Module*, 2> ShadowModules; > + > /// \brief The number of modules we have created in total. > unsigned NumCreatedModules = 0; > > @@ -195,6 +198,17 @@ private: > /// header. > llvm::DenseMap<const DirectoryEntry *, Module *> UmbrellaDirs; > > + /// \brief The set of modules provided explicitly (e.g. by > -fmodule-map-file), > + /// which are allowed to shadow other implicitly discovered modules. > + llvm::DenseSet<const Module *> ExplicitlyProvidedModules; > + > + bool mayShadowModuleBeingParsed(Module *ExistingModule, > + bool IsExplicitlyProvided) { > + assert(!ExistingModule->Parent && "expected top-level module"); > + return !IsExplicitlyProvided && > + ExplicitlyProvidedModules.count(ExistingModule); > + } > + > /// \brief The set of attributes that can be attached to a module. > struct Attributes { > /// \brief Whether this is a system module. > @@ -475,9 +489,9 @@ public: > /// > /// \returns The found or newly-created module, along with a boolean > value > /// that will be true if the module is newly-created. > - std::pair<Module *, bool> findOrCreateModule(StringRef Name, Module > *Parent, > - bool IsFramework, > - bool IsExplicit); > + std::pair<Module *, bool> > + findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework, > + bool IsExplicit, bool UsesExplicitModuleMapFile = > false); > > /// \brief Create a 'global module' for a C++ Modules TS module > interface > /// unit. > @@ -502,6 +516,11 @@ public: > Module *inferFrameworkModule(const DirectoryEntry *FrameworkDir, > bool IsSystem, Module *Parent); > > + /// \brief Create a new top-level module that is shadowed by > + /// \p ShadowingModule. > + Module *createShadowedModule(StringRef Name, bool IsFramework, > + Module *ShadowingModule); > + > /// \brief Retrieve the module map file containing the definition of > the given > /// module. > /// > @@ -587,6 +606,8 @@ public: > /// \brief Marks this header as being excluded from the given module. > void excludeHeader(Module *Mod, Module::Header Header); > > + void setExplicitlyProvided(Module *Mod); > + > /// \brief Parse the given module map file, and record any modules we > /// encounter. > /// > @@ -606,10 +627,15 @@ public: > /// \param ExternModuleLoc The location of the "extern module" > declaration > /// that caused us to load this module map file, if any. > /// > + /// \param IsExplicitlyProvided Whether this module map file was > provided > + /// explicitly by the user (e.g. -fmodule-map-file), rather than found > + /// implicitly. > + /// > /// \returns true if an error occurred, false otherwise. > bool parseModuleMapFile(const FileEntry *File, bool IsSystem, > - const DirectoryEntry *HomeDir, FileID ID = > FileID(), > - unsigned *Offset = nullptr, > + const DirectoryEntry *HomeDir, > + bool IsExplicitlyProvided = false, > + FileID ID = FileID(), unsigned *Offset = > nullptr, > SourceLocation ExternModuleLoc = > SourceLocation()); > > /// \brief Dump the contents of the module map, for debugging purposes. > > Modified: cfe/trunk/lib/Basic/Module.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/ > Module.cpp?rev=321855&r1=321854&r2=321855&view=diff > ============================================================ > ================== > --- cfe/trunk/lib/Basic/Module.cpp (original) > +++ cfe/trunk/lib/Basic/Module.cpp Thu Jan 4 18:33:18 2018 > @@ -95,11 +95,16 @@ static bool hasFeature(StringRef Feature > > bool Module::isAvailable(const LangOptions &LangOpts, const TargetInfo > &Target, > Requirement &Req, > - UnresolvedHeaderDirective &MissingHeader) const { > + UnresolvedHeaderDirective &MissingHeader, > + Module *&ShadowingModule) const { > if (IsAvailable) > return true; > > for (const Module *Current = this; Current; Current = Current->Parent) { > + if (Current->ShadowingModule) { > + ShadowingModule = Current->ShadowingModule; > + return false; > + } > for (unsigned I = 0, N = Current->Requirements.size(); I != N; ++I) { > if (hasFeature(Current->Requirements[I].first, LangOpts, Target) != > Current->Requirements[I].second) { > > Modified: cfe/trunk/lib/Lex/HeaderSearch.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ > HeaderSearch.cpp?rev=321855&r1=321854&r2=321855&view=diff > ============================================================ > ================== > --- cfe/trunk/lib/Lex/HeaderSearch.cpp (original) > +++ cfe/trunk/lib/Lex/HeaderSearch.cpp Thu Jan 4 18:33:18 2018 > @@ -1367,7 +1367,8 @@ bool HeaderSearch::loadModuleMapFile(con > } > } > > - switch (loadModuleMapFileImpl(File, IsSystem, Dir, ID, Offset)) { > + switch (loadModuleMapFileImpl(File, IsSystem, Dir, > + /*IsExplictlyProvided=*/true, ID, > Offset)) { > case LMM_AlreadyLoaded: > case LMM_NewlyLoaded: > return false; > @@ -1378,10 +1379,9 @@ bool HeaderSearch::loadModuleMapFile(con > llvm_unreachable("Unknown load module map result"); > } > > -HeaderSearch::LoadModuleMapResult > -HeaderSearch::loadModuleMapFileImpl(const FileEntry *File, bool IsSystem, > - const DirectoryEntry *Dir, FileID ID, > - unsigned *Offset) { > +HeaderSearch::LoadModuleMapResult HeaderSearch::loadModuleMapFileImpl( > + const FileEntry *File, bool IsSystem, const DirectoryEntry *Dir, > + bool IsExplicitlyProvided, FileID ID, unsigned *Offset) { > assert(File && "expected FileEntry"); > > // Check whether we've already loaded this module map, and mark it as > being > @@ -1390,14 +1390,16 @@ HeaderSearch::loadModuleMapFileImpl(cons > if (!AddResult.second) > return AddResult.first->second ? LMM_AlreadyLoaded : > LMM_InvalidModuleMap; > > - if (ModMap.parseModuleMapFile(File, IsSystem, Dir, ID, Offset)) { > + if (ModMap.parseModuleMapFile(File, IsSystem, Dir, > IsExplicitlyProvided, ID, > + Offset)) { > LoadedModuleMaps[File] = false; > return LMM_InvalidModuleMap; > } > > // Try to load a corresponding private module map. > if (const FileEntry *PMMFile = getPrivateModuleMap(File, FileMgr)) { > - if (ModMap.parseModuleMapFile(PMMFile, IsSystem, Dir)) { > + if (ModMap.parseModuleMapFile(PMMFile, IsSystem, Dir, > + IsExplicitlyProvided)) { > LoadedModuleMaps[File] = false; > return LMM_InvalidModuleMap; > } > @@ -1468,8 +1470,8 @@ HeaderSearch::loadModuleMapFile(const Di > return KnownDir->second ? LMM_AlreadyLoaded : LMM_InvalidModuleMap; > > if (const FileEntry *ModuleMapFile = lookupModuleMapFile(Dir, > IsFramework)) { > - LoadModuleMapResult Result = > - loadModuleMapFileImpl(ModuleMapFile, IsSystem, Dir); > + LoadModuleMapResult Result = loadModuleMapFileImpl( > + ModuleMapFile, IsSystem, Dir, /*IsExplicitlyProvided=*/false); > // Add Dir explicitly in case ModuleMapFile is in a subdirectory. > // E.g. Foo.framework/Modules/module.modulemap > // ^Dir ^ModuleMapFile > > Modified: cfe/trunk/lib/Lex/ModuleMap.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ > ModuleMap.cpp?rev=321855&r1=321854&r2=321855&view=diff > ============================================================ > ================== > --- cfe/trunk/lib/Lex/ModuleMap.cpp (original) > +++ cfe/trunk/lib/Lex/ModuleMap.cpp Thu Jan 4 18:33:18 2018 > @@ -281,6 +281,8 @@ ModuleMap::ModuleMap(SourceManager &Sour > ModuleMap::~ModuleMap() { > for (auto &M : Modules) > delete M.getValue(); > + for (auto *M : ShadowModules) > + delete M; > } > > void ModuleMap::setTarget(const TargetInfo &Target) { > @@ -744,14 +746,13 @@ Module *ModuleMap::lookupModuleQualified > 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 +760,8 @@ std::pair<Module *, bool> ModuleMap::fin > if (LangOpts.CurrentModule == Name) > SourceModule = Result; > Modules[Name] = Result; > + if (UsesExplicitModuleMapFile) > + ExplicitlyProvidedModules.insert(Result); > } > return std::make_pair(Result, true); > } > @@ -999,6 +1002,20 @@ Module *ModuleMap::inferFrameworkModule( > 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; > + ShadowModules.push_back(Result); > + > + return Result; > +} > + > void ModuleMap::setUmbrellaHeader(Module *Mod, const FileEntry > *UmbrellaHeader, > Twine NameAsWritten) { > Headers[UmbrellaHeader].push_back(KnownHeader(Mod, NormalHeader)); > @@ -1116,6 +1133,11 @@ void ModuleMap::excludeHeader(Module *Mo > 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 +1341,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 +1369,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 +1810,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 +1836,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 +2041,7 @@ void ModuleMapParser::parseExternModuleD > 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 +2848,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 +2879,7 @@ bool ModuleMap::parseModuleMapFile(const > 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 +2892,6 @@ bool ModuleMap::parseModuleMapFile(const > // Notify callbacks that we parsed it. > for (const auto &Cb : Callbacks) > Cb->moduleMapFileRead(Start, *File, IsSystem); > + > return Result; > } > > Modified: cfe/trunk/lib/Lex/PPDirectives.cpp > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ > PPDirectives.cpp?rev=321855&r1=321854&r2=321855&view=diff > ============================================================ > ================== > --- cfe/trunk/lib/Lex/PPDirectives.cpp (original) > +++ cfe/trunk/lib/Lex/PPDirectives.cpp Thu Jan 4 18:33:18 2018 > @@ -1655,12 +1655,18 @@ bool Preprocessor::checkModuleIsAvailabl > DiagnosticsEngine &Diags, > Module *M) { > Module::Requirement Requirement; > Module::UnresolvedHeaderDirective MissingHeader; > - if (M->isAvailable(LangOpts, TargetInfo, Requirement, MissingHeader)) > + Module *ShadowingModule = nullptr; > + if (M->isAvailable(LangOpts, TargetInfo, Requirement, MissingHeader, > + ShadowingModule)) > return false; > > if (MissingHeader.FileNameLoc.isValid()) { > Diags.Report(MissingHeader.FileNameLoc, diag::err_module_header_ > missing) > << MissingHeader.IsUmbrella << MissingHeader.FileName; > + } else if (ShadowingModule) { > + Diags.Report(M->DefinitionLoc, diag::err_module_shadowed) << M->Name; > + Diags.Report(ShadowingModule->DefinitionLoc, > + diag::note_previous_definition); > } else { > // FIXME: Track the location at which the requirement was specified, > and > // use it here. > @@ -2024,6 +2030,15 @@ void Preprocessor::HandleIncludeDirectiv > > // Determine if we're switching to building a new submodule, and which > one. > if (auto *M = SuggestedModule.getModule()) { > + if (M->getTopLevelModule()->ShadowingModule) { > + // We are building a submodule that belongs to a shadowed module. > This > + // means we find header files in the shadowed module. > + Diag(M->DefinitionLoc, diag::err_module_build_shadowed_submodule) > + << M->getFullModuleName(); > + Diag(M->getTopLevelModule()->ShadowingModule->DefinitionLoc, > + diag::note_previous_definition); > + return; > + } > // When building a pch, -fmodule-name tells the compiler to textually > // include headers in the specified module. We are not building the > // specified module. > > Added: cfe/trunk/test/Modules/Inputs/shadow/A1/A.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ > Modules/Inputs/shadow/A1/A.h?rev=321855&view=auto > ============================================================ > ================== > --- cfe/trunk/test/Modules/Inputs/shadow/A1/A.h (added) > +++ cfe/trunk/test/Modules/Inputs/shadow/A1/A.h Thu Jan 4 18:33:18 2018 > @@ -0,0 +1 @@ > +#define A1_A_h > > Added: cfe/trunk/test/Modules/Inputs/shadow/A1/module.modulemap > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ > Modules/Inputs/shadow/A1/module.modulemap?rev=321855&view=auto > ============================================================ > ================== > --- cfe/trunk/test/Modules/Inputs/shadow/A1/module.modulemap (added) > +++ cfe/trunk/test/Modules/Inputs/shadow/A1/module.modulemap Thu Jan 4 > 18:33:18 2018 > @@ -0,0 +1,5 @@ > +module A { > + header "A.h" > +} > + > +module A1 {} > > Added: cfe/trunk/test/Modules/Inputs/shadow/A2/A.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ > Modules/Inputs/shadow/A2/A.h?rev=321855&view=auto > ============================================================ > ================== > --- cfe/trunk/test/Modules/Inputs/shadow/A2/A.h (added) > +++ cfe/trunk/test/Modules/Inputs/shadow/A2/A.h Thu Jan 4 18:33:18 2018 > @@ -0,0 +1 @@ > +#define A2_A_h > > Added: cfe/trunk/test/Modules/Inputs/shadow/A2/module.modulemap > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ > Modules/Inputs/shadow/A2/module.modulemap?rev=321855&view=auto > ============================================================ > ================== > --- cfe/trunk/test/Modules/Inputs/shadow/A2/module.modulemap (added) > +++ cfe/trunk/test/Modules/Inputs/shadow/A2/module.modulemap Thu Jan 4 > 18:33:18 2018 > @@ -0,0 +1,5 @@ > +module A { > + header "A.h" > +} > + > +module A2 {} > > Added: cfe/trunk/test/Modules/Inputs/shadowed-submodule/A1/Foo.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ > Modules/Inputs/shadowed-submodule/A1/Foo.h?rev=321855&view=auto > ============================================================ > ================== > --- cfe/trunk/test/Modules/Inputs/shadowed-submodule/A1/Foo.h (added) > +++ cfe/trunk/test/Modules/Inputs/shadowed-submodule/A1/Foo.h Thu Jan 4 > 18:33:18 2018 > @@ -0,0 +1 @@ > +#include <stdarg.h> // expected-error {{could not build module 'A'}} > > Added: cfe/trunk/test/Modules/Inputs/shadowed-submodule/A1/module. > modulemap > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ > Modules/Inputs/shadowed-submodule/A1/module.modulemap?rev=321855&view=auto > ============================================================ > ================== > --- cfe/trunk/test/Modules/Inputs/shadowed-submodule/A1/module.modulemap > (added) > +++ cfe/trunk/test/Modules/Inputs/shadowed-submodule/A1/module.modulemap > Thu Jan 4 18:33:18 2018 > @@ -0,0 +1,14 @@ > +module A [system] { // expected-note {{previous definition is here}} > + module sub { > + header "sys/A.h" > + } > + module sub2 { > + header "sys/A2.h" > + } > + module stdarg { > + header "stdarg.h" > + export * > + } > +} > + > +module A2 {} > > Added: cfe/trunk/test/Modules/Inputs/shadowed-submodule/A1/sys/A.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ > Modules/Inputs/shadowed-submodule/A1/sys/A.h?rev=321855&view=auto > ============================================================ > ================== > --- cfe/trunk/test/Modules/Inputs/shadowed-submodule/A1/sys/A.h (added) > +++ cfe/trunk/test/Modules/Inputs/shadowed-submodule/A1/sys/A.h Thu Jan > 4 18:33:18 2018 > @@ -0,0 +1 @@ > +#include <sys/A2.h> > > Added: cfe/trunk/test/Modules/Inputs/shadowed-submodule/A1/sys/A2.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ > Modules/Inputs/shadowed-submodule/A1/sys/A2.h?rev=321855&view=auto > ============================================================ > ================== > --- cfe/trunk/test/Modules/Inputs/shadowed-submodule/A1/sys/A2.h (added) > +++ cfe/trunk/test/Modules/Inputs/shadowed-submodule/A1/sys/A2.h Thu Jan > 4 18:33:18 2018 > @@ -0,0 +1 @@ > +// nothing > > Added: cfe/trunk/test/Modules/Inputs/shadowed-submodule/A2/Foo.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ > Modules/Inputs/shadowed-submodule/A2/Foo.h?rev=321855&view=auto > ============================================================ > ================== > --- cfe/trunk/test/Modules/Inputs/shadowed-submodule/A2/Foo.h (added) > +++ cfe/trunk/test/Modules/Inputs/shadowed-submodule/A2/Foo.h Thu Jan 4 > 18:33:18 2018 > @@ -0,0 +1 @@ > +#include <stdarg.h> > > Added: cfe/trunk/test/Modules/Inputs/shadowed-submodule/A2/module. > modulemap > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ > Modules/Inputs/shadowed-submodule/A2/module.modulemap?rev=321855&view=auto > ============================================================ > ================== > --- cfe/trunk/test/Modules/Inputs/shadowed-submodule/A2/module.modulemap > (added) > +++ cfe/trunk/test/Modules/Inputs/shadowed-submodule/A2/module.modulemap > Thu Jan 4 18:33:18 2018 > @@ -0,0 +1,14 @@ > +module A [system] { > + module sub { > + header "sys/A.h" > + } > + module sub2 { // expected-error {{build a shadowed submodule 'A.sub2'}} > + header "sys/A2.h" > + } > + module stdarg { > + header "stdarg.h" > + export * > + } > +} > + > +module A2 {} > > Added: cfe/trunk/test/Modules/Inputs/shadowed-submodule/A2/sys/A.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ > Modules/Inputs/shadowed-submodule/A2/sys/A.h?rev=321855&view=auto > ============================================================ > ================== > --- cfe/trunk/test/Modules/Inputs/shadowed-submodule/A2/sys/A.h (added) > +++ cfe/trunk/test/Modules/Inputs/shadowed-submodule/A2/sys/A.h Thu Jan > 4 18:33:18 2018 > @@ -0,0 +1 @@ > +#include <sys/A2.h> > > Added: cfe/trunk/test/Modules/Inputs/shadowed-submodule/A2/sys/A2.h > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ > Modules/Inputs/shadowed-submodule/A2/sys/A2.h?rev=321855&view=auto > ============================================================ > ================== > --- cfe/trunk/test/Modules/Inputs/shadowed-submodule/A2/sys/A2.h (added) > +++ cfe/trunk/test/Modules/Inputs/shadowed-submodule/A2/sys/A2.h Thu Jan > 4 18:33:18 2018 > @@ -0,0 +1 @@ > +// nothing > > Added: cfe/trunk/test/Modules/Inputs/shadowed-submodule/Foo/module. > modulemap > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ > Modules/Inputs/shadowed-submodule/Foo/module. > modulemap?rev=321855&view=auto > ============================================================ > ================== > --- cfe/trunk/test/Modules/Inputs/shadowed-submodule/Foo/module.modulemap > (added) > +++ cfe/trunk/test/Modules/Inputs/shadowed-submodule/Foo/module.modulemap > Thu Jan 4 18:33:18 2018 > @@ -0,0 +1,3 @@ > +module Foo { > + header "../A1/Foo.h" > +} > > Added: cfe/trunk/test/Modules/shadow.m > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ > Modules/shadow.m?rev=321855&view=auto > ============================================================ > ================== > --- cfe/trunk/test/Modules/shadow.m (added) > +++ cfe/trunk/test/Modules/shadow.m Thu Jan 4 18:33:18 2018 > @@ -0,0 +1,21 @@ > +// RUN: rm -rf %t > +// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps > -fmodules-cache-path=%t -I %S/Inputs/shadow/A1 -I %S/Inputs/shadow/A2 %s > -fsyntax-only 2>&1 | FileCheck %s -check-prefix=REDEFINITION > +// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps > -fmodules-cache-path=%t -fmodule-map-file=%S/Inputs/shadow/A1/module.modulemap > -fmodule-map-file=%S/Inputs/shadow/A2/module.modulemap %s -fsyntax-only > 2>&1 | FileCheck %s -check-prefix=REDEFINITION > +// REDEFINITION: error: redefinition of module 'A' > +// REDEFINITION: note: previously defined > + > +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps > -fmodules-cache-path=%t -fmodule-map-file=%S/Inputs/shadow/A1/module.modulemap > -I %S/Inputs/shadow %s -verify > + > +@import A1; > +@import A2; > +@import A; > + > +#import "A2/A.h" // expected-note {{implicitly imported}} > +// expected-error@A2/module.modulemap:1 {{import of shadowed module 'A'}} > +// expected-note@A1/module.modulemap:1 {{previous definition}} > + > +#if defined(A2_A_h) > +#error got the wrong definition of module A > +#elif !defined(A1_A_h) > +#error missing definition from A1 > +#endif > > Added: cfe/trunk/test/Modules/shadowed-submodule.m > URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ > Modules/shadowed-submodule.m?rev=321855&view=auto > ============================================================ > ================== > --- cfe/trunk/test/Modules/shadowed-submodule.m (added) > +++ cfe/trunk/test/Modules/shadowed-submodule.m Thu Jan 4 18:33:18 2018 > @@ -0,0 +1,5 @@ > +// RUN: rm -rf %t > +// RUN: %clang_cc1 -fmodules -fimplicit-module-maps > -fmodules-cache-path=%t -I %S/Inputs/shadowed-submodule/Foo -I > %S/Inputs/shadowed-submodule/A2 %s -verify > + > +@import Foo; // expected-error {{module 'A' was built in directory}} > + // expected-note@shadowed-submodule.m:4 {{imported by > module 'Foo'}} > > > _______________________________________________ > cfe-commits mailing list > cfe-commits@lists.llvm.org > http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits >
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits