<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Apr 14, 2014 at 11:00 AM, Ben Langmuir <span dir="ltr"><<a href="mailto:blangmuir@apple.com" target="_blank">blangmuir@apple.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: benlangmuir<br>
Date: Mon Apr 14 13:00:01 2014<br>
New Revision: 206201<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=206201&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=206201&view=rev</a><br>
Log:<br>
Allow multiple modules with the same name to coexist in the module cache<br>
<br>
To differentiate between two modules with the same name, we will<br>
consider the path the module map file that they are defined by* part of<br>
the ‘key’ for looking up the precompiled module (pcm file).<br>
Specifically, this patch renames the precompiled module (pcm) files from<br>
  cache-path/<module hash>/Foo.pcm<br>
to<br>
  cache-path/<module hash>/Foo-<hash of module map path>.pcm<br>
<br>
In addition, I’ve taught the ASTReader to re-resolve the names of<br>
imported modules during module loading so that if the header search<br>
context changes between when a module was originally built and when it<br>
is loaded we can rebuild it if necessary.  For example, if module A<br>
imports module B<br>
<br>
first time:<br>
clang -I /path/to/A -I /path/to/B ...<br>
<br>
second time:<br>
clang -I /path/to/A -I /different/path/to/B ...<br>
<br>
will now rebuild A as expected.<br>
<br>
* in the case of inferred modules, we use the module map file that<br>
allowed the inference, not the __inferred_module.map file, since the<br>
inferred file path is the same for every inferred module.<br>
<br>
Added:<br>
    cfe/trunk/test/Modules/Inputs/modules-with-same-name/<br>
    cfe/trunk/test/Modules/Inputs/modules-with-same-name/DependsOnA/<br>
    cfe/trunk/test/Modules/Inputs/modules-with-same-name/DependsOnA/DependsOnA.h<br>
    cfe/trunk/test/Modules/Inputs/modules-with-same-name/DependsOnA/module.modulemap<br>
    cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/<br>
    cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/A/<br>
    cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/A/a.h<br>
    cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/A/module.modulemap<br>
    cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/<br>
    cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/A/<br>
    cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/A/a.h<br>
    cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/A/module.modulemap<br>
    cfe/trunk/test/Modules/modules-with-same-name.m<br>
    cfe/trunk/test/Modules/resolution-change.m<br>
Modified:<br>
    cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td<br>
    cfe/trunk/include/clang/Basic/Module.h<br>
    cfe/trunk/include/clang/Frontend/FrontendActions.h<br>
    cfe/trunk/include/clang/Lex/HeaderSearch.h<br>
    cfe/trunk/include/clang/Lex/ModuleMap.h<br>
    cfe/trunk/include/clang/Serialization/ASTBitCodes.h<br>
    cfe/trunk/include/clang/Serialization/ASTReader.h<br>
    cfe/trunk/include/clang/Serialization/Module.h<br>
    cfe/trunk/lib/Basic/Module.cpp<br>
    cfe/trunk/lib/Frontend/CompilerInstance.cpp<br>
    cfe/trunk/lib/Frontend/FrontendAction.cpp<br>
    cfe/trunk/lib/Frontend/FrontendActions.cpp<br>
    cfe/trunk/lib/Lex/HeaderSearch.cpp<br>
    cfe/trunk/lib/Lex/ModuleMap.cpp<br>
    cfe/trunk/lib/Serialization/ASTReader.cpp<br>
    cfe/trunk/lib/Serialization/ASTWriter.cpp<br>
    cfe/trunk/lib/Serialization/GlobalModuleIndex.cpp<br>
    cfe/trunk/lib/Serialization/ModuleManager.cpp<br>
    cfe/trunk/test/Index/annotate-module.m<br>
    cfe/trunk/test/Index/pch-depending-on-deleted-module.c<br>
    cfe/trunk/test/Modules/dependency-gen-pch.m<br>
    cfe/trunk/test/Modules/diamond-pch.c<br>
    cfe/trunk/test/Modules/macro-undef-through-pch.m<br>
    cfe/trunk/test/Modules/prune.m<br>
    cfe/trunk/test/Modules/redecls/main.m<br>
    cfe/trunk/test/Modules/system_version.m<br>
    cfe/trunk/test/PCH/modified-module-dependency.m<br>
<br>
Modified: cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td (original)<br>
+++ cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td Mon Apr 14 13:00:01 2014<br>
@@ -48,7 +48,12 @@ def err_pch_different_branch : Error<<br>
     "PCH file built from a different branch (%0) than the compiler (%1)">;<br>
 def err_pch_with_compiler_errors : Error<<br>
     "PCH file contains compiler errors">;<br>
-<br>
+<br>
+def err_imported_module_not_found : Error<<br>
+    "module '%0' imported by AST file '%1' not found">, DefaultFatal;<br>
+def err_imported_module_modmap_changed : Error<<br>
+    "module '%0' imported by AST file '%1' found in a different module map file"<br>
+    " (%2) than when the importing AST file was built (%3)">, DefaultFatal;<br>
 def warn_module_conflict : Warning<<br>
     "module '%0' conflicts with already-imported module '%1': %2">,<br>
     InGroup<ModuleConflict>;<br>
<br>
Modified: cfe/trunk/include/clang/Basic/Module.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Module.h?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Module.h?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Basic/Module.h (original)<br>
+++ cfe/trunk/include/clang/Basic/Module.h Mon Apr 14 13:00:01 2014<br>
@@ -51,10 +51,21 @@ public:<br>
<br>
   /// \brief The location of the module definition.<br>
   SourceLocation DefinitionLoc;<br>
-<br>
+<br>
   /// \brief The parent of this module. This will be NULL for the top-level<br>
   /// module.<br>
   Module *Parent;<br>
+<br>
+  /// \brief The module map file that (along with the module name) uniquely<br>
+  /// identifies this module.<br>
+  ///<br>
+  /// The particular module that \c Name refers to may depend on how the module<br>
+  /// was found in header search. However, the combination of \c Name and<br>
+  /// \c ModuleMap will be globally unique for top-level modules. In the case of<br>
+  /// inferred modules, \c ModuleMap will contain the module map that allowed<br>
+  /// the inference (e.g. contained 'Module *') rather than the virtual<br>
+  /// inferred module map file.<br>
+  const FileEntry *ModuleMap;<br>
<br>
   /// \brief The umbrella header or directory.<br>
   llvm::PointerUnion<const DirectoryEntry *, const FileEntry *> Umbrella;<br>
@@ -264,8 +275,10 @@ public:<br>
   std::vector<Conflict> Conflicts;<br>
<br>
   /// \brief Construct a new module or submodule.<br>
-  Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,<br>
-         bool IsFramework, bool IsExplicit);<br>
+  ///<br>
+  /// For an explanation of \p ModuleMap, see Module::ModuleMap.<br>
+  Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,<br>
+         const FileEntry *ModuleMap, bool IsFramework, bool IsExplicit);<br>
<br>
   ~Module();<br>
<br>
<br>
Modified: cfe/trunk/include/clang/Frontend/FrontendActions.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/FrontendActions.h?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/FrontendActions.h?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Frontend/FrontendActions.h (original)<br>
+++ cfe/trunk/include/clang/Frontend/FrontendActions.h Mon Apr 14 13:00:01 2014<br>
@@ -17,6 +17,7 @@<br>
 namespace clang {<br>
<br>
 class Module;<br>
+class FileEntry;<br>
<br>
 //===----------------------------------------------------------------------===//<br>
 // Custom Consumer Actions<br>
@@ -92,7 +93,8 @@ public:<br>
 };<br>
<br>
 class GenerateModuleAction : public ASTFrontendAction {<br>
-  clang::Module *Module;<br>
+  Module *Module;<br>
+  const FileEntry *ModuleMapForUniquing;<br>
   bool IsSystem;<br>
<br>
 protected:<br>
@@ -106,8 +108,10 @@ protected:<br>
   bool hasASTFileSupport() const override { return false; }<br>
<br>
 public:<br>
-  explicit GenerateModuleAction(bool IsSystem = false)<br>
-    : ASTFrontendAction(), IsSystem(IsSystem) { }<br>
+  GenerateModuleAction(const FileEntry *ModuleMap = nullptr,<br>
+                       bool IsSystem = false)<br>
+    : ASTFrontendAction(), ModuleMapForUniquing(ModuleMap), IsSystem(IsSystem)<br>
+  { }<br>
<br>
   bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename) override;<br>
<br>
@@ -115,11 +119,11 @@ public:<br>
   /// create the PCHGenerator instance returned by CreateASTConsumer.<br>
   ///<br>
   /// \returns true if an error occurred, false otherwise.<br>
-  static bool ComputeASTConsumerArguments(CompilerInstance &CI,<br>
-                                          StringRef InFile,<br>
-                                          std::string &Sysroot,<br>
-                                          std::string &OutputFile,<br>
-                                          raw_ostream *&OS);<br>
+  bool ComputeASTConsumerArguments(CompilerInstance &CI,<br>
+                                   StringRef InFile,<br>
+                                   std::string &Sysroot,<br>
+                                   std::string &OutputFile,<br>
+                                   raw_ostream *&OS);<br>
 };<br>
<br>
 class SyntaxOnlyAction : public ASTFrontendAction {<br>
<br>
Modified: cfe/trunk/include/clang/Lex/HeaderSearch.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/HeaderSearch.h?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/HeaderSearch.h?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Lex/HeaderSearch.h (original)<br>
+++ cfe/trunk/include/clang/Lex/HeaderSearch.h Mon Apr 14 13:00:01 2014<br>
@@ -493,9 +493,12 @@ public:<br>
   ///<br>
   /// \param ModuleName The module whose module file name will be returned.<br>
   ///<br>
+  /// \param ModuleMapPath A path that when combined with \c ModuleName<br>
+  /// uniquely identifies this module. See Module::ModuleMap.<br>
+  ///<br>
   /// \returns The name of the module file that corresponds to this module,<br>
   /// or an empty string if this module does not correspond to any module file.<br>
-  std::string getModuleFileName(StringRef ModuleName);<br>
+  std::string getModuleFileName(StringRef ModuleName, StringRef ModuleMapPath);<br>
<br>
   /// \brief Lookup a module Search for a module with the given name.<br>
   ///<br>
<br>
Modified: cfe/trunk/include/clang/Lex/ModuleMap.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/ModuleMap.h?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/ModuleMap.h?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Lex/ModuleMap.h (original)<br>
+++ cfe/trunk/include/clang/Lex/ModuleMap.h Mon Apr 14 13:00:01 2014<br>
@@ -131,6 +131,10 @@ private:<br>
     /// \brief Whether the modules we infer are [system] modules.<br>
     unsigned InferSystemModules : 1;<br>
<br>
+    /// \brief If \c InferModules is non-zero, the module map file that allowed<br>
+    /// inferred modules.  Otherwise, nullptr.<br>
+    const FileEntry *ModuleMapFile;<br>
+<br>
     /// \brief The names of modules that cannot be inferred within this<br>
     /// directory.<br>
     SmallVector<std::string, 2> ExcludedModules;<br>
@@ -293,13 +297,17 @@ public:<br>
   /// \param Parent The module that will act as the parent of this submodule,<br>
   /// or NULL to indicate that this is a top-level module.<br>
   ///<br>
+  /// \param ModuleMap The module map that defines or allows the inference of<br>
+  /// this module.<br>
+  ///<br>
   /// \param IsFramework Whether this is a framework module.<br>
   ///<br>
   /// \param IsExplicit Whether this is an explicit submodule.<br>
   ///<br>
   /// \returns The found or newly-created module, along with a boolean value<br>
   /// that will be true if the module is newly-created.<br>
-  std::pair<Module *, bool> findOrCreateModule(StringRef Name, Module *Parent,<br>
+  std::pair<Module *, bool> findOrCreateModule(StringRef Name, Module *Parent,<br>
+                                               const FileEntry *ModuleMap,<br>
                                                bool IsFramework,<br>
                                                bool IsExplicit);<br>
<br>
<br>
Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)<br>
+++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Mon Apr 14 13:00:01 2014<br>
@@ -281,7 +281,14 @@ namespace clang {<br>
       HEADER_SEARCH_OPTIONS = 11,<br>
<br>
       /// \brief Record code for the preprocessor options table.<br>
-      PREPROCESSOR_OPTIONS = 12<br>
+      PREPROCESSOR_OPTIONS = 12,<br>
+<br>
+      /// \brief Record code for the module name.<br>
+      MODULE_NAME = 13,<br>
+<br>
+      /// \brief Record code for the module map file that was used to build this<br>
+      /// AST file.<br>
+      MODULE_MAP_FILE = 14<br>
     };<br>
<br>
     /// \brief Record types that occur within the input-files block<br>
<br>
Modified: cfe/trunk/include/clang/Serialization/ASTReader.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Serialization/ASTReader.h (original)<br>
+++ cfe/trunk/include/clang/Serialization/ASTReader.h Mon Apr 14 13:00:01 2014<br>
@@ -1079,6 +1079,7 @@ private:<br>
                             unsigned ClientLoadCapabilities);<br>
   ASTReadResult ReadControlBlock(ModuleFile &F,<br>
                                  SmallVectorImpl<ImportedModule> &Loaded,<br>
+                                 const ModuleFile *ImportedBy,<br>
                                  unsigned ClientLoadCapabilities);<br>
   ASTReadResult ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities);<br>
   bool ParseLineTable(ModuleFile &F, SmallVectorImpl<uint64_t> &Record);<br>
<br>
Modified: cfe/trunk/include/clang/Serialization/Module.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/Module.h?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/Module.h?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/include/clang/Serialization/Module.h (original)<br>
+++ cfe/trunk/include/clang/Serialization/Module.h Mon Apr 14 13:00:01 2014<br>
@@ -116,6 +116,9 @@ public:<br>
   /// \brief The file name of the module file.<br>
   std::string FileName;<br>
<br>
+  /// \brief The name of the module.<br>
+  std::string ModuleName;<br>
+<br>
   std::string getTimestampFilename() const {<br>
     return FileName + ".timestamp";<br>
   }<br>
@@ -137,6 +140,8 @@ public:<br>
   /// allow resolving headers even after headers+PCH was moved to a new path.<br>
   std::string OriginalDir;<br>
<br>
+  std::string ModuleMapPath;<br>
+<br>
   /// \brief Whether this precompiled header is a relocatable PCH file.<br>
   bool RelocatablePCH;<br>
<br>
<br>
Modified: cfe/trunk/lib/Basic/Module.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Module.cpp?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Module.cpp?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Basic/Module.cpp (original)<br>
+++ cfe/trunk/lib/Basic/Module.cpp Mon Apr 14 13:00:01 2014<br>
@@ -25,8 +25,8 @@<br>
 using namespace clang;<br>
<br>
 Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,<br>
-               bool IsFramework, bool IsExplicit)<br>
-  : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),<br>
+               const FileEntry *File, bool IsFramework, bool IsExplicit)<br>
+  : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), ModuleMap(File),<br>
     Umbrella(), ASTFile(0), IsAvailable(true), IsFromModuleFile(false),<br>
     IsFramework(IsFramework), IsExplicit(IsExplicit), IsSystem(false),<br>
     IsExternC(false), InferSubmodules(false), InferExplicitSubmodules(false),<br>
<br>
Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)<br>
+++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Mon Apr 14 13:00:01 2014<br>
@@ -870,8 +870,9 @@ static void compileModuleImpl(CompilerIn<br>
     SourceMgr.overrideFileContents(ModuleMapFile, ModuleMapBuffer);<br>
   }<br>
<br>
-  // Construct a module-generating action.<br>
-  GenerateModuleAction CreateModuleAction(Module->IsSystem);<br>
+  // Construct a module-generating action. Passing through Module->ModuleMap is<br>
+  // safe because the FileManager is shared between the compiler instances.<br>
+  GenerateModuleAction CreateModuleAction(Module->ModuleMap, Module->IsSystem);<br>
<br>
   // Execute the action to actually build the module in-place. Use a separate<br>
   // thread so that we get a stack large enough.<br>
<br>
Modified: cfe/trunk/lib/Frontend/FrontendAction.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendAction.cpp?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendAction.cpp?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Frontend/FrontendAction.cpp (original)<br>
+++ cfe/trunk/lib/Frontend/FrontendAction.cpp Mon Apr 14 13:00:01 2014<br>
@@ -256,6 +256,10 @@ bool FrontendAction::BeginSourceFile(Com<br>
     if (!BeginSourceFileAction(CI, InputFile))<br>
       goto failure;<br>
<br>
+    // Initialize the main file entry.<br>
+    if (!CI.InitializeSourceManager(CurrentInput))<br>
+      goto failure;<br>
+<br>
     return true;<br>
   }<br>
<br>
@@ -302,6 +306,11 @@ bool FrontendAction::BeginSourceFile(Com<br>
   if (!BeginSourceFileAction(CI, InputFile))<br>
     goto failure;<br>
<br>
+  // Initialize the main file entry. It is important that this occurs after<br>
+  // BeginSourceFileAction, which may change CurrentInput during module builds.<br>
+  if (!CI.InitializeSourceManager(CurrentInput))<br>
+    goto failure;<br>
+<br>
   // Create the AST context and consumer unless this is a preprocessor only<br>
   // action.<br>
   if (!usesPreprocessorOnly()) {<br>
@@ -389,13 +398,6 @@ bool FrontendAction::BeginSourceFile(Com<br>
 bool FrontendAction::Execute() {<br>
   CompilerInstance &CI = getCompilerInstance();<br>
<br>
-  // Initialize the main file entry. This needs to be delayed until after PCH<br>
-  // has loaded.<br>
-  if (!isCurrentFileAST()) {<br>
-    if (!CI.InitializeSourceManager(getCurrentInput()))<br>
-      return false;<br>
-  }<br>
-<br>
   if (CI.hasFrontendTimer()) {<br>
     llvm::TimeRegion Timer(CI.getFrontendTimer());<br>
     ExecuteAction();<br>
<br>
Modified: cfe/trunk/lib/Frontend/FrontendActions.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendActions.cpp?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendActions.cpp?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Frontend/FrontendActions.cpp (original)<br>
+++ cfe/trunk/lib/Frontend/FrontendActions.cpp Mon Apr 14 13:00:01 2014<br>
@@ -299,6 +299,11 @@ bool GenerateModuleAction::BeginSourceFi<br>
     return false;<br>
   }<br>
<br>
+  if (!ModuleMapForUniquing)<br>
+    ModuleMapForUniquing = ModuleMap;<br>
+  Module->ModuleMap = ModuleMapForUniquing;<br>
+  assert(Module->ModuleMap && "missing module map file");<br>
+<br>
   FileManager &FileMgr = CI.getFileManager();<br>
<br>
   // Collect the set of #includes we need to build the module.<br>
@@ -337,10 +342,9 @@ bool GenerateModuleAction::ComputeASTCon<br>
   // in the module cache.<br>
   if (CI.getFrontendOpts().OutputFile.empty()) {<br>
     HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();<br>
-    SmallString<256> ModuleFileName(HS.getModuleCachePath());<br>
-    llvm::sys::path::append(ModuleFileName,<br>
-                            CI.getLangOpts().CurrentModule + ".pcm");<br>
-    CI.getFrontendOpts().OutputFile = ModuleFileName.str();<br>
+    CI.getFrontendOpts().OutputFile =<br>
+        HS.getModuleFileName(CI.getLangOpts().CurrentModule,<br>
+                             ModuleMapForUniquing->getName());<br>
   }<br>
<br>
   // We use createOutputFile here because this is exposed via libclang, and we<br>
<br>
Modified: cfe/trunk/lib/Lex/HeaderSearch.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/HeaderSearch.cpp?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/HeaderSearch.cpp?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Lex/HeaderSearch.cpp (original)<br>
+++ cfe/trunk/lib/Lex/HeaderSearch.cpp Mon Apr 14 13:00:01 2014<br>
@@ -18,6 +18,8 @@<br>
 #include "clang/Lex/HeaderSearchOptions.h"<br>
 #include "clang/Lex/LexDiagnostic.h"<br>
 #include "clang/Lex/Lexer.h"<br>
+#include "llvm/ADT/APInt.h"<br>
+#include "llvm/ADT/Hashing.h"<br>
 #include "llvm/ADT/SmallString.h"<br>
 #include "llvm/Support/Capacity.h"<br>
 #include "llvm/Support/FileSystem.h"<br>
@@ -112,24 +114,33 @@ const HeaderMap *HeaderSearch::CreateHea<br>
 }<br>
<br>
 std::string HeaderSearch::getModuleFileName(Module *Module) {<br>
-  // If we don't have a module cache path, we can't do anything.<br>
-  if (ModuleCachePath.empty())<br>
-    return std::string();<br>
-<br>
-<br>
-  SmallString<256> Result(ModuleCachePath);<br>
-  llvm::sys::path::append(Result, Module->getTopLevelModule()->Name + ".pcm");<br>
-  return Result.str().str();<br>
+  return getModuleFileName(Module->Name, Module->ModuleMap->getName());<br>
 }<br>
<br>
-std::string HeaderSearch::getModuleFileName(StringRef ModuleName) {<br>
+std::string HeaderSearch::getModuleFileName(StringRef ModuleName,<br>
+                                            StringRef ModuleMapPath) {<br>
   // If we don't have a module cache path, we can't do anything.<br>
   if (ModuleCachePath.empty())<br>
     return std::string();<br>
-<br>
-<br>
+<br>
   SmallString<256> Result(ModuleCachePath);<br>
-  llvm::sys::path::append(Result, ModuleName + ".pcm");<br>
+  llvm::sys::fs::make_absolute(Result);<br>
+<br>
+  if (HSOpts->DisableModuleHash) {<br>
+    llvm::sys::path::append(Result, ModuleName + ".pcm");<br>
+  } else {<br>
+    // Construct the name <ModuleName>-<hash of ModuleMapPath>.pcm which should<br>
+    // be globally unique to this particular module. To avoid false-negatives<br>
+    // on case-insensitive filesystems, we use lower-case, which is safe because<br>
+    // to cause a collision the modules must have the same name, which is an<br>
+    // error if they are imported in the same translation.<br></blockquote><div><br></div><div>Consider:</div><div><br></div><div>  foo/module.modulemap defines a module X</div><div>  FOO/module.modulemap also defines a module X</div><div><br></div><div>If we cause foo/module.modulemap's X to be built, and then we try to import X from FOO/module.modulemap, won't we import the wrong module from the module cache? (Put another way, if this were correct, why would we ever need to include the module map file's hash in the filename?)</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
+    SmallString<256> AbsModuleMapPath(ModuleMapPath);<br>
+    llvm::sys::fs::make_absolute(AbsModuleMapPath);<br>
+    llvm::APInt Code(64, llvm::hash_value(AbsModuleMapPath.str().lower()));<br>
+    SmallString<128> HashStr;<br>
+    Code.toStringUnsigned(HashStr, /*Radix*/36);<br>
+    llvm::sys::path::append(Result, ModuleName + "-" + HashStr.str() + ".pcm");<br>
+  }<br>
   return Result.str().str();<br>
 }<br>
<br>
<br>
Modified: cfe/trunk/lib/Lex/ModuleMap.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ModuleMap.cpp?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ModuleMap.cpp?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Lex/ModuleMap.cpp (original)<br>
+++ cfe/trunk/lib/Lex/ModuleMap.cpp Mon Apr 14 13:00:01 2014<br>
@@ -363,8 +363,8 @@ ModuleMap::findModuleForHeader(const Fil<br>
         SmallString<32> NameBuf;<br>
         StringRef Name = sanitizeFilenameAsIdentifier(<br>
             llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);<br>
-        Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,<br>
-                                    Explicit).first;<br>
+        Result = findOrCreateModule(Name, Result, UmbrellaModule->ModuleMap,<br>
+                                    /*IsFramework=*/false, Explicit).first;<br>
<br>
         // Associate the module and the directory.<br>
         UmbrellaDirs[SkippedDirs[I-1]] = Result;<br>
@@ -378,9 +378,9 @@ ModuleMap::findModuleForHeader(const Fil<br>
       // Infer a submodule with the same name as this header file.<br>
       SmallString<32> NameBuf;<br>
       StringRef Name = sanitizeFilenameAsIdentifier(<br>
-                                                    llvm::sys::path::stem(File->getName()), NameBuf);<br>
-      Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,<br>
-                                  Explicit).first;<br>
+                         llvm::sys::path::stem(File->getName()), NameBuf);<br>
+      Result = findOrCreateModule(Name, Result, UmbrellaModule->ModuleMap,<br>
+                                  /*IsFramework=*/false, Explicit).first;<br>
       Result->addTopHeader(File);<br>
<br>
       // If inferred submodules export everything they import, add a<br>
@@ -518,15 +518,16 @@ Module *ModuleMap::lookupModuleQualified<br>
 }<br>
<br>
 std::pair<Module *, bool><br>
-ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool IsFramework,<br>
+ModuleMap::findOrCreateModule(StringRef Name, Module *Parent,<br>
+                              const FileEntry *ModuleMap, bool IsFramework,<br>
                               bool IsExplicit) {<br>
   // Try to find an existing module with this name.<br>
   if (Module *Sub = lookupModuleQualified(Name, Parent))<br>
     return std::make_pair(Sub, false);<br>
<br>
   // Create a new module with this name.<br>
-  Module *Result = new Module(Name, SourceLocation(), Parent, IsFramework,<br>
-                              IsExplicit);<br>
+  Module *Result = new Module(Name, SourceLocation(), Parent, ModuleMap,<br>
+                              IsFramework, IsExplicit);<br>
   if (LangOpts.CurrentModule == Name) {<br>
     SourceModule = Result;<br>
     SourceModuleName = Name;<br>
@@ -595,6 +596,7 @@ ModuleMap::inferFrameworkModule(StringRe<br>
<br>
   // If the framework has a parent path from which we're allowed to infer<br>
   // a framework module, do so.<br>
+  const FileEntry *ModuleMapFile = nullptr;<br>
   if (!Parent) {<br>
     // Determine whether we're allowed to infer a module map.<br>
<br>
@@ -639,6 +641,7 @@ ModuleMap::inferFrameworkModule(StringRe<br>
<br>
           if (inferred->second.InferSystemModules)<br>
             IsSystem = true;<br>
+          ModuleMapFile = inferred->second.ModuleMapFile;<br>
         }<br>
       }<br>
     }<br>
@@ -646,7 +649,8 @@ ModuleMap::inferFrameworkModule(StringRe<br>
     // If we're not allowed to infer a framework module, don't.<br>
     if (!canInfer)<br>
       return 0;<br>
-  }<br>
+  } else<br>
+    ModuleMapFile = Parent->ModuleMap;<br>
<br>
<br>
   // Look for an umbrella header.<br>
@@ -660,7 +664,7 @@ ModuleMap::inferFrameworkModule(StringRe<br>
   if (!UmbrellaHeader)<br>
     return 0;<br>
<br>
-  Module *Result = new Module(ModuleName, SourceLocation(), Parent,<br>
+  Module *Result = new Module(ModuleName, SourceLocation(), Parent, ModuleMapFile,<br>
                               /*IsFramework=*/true, /*IsExplicit=*/false);<br>
   if (LangOpts.CurrentModule == ModuleName) {<br>
     SourceModule = Result;<br>
@@ -954,6 +958,9 @@ namespace clang {<br>
<br>
     DiagnosticsEngine &Diags;<br>
     ModuleMap &Map;<br>
+<br>
+    /// \brief The current module map file.<br>
+    const FileEntry *ModuleMapFile;<br>
<br>
     /// \brief The directory that this module map resides in.<br>
     const DirectoryEntry *Directory;<br>
@@ -1007,12 +1014,14 @@ namespace clang {<br>
                              const TargetInfo *Target,<br>
                              DiagnosticsEngine &Diags,<br>
                              ModuleMap &Map,<br>
+                             const FileEntry *ModuleMapFile,<br>
                              const DirectoryEntry *Directory,<br>
                              const DirectoryEntry *BuiltinIncludeDir,<br>
                              bool IsSystem)<br>
       : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags), Map(Map),<br>
-        Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),<br>
-        IsSystem(IsSystem), HadError(false), ActiveModule(0)<br>
+        ModuleMapFile(ModuleMapFile), Directory(Directory),<br>
+        BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),<br>
+        HadError(false), ActiveModule(0)<br>
     {<br>
       Tok.clear();<br>
       consumeToken();<br>
@@ -1359,9 +1368,14 @@ void ModuleMapParser::parseModuleDecl()<br>
     return;<br>
   }<br>
<br>
+  // If this is a submodule, use the parent's module map, since we don't want<br>
+  // the private module map file.<br>
+  const FileEntry *ModuleMap = ActiveModule ? ActiveModule->ModuleMap<br>
+                                            : ModuleMapFile;<br>
+<br>
   // Start defining this module.<br>
-  ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, Framework,<br>
-                                        Explicit).first;<br>
+  ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule, ModuleMap,<br>
+                                        Framework, Explicit).first;<br>
   ActiveModule->DefinitionLoc = ModuleNameLoc;<br>
   if (Attrs.IsSystem || IsSystem)<br>
     ActiveModule->IsSystem = true;<br>
@@ -2020,6 +2034,7 @@ void ModuleMapParser::parseInferredModul<br>
     // We'll be inferring framework modules for this directory.<br>
     Map.InferredDirectories[Directory].InferModules = true;<br>
     Map.InferredDirectories[Directory].InferSystemModules = Attrs.IsSystem;<br>
+    Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;<br>
     // FIXME: Handle the 'framework' keyword.<br>
   }<br>
<br>
@@ -2256,7 +2271,7 @@ bool ModuleMap::parseModuleMapFile(const<br>
<br>
   // Parse this module map file.<br>
   Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);<br>
-  ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, Dir,<br>
+  ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,<br>
                          BuiltinIncludeDir, IsSystem);<br>
   bool Result = Parser.parseModuleMapFile();<br>
   ParsedModuleMap[File] = Result;<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTReader.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTReader.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTReader.cpp Mon Apr 14 13:00:01 2014<br>
@@ -1161,7 +1161,7 @@ std::pair<SourceLocation, StringRef> AST<br>
<br>
   // FIXME: Can we map this down to a particular submodule? That would be<br>
   // ideal.<br>
-  return std::make_pair(M->ImportLoc, llvm::sys::path::stem(M->FileName));<br>
+  return std::make_pair(M->ImportLoc, StringRef(M->ModuleName));<br>
 }<br>
<br>
 /// \brief Find the location where the module F is imported.<br>
@@ -1172,14 +1172,10 @@ SourceLocation ASTReader::getImportLocat<br>
   // Otherwise we have a PCH. It's considered to be "imported" at the first<br>
   // location of its includer.<br>
   if (F->ImportedBy.empty() || !F->ImportedBy[0]) {<br>
-    // Main file is the importer. We assume that it is the first entry in the<br>
-    // entry table. We can't ask the manager, because at the time of PCH loading<br>
-    // the main file entry doesn't exist yet.<br>
-    // The very first entry is the invalid instantiation loc, which takes up<br>
-    // offsets 0 and 1.<br>
-    return SourceLocation::getFromRawEncoding(2U);<br>
+    // Main file is the importer.<br>
+    assert(!SourceMgr.getMainFileID().isInvalid() && "missing main file");<br>
+    return SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());<br>
   }<br>
-  //return F->Loaders[0]->FirstLoc;<br>
   return F->ImportedBy[0]->FirstLoc;<br>
 }<br>
<br>
@@ -2089,6 +2085,7 @@ void ASTReader::MaybeAddSystemRootToFile<br>
 ASTReader::ASTReadResult<br>
 ASTReader::ReadControlBlock(ModuleFile &F,<br>
                             SmallVectorImpl<ImportedModule> &Loaded,<br>
+                            const ModuleFile *ImportedBy,<br>
                             unsigned ClientLoadCapabilities) {<br>
   BitstreamCursor &Stream = F.Stream;<br>
<br>
@@ -2314,6 +2311,44 @@ ASTReader::ReadControlBlock(ModuleFile &<br>
       F.OriginalDir = Blob;<br>
       break;<br>
<br>
+    case MODULE_NAME:<br>
+      F.ModuleName = Blob;<br>
+      break;<br>
+<br>
+    case MODULE_MAP_FILE:<br>
+      F.ModuleMapPath = Blob;<br>
+<br>
+      // Try to resolve ModuleName in the current header search context and<br>
+      // verify that it is found in the same module map file as we saved. If the<br>
+      // top-level AST file is a main file, skip this check because there is no<br>
+      // usable header search context.<br>
+      assert(!F.ModuleName.empty() &&<br>
+             "MODULE_NAME should come before MOUDLE_MAP_FILE");<br>
+      if (F.Kind == MK_Module &&<br>
+          (*ModuleMgr.begin())->Kind != MK_MainFile) {<br>
+        Module *M = PP.getHeaderSearchInfo().lookupModule(F.ModuleName);<br>
+        if (!M) {<br>
+          assert(ImportedBy && "top-level import should be verified");<br>
+          if ((ClientLoadCapabilities & ARR_Missing) == 0)<br>
+            Diag(diag::err_imported_module_not_found)<br>
+              << F.ModuleName << ImportedBy->FileName;<br>
+          return Missing;<br>
+        }<br>
+<br>
+        const FileEntry *StoredModMap = FileMgr.getFile(F.ModuleMapPath);<br>
+        if (StoredModMap == nullptr || StoredModMap != M->ModuleMap) {<br>
+          assert(M->ModuleMap && "found module is missing module map file");<br>
+          assert(M->Name == F.ModuleName && "found module with different name");<br>
+          assert(ImportedBy && "top-level import should be verified");<br>
+          if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)<br>
+            Diag(diag::err_imported_module_modmap_changed)<br>
+              << F.ModuleName << ImportedBy->FileName<br>
+              << M->ModuleMap->getName() << F.ModuleMapPath;<br>
+          return OutOfDate;<br>
+        }<br>
+      }<br>
+      break;<br>
+<br>
     case INPUT_FILE_OFFSETS:<br>
       F.InputFileOffsets = (const uint32_t *)Blob.data();<br>
       F.InputFilesLoaded.resize(Record[0]);<br>
@@ -3537,7 +3572,7 @@ ASTReader::ReadASTCore(StringRef FileNam<br>
       break;<br>
     case CONTROL_BLOCK_ID:<br>
       HaveReadControlBlock = true;<br>
-      switch (ReadControlBlock(F, Loaded, ClientLoadCapabilities)) {<br>
+      switch (ReadControlBlock(F, Loaded, ImportedBy, ClientLoadCapabilities)) {<br>
       case Success:<br>
         break;<br>
<br>
@@ -4059,13 +4094,19 @@ ASTReader::ReadSubmoduleBlock(ModuleFile<br>
       bool InferExportWildcard = Record[Idx++];<br>
       bool ConfigMacrosExhaustive = Record[Idx++];<br>
<br>
-      Module *ParentModule = 0;<br>
-      if (Parent)<br>
+      Module *ParentModule = nullptr;<br>
+      const FileEntry *ModuleMap = nullptr;<br>
+      if (Parent) {<br>
         ParentModule = getSubmodule(Parent);<br>
-<br>
+        ModuleMap = ParentModule->ModuleMap;<br>
+      }<br>
+<br>
+      if (!F.ModuleMapPath.empty())<br>
+        ModuleMap = FileMgr.getFile(F.ModuleMapPath);<br>
+<br>
       // Retrieve this (sub)module from the module map, creating it if<br>
       // necessary.<br>
-      CurrentModule = ModMap.findOrCreateModule(Name, ParentModule,<br>
+      CurrentModule = ModMap.findOrCreateModule(Name, ParentModule, ModuleMap,<br>
                                                 IsFramework,<br>
                                                 IsExplicit).first;<br>
       SubmoduleID GlobalIndex = GlobalID - NUM_PREDEF_SUBMODULE_IDS;<br>
@@ -4090,7 +4131,7 @@ ASTReader::ReadSubmoduleBlock(ModuleFile<br>
<br>
         CurrentModule->setASTFile(F.File);<br>
       }<br>
-<br>
+<br>
       CurrentModule->IsFromModuleFile = true;<br>
       CurrentModule->IsSystem = IsSystem || CurrentModule->IsSystem;<br>
       CurrentModule->IsExternC = IsExternC;<br>
<br>
Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ASTWriter.cpp Mon Apr 14 13:00:01 2014<br>
@@ -798,6 +798,8 @@ void ASTWriter::WriteBlockInfoBlock() {<br>
   // Control Block.<br>
   BLOCK(CONTROL_BLOCK);<br>
   RECORD(METADATA);<br>
+  RECORD(MODULE_NAME);<br>
+  RECORD(MODULE_MAP_FILE);<br>
   RECORD(IMPORTS);<br>
   RECORD(LANGUAGE_OPTIONS);<br>
   RECORD(TARGET_OPTIONS);<br>
@@ -1050,6 +1052,32 @@ void ASTWriter::WriteControlBlock(Prepro<br>
   Stream.EmitRecordWithBlob(MetadataAbbrevCode, Record,<br>
                             getClangFullRepositoryVersion());<br>
<br>
+  // Module name<br>
+  if (WritingModule) {<br>
+    BitCodeAbbrev *Abbrev = new BitCodeAbbrev();<br>
+    Abbrev->Add(BitCodeAbbrevOp(MODULE_NAME));<br>
+    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name<br>
+    unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev);<br>
+    RecordData Record;<br>
+    Record.push_back(MODULE_NAME);<br>
+    Stream.EmitRecordWithBlob(AbbrevCode, Record, WritingModule->Name);<br>
+  }<br>
+<br>
+  // Module map file<br>
+  if (WritingModule) {<br>
+    BitCodeAbbrev *Abbrev = new BitCodeAbbrev();<br>
+    Abbrev->Add(BitCodeAbbrevOp(MODULE_MAP_FILE));<br>
+    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Filename<br>
+    unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev);<br>
+<br>
+    assert(WritingModule->ModuleMap && "missing module map");<br>
+    SmallString<128> ModuleMap(WritingModule->ModuleMap->getName());<br>
+    llvm::sys::fs::make_absolute(ModuleMap);<br>
+    RecordData Record;<br>
+    Record.push_back(MODULE_MAP_FILE);<br>
+    Stream.EmitRecordWithBlob(AbbrevCode, Record, ModuleMap.str());<br>
+  }<br>
+<br>
   // Imports<br>
   if (Chain) {<br>
     serialization::ModuleManager &Mgr = Chain->getModuleManager();<br>
@@ -1065,7 +1093,6 @@ void ASTWriter::WriteControlBlock(Prepro<br>
       AddSourceLocation((*M)->ImportLoc, Record);<br>
       Record.push_back((*M)->File->getSize());<br>
       Record.push_back((*M)->File->getModificationTime());<br>
-      // FIXME: This writes the absolute path for AST files we depend on.<br>
       const std::string &FileName = (*M)->FileName;<br>
       Record.push_back(FileName.size());<br>
       Record.append(FileName.begin(), FileName.end());<br>
<br>
Modified: cfe/trunk/lib/Serialization/GlobalModuleIndex.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/GlobalModuleIndex.cpp?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/GlobalModuleIndex.cpp?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Serialization/GlobalModuleIndex.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/GlobalModuleIndex.cpp Mon Apr 14 13:00:01 2014<br>
@@ -14,6 +14,7 @@<br>
 #include "ASTReaderInternals.h"<br>
 #include "clang/Basic/FileManager.h"<br>
 #include "clang/Basic/OnDiskHashTable.h"<br>
+#include "clang/Lex/HeaderSearch.h"<br>
 #include "clang/Serialization/ASTBitCodes.h"<br>
 #include "clang/Serialization/GlobalModuleIndex.h"<br>
 #include "clang/Serialization/Module.h"<br>
@@ -203,7 +204,12 @@ GlobalModuleIndex::GlobalModuleIndex(llv<br>
       assert(Idx == Record.size() && "More module info?");<br>
<br>
       // Record this module as an unresolved module.<br>
-      UnresolvedModules[llvm::sys::path::stem(Modules[ID].FileName)] = ID;<br>
+      // FIXME: this doesn't work correctly for module names containing path<br>
+      // separators.<br>
+      StringRef ModuleName = llvm::sys::path::stem(Modules[ID].FileName);<br>
+      // Remove the -<hash of ModuleMapPath><br>
+      ModuleName = ModuleName.rsplit('-').first;<br>
+      UnresolvedModules[ModuleName] = ID;<br>
       break;<br>
     }<br>
<br>
@@ -308,7 +314,7 @@ bool GlobalModuleIndex::lookupIdentifier<br>
<br>
 bool GlobalModuleIndex::loadedModuleFile(ModuleFile *File) {<br>
   // Look for the module in the global module index based on the module name.<br>
-  StringRef Name = llvm::sys::path::stem(File->FileName);<br>
+  StringRef Name = File->ModuleName;<br>
   llvm::StringMap<unsigned>::iterator Known = UnresolvedModules.find(Name);<br>
   if (Known == UnresolvedModules.end()) {<br>
     return true;<br>
<br>
Modified: cfe/trunk/lib/Serialization/ModuleManager.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ModuleManager.cpp?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ModuleManager.cpp?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/lib/Serialization/ModuleManager.cpp (original)<br>
+++ cfe/trunk/lib/Serialization/ModuleManager.cpp Mon Apr 14 13:00:01 2014<br>
@@ -11,6 +11,7 @@<br>
 //  modules for the ASTReader.<br>
 //<br>
 //===----------------------------------------------------------------------===//<br>
+#include "clang/Lex/HeaderSearch.h"<br>
 #include "clang/Lex/ModuleMap.h"<br>
 #include "clang/Serialization/GlobalModuleIndex.h"<br>
 #include "clang/Serialization/ModuleManager.h"<br>
@@ -155,7 +156,7 @@ void ModuleManager::removeModules(Module<br>
<br>
     FileMgr.invalidateCache((*victim)->File);<br>
     if (modMap) {<br>
-      StringRef ModuleName = llvm::sys::path::stem((*victim)->FileName);<br>
+      StringRef ModuleName = (*victim)->ModuleName;<br>
       if (Module *mod = modMap->findModule(ModuleName)) {<br>
         mod->setASTFile(0);<br>
       }<br>
@@ -429,7 +430,7 @@ namespace llvm {<br>
     }<br>
<br>
     std::string getNodeLabel(ModuleFile *M, const ModuleManager&) {<br>
-      return llvm::sys::path::stem(M->FileName);<br>
+      return M->ModuleName;<br>
     }<br>
   };<br>
 }<br>
<br>
Modified: cfe/trunk/test/Index/annotate-module.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/annotate-module.m?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/annotate-module.m?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Index/annotate-module.m (original)<br>
+++ cfe/trunk/test/Index/annotate-module.m Mon Apr 14 13:00:01 2014<br>
@@ -44,6 +44,6 @@ int glob;<br>
 // RUN: c-index-test -cursor-at=%s:3:11 %s -fmodules-cache-path=%t.cache -fmodules -F %S/../Modules/Inputs \<br>
 // RUN:     | FileCheck %s -check-prefix=CHECK-CURSOR<br>
<br>
-// CHECK-CURSOR:      3:1 ModuleImport=DependsOnModule:3:1 (Definition) Extent=[3:1 - 3:24] Spelling=DependsOnModule ([3:9 - 3:24]) ModuleName=DependsOnModule ({{.*}}DependsOnModule.pcm) Headers(2):<br>
+// CHECK-CURSOR:      3:1 ModuleImport=DependsOnModule:3:1 (Definition) Extent=[3:1 - 3:24] Spelling=DependsOnModule ([3:9 - 3:24]) ModuleName=DependsOnModule ({{.*}}DependsOnModule-{{[^.]*}}.pcm) Headers(2):<br>
 // CHECK-CURSOR-NEXT: {{.*}}other.h<br>
 // CHECK-CURSOR-NEXT: {{.*}}DependsOnModule.h<br>
<br>
Modified: cfe/trunk/test/Index/pch-depending-on-deleted-module.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/pch-depending-on-deleted-module.c?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/pch-depending-on-deleted-module.c?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Index/pch-depending-on-deleted-module.c (original)<br>
+++ cfe/trunk/test/Index/pch-depending-on-deleted-module.c Mon Apr 14 13:00:01 2014<br>
@@ -4,10 +4,10 @@<br>
 // RUN: mkdir %t<br>
<br>
 // RUN: %clang_cc1 -x c-header -fmodules -fdisable-module-hash -fmodules-cache-path=%t/modules-cache -emit-pch -I %S/Inputs/Headers -o %t/use_LibA.pch %s<br>
-// RUN: %clang_cc1 -fmodules -fdisable-module-hash -fmodules-cache-path=%t/modules-cache -verify-pch %t/use_LibA.pch<br>
+// RUN: %clang_cc1 -fmodules -fdisable-module-hash -fmodules-cache-path=%t/modules-cache -I %S/Inputs/Headers -verify-pch %t/use_LibA.pch<br>
 // RUN: rm -f %t/modules-cache/LibA.pcm<br>
-// RUN: not %clang_cc1 -fmodules -fdisable-module-hash -fmodules-cache-path=modules-cache -verify-pch %t/use_LibA.pch 2>&1 | FileCheck -check-prefix=VERIFY %s<br>
-// RUN: not c-index-test -test-load-source all -x c -fmodules -fdisable-module-hash -fmodules-cache-path=modules-cache -include-pch %t/use_LibA.pch %s 2>&1 | FileCheck -check-prefix=INDEX %s<br>
+// RUN: not %clang_cc1 -fmodules -fdisable-module-hash -fmodules-cache-path=%t/modules-cache -I %S/Inputs/Headers -verify-pch %t/use_LibA.pch 2>&1 | FileCheck -check-prefix=VERIFY %s<br>
+// RUN: not c-index-test -test-load-source all -x c -fmodules -Xclang -fdisable-module-hash -fmodules-cache-path=%t/modules-cache -I %S/Inputs/Headers -include-pch %t/use_LibA.pch %s 2>&1 | FileCheck -check-prefix=INDEX %s<br>
<br>
 // VERIFY: fatal error: malformed or corrupted AST file: 'Unable to load module<br>
 // INDEX: {{^}}Failure: AST deserialization error occurred{{$}}<br>
<br>
Added: cfe/trunk/test/Modules/Inputs/modules-with-same-name/DependsOnA/DependsOnA.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/modules-with-same-name/DependsOnA/DependsOnA.h?rev=206201&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/modules-with-same-name/DependsOnA/DependsOnA.h?rev=206201&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/Modules/Inputs/modules-with-same-name/DependsOnA/DependsOnA.h (added)<br>
+++ cfe/trunk/test/Modules/Inputs/modules-with-same-name/DependsOnA/DependsOnA.h Mon Apr 14 13:00:01 2014<br>
@@ -0,0 +1 @@<br>
+@import A;<br>
<br>
Added: cfe/trunk/test/Modules/Inputs/modules-with-same-name/DependsOnA/module.modulemap<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/modules-with-same-name/DependsOnA/module.modulemap?rev=206201&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/modules-with-same-name/DependsOnA/module.modulemap?rev=206201&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/Modules/Inputs/modules-with-same-name/DependsOnA/module.modulemap (added)<br>
+++ cfe/trunk/test/Modules/Inputs/modules-with-same-name/DependsOnA/module.modulemap Mon Apr 14 13:00:01 2014<br>
@@ -0,0 +1,4 @@<br>
+module DependsOnA {<br>
+  header "DependsOnA.h"<br>
+  export *<br>
+}<br>
<br>
Added: cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/A/a.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/A/a.h?rev=206201&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/A/a.h?rev=206201&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/A/a.h (added)<br>
+++ cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/A/a.h Mon Apr 14 13:00:01 2014<br>
@@ -0,0 +1 @@<br>
+#define FROM_PATH 1<br>
<br>
Added: cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/A/module.modulemap<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/A/module.modulemap?rev=206201&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/A/module.modulemap?rev=206201&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/A/module.modulemap (added)<br>
+++ cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/A/module.modulemap Mon Apr 14 13:00:01 2014<br>
@@ -0,0 +1,3 @@<br>
+module A {<br>
+  header "a.h"<br>
+}<br>
<br>
Added: cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/A/a.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/A/a.h?rev=206201&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/A/a.h?rev=206201&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/A/a.h (added)<br>
+++ cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/A/a.h Mon Apr 14 13:00:01 2014<br>
@@ -0,0 +1 @@<br>
+#define FROM_PATH 2<br>
<br>
Added: cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/A/module.modulemap<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/A/module.modulemap?rev=206201&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/A/module.modulemap?rev=206201&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/A/module.modulemap (added)<br>
+++ cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/A/module.modulemap Mon Apr 14 13:00:01 2014<br>
@@ -0,0 +1,3 @@<br>
+module A {<br>
+  header "a.h"<br>
+}<br>
<br>
Modified: cfe/trunk/test/Modules/dependency-gen-pch.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/dependency-gen-pch.m?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/dependency-gen-pch.m?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Modules/dependency-gen-pch.m (original)<br>
+++ cfe/trunk/test/Modules/dependency-gen-pch.m Mon Apr 14 13:00:01 2014<br>
@@ -1,7 +1,7 @@<br>
 // RUN: rm -rf %t-mcp<br>
 // RUN: mkdir -p %t-mcp<br>
<br>
-// RUN: %clang_cc1 -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 -module-file-deps -dependency-file %t.d -MT %s.o -I %S/Inputs -fmodules -fmodules-cache-path=%t-mcp -emit-pch -o %t.pch %s<br>
+// RUN: %clang_cc1 -isysroot %S/Inputs/System -triple x86_64-apple-darwin10 -module-file-deps -dependency-file %t.d -MT %s.o -I %S/Inputs -fmodules -fdisable-module-hash -fmodules-cache-path=%t-mcp -emit-pch -o %t.pch %s<br>
 // RUN: FileCheck %s < %t.d<br>
 // CHECK: dependency-gen-pch.m.o<br>
 // CHECK-NEXT: dependency-gen-pch.m<br>
<br>
Modified: cfe/trunk/test/Modules/diamond-pch.c<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/diamond-pch.c?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/diamond-pch.c?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Modules/diamond-pch.c (original)<br>
+++ cfe/trunk/test/Modules/diamond-pch.c Mon Apr 14 13:00:01 2014<br>
@@ -4,7 +4,7 @@<br>
 // RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_right %S/Inputs/module.map<br>
 // RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodules-cache-path=%t -fmodule-name=diamond_bottom %S/Inputs/module.map<br>
 // RUN: %clang_cc1 -fmodules -x objective-c -emit-pch -fmodules-cache-path=%t -I %S/Inputs -o %t.pch %S/Inputs/diamond.h<br>
-// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -include-pch %t.pch %s -verify<br>
+// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t -include-pch %t.pch %s -I %S/Inputs -verify<br>
 // FIXME: When we have a syntax for modules in C, use that.<br>
<br>
 void test_diamond(int i, float f, double d, char c) {<br>
<br>
Modified: cfe/trunk/test/Modules/macro-undef-through-pch.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/macro-undef-through-pch.m?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/macro-undef-through-pch.m?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Modules/macro-undef-through-pch.m (original)<br>
+++ cfe/trunk/test/Modules/macro-undef-through-pch.m Mon Apr 14 13:00:01 2014<br>
@@ -2,7 +2,9 @@<br>
 // RUN: %clang_cc1 -x objective-c-header -fmodules -fmodules-cache-path=%t \<br>
 // RUN:            -I%S/Inputs/macro-undef-through-pch -emit-pch \<br>
 // RUN:            %S/Inputs/macro-undef-through-pch/foo.h -o %t.pch<br>
-// RUN: %clang_cc1 -x objective-c -fmodules -fmodules-cache-path=%t -include-pch %t.pch %s<br>
+// RUN: %clang_cc1 -x objective-c -fmodules -fmodules-cache-path=%t \<br>
+// RUN:            -I%S/Inputs/macro-undef-through-pch -emit-pch \<br>
+// RUN:            -include-pch %t.pch %s<br>
<br>
 // PR19215<br>
 #undef AB<br>
<br>
Added: cfe/trunk/test/Modules/modules-with-same-name.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/modules-with-same-name.m?rev=206201&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/modules-with-same-name.m?rev=206201&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/Modules/modules-with-same-name.m (added)<br>
+++ cfe/trunk/test/Modules/modules-with-same-name.m Mon Apr 14 13:00:01 2014<br>
@@ -0,0 +1,35 @@<br>
+// REQUIRES: shell<br>
+// RUN: rm -rf %t<br>
+<br>
+// A from path 1<br>
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fmodules-ignore-macro=EXPECTED_PATH -fmodules-ignore-macro=DIRECT -fsyntax-only %s -verify -I %S/Inputs/modules-with-same-name/path1/A -DDIRECT -DEXPECTED_PATH=1<br>
+<br>
+// A from path 2<br>
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fmodules-ignore-macro=EXPECTED_PATH -fmodules-ignore-macro=DIRECT -fsyntax-only %s -verify -I %S/Inputs/modules-with-same-name/path2/A -DDIRECT -DEXPECTED_PATH=2<br>
+<br>
+// Confirm that we have two pcm files (one for each 'A').<br>
+// RUN: find %t -name "A-*.pcm" | count 2<br>
+<br>
+// DependsOnA, using A from path 1<br>
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fmodules-ignore-macro=EXPECTED_PATH -fmodules-ignore-macro=DIRECT -fsyntax-only %s -verify -I %S/Inputs/modules-with-same-name/DependsOnA -I %S/Inputs/modules-with-same-name/path1/A -DEXPECTED_PATH=1<br>
+<br>
+// Confirm that we have three pcm files (one for each 'A', and one for 'DependsOnA')<br>
+// RUN: find %t -name "*.pcm" | count 3<br>
+<br>
+// DependsOnA, using A from path 2<br>
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -fmodules-ignore-macro=EXPECTED_PATH -fmodules-ignore-macro=DIRECT -fsyntax-only %s -verify -I %S/Inputs/modules-with-same-name/DependsOnA -I %S/Inputs/modules-with-same-name/path2/A -DEXPECTED_PATH=2<br>
+<br>
+// Confirm that we still have three pcm files, since DependsOnA will be rebuilt<br>
+// RUN: find %t -name "*.pcm" | count 3<br>
+<br>
+#ifdef DIRECT<br>
+@import A;<br>
+#else<br>
+@import DependsOnA;<br>
+#endif<br>
+<br>
+#if FROM_PATH != EXPECTED_PATH<br>
+#error "Got the wrong module!"<br>
+#endif<br>
+<br>
+// expected-no-diagnostics<br>
<br>
Modified: cfe/trunk/test/Modules/prune.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/prune.m?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/prune.m?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Modules/prune.m (original)<br>
+++ cfe/trunk/test/Modules/prune.m Mon Apr 14 13:00:01 2014<br>
@@ -14,33 +14,33 @@<br>
 // RUN: %clang_cc1 -DIMPORT_DEPENDS_ON_MODULE -fmodules-ignore-macro=DIMPORT_DEPENDS_ON_MODULE -fmodules -F %S/Inputs -fmodules-cache-path=%t %s -verify<br>
 // RUN: %clang_cc1 -DIMPORT_DEPENDS_ON_MODULE -fmodules-ignore-macro=DIMPORT_DEPENDS_ON_MODULE -fmodules -F %S/Inputs -fmodules-cache-path=%t %s -verify<br>
 // RUN: ls %t | grep modules.timestamp<br>
-// RUN: ls -R %t | grep ^Module.pcm<br>
-// RUN: ls -R %t | grep DependsOnModule.pcm<br>
+// RUN: ls -R %t | grep ^Module.*pcm<br>
+// RUN: ls -R %t | grep DependsOnModule.*pcm<br>
<br>
 // Set the timestamp back more than two days. We should try to prune,<br>
 // but nothing gets pruned because the module files are new enough.<br>
 // RUN: touch -m -a -t 201101010000 %t/modules.timestamp<br>
 // RUN: %clang_cc1 -fmodules -F %S/Inputs -fmodules-cache-path=%t -fmodules -fmodules-prune-interval=172800 -fmodules-prune-after=345600 %s -verify<br>
 // RUN: ls %t | grep modules.timestamp<br>
-// RUN: ls -R %t | grep ^Module.pcm<br>
-// RUN: ls -R %t | grep DependsOnModule.pcm<br>
+// RUN: ls -R %t | grep ^Module.*pcm<br>
+// RUN: ls -R %t | grep DependsOnModule.*pcm<br>
<br>
 // Set the DependsOnModule access time back more than four days.<br>
 // This shouldn't prune anything, because the timestamp has been updated, so<br>
 // the pruning mechanism won't fire.<br>
-// RUN: find %t -name DependsOnModule.pcm | xargs touch -a -t 201101010000<br>
+// RUN: find %t -name DependsOnModule*.pcm | xargs touch -a -t 201101010000<br>
 // RUN: %clang_cc1 -fmodules -F %S/Inputs -fmodules-cache-path=%t -fmodules -fmodules-prune-interval=172800 -fmodules-prune-after=345600 %s -verify<br>
 // RUN: ls %t | grep modules.timestamp<br>
-// RUN: ls -R %t | grep ^Module.pcm<br>
-// RUN: ls -R %t | grep DependsOnModule.pcm<br>
+// RUN: ls -R %t | grep ^Module.*pcm<br>
+// RUN: ls -R %t | grep DependsOnModule.*pcm<br>
<br>
 // Set both timestamp and DependsOnModule.pcm back beyond the cutoff.<br>
 // This should trigger pruning, which will remove DependsOnModule but not Module.<br>
 // RUN: touch -m -a -t 201101010000 %t/modules.timestamp<br>
-// RUN: find %t -name DependsOnModule.pcm | xargs touch -a -t 201101010000<br>
+// RUN: find %t -name DependsOnModule..pcm | xargs touch -a -t 201101010000<br>
 // RUN: %clang_cc1 -fmodules -F %S/Inputs -fmodules-cache-path=%t -fmodules -fmodules-prune-interval=172800 -fmodules-prune-after=345600 %s -verify<br>
 // RUN: ls %t | grep modules.timestamp<br>
-// RUN: ls -R %t | grep ^Module.pcm<br>
-// RUN: ls -R %t | not grep DependsOnModule.pcm<br>
+// RUN: ls -R %t | grep ^Module.*pcm<br>
+// RUN: ls -R %t | not grep DependsOnModule.*pcm<br>
<br>
 // expected-no-diagnostics<br>
<br>
Modified: cfe/trunk/test/Modules/redecls/main.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/redecls/main.m?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/redecls/main.m?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Modules/redecls/main.m (original)<br>
+++ cfe/trunk/test/Modules/redecls/main.m Mon Apr 14 13:00:01 2014<br>
@@ -3,7 +3,7 @@<br>
 // RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodule-name=b %S/module.map -fmodules-cache-path=%t.mcp<br>
 // RUN: %clang_cc1 -fmodules %s -emit-pch -o %t1.pch -fmodules-cache-path=%t.mcp -I %S<br>
 // RUN: %clang_cc1 -fmodules %s -emit-pch -o %t2.pch -include-pch %t1.pch -fmodules-cache-path=%t.mcp -I %S<br>
-// RUN: %clang_cc1 -fmodules %s -fsyntax-only -include-pch %t2.pch -fmodules-cache-path=%t.mcp -verify<br>
+// RUN: %clang_cc1 -fmodules %s -fsyntax-only -include-pch %t2.pch -I %S -fmodules-cache-path=%t.mcp -verify<br>
<br>
 #ifndef HEADER1<br>
 #define HEADER1<br>
<br>
Added: cfe/trunk/test/Modules/resolution-change.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/resolution-change.m?rev=206201&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/resolution-change.m?rev=206201&view=auto</a><br>
==============================================================================<br>
--- cfe/trunk/test/Modules/resolution-change.m (added)<br>
+++ cfe/trunk/test/Modules/resolution-change.m Mon Apr 14 13:00:01 2014<br>
@@ -0,0 +1,24 @@<br>
+// RUN: rm -rf %t<br>
+<br>
+// Build PCH using A from path 1<br>
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs/modules-with-same-name/DependsOnA -I %S/Inputs/modules-with-same-name/path1/A -emit-pch -o %t-A.pch %s<br>
+<br>
+// Use the PCH with the same header search options; should be fine<br>
+// RUN: %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs/modules-with-same-name/DependsOnA -I %S/Inputs/modules-with-same-name/path1/A -include-pch %t-A.pch %s -fsyntax-only -Werror<br>
+<br>
+// Use the PCH with no way to resolve DependsOnA<br>
+// RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t -include-pch %t-A.pch %s -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-NODOA %s<br>
+// CHECK-NODOA: module 'DependsOnA' imported by AST file '{{.*A.pch}}' not found<br>
+<br>
+// Use the PCH with no way to resolve A<br>
+// RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs/modules-with-same-name/DependsOnA -include-pch %t-A.pch %s -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-NOA %s<br>
+// CHECK-NOA: module 'A' imported by AST file '{{.*DependsOnA.*pcm}}' not found<br>
+<br>
+// Use the PCH and have it resolve the the other A<br>
+// RUN: not %clang_cc1 -fmodules -fmodules-cache-path=%t -I %S/Inputs/modules-with-same-name/DependsOnA -I %S/Inputs/modules-with-same-name/path2/A -include-pch %t-A.pch %s -fsyntax-only 2>&1 | FileCheck -check-prefix=CHECK-WRONGA %s<br>
+// CHECK-WRONGA: module 'A' imported by AST file '{{.*DependsOnA.*pcm}}' found in a different module map file ({{.*path2.*}}) than when the importing AST file was built ({{.*path1.*}})<br>
+<br>
+#ifndef HEADER<br>
+#define HEADER<br>
+@import DependsOnA;<br>
+#endif<br>
<br>
Modified: cfe/trunk/test/Modules/system_version.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/system_version.m?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/system_version.m?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/Modules/system_version.m (original)<br>
+++ cfe/trunk/test/Modules/system_version.m Mon Apr 14 13:00:01 2014<br>
@@ -11,21 +11,21 @@<br>
<br>
 // Run once with no system version file. We should end up with one module.<br>
 // RUN: %clang_cc1 -fmodules-cache-path=%t/cache -fmodules -isysroot %t -I %t/usr/include %s -verify<br>
-// RUN: ls -R %t | grep -c ModA.pcm| grep 1<br>
+// RUN: ls -R %t | grep -c "ModA.*pcm" | grep 1<br>
<br>
 // Add a system version file and run again. We should now have two<br>
 // module variants.<br>
 // RUN: mkdir -p %t/System/Library/CoreServices<br>
 // RUN: echo "hello" > %t/System/Library/CoreServices/SystemVersion.plist<br>
 // RUN: %clang_cc1 -fmodules-cache-path=%t/cache -fmodules -isysroot %t -I %t/usr/include %s -verify<br>
-// RUN: ls -R %t | grep -c ModA.pcm| grep 2<br>
+// RUN: ls -R %t | grep -c "ModA.*pcm" | grep 2<br>
<br>
 // Change the system version file and run again. We should now have three<br>
 // module variants.<br>
 // RUN: mkdir -p %t/System/Library/CoreServices<br>
 // RUN: echo "modules" > %t/System/Library/CoreServices/SystemVersion.plist<br>
 // RUN: %clang_cc1 -fmodules-cache-path=%t/cache -fmodules -isysroot %t -I %t/usr/include %s -verify<br>
-// RUN: ls -R %t | grep -c ModA.pcm| grep 3<br>
+// RUN: ls -R %t | grep -c "ModA.*pcm" | grep 3<br>
<br>
 // expected-no-diagnostics<br>
 @import ModA;<br>
<br>
Modified: cfe/trunk/test/PCH/modified-module-dependency.m<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/modified-module-dependency.m?rev=206201&r1=206200&r2=206201&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/modified-module-dependency.m?rev=206201&r1=206200&r2=206201&view=diff</a><br>
==============================================================================<br>
--- cfe/trunk/test/PCH/modified-module-dependency.m (original)<br>
+++ cfe/trunk/test/PCH/modified-module-dependency.m Mon Apr 14 13:00:01 2014<br>
@@ -5,13 +5,13 @@<br>
 // RUN: cp %S/modified-module-dependency.module.map %t-dir/module.map<br>
<br>
 // Precompile prefix.pch.<br>
-// RUN: %clang_cc1 -x objective-c -I %t-dir -fmodules -fmodules-cache-path=%t-dir/cache -emit-pch %t-dir/prefix.h -o %t-dir/prefix.pch<br>
+// RUN: %clang_cc1 -x objective-c -I %t-dir -fmodules -fmodules-cache-path=%t-dir/cache -fdisable-module-hash -emit-pch %t-dir/prefix.h -o %t-dir/prefix.pch<br>
<br>
 // Modify the dependency.<br>
 // RUN: echo ' ' >> %t-dir/test.h<br>
<br>
 // Run and check the diagnostics.<br>
-// RUN: not %clang_cc1 -x objective-c -include-pch %t-dir/prefix.pch -fmodules -fmodules-cache-path=%t-dir/cache -fsyntax-only %s 2> %t-dir/log<br>
+// RUN: not %clang_cc1 -x objective-c -I %t-dir -include-pch %t-dir/prefix.pch -fmodules -fmodules-cache-path=%t-dir/cache -fdisable-module-hash -fsyntax-only %s 2> %t-dir/log<br>
 // RUN: FileCheck %s < %t-dir/log<br>
<br>
 // CHECK: file '[[TEST_H:.*[/\\]test\.h]]' has been modified since the precompiled header '[[PREFIX_PCH:.*/prefix\.pch]]' was built<br>
<br>
<br>
_______________________________________________<br>
cfe-commits mailing list<br>
<a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</blockquote></div><br></div></div>