andrewjcg updated this revision to Diff 163621.
andrewjcg added a comment.

fix umbrella writing


Repository:
  rC Clang

https://reviews.llvm.org/D51568

Files:
  include/clang/Driver/CC1Options.td
  include/clang/Lex/HeaderSearchOptions.h
  lib/Frontend/CompilerInvocation.cpp
  lib/Serialization/ASTWriter.cpp
  test/Modules/relocatable-modules.modulemap

Index: test/Modules/relocatable-modules.modulemap
===================================================================
--- /dev/null
+++ test/Modules/relocatable-modules.modulemap
@@ -0,0 +1,29 @@
+// Build two otherwise identical modules in two different directories and
+// verify that using `-fdisable-module-directory` makes them identical.
+//
+// RUN: rm -rf %t
+//
+// RUN: mkdir -p %t/p1
+// RUN: cd %t/p1
+// RUN: mkdir -p main other
+// RUN: grep "<AM>" %s > main/a.modulemap
+// RUN: grep "<AH>" %s > main/a.h
+// RUN: grep "<BH>" %s > other/b.h
+// RUN: %clang_cc1 -x c++ -fmodules -emit-module -fdisable-module-directory \
+// RUN:   -fmodule-name="a" -Imain -I. -o - main/a.modulemap > a.pcm
+//
+// RUN: mkdir -p %t/p2
+// RUN: cd %t/p2
+// RUN: mkdir -p main other
+// RUN: grep "<AM>" %s > main/a.modulemap
+// RUN: grep "<AH>" %s > main/a.h
+// RUN: grep "<BH>" %s > other/b.h
+// RUN: %clang_cc1 -x c++ -fmodules -emit-module -fdisable-module-directory \
+// RUN:   -fmodule-name="a" -Imain -I. -o - main/a.modulemap > a.pcm
+//
+// RUN: diff %t/p1/a.pcm %t/p2/a.pcm
+
+module "a" {                // <AM>
+}                           // <AM>
+
+#include "b.h"              // <AH>
Index: lib/Serialization/ASTWriter.cpp
===================================================================
--- lib/Serialization/ASTWriter.cpp
+++ lib/Serialization/ASTWriter.cpp
@@ -1339,9 +1339,14 @@
 ///
 /// \return \c true if the path was changed.
 static bool cleanPathForOutput(FileManager &FileMgr,
-                               SmallVectorImpl<char> &Path) {
-  bool Changed = FileMgr.makeAbsolutePath(Path);
-  return Changed | llvm::sys::path::remove_dots(Path);
+                               SmallVectorImpl<char> &Path,
+                               bool MakeAbsolute = true) {
+  bool Changed = false;
+  if (MakeAbsolute) {
+    Changed |= FileMgr.makeAbsolutePath(Path);
+  }
+  Changed |= llvm::sys::path::remove_dots(Path);
+  return Changed;
 }
 
 /// Adjusts the given filename to only write out the portion of the
@@ -1503,7 +1508,11 @@
     Stream.EmitRecordWithBlob(AbbrevCode, Record, WritingModule->Name);
   }
 
-  if (WritingModule && WritingModule->Directory) {
+  if (WritingModule &&
+      WritingModule->Directory &&
+      !PP.getHeaderSearchInfo()
+          .getHeaderSearchOpts()
+          .DisableModuleDirectory) {
     SmallString<128> BaseDir(WritingModule->Directory->getName());
     cleanPathForOutput(Context.getSourceManager().getFileManager(), BaseDir);
 
@@ -2952,12 +2961,26 @@
     // Emit the umbrella header, if there is one.
     if (auto UmbrellaHeader = Mod->getUmbrellaHeader()) {
       RecordData::value_type Record[] = {SUBMODULE_UMBRELLA_HEADER};
-      Stream.EmitRecordWithBlob(UmbrellaAbbrev, Record,
-                                UmbrellaHeader.NameAsWritten);
+      SmallString<128> Buffer;
+      if (PP->getHeaderSearchInfo()
+              .getHeaderSearchOpts()
+              .DisableModuleDirectory) {
+        llvm::sys::path::append(Buffer, Mod->Directory->getName());
+      }
+      llvm::sys::path::append(Buffer, UmbrellaHeader.NameAsWritten);
+      llvm::sys::path::remove_dots(Buffer);
+      Stream.EmitRecordWithBlob(UmbrellaAbbrev, Record, Buffer);
     } else if (auto UmbrellaDir = Mod->getUmbrellaDir()) {
       RecordData::value_type Record[] = {SUBMODULE_UMBRELLA_DIR};
-      Stream.EmitRecordWithBlob(UmbrellaDirAbbrev, Record,
-                                UmbrellaDir.NameAsWritten);
+      SmallString<128> Buffer;
+      if (PP->getHeaderSearchInfo()
+              .getHeaderSearchOpts()
+              .DisableModuleDirectory) {
+        llvm::sys::path::append(Buffer, Mod->Directory->getName());
+      }
+      llvm::sys::path::append(Buffer, UmbrellaDir.NameAsWritten);
+      llvm::sys::path::remove_dots(Buffer);
+      Stream.EmitRecordWithBlob(UmbrellaDirAbbrev, Record, Buffer);
     }
 
     // Emit the headers.
@@ -4515,7 +4538,11 @@
   assert(Context && "should have context when outputting path");
 
   bool Changed =
-      cleanPathForOutput(Context->getSourceManager().getFileManager(), Path);
+      cleanPathForOutput(Context->getSourceManager().getFileManager(),
+                         Path,
+                         !PP->getHeaderSearchInfo()
+                             .getHeaderSearchOpts()
+                             .DisableModuleDirectory);
 
   // Remove a prefix to make the path relative, if relevant.
   const char *PathBegin = Path.data();
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -1746,6 +1746,7 @@
     Opts.AddPrebuiltModulePath(A->getValue());
   Opts.DisableModuleHash = Args.hasArg(OPT_fdisable_module_hash);
   Opts.ModulesHashContent = Args.hasArg(OPT_fmodules_hash_content);
+  Opts.DisableModuleDirectory = Args.hasArg(OPT_fdisable_module_directory);
   Opts.ModulesValidateDiagnosticOptions =
       !Args.hasArg(OPT_fmodules_disable_diagnostic_validation);
   Opts.ImplicitModuleMaps = Args.hasArg(OPT_fimplicit_module_maps);
Index: include/clang/Lex/HeaderSearchOptions.h
===================================================================
--- include/clang/Lex/HeaderSearchOptions.h
+++ include/clang/Lex/HeaderSearchOptions.h
@@ -203,14 +203,19 @@
 
   unsigned ModulesHashContent : 1;
 
+  /// Do not relativize paths to the module directory or absolutify non-module-
+  /// directory-relative paths.
+  unsigned DisableModuleDirectory : 1;
+
   HeaderSearchOptions(StringRef _Sysroot = "/")
       : Sysroot(_Sysroot), ModuleFormat("raw"), DisableModuleHash(false),
         ImplicitModuleMaps(false), ModuleMapFileHomeIsCwd(false),
         UseBuiltinIncludes(true), UseStandardSystemIncludes(true),
         UseStandardCXXIncludes(true), UseLibcxx(false), Verbose(false),
         ModulesValidateOncePerBuildSession(false),
         ModulesValidateSystemHeaders(false), UseDebugInfo(false),
-        ModulesValidateDiagnosticOptions(true), ModulesHashContent(false) {}
+        ModulesValidateDiagnosticOptions(true), ModulesHashContent(false),
+        DisableModuleDirectory(true) {}
 
   /// AddPath - Add the \p Path path to the specified \p Group list.
   void AddPath(StringRef Path, frontend::IncludeDirGroup Group,
Index: include/clang/Driver/CC1Options.td
===================================================================
--- include/clang/Driver/CC1Options.td
+++ include/clang/Driver/CC1Options.td
@@ -751,6 +751,9 @@
   HelpText<"Disable the module hash">;
 def fmodules_hash_content : Flag<["-"], "fmodules-hash-content">,
   HelpText<"Enable hashing the content of a module file">;
+def fdisable_module_directory : Flag<["-"], "fdisable-module-directory">,
+  HelpText<"Do not relativize paths to the module home directory or absolutify "
+           "paths that are not relative to the module home directory.">;
 def c_isystem : JoinedOrSeparate<["-"], "c-isystem">, MetaVarName<"<directory>">,
   HelpText<"Add directory to the C SYSTEM include search path">;
 def objc_isystem : JoinedOrSeparate<["-"], "objc-isystem">,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to