]> granicus.if.org Git - clang/commitdiff
Add -fmodule-map-file option.
authorDaniel Jasper <djasper@google.com>
Tue, 24 Sep 2013 09:27:13 +0000 (09:27 +0000)
committerDaniel Jasper <djasper@google.com>
Tue, 24 Sep 2013 09:27:13 +0000 (09:27 +0000)
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

docs/Modules.rst
include/clang/Driver/CC1Options.td
include/clang/Lex/HeaderSearchOptions.h
lib/Frontend/CompilerInvocation.cpp
lib/Lex/HeaderSearch.cpp
test/Modules/Inputs/modular_maps/modulea.map [moved from test/Modules/Inputs/modular_maps/module.map with 100% similarity]
test/Modules/modular_maps.cpp

index 02393d7ba9f6997d67464d4f838fe20dfb53ceb7..912cdafc8c37f791b68843fb59d081b32e70d7d0 100644 (file)
@@ -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=<file>``
+  Load the given module map file if a header from its directory or one of its subdirectories is loaded.
+
 Module Map Language
 ===================
 
index d5a8b775d74bce4903a0c4198bf68639a384cbcd..1b96ef38c10175b698eecaf57ca5c982fdec0a38 100644 (file)
@@ -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<"<name>">,
-  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<"<file>">,
+  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<"<directory>">,
index 830f48dce8b566e1481791fc81b8c31bddf4031f..0b21c0dd34922d2d3aca13805a93328a030cf286 100644 (file)
@@ -120,6 +120,9 @@ public:
   /// of computing the module hash.
   llvm::SetVector<std::string> ModulesIgnoreMacros;
 
+  /// \brief The set of user-provided module-map-files.
+  llvm::SetVector<std::string> ModuleMapFiles;
+
   /// Include the compiler builtin includes.
   unsigned UseBuiltinIncludes : 1;
 
index c8c676899c57d7f300cc74c6bfe8893d97154f04..afba109453d3268f46b277a0c29f6cea37ee95d2 100644 (file)
@@ -896,6 +896,9 @@ static void ParseHeaderSearchArgs(HeaderSearchOptions &Opts, ArgList &Args) {
     StringRef MacroDef = (*it)->getValue();
     Opts.ModulesIgnoreMacros.insert(MacroDef.split('=').first);
   }
+  std::vector<std::string> 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;
index ec84bb16d60608865aee4607b43a768dcaad0420..5bcc4ea044159d48c22f13b2294e21ebfb44bf2f 100644 (file)
@@ -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<std::string>::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.
index c521fb28f7274763dc7bdadba6809b5c51c7a690..5070f7d5bf95da02ecbbaac1bd10ea8843d837ef 100644 (file)
@@ -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}}