From 4acb6a7747b2631f77c82abcef5e1384222a4adb Mon Sep 17 00:00:00 2001 From: Daniel Jasper Date: Tue, 25 Nov 2014 09:45:48 +0000 Subject: [PATCH] Add flag -f(no-)modules-implicit-maps. This suppresses the implicit search for files called 'module.modulemap' and similar. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@222745 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/Modules.rst | 3 + include/clang/Basic/LangOptions.def | 1 + include/clang/Driver/Options.td | 6 ++ include/clang/Lex/HeaderSearch.h | 4 +- lib/Frontend/CompilerInvocation.cpp | 2 + lib/Lex/HeaderSearch.cpp | 102 ++++++++++++++++------------ test/Modules/no-implicit-maps.cpp | 3 + 7 files changed, 75 insertions(+), 46 deletions(-) create mode 100644 test/Modules/no-implicit-maps.cpp diff --git a/docs/Modules.rst b/docs/Modules.rst index df471a45fb..1575ce6964 100644 --- a/docs/Modules.rst +++ b/docs/Modules.rst @@ -207,6 +207,9 @@ Command-line parameters ``-fmodules-search-all`` If a symbol is not found, search modules referenced in the current module maps but not imported for symbols, so the error message can reference the module by name. Note that if the global module index has not been built before, this might take some time as it needs to build all the modules. Note that this option doesn't apply in module builds, to avoid the recursion. +``-fno-modules-implicit-maps`` + Suppresses the implicit search for files called ``module.modulemap`` and similar. Instead, module files need to be explicitly specified via ``-fmodule-map-file`` or transitively used. + Module Semantics ================ diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def index 8fbfe96616..2c02d2aa7b 100644 --- a/include/clang/Basic/LangOptions.def +++ b/include/clang/Basic/LangOptions.def @@ -126,6 +126,7 @@ LANGOPT(ModulesDeclUse , 1, 0, "require declaration of module uses") LANGOPT(ModulesSearchAll , 1, 1, "search even non-imported modules to find unresolved references") LANGOPT(ModulesStrictDeclUse, 1, 0, "require declaration of module uses and all headers to be in modules") LANGOPT(ModulesErrorRecovery, 1, 1, "automatically import modules as needed when performing error recovery") +BENIGN_LANGOPT(ModulesImplicitMaps, 1, 1, "use files called module.modulemap implicitly as module maps") COMPATIBLE_LANGOPT(Optimize , 1, 0, "__OPTIMIZE__ predefined macro") COMPATIBLE_LANGOPT(OptimizeSize , 1, 0, "__OPTIMIZE_SIZE__ predefined macro") LANGOPT(Static , 1, 0, "__STATIC__ predefined macro (as opposed to __DYNAMIC__)") diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index 8b4aba4ebd..acf9acc2bd 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -675,6 +675,12 @@ def fmodules_strict_decluse : Flag <["-"], "fmodules-strict-decluse">, Group; def fno_modules_search_all : Flag <["-"], "fno-modules-search-all">, Group, Flags<[DriverOption, CC1Option]>; +def fmodules_implicit_maps : + Flag <["-"], "fmodules-implicit-maps">, + Group, Flags<[DriverOption, CC1Option]>; +def fno_modules_implicit_maps : + Flag <["-"], "fno-modules-implicit-maps">, + Group, Flags<[DriverOption, CC1Option]>; def fretain_comments_from_system_headers : Flag<["-"], "fretain-comments-from-system-headers">, Group, Flags<[CC1Option]>; def fmudflapth : Flag<["-"], "fmudflapth">, Group; diff --git a/include/clang/Lex/HeaderSearch.h b/include/clang/Lex/HeaderSearch.h index 47e3313320..190a0c9833 100644 --- a/include/clang/Lex/HeaderSearch.h +++ b/include/clang/Lex/HeaderSearch.h @@ -252,7 +252,7 @@ class HeaderSearch { unsigned NumMultiIncludeFileOptzn; unsigned NumFrameworkLookups, NumSubFrameworkLookups; - bool EnabledModules; + const LangOptions &LangOpts; // HeaderSearch doesn't support default or copy construction. HeaderSearch(const HeaderSearch&) LLVM_DELETED_FUNCTION; @@ -479,7 +479,7 @@ public: const HeaderMap *CreateHeaderMap(const FileEntry *FE); /// Returns true if modules are enabled. - bool enabledModules() const { return EnabledModules; } + bool enabledModules() const { return LangOpts.Modules; } /// \brief Retrieve the name of the module file that should be used to /// load the given module. diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index f261c6c733..bdd0f42d61 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1465,6 +1465,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, !Args.hasArg(OPT_fno_modules_search_all) && Args.hasArg(OPT_fmodules_search_all); Opts.ModulesErrorRecovery = !Args.hasArg(OPT_fno_modules_error_recovery); + Opts.ModulesImplicitMaps = Args.hasFlag(OPT_fmodules_implicit_maps, + OPT_fno_modules_implicit_maps, true); Opts.CharIsSigned = Opts.OpenCL || !Args.hasArg(OPT_fno_signed_char); Opts.WChar = Opts.CPlusPlus && !Args.hasArg(OPT_fno_wchar); Opts.ShortWChar = Args.hasFlag(OPT_fshort_wchar, OPT_fno_short_wchar, false); diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp index 6345e75708..125fe260e1 100644 --- a/lib/Lex/HeaderSearch.cpp +++ b/lib/Lex/HeaderSearch.cpp @@ -50,7 +50,8 @@ HeaderSearch::HeaderSearch(IntrusiveRefCntPtr HSOpts, const LangOptions &LangOpts, const TargetInfo *Target) : HSOpts(HSOpts), Diags(Diags), FileMgr(SourceMgr.getFileManager()), - FrameworkMap(64), ModMap(SourceMgr, Diags, LangOpts, Target, *this) { + FrameworkMap(64), ModMap(SourceMgr, Diags, LangOpts, Target, *this), + LangOpts(LangOpts) { AngledDirIdx = 0; SystemDirIdx = 0; NoCurDirSearch = false; @@ -60,8 +61,6 @@ HeaderSearch::HeaderSearch(IntrusiveRefCntPtr HSOpts, NumIncluded = 0; NumMultiIncludeFileOptzn = 0; NumFrameworkLookups = NumSubFrameworkLookups = 0; - - EnabledModules = LangOpts.Modules; } HeaderSearch::~HeaderSearch() { @@ -149,7 +148,7 @@ std::string HeaderSearch::getModuleFileName(StringRef ModuleName, Module *HeaderSearch::lookupModule(StringRef ModuleName, bool AllowSearch) { // Look in the module map to determine if there is a module by this name. Module *Module = ModMap.findModule(ModuleName); - if (Module || !AllowSearch) + if (Module || !AllowSearch || !LangOpts.ModulesImplicitMaps) return Module; // Look through the various header search paths to load any available module @@ -1062,7 +1061,7 @@ StringRef HeaderSearch::getUniqueFrameworkName(StringRef Framework) { bool HeaderSearch::hasModuleMap(StringRef FileName, const DirectoryEntry *Root, bool IsSystem) { - if (!enabledModules()) + if (!enabledModules() || !LangOpts.ModulesImplicitMaps) return false; SmallVector FixUpDirectories; @@ -1170,6 +1169,8 @@ HeaderSearch::loadModuleMapFileImpl(const FileEntry *File, bool IsSystem) { const FileEntry * HeaderSearch::lookupModuleMapFile(const DirectoryEntry *Dir, bool IsFramework) { + if (!LangOpts.ModulesImplicitMaps) + return nullptr; // For frameworks, the preferred spelling is Modules/module.modulemap, but // module.map at the framework root is also accepted. SmallString<128> ModuleMapFileName(Dir->getName()); @@ -1190,12 +1191,12 @@ Module *HeaderSearch::loadFrameworkModule(StringRef Name, bool IsSystem) { if (Module *Module = ModMap.findModule(Name)) return Module; - + // Try to load a module map file. switch (loadModuleMapFile(Dir, IsSystem, /*IsFramework*/true)) { case LMM_InvalidModuleMap: break; - + case LMM_AlreadyLoaded: case LMM_NoDirectory: return nullptr; @@ -1206,7 +1207,10 @@ Module *HeaderSearch::loadFrameworkModule(StringRef Name, // Try to infer a module map from the framework directory. - return ModMap.inferFrameworkModule(Name, Dir, IsSystem, /*Parent=*/nullptr); + if (LangOpts.ModulesImplicitMaps) + return ModMap.inferFrameworkModule(Name, Dir, IsSystem, /*Parent=*/nullptr); + + return nullptr; } @@ -1242,45 +1246,49 @@ HeaderSearch::loadModuleMapFile(const DirectoryEntry *Dir, bool IsSystem, void HeaderSearch::collectAllModules(SmallVectorImpl &Modules) { Modules.clear(); - - // Load module maps for each of the header search directories. - for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { - bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory(); - if (SearchDirs[Idx].isFramework()) { - std::error_code EC; - SmallString<128> DirNative; - llvm::sys::path::native(SearchDirs[Idx].getFrameworkDir()->getName(), - DirNative); - - // Search each of the ".framework" directories to load them as modules. - for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd; - Dir != DirEnd && !EC; Dir.increment(EC)) { - if (llvm::sys::path::extension(Dir->path()) != ".framework") - continue; - - const DirectoryEntry *FrameworkDir = FileMgr.getDirectory(Dir->path()); - if (!FrameworkDir) - continue; - - // Load this framework module. - loadFrameworkModule(llvm::sys::path::stem(Dir->path()), FrameworkDir, - IsSystem); + + if (LangOpts.ModulesImplicitMaps) { + // Load module maps for each of the header search directories. + for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { + bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory(); + if (SearchDirs[Idx].isFramework()) { + std::error_code EC; + SmallString<128> DirNative; + llvm::sys::path::native(SearchDirs[Idx].getFrameworkDir()->getName(), + DirNative); + + // Search each of the ".framework" directories to load them as modules. + for (llvm::sys::fs::directory_iterator Dir(DirNative.str(), EC), DirEnd; + Dir != DirEnd && !EC; Dir.increment(EC)) { + if (llvm::sys::path::extension(Dir->path()) != ".framework") + continue; + + const DirectoryEntry *FrameworkDir = + FileMgr.getDirectory(Dir->path()); + if (!FrameworkDir) + continue; + + // Load this framework module. + loadFrameworkModule(llvm::sys::path::stem(Dir->path()), FrameworkDir, + IsSystem); + } + continue; } - continue; + + // FIXME: Deal with header maps. + if (SearchDirs[Idx].isHeaderMap()) + continue; + + // Try to load a module map file for the search directory. + loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem, + /*IsFramework*/ false); + + // Try to load module map files for immediate subdirectories of this + // search directory. + loadSubdirectoryModuleMaps(SearchDirs[Idx]); } - - // FIXME: Deal with header maps. - if (SearchDirs[Idx].isHeaderMap()) - continue; - - // Try to load a module map file for the search directory. - loadModuleMapFile(SearchDirs[Idx].getDir(), IsSystem, /*IsFramework*/false); - - // Try to load module map files for immediate subdirectories of this search - // directory. - loadSubdirectoryModuleMaps(SearchDirs[Idx]); } - + // Populate the list of modules. for (ModuleMap::module_iterator M = ModMap.module_begin(), MEnd = ModMap.module_end(); @@ -1290,6 +1298,9 @@ void HeaderSearch::collectAllModules(SmallVectorImpl &Modules) { } void HeaderSearch::loadTopLevelSystemModules() { + if (!LangOpts.ModulesImplicitMaps) + return; + // Load module maps for each of the header search directories. for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) { // We only care about normal header directories. @@ -1305,6 +1316,9 @@ void HeaderSearch::loadTopLevelSystemModules() { } void HeaderSearch::loadSubdirectoryModuleMaps(DirectoryLookup &SearchDir) { + assert(LangOpts.ModulesImplicitMaps && + "Should not be loading subdirectory module maps"); + if (SearchDir.haveSearchedAllModuleMaps()) return; diff --git a/test/Modules/no-implicit-maps.cpp b/test/Modules/no-implicit-maps.cpp new file mode 100644 index 0000000000..cb270a0501 --- /dev/null +++ b/test/Modules/no-implicit-maps.cpp @@ -0,0 +1,3 @@ +// RUN: rm -rf %t +// RUN: %clang_cc1 -x objective-c -fno-modules-implicit-maps -fmodules-cache-path=%t -fmodules -I %S/Inputs/private %s -verify +@import libPrivate1; // expected-error {{not found}} -- 2.40.0