[PATCH] Add -fmodule-map-file option.

Daniel Jasper djasper at google.com
Tue Sep 17 06:53:24 PDT 2013


Hi doug.gregor, rsmith, chandlerc,

With this options, 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.

http://llvm-reviews.chandlerc.com/D1697

Files:
  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/module.map
  test/Modules/Inputs/modular_maps/modulea.map
  test/Modules/modular_maps.cpp

Index: docs/Modules.rst
===================================================================
--- docs/Modules.rst
+++ docs/Modules.rst
@@ -188,6 +188,9 @@
 ``-module-file-info <module file name>``
   Debugging aid that prints information about a given module file (with a ``.pcm`` extension), including the language and preprocessor options that particular module variant was built with.
 
+``-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: include/clang/Driver/CC1Options.td
===================================================================
--- include/clang/Driver/CC1Options.td
+++ include/clang/Driver/CC1Options.td
@@ -483,9 +483,12 @@
 
 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: include/clang/Lex/HeaderSearchOptions.h
===================================================================
--- include/clang/Lex/HeaderSearchOptions.h
+++ include/clang/Lex/HeaderSearchOptions.h
@@ -120,6 +120,9 @@
   /// 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: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -893,6 +893,9 @@
     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: lib/Lex/HeaderSearch.cpp
===================================================================
--- lib/Lex/HeaderSearch.cpp
+++ lib/Lex/HeaderSearch.cpp
@@ -940,26 +940,48 @@
     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: test/Modules/Inputs/modular_maps/module.map
===================================================================
--- test/Modules/Inputs/modular_maps/module.map
+++ /dev/null
@@ -1,6 +0,0 @@
-module A {
-  header "a.h"
-}
-
-extern module B "moduleb.map"
-
Index: test/Modules/Inputs/modular_maps/modulea.map
===================================================================
--- /dev/null
+++ test/Modules/Inputs/modular_maps/modulea.map
@@ -0,0 +1,6 @@
+module A {
+  header "a.h"
+}
+
+extern module B "moduleb.map"
+
Index: test/Modules/modular_maps.cpp
===================================================================
--- test/Modules/modular_maps.cpp
+++ 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}}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1697.1.patch
Type: text/x-patch
Size: 5466 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20130917/f2ae7038/attachment.bin>


More information about the cfe-commits mailing list