From: Daniel Jasper Date: Tue, 24 Sep 2013 09:27:13 +0000 (+0000) Subject: Add -fmodule-map-file option. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1b8840ce0d7a3383915b29dc3779dfadec817458;p=clang Add -fmodule-map-file option. With this option, arbitrarily named module map files can be specified to be loaded as required for headers in the respective (sub)directories. This, together with the extern module declaration allows for specifying module maps in a modular fashion without the need for files called "module.map". Among other things, this allows a directory to contain two modules that are completely independent of one another. Review: http://llvm-reviews.chandlerc.com/D1697. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@191284 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/docs/Modules.rst b/docs/Modules.rst index 02393d7ba9..912cdafc8c 100644 --- a/docs/Modules.rst +++ b/docs/Modules.rst @@ -194,6 +194,9 @@ Command-line parameters ``-fmodule-name=module-id`` Consider a source file as a part of the given module. +``-fmodule-map-file=`` + Load the given module map file if a header from its directory or one of its subdirectories is loaded. + Module Map Language =================== diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index d5a8b775d7..1b96ef38c1 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -483,9 +483,12 @@ def fno_deprecated_macro : Flag<["-"], "fno-deprecated-macro">, def nostdsysteminc : Flag<["-"], "nostdsysteminc">, HelpText<"Disable standard system #include directories">; -def fmodule_name : Joined<["-"], "fmodule-name=">, +def fmodule_name : Joined<["-"], "fmodule-name=">, MetaVarName<"">, - HelpText<"Specify the name of the module to build">; + HelpText<"Specify the name of the module to build">; +def fmodule_map_file : Joined<["-"], "fmodule-map-file=">, + MetaVarName<"">, + HelpText<"Load this module map file">; def fdisable_module_hash : Flag<["-"], "fdisable-module-hash">, HelpText<"Disable the module hash">; def c_isystem : JoinedOrSeparate<["-"], "c-isystem">, MetaVarName<"">, diff --git a/include/clang/Lex/HeaderSearchOptions.h b/include/clang/Lex/HeaderSearchOptions.h index 830f48dce8..0b21c0dd34 100644 --- a/include/clang/Lex/HeaderSearchOptions.h +++ b/include/clang/Lex/HeaderSearchOptions.h @@ -120,6 +120,9 @@ public: /// of computing the module hash. llvm::SetVector ModulesIgnoreMacros; + /// \brief The set of user-provided module-map-files. + llvm::SetVector ModuleMapFiles; + /// Include the compiler builtin includes. unsigned UseBuiltinIncludes : 1; diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index c8c676899c..afba109453 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -896,6 +896,9 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) { StringRef MacroDef = (*it)->getValue(); Opts.ModulesIgnoreMacros.insert(MacroDef.split('=').first); } + std::vector ModuleMapFiles = + Args.getAllArgValues(OPT_fmodule_map_file); + Opts.ModuleMapFiles.insert(ModuleMapFiles.begin(), ModuleMapFiles.end()); // Add -I..., -F..., and -index-header-map options in order. bool IsIndexHeaderMap = false; diff --git a/lib/Lex/HeaderSearch.cpp b/lib/Lex/HeaderSearch.cpp index ec84bb16d6..5bcc4ea044 100644 --- a/lib/Lex/HeaderSearch.cpp +++ b/lib/Lex/HeaderSearch.cpp @@ -941,26 +941,48 @@ bool HeaderSearch::hasModuleMap(StringRef FileName, DirName = llvm::sys::path::parent_path(DirName); if (DirName.empty()) return false; - + // Determine whether this directory exists. const DirectoryEntry *Dir = FileMgr.getDirectory(DirName); if (!Dir) return false; - // Try to load the module map file in this directory. + // Load user-specified module map files in 'Dir'. + bool ModuleMapFound = false; + for (llvm::SetVector::iterator + I = HSOpts->ModuleMapFiles.begin(), + E = HSOpts->ModuleMapFiles.end(); + I != E; ++I) { + StringRef ModuleMapFileDir = llvm::sys::path::parent_path(*I); + if (!llvm::sys::fs::equivalent(ModuleMapFileDir, DirName)) + continue; + + const FileEntry *File = FileMgr.getFile(*I); + if (!File) + continue; + + loadModuleMapFile(File, /*IsSystem=*/false); + ModuleMapFound = true; + } + + // Try to load the "module.map" file in this directory. switch (loadModuleMapFile(Dir, IsSystem)) { case LMM_NewlyLoaded: case LMM_AlreadyLoaded: + ModuleMapFound = true; + break; + + case LMM_NoDirectory: + case LMM_InvalidModuleMap: + break; + } + + if (ModuleMapFound) { // Success. All of the directories we stepped through inherit this module // map file. for (unsigned I = 0, N = FixUpDirectories.size(); I != N; ++I) DirectoryHasModuleMap[FixUpDirectories[I]] = true; - return true; - - case LMM_NoDirectory: - case LMM_InvalidModuleMap: - break; } // If we hit the top of our search, we're done. diff --git a/test/Modules/Inputs/modular_maps/module.map b/test/Modules/Inputs/modular_maps/modulea.map similarity index 100% rename from test/Modules/Inputs/modular_maps/module.map rename to test/Modules/Inputs/modular_maps/modulea.map diff --git a/test/Modules/modular_maps.cpp b/test/Modules/modular_maps.cpp index c521fb28f7..5070f7d5bf 100644 --- a/test/Modules/modular_maps.cpp +++ b/test/Modules/modular_maps.cpp @@ -1,5 +1,5 @@ // RUN: rm -rf %t -// RUN: %clang_cc1 -x objective-c++ -fmodules-cache-path=%t -fmodules -I %S/Inputs/modular_maps %s -verify +// RUN: %clang_cc1 -x objective-c++ -fmodules-cache-path=%t -fmodules -fmodule-map-file=%S/Inputs/modular_maps/modulea.map -I %S/Inputs/modular_maps %s -verify #include "a.h" #include "b.h" // expected-error {{private header}}