r321855 - Reapply r321781: [Modules] Allow modules specified by -fmodule-map-file to shadow implicitly found ones
Eric Fiselier via cfe-commits
cfe-commits at lists.llvm.org
Mon Jan 8 21:31:05 PST 2018
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 at 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
> +
> + at import A1;
> + at import A2;
> + at import A;
> +
> +#import "A2/A.h" // expected-note {{implicitly imported}}
> +// expected-error at A2/module.modulemap:1 {{import of shadowed module 'A'}}
> +// expected-note at 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
> +
> + at import Foo; // expected-error {{module 'A' was built in directory}}
> + // expected-note at shadowed-submodule.m:4 {{imported by
> module 'Foo'}}
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180108/6daa08d3/attachment-0001.html>
More information about the cfe-commits
mailing list