r206201 - Allow multiple modules with the same name to coexist in the module cache

Richard Smith richard at metafoo.co.uk
Thu Dec 11 13:25:06 PST 2014


On Thu, Dec 11, 2014 at 11:00 AM, Ben Langmuir <blangmuir at apple.com> wrote:

>
> On Dec 11, 2014, at 10:55 AM, Ben Langmuir <blangmuir at apple.com> wrote:
>
>
> On Dec 10, 2014, at 5:42 PM, Richard Smith <richard at metafoo.co.uk> wrote:
>
> On Mon, Apr 14, 2014 at 11:00 AM, Ben Langmuir <blangmuir at apple.com>
> wrote:
>
>> Author: benlangmuir
>> Date: Mon Apr 14 13:00:01 2014
>> New Revision: 206201
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=206201&view=rev
>> Log:
>> Allow multiple modules with the same name to coexist in the module cache
>>
>> To differentiate between two modules with the same name, we will
>> consider the path the module map file that they are defined by* part of
>> the ‘key’ for looking up the precompiled module (pcm file).
>> Specifically, this patch renames the precompiled module (pcm) files from
>>   cache-path/<module hash>/Foo.pcm
>> to
>>   cache-path/<module hash>/Foo-<hash of module map path>.pcm
>>
>> In addition, I’ve taught the ASTReader to re-resolve the names of
>> imported modules during module loading so that if the header search
>> context changes between when a module was originally built and when it
>> is loaded we can rebuild it if necessary.  For example, if module A
>> imports module B
>>
>> first time:
>> clang -I /path/to/A -I /path/to/B ...
>>
>> second time:
>> clang -I /path/to/A -I /different/path/to/B ...
>>
>> will now rebuild A as expected.
>>
>> * in the case of inferred modules, we use the module map file that
>> allowed the inference, not the __inferred_module.map file, since the
>> inferred file path is the same for every inferred module.
>>
>> Added:
>>     cfe/trunk/test/Modules/Inputs/modules-with-same-name/
>>     cfe/trunk/test/Modules/Inputs/modules-with-same-name/DependsOnA/
>>
>> cfe/trunk/test/Modules/Inputs/modules-with-same-name/DependsOnA/DependsOnA.h
>>
>> cfe/trunk/test/Modules/Inputs/modules-with-same-name/DependsOnA/module.modulemap
>>     cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/
>>     cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/A/
>>     cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/A/a.h
>>
>> cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/A/module.modulemap
>>     cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/
>>     cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/A/
>>     cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/A/a.h
>>
>> cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/A/module.modulemap
>>     cfe/trunk/test/Modules/modules-with-same-name.m
>>     cfe/trunk/test/Modules/resolution-change.m
>> Modified:
>>     cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td
>>     cfe/trunk/include/clang/Basic/Module.h
>>     cfe/trunk/include/clang/Frontend/FrontendActions.h
>>     cfe/trunk/include/clang/Lex/HeaderSearch.h
>>     cfe/trunk/include/clang/Lex/ModuleMap.h
>>     cfe/trunk/include/clang/Serialization/ASTBitCodes.h
>>     cfe/trunk/include/clang/Serialization/ASTReader.h
>>     cfe/trunk/include/clang/Serialization/Module.h
>>     cfe/trunk/lib/Basic/Module.cpp
>>     cfe/trunk/lib/Frontend/CompilerInstance.cpp
>>     cfe/trunk/lib/Frontend/FrontendAction.cpp
>>     cfe/trunk/lib/Frontend/FrontendActions.cpp
>>     cfe/trunk/lib/Lex/HeaderSearch.cpp
>>     cfe/trunk/lib/Lex/ModuleMap.cpp
>>     cfe/trunk/lib/Serialization/ASTReader.cpp
>>     cfe/trunk/lib/Serialization/ASTWriter.cpp
>>     cfe/trunk/lib/Serialization/GlobalModuleIndex.cpp
>>     cfe/trunk/lib/Serialization/ModuleManager.cpp
>>     cfe/trunk/test/Index/annotate-module.m
>>     cfe/trunk/test/Index/pch-depending-on-deleted-module.c
>>     cfe/trunk/test/Modules/dependency-gen-pch.m
>>     cfe/trunk/test/Modules/diamond-pch.c
>>     cfe/trunk/test/Modules/macro-undef-through-pch.m
>>     cfe/trunk/test/Modules/prune.m
>>     cfe/trunk/test/Modules/redecls/main.m
>>     cfe/trunk/test/Modules/system_version.m
>>     cfe/trunk/test/PCH/modified-module-dependency.m
>>
>> Modified: cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td
>> (original)
>> +++ cfe/trunk/include/clang/Basic/DiagnosticSerializationKinds.td Mon Apr
>> 14 13:00:01 2014
>> @@ -48,7 +48,12 @@ def err_pch_different_branch : Error<
>>      "PCH file built from a different branch (%0) than the compiler
>> (%1)">;
>>  def err_pch_with_compiler_errors : Error<
>>      "PCH file contains compiler errors">;
>> -
>> +
>> +def err_imported_module_not_found : Error<
>> +    "module '%0' imported by AST file '%1' not found">, DefaultFatal;
>> +def err_imported_module_modmap_changed : Error<
>> +    "module '%0' imported by AST file '%1' found in a different module
>> map file"
>> +    " (%2) than when the importing AST file was built (%3)">,
>> DefaultFatal;
>>  def warn_module_conflict : Warning<
>>      "module '%0' conflicts with already-imported module '%1': %2">,
>>      InGroup<ModuleConflict>;
>>
>> Modified: cfe/trunk/include/clang/Basic/Module.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Module.h?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/Basic/Module.h (original)
>> +++ cfe/trunk/include/clang/Basic/Module.h Mon Apr 14 13:00:01 2014
>> @@ -51,10 +51,21 @@ public:
>>
>>    /// \brief The location of the module definition.
>>    SourceLocation DefinitionLoc;
>> -
>> +
>>    /// \brief The parent of this module. This will be NULL for the
>> top-level
>>    /// module.
>>    Module *Parent;
>> +
>> +  /// \brief The module map file that (along with the module name)
>> uniquely
>> +  /// identifies this module.
>> +  ///
>> +  /// The particular module that \c Name refers to may depend on how the
>> module
>> +  /// was found in header search. However, the combination of \c Name and
>> +  /// \c ModuleMap will be globally unique for top-level modules. In the
>> case of
>> +  /// inferred modules, \c ModuleMap will contain the module map that
>> allowed
>> +  /// the inference (e.g. contained 'Module *') rather than the virtual
>> +  /// inferred module map file.
>> +  const FileEntry *ModuleMap;
>>
>>    /// \brief The umbrella header or directory.
>>    llvm::PointerUnion<const DirectoryEntry *, const FileEntry *> Umbrella;
>> @@ -264,8 +275,10 @@ public:
>>    std::vector<Conflict> Conflicts;
>>
>>    /// \brief Construct a new module or submodule.
>> -  Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
>> -         bool IsFramework, bool IsExplicit);
>> +  ///
>> +  /// For an explanation of \p ModuleMap, see Module::ModuleMap.
>> +  Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent,
>> +         const FileEntry *ModuleMap, bool IsFramework, bool IsExplicit);
>>
>>    ~Module();
>>
>>
>> Modified: cfe/trunk/include/clang/Frontend/FrontendActions.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/FrontendActions.h?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/Frontend/FrontendActions.h (original)
>> +++ cfe/trunk/include/clang/Frontend/FrontendActions.h Mon Apr 14
>> 13:00:01 2014
>> @@ -17,6 +17,7 @@
>>  namespace clang {
>>
>>  class Module;
>> +class FileEntry;
>>
>>
>>  //===----------------------------------------------------------------------===//
>>  // Custom Consumer Actions
>> @@ -92,7 +93,8 @@ public:
>>  };
>>
>>  class GenerateModuleAction : public ASTFrontendAction {
>> -  clang::Module *Module;
>> +  Module *Module;
>> +  const FileEntry *ModuleMapForUniquing;
>>    bool IsSystem;
>>
>>  protected:
>> @@ -106,8 +108,10 @@ protected:
>>    bool hasASTFileSupport() const override { return false; }
>>
>>  public:
>> -  explicit GenerateModuleAction(bool IsSystem = false)
>> -    : ASTFrontendAction(), IsSystem(IsSystem) { }
>> +  GenerateModuleAction(const FileEntry *ModuleMap = nullptr,
>> +                       bool IsSystem = false)
>> +    : ASTFrontendAction(), ModuleMapForUniquing(ModuleMap),
>> IsSystem(IsSystem)
>> +  { }
>>
>>    bool BeginSourceFileAction(CompilerInstance &CI, StringRef Filename)
>> override;
>>
>> @@ -115,11 +119,11 @@ public:
>>    /// create the PCHGenerator instance returned by CreateASTConsumer.
>>    ///
>>    /// \returns true if an error occurred, false otherwise.
>> -  static bool ComputeASTConsumerArguments(CompilerInstance &CI,
>> -                                          StringRef InFile,
>> -                                          std::string &Sysroot,
>> -                                          std::string &OutputFile,
>> -                                          raw_ostream *&OS);
>> +  bool ComputeASTConsumerArguments(CompilerInstance &CI,
>> +                                   StringRef InFile,
>> +                                   std::string &Sysroot,
>> +                                   std::string &OutputFile,
>> +                                   raw_ostream *&OS);
>>  };
>>
>>  class SyntaxOnlyAction : public ASTFrontendAction {
>>
>> Modified: cfe/trunk/include/clang/Lex/HeaderSearch.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/HeaderSearch.h?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/Lex/HeaderSearch.h (original)
>> +++ cfe/trunk/include/clang/Lex/HeaderSearch.h Mon Apr 14 13:00:01 2014
>> @@ -493,9 +493,12 @@ public:
>>    ///
>>    /// \param ModuleName The module whose module file name will be
>> returned.
>>    ///
>> +  /// \param ModuleMapPath A path that when combined with \c ModuleName
>> +  /// uniquely identifies this module. See Module::ModuleMap.
>> +  ///
>>    /// \returns The name of the module file that corresponds to this
>> module,
>>    /// or an empty string if this module does not correspond to any
>> module file.
>> -  std::string getModuleFileName(StringRef ModuleName);
>> +  std::string getModuleFileName(StringRef ModuleName, StringRef
>> ModuleMapPath);
>>
>>    /// \brief Lookup a module Search for a module with the given name.
>>    ///
>>
>> Modified: cfe/trunk/include/clang/Lex/ModuleMap.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Lex/ModuleMap.h?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/Lex/ModuleMap.h (original)
>> +++ cfe/trunk/include/clang/Lex/ModuleMap.h Mon Apr 14 13:00:01 2014
>> @@ -131,6 +131,10 @@ private:
>>      /// \brief Whether the modules we infer are [system] modules.
>>      unsigned InferSystemModules : 1;
>>
>> +    /// \brief If \c InferModules is non-zero, the module map file that
>> allowed
>> +    /// inferred modules.  Otherwise, nullptr.
>> +    const FileEntry *ModuleMapFile;
>> +
>>      /// \brief The names of modules that cannot be inferred within this
>>      /// directory.
>>      SmallVector<std::string, 2> ExcludedModules;
>> @@ -293,13 +297,17 @@ public:
>>    /// \param Parent The module that will act as the parent of this
>> submodule,
>>    /// or NULL to indicate that this is a top-level module.
>>    ///
>> +  /// \param ModuleMap The module map that defines or allows the
>> inference of
>> +  /// this module.
>> +  ///
>>    /// \param IsFramework Whether this is a framework module.
>>    ///
>>    /// \param IsExplicit Whether this is an explicit submodule.
>>    ///
>>    /// \returns The found or newly-created module, along with a boolean
>> value
>>    /// that will be true if the module is newly-created.
>> -  std::pair<Module *, bool> findOrCreateModule(StringRef Name, Module
>> *Parent,
>> +  std::pair<Module *, bool> findOrCreateModule(StringRef Name, Module
>> *Parent,
>> +                                               const FileEntry
>> *ModuleMap,
>>                                                 bool IsFramework,
>>                                                 bool IsExplicit);
>>
>>
>> Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original)
>> +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Mon Apr 14
>> 13:00:01 2014
>> @@ -281,7 +281,14 @@ namespace clang {
>>        HEADER_SEARCH_OPTIONS = 11,
>>
>>        /// \brief Record code for the preprocessor options table.
>> -      PREPROCESSOR_OPTIONS = 12
>> +      PREPROCESSOR_OPTIONS = 12,
>> +
>> +      /// \brief Record code for the module name.
>> +      MODULE_NAME = 13,
>> +
>> +      /// \brief Record code for the module map file that was used to
>> build this
>> +      /// AST file.
>> +      MODULE_MAP_FILE = 14
>>      };
>>
>>      /// \brief Record types that occur within the input-files block
>>
>> Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
>> +++ cfe/trunk/include/clang/Serialization/ASTReader.h Mon Apr 14 13:00:01
>> 2014
>> @@ -1079,6 +1079,7 @@ private:
>>                              unsigned ClientLoadCapabilities);
>>    ASTReadResult ReadControlBlock(ModuleFile &F,
>>                                   SmallVectorImpl<ImportedModule> &Loaded,
>> +                                 const ModuleFile *ImportedBy,
>>                                   unsigned ClientLoadCapabilities);
>>    ASTReadResult ReadASTBlock(ModuleFile &F, unsigned
>> ClientLoadCapabilities);
>>    bool ParseLineTable(ModuleFile &F, SmallVectorImpl<uint64_t> &Record);
>>
>> Modified: cfe/trunk/include/clang/Serialization/Module.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/Module.h?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/include/clang/Serialization/Module.h (original)
>> +++ cfe/trunk/include/clang/Serialization/Module.h Mon Apr 14 13:00:01
>> 2014
>> @@ -116,6 +116,9 @@ public:
>>    /// \brief The file name of the module file.
>>    std::string FileName;
>>
>> +  /// \brief The name of the module.
>> +  std::string ModuleName;
>> +
>>    std::string getTimestampFilename() const {
>>      return FileName + ".timestamp";
>>    }
>> @@ -137,6 +140,8 @@ public:
>>    /// allow resolving headers even after headers+PCH was moved to a new
>> path.
>>    std::string OriginalDir;
>>
>> +  std::string ModuleMapPath;
>> +
>>    /// \brief Whether this precompiled header is a relocatable PCH file.
>>    bool RelocatablePCH;
>>
>>
>> Modified: cfe/trunk/lib/Basic/Module.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/Module.cpp?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Basic/Module.cpp (original)
>> +++ cfe/trunk/lib/Basic/Module.cpp Mon Apr 14 13:00:01 2014
>> @@ -25,8 +25,8 @@
>>  using namespace clang;
>>
>>  Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module
>> *Parent,
>> -               bool IsFramework, bool IsExplicit)
>> -  : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),
>> +               const FileEntry *File, bool IsFramework, bool IsExplicit)
>> +  : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent),
>> ModuleMap(File),
>>      Umbrella(), ASTFile(0), IsAvailable(true), IsFromModuleFile(false),
>>      IsFramework(IsFramework), IsExplicit(IsExplicit), IsSystem(false),
>>      IsExternC(false), InferSubmodules(false),
>> InferExplicitSubmodules(false),
>>
>> Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)
>> +++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Mon Apr 14 13:00:01 2014
>> @@ -870,8 +870,9 @@ static void compileModuleImpl(CompilerIn
>>      SourceMgr.overrideFileContents(ModuleMapFile, ModuleMapBuffer);
>>    }
>>
>> -  // Construct a module-generating action.
>> -  GenerateModuleAction CreateModuleAction(Module->IsSystem);
>> +  // Construct a module-generating action. Passing through
>> Module->ModuleMap is
>> +  // safe because the FileManager is shared between the compiler
>> instances.
>> +  GenerateModuleAction CreateModuleAction(Module->ModuleMap,
>> Module->IsSystem);
>>
>>    // Execute the action to actually build the module in-place. Use a
>> separate
>>    // thread so that we get a stack large enough.
>>
>> Modified: cfe/trunk/lib/Frontend/FrontendAction.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendAction.cpp?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Frontend/FrontendAction.cpp (original)
>> +++ cfe/trunk/lib/Frontend/FrontendAction.cpp Mon Apr 14 13:00:01 2014
>> @@ -256,6 +256,10 @@ bool FrontendAction::BeginSourceFile(Com
>>      if (!BeginSourceFileAction(CI, InputFile))
>>        goto failure;
>>
>> +    // Initialize the main file entry.
>> +    if (!CI.InitializeSourceManager(CurrentInput))
>> +      goto failure;
>> +
>>      return true;
>>    }
>>
>> @@ -302,6 +306,11 @@ bool FrontendAction::BeginSourceFile(Com
>>    if (!BeginSourceFileAction(CI, InputFile))
>>      goto failure;
>>
>> +  // Initialize the main file entry. It is important that this occurs
>> after
>> +  // BeginSourceFileAction, which may change CurrentInput during module
>> builds.
>> +  if (!CI.InitializeSourceManager(CurrentInput))
>> +    goto failure;
>> +
>>    // Create the AST context and consumer unless this is a preprocessor
>> only
>>    // action.
>>    if (!usesPreprocessorOnly()) {
>> @@ -389,13 +398,6 @@ bool FrontendAction::BeginSourceFile(Com
>>  bool FrontendAction::Execute() {
>>    CompilerInstance &CI = getCompilerInstance();
>>
>> -  // Initialize the main file entry. This needs to be delayed until
>> after PCH
>> -  // has loaded.
>> -  if (!isCurrentFileAST()) {
>> -    if (!CI.InitializeSourceManager(getCurrentInput()))
>> -      return false;
>> -  }
>> -
>>    if (CI.hasFrontendTimer()) {
>>      llvm::TimeRegion Timer(CI.getFrontendTimer());
>>      ExecuteAction();
>>
>> Modified: cfe/trunk/lib/Frontend/FrontendActions.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendActions.cpp?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Frontend/FrontendActions.cpp (original)
>> +++ cfe/trunk/lib/Frontend/FrontendActions.cpp Mon Apr 14 13:00:01 2014
>> @@ -299,6 +299,11 @@ bool GenerateModuleAction::BeginSourceFi
>>      return false;
>>    }
>>
>> +  if (!ModuleMapForUniquing)
>> +    ModuleMapForUniquing = ModuleMap;
>> +  Module->ModuleMap = ModuleMapForUniquing;
>> +  assert(Module->ModuleMap && "missing module map file");
>> +
>>    FileManager &FileMgr = CI.getFileManager();
>>
>>    // Collect the set of #includes we need to build the module.
>> @@ -337,10 +342,9 @@ bool GenerateModuleAction::ComputeASTCon
>>    // in the module cache.
>>    if (CI.getFrontendOpts().OutputFile.empty()) {
>>      HeaderSearch &HS = CI.getPreprocessor().getHeaderSearchInfo();
>> -    SmallString<256> ModuleFileName(HS.getModuleCachePath());
>> -    llvm::sys::path::append(ModuleFileName,
>> -                            CI.getLangOpts().CurrentModule + ".pcm");
>> -    CI.getFrontendOpts().OutputFile = ModuleFileName.str();
>> +    CI.getFrontendOpts().OutputFile =
>> +        HS.getModuleFileName(CI.getLangOpts().CurrentModule,
>> +                             ModuleMapForUniquing->getName());
>>    }
>>
>>    // We use createOutputFile here because this is exposed via libclang,
>> and we
>>
>> Modified: cfe/trunk/lib/Lex/HeaderSearch.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/HeaderSearch.cpp?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Lex/HeaderSearch.cpp (original)
>> +++ cfe/trunk/lib/Lex/HeaderSearch.cpp Mon Apr 14 13:00:01 2014
>> @@ -18,6 +18,8 @@
>>  #include "clang/Lex/HeaderSearchOptions.h"
>>  #include "clang/Lex/LexDiagnostic.h"
>>  #include "clang/Lex/Lexer.h"
>> +#include "llvm/ADT/APInt.h"
>> +#include "llvm/ADT/Hashing.h"
>>  #include "llvm/ADT/SmallString.h"
>>  #include "llvm/Support/Capacity.h"
>>  #include "llvm/Support/FileSystem.h"
>> @@ -112,24 +114,33 @@ const HeaderMap *HeaderSearch::CreateHea
>>  }
>>
>>  std::string HeaderSearch::getModuleFileName(Module *Module) {
>> -  // If we don't have a module cache path, we can't do anything.
>> -  if (ModuleCachePath.empty())
>> -    return std::string();
>> -
>> -
>> -  SmallString<256> Result(ModuleCachePath);
>> -  llvm::sys::path::append(Result, Module->getTopLevelModule()->Name +
>> ".pcm");
>> -  return Result.str().str();
>> +  return getModuleFileName(Module->Name, Module->ModuleMap->getName());
>>  }
>>
>> -std::string HeaderSearch::getModuleFileName(StringRef ModuleName) {
>> +std::string HeaderSearch::getModuleFileName(StringRef ModuleName,
>> +                                            StringRef ModuleMapPath) {
>>    // If we don't have a module cache path, we can't do anything.
>>    if (ModuleCachePath.empty())
>>      return std::string();
>> -
>> -
>> +
>>    SmallString<256> Result(ModuleCachePath);
>> -  llvm::sys::path::append(Result, ModuleName + ".pcm");
>> +  llvm::sys::fs::make_absolute(Result);
>> +
>> +  if (HSOpts->DisableModuleHash) {
>> +    llvm::sys::path::append(Result, ModuleName + ".pcm");
>> +  } else {
>> +    // Construct the name <ModuleName>-<hash of ModuleMapPath>.pcm which
>> should
>> +    // be globally unique to this particular module. To avoid
>> false-negatives
>> +    // on case-insensitive filesystems, we use lower-case, which is safe
>> because
>> +    // to cause a collision the modules must have the same name, which
>> is an
>> +    // error if they are imported in the same translation.
>>
>
> Consider:
>
>   foo/module.modulemap defines a module X
>   FOO/module.modulemap also defines a module X
>
> 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?)
>
>
> The hash in the filename isn’t functionally necessary, since we can
> rebuild a module if the module map path has changed since it was built.  If
> we attempt to load a module with a hash collision (as in this case) we will
> discover that the module map path has changed in ReadModuleMapFileBlock,
> and rebuild it.  Obviously that sucks if you really have both FOO and foo.
>
>
> To be clear: the hash prevents excessive rebuilding, but currently falls
> over in edge case.
>

I've tried to clarify this comment in r224055, as well as adding a call to
realpath here; we could get into a situation where a module map file was
named as '/foo/module.map' in some cases and as '/foo/./module.map' in
others, and that resulted in rejects-valids (and crashes if we managed to
get two module files providing the same module loaded into the same
compilation -- we don't actually appear to guard against this).

> The problem this code solves on a case-insensitive filesystem:
> * I have two modules, A and B.  A imports B.  B is in some directory name
> foo.
> * I build A.pcm with -I FOO
> * I build a TU that imports B and then A, but specify -I foo.
>
> So when I import B, it will be “missing” if the hash of “foo" is different
> than “FOO".  And then when I load A, it will pull in the other B.pcm,
> leading to an error.
>
>
> I’m open to solving this some other way if you have ideas :-)  I looked at
> getting the canonical casing for the path, but IIRC it was really expensive
> on Windows and basically required doing a listdir on every component of the
> path.
>
> Ben
>
>
>
>> +    SmallString<256> AbsModuleMapPath(ModuleMapPath);
>> +    llvm::sys::fs::make_absolute(AbsModuleMapPath);
>> +    llvm::APInt Code(64,
>> llvm::hash_value(AbsModuleMapPath.str().lower()));
>> +    SmallString<128> HashStr;
>> +    Code.toStringUnsigned(HashStr, /*Radix*/36);
>> +    llvm::sys::path::append(Result, ModuleName + "-" + HashStr.str() +
>> ".pcm");
>> +  }
>>    return Result.str().str();
>>  }
>>
>>
>> Modified: cfe/trunk/lib/Lex/ModuleMap.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/ModuleMap.cpp?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Lex/ModuleMap.cpp (original)
>> +++ cfe/trunk/lib/Lex/ModuleMap.cpp Mon Apr 14 13:00:01 2014
>> @@ -363,8 +363,8 @@ ModuleMap::findModuleForHeader(const Fil
>>          SmallString<32> NameBuf;
>>          StringRef Name = sanitizeFilenameAsIdentifier(
>>              llvm::sys::path::stem(SkippedDirs[I-1]->getName()), NameBuf);
>> -        Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
>> -                                    Explicit).first;
>> +        Result = findOrCreateModule(Name, Result,
>> UmbrellaModule->ModuleMap,
>> +                                    /*IsFramework=*/false,
>> Explicit).first;
>>
>>          // Associate the module and the directory.
>>          UmbrellaDirs[SkippedDirs[I-1]] = Result;
>> @@ -378,9 +378,9 @@ ModuleMap::findModuleForHeader(const Fil
>>        // Infer a submodule with the same name as this header file.
>>        SmallString<32> NameBuf;
>>        StringRef Name = sanitizeFilenameAsIdentifier(
>> -
>> llvm::sys::path::stem(File->getName()), NameBuf);
>> -      Result = findOrCreateModule(Name, Result, /*IsFramework=*/false,
>> -                                  Explicit).first;
>> +                         llvm::sys::path::stem(File->getName()),
>> NameBuf);
>> +      Result = findOrCreateModule(Name, Result,
>> UmbrellaModule->ModuleMap,
>> +                                  /*IsFramework=*/false, Explicit).first;
>>        Result->addTopHeader(File);
>>
>>        // If inferred submodules export everything they import, add a
>> @@ -518,15 +518,16 @@ Module *ModuleMap::lookupModuleQualified
>>  }
>>
>>  std::pair<Module *, bool>
>> -ModuleMap::findOrCreateModule(StringRef Name, Module *Parent, bool
>> IsFramework,
>> +ModuleMap::findOrCreateModule(StringRef Name, Module *Parent,
>> +                              const FileEntry *ModuleMap, bool
>> IsFramework,
>>                                bool IsExplicit) {
>>    // Try to find an existing module with this name.
>>    if (Module *Sub = lookupModuleQualified(Name, Parent))
>>      return std::make_pair(Sub, false);
>>
>>    // Create a new module with this name.
>> -  Module *Result = new Module(Name, SourceLocation(), Parent,
>> IsFramework,
>> -                              IsExplicit);
>> +  Module *Result = new Module(Name, SourceLocation(), Parent, ModuleMap,
>> +                              IsFramework, IsExplicit);
>>    if (LangOpts.CurrentModule == Name) {
>>      SourceModule = Result;
>>      SourceModuleName = Name;
>> @@ -595,6 +596,7 @@ ModuleMap::inferFrameworkModule(StringRe
>>
>>    // If the framework has a parent path from which we're allowed to infer
>>    // a framework module, do so.
>> +  const FileEntry *ModuleMapFile = nullptr;
>>    if (!Parent) {
>>      // Determine whether we're allowed to infer a module map.
>>
>> @@ -639,6 +641,7 @@ ModuleMap::inferFrameworkModule(StringRe
>>
>>            if (inferred->second.InferSystemModules)
>>              IsSystem = true;
>> +          ModuleMapFile = inferred->second.ModuleMapFile;
>>          }
>>        }
>>      }
>> @@ -646,7 +649,8 @@ ModuleMap::inferFrameworkModule(StringRe
>>      // If we're not allowed to infer a framework module, don't.
>>      if (!canInfer)
>>        return 0;
>> -  }
>> +  } else
>> +    ModuleMapFile = Parent->ModuleMap;
>>
>>
>>    // Look for an umbrella header.
>> @@ -660,7 +664,7 @@ ModuleMap::inferFrameworkModule(StringRe
>>    if (!UmbrellaHeader)
>>      return 0;
>>
>> -  Module *Result = new Module(ModuleName, SourceLocation(), Parent,
>> +  Module *Result = new Module(ModuleName, SourceLocation(), Parent,
>> ModuleMapFile,
>>                                /*IsFramework=*/true,
>> /*IsExplicit=*/false);
>>    if (LangOpts.CurrentModule == ModuleName) {
>>      SourceModule = Result;
>> @@ -954,6 +958,9 @@ namespace clang {
>>
>>      DiagnosticsEngine &Diags;
>>      ModuleMap ⤅
>> +
>> +    /// \brief The current module map file.
>> +    const FileEntry *ModuleMapFile;
>>
>>      /// \brief The directory that this module map resides in.
>>      const DirectoryEntry *Directory;
>> @@ -1007,12 +1014,14 @@ namespace clang {
>>                               const TargetInfo *Target,
>>                               DiagnosticsEngine &Diags,
>>                               ModuleMap &Map,
>> +                             const FileEntry *ModuleMapFile,
>>                               const DirectoryEntry *Directory,
>>                               const DirectoryEntry *BuiltinIncludeDir,
>>                               bool IsSystem)
>>        : L(L), SourceMgr(SourceMgr), Target(Target), Diags(Diags),
>> Map(Map),
>> -        Directory(Directory), BuiltinIncludeDir(BuiltinIncludeDir),
>> -        IsSystem(IsSystem), HadError(false), ActiveModule(0)
>> +        ModuleMapFile(ModuleMapFile), Directory(Directory),
>> +        BuiltinIncludeDir(BuiltinIncludeDir), IsSystem(IsSystem),
>> +        HadError(false), ActiveModule(0)
>>      {
>>        Tok.clear();
>>        consumeToken();
>> @@ -1359,9 +1368,14 @@ void ModuleMapParser::parseModuleDecl()
>>      return;
>>    }
>>
>> +  // If this is a submodule, use the parent's module map, since we don't
>> want
>> +  // the private module map file.
>> +  const FileEntry *ModuleMap = ActiveModule ? ActiveModule->ModuleMap
>> +                                            : ModuleMapFile;
>> +
>>    // Start defining this module.
>> -  ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule,
>> Framework,
>> -                                        Explicit).first;
>> +  ActiveModule = Map.findOrCreateModule(ModuleName, ActiveModule,
>> ModuleMap,
>> +                                        Framework, Explicit).first;
>>    ActiveModule->DefinitionLoc = ModuleNameLoc;
>>    if (Attrs.IsSystem || IsSystem)
>>      ActiveModule->IsSystem = true;
>> @@ -2020,6 +2034,7 @@ void ModuleMapParser::parseInferredModul
>>      // We'll be inferring framework modules for this directory.
>>      Map.InferredDirectories[Directory].InferModules = true;
>>      Map.InferredDirectories[Directory].InferSystemModules =
>> Attrs.IsSystem;
>> +    Map.InferredDirectories[Directory].ModuleMapFile = ModuleMapFile;
>>      // FIXME: Handle the 'framework' keyword.
>>    }
>>
>> @@ -2256,7 +2271,7 @@ bool ModuleMap::parseModuleMapFile(const
>>
>>    // Parse this module map file.
>>    Lexer L(ID, SourceMgr.getBuffer(ID), SourceMgr, MMapLangOpts);
>> -  ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, Dir,
>> +  ModuleMapParser Parser(L, SourceMgr, Target, Diags, *this, File, Dir,
>>                           BuiltinIncludeDir, IsSystem);
>>    bool Result = Parser.parseModuleMapFile();
>>    ParsedModuleMap[File] = Result;
>>
>> Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
>> +++ cfe/trunk/lib/Serialization/ASTReader.cpp Mon Apr 14 13:00:01 2014
>> @@ -1161,7 +1161,7 @@ std::pair<SourceLocation, StringRef> AST
>>
>>    // FIXME: Can we map this down to a particular submodule? That would be
>>    // ideal.
>> -  return std::make_pair(M->ImportLoc,
>> llvm::sys::path::stem(M->FileName));
>> +  return std::make_pair(M->ImportLoc, StringRef(M->ModuleName));
>>  }
>>
>>  /// \brief Find the location where the module F is imported.
>> @@ -1172,14 +1172,10 @@ SourceLocation ASTReader::getImportLocat
>>    // Otherwise we have a PCH. It's considered to be "imported" at the
>> first
>>    // location of its includer.
>>    if (F->ImportedBy.empty() || !F->ImportedBy[0]) {
>> -    // Main file is the importer. We assume that it is the first entry
>> in the
>> -    // entry table. We can't ask the manager, because at the time of PCH
>> loading
>> -    // the main file entry doesn't exist yet.
>> -    // The very first entry is the invalid instantiation loc, which
>> takes up
>> -    // offsets 0 and 1.
>> -    return SourceLocation::getFromRawEncoding(2U);
>> +    // Main file is the importer.
>> +    assert(!SourceMgr.getMainFileID().isInvalid() && "missing main
>> file");
>> +    return SourceMgr.getLocForStartOfFile(SourceMgr.getMainFileID());
>>    }
>> -  //return F->Loaders[0]->FirstLoc;
>>    return F->ImportedBy[0]->FirstLoc;
>>  }
>>
>> @@ -2089,6 +2085,7 @@ void ASTReader::MaybeAddSystemRootToFile
>>  ASTReader::ASTReadResult
>>  ASTReader::ReadControlBlock(ModuleFile &F,
>>                              SmallVectorImpl<ImportedModule> &Loaded,
>> +                            const ModuleFile *ImportedBy,
>>                              unsigned ClientLoadCapabilities) {
>>    BitstreamCursor &Stream = F.Stream;
>>
>> @@ -2314,6 +2311,44 @@ ASTReader::ReadControlBlock(ModuleFile &
>>        F.OriginalDir = Blob;
>>        break;
>>
>> +    case MODULE_NAME:
>> +      F.ModuleName = Blob;
>> +      break;
>> +
>> +    case MODULE_MAP_FILE:
>> +      F.ModuleMapPath = Blob;
>> +
>> +      // Try to resolve ModuleName in the current header search context
>> and
>> +      // verify that it is found in the same module map file as we
>> saved. If the
>> +      // top-level AST file is a main file, skip this check because
>> there is no
>> +      // usable header search context.
>> +      assert(!F.ModuleName.empty() &&
>> +             "MODULE_NAME should come before MOUDLE_MAP_FILE");
>> +      if (F.Kind == MK_Module &&
>> +          (*ModuleMgr.begin())->Kind != MK_MainFile) {
>> +        Module *M = PP.getHeaderSearchInfo().lookupModule(F.ModuleName);
>> +        if (!M) {
>> +          assert(ImportedBy && "top-level import should be verified");
>> +          if ((ClientLoadCapabilities & ARR_Missing) == 0)
>> +            Diag(diag::err_imported_module_not_found)
>> +              << F.ModuleName << ImportedBy->FileName;
>> +          return Missing;
>> +        }
>> +
>> +        const FileEntry *StoredModMap = FileMgr.getFile(F.ModuleMapPath);
>> +        if (StoredModMap == nullptr || StoredModMap != M->ModuleMap) {
>> +          assert(M->ModuleMap && "found module is missing module map
>> file");
>> +          assert(M->Name == F.ModuleName && "found module with different
>> name");
>> +          assert(ImportedBy && "top-level import should be verified");
>> +          if ((ClientLoadCapabilities & ARR_OutOfDate) == 0)
>> +            Diag(diag::err_imported_module_modmap_changed)
>> +              << F.ModuleName << ImportedBy->FileName
>> +              << M->ModuleMap->getName() << F.ModuleMapPath;
>> +          return OutOfDate;
>> +        }
>> +      }
>> +      break;
>> +
>>      case INPUT_FILE_OFFSETS:
>>        F.InputFileOffsets = (const uint32_t *)Blob.data();
>>        F.InputFilesLoaded.resize(Record[0]);
>> @@ -3537,7 +3572,7 @@ ASTReader::ReadASTCore(StringRef FileNam
>>        break;
>>      case CONTROL_BLOCK_ID:
>>        HaveReadControlBlock = true;
>> -      switch (ReadControlBlock(F, Loaded, ClientLoadCapabilities)) {
>> +      switch (ReadControlBlock(F, Loaded, ImportedBy,
>> ClientLoadCapabilities)) {
>>        case Success:
>>          break;
>>
>> @@ -4059,13 +4094,19 @@ ASTReader::ReadSubmoduleBlock(ModuleFile
>>        bool InferExportWildcard = Record[Idx++];
>>        bool ConfigMacrosExhaustive = Record[Idx++];
>>
>> -      Module *ParentModule = 0;
>> -      if (Parent)
>> +      Module *ParentModule = nullptr;
>> +      const FileEntry *ModuleMap = nullptr;
>> +      if (Parent) {
>>          ParentModule = getSubmodule(Parent);
>> -
>> +        ModuleMap = ParentModule->ModuleMap;
>> +      }
>> +
>> +      if (!F.ModuleMapPath.empty())
>> +        ModuleMap = FileMgr.getFile(F.ModuleMapPath);
>> +
>>        // Retrieve this (sub)module from the module map, creating it if
>>        // necessary.
>> -      CurrentModule = ModMap.findOrCreateModule(Name, ParentModule,
>> +      CurrentModule = ModMap.findOrCreateModule(Name, ParentModule,
>> ModuleMap,
>>                                                  IsFramework,
>>                                                  IsExplicit).first;
>>        SubmoduleID GlobalIndex = GlobalID - NUM_PREDEF_SUBMODULE_IDS;
>> @@ -4090,7 +4131,7 @@ ASTReader::ReadSubmoduleBlock(ModuleFile
>>
>>          CurrentModule->setASTFile(F.File);
>>        }
>> -
>> +
>>        CurrentModule->IsFromModuleFile = true;
>>        CurrentModule->IsSystem = IsSystem || CurrentModule->IsSystem;
>>        CurrentModule->IsExternC = IsExternC;
>>
>> Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original)
>> +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Mon Apr 14 13:00:01 2014
>> @@ -798,6 +798,8 @@ void ASTWriter::WriteBlockInfoBlock() {
>>    // Control Block.
>>    BLOCK(CONTROL_BLOCK);
>>    RECORD(METADATA);
>> +  RECORD(MODULE_NAME);
>> +  RECORD(MODULE_MAP_FILE);
>>    RECORD(IMPORTS);
>>    RECORD(LANGUAGE_OPTIONS);
>>    RECORD(TARGET_OPTIONS);
>> @@ -1050,6 +1052,32 @@ void ASTWriter::WriteControlBlock(Prepro
>>    Stream.EmitRecordWithBlob(MetadataAbbrevCode, Record,
>>                              getClangFullRepositoryVersion());
>>
>> +  // Module name
>> +  if (WritingModule) {
>> +    BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
>> +    Abbrev->Add(BitCodeAbbrevOp(MODULE_NAME));
>> +    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Name
>> +    unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev);
>> +    RecordData Record;
>> +    Record.push_back(MODULE_NAME);
>> +    Stream.EmitRecordWithBlob(AbbrevCode, Record, WritingModule->Name);
>> +  }
>> +
>> +  // Module map file
>> +  if (WritingModule) {
>> +    BitCodeAbbrev *Abbrev = new BitCodeAbbrev();
>> +    Abbrev->Add(BitCodeAbbrevOp(MODULE_MAP_FILE));
>> +    Abbrev->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::Blob)); // Filename
>> +    unsigned AbbrevCode = Stream.EmitAbbrev(Abbrev);
>> +
>> +    assert(WritingModule->ModuleMap && "missing module map");
>> +    SmallString<128> ModuleMap(WritingModule->ModuleMap->getName());
>> +    llvm::sys::fs::make_absolute(ModuleMap);
>> +    RecordData Record;
>> +    Record.push_back(MODULE_MAP_FILE);
>> +    Stream.EmitRecordWithBlob(AbbrevCode, Record, ModuleMap.str());
>> +  }
>> +
>>    // Imports
>>    if (Chain) {
>>      serialization::ModuleManager &Mgr = Chain->getModuleManager();
>> @@ -1065,7 +1093,6 @@ void ASTWriter::WriteControlBlock(Prepro
>>        AddSourceLocation((*M)->ImportLoc, Record);
>>        Record.push_back((*M)->File->getSize());
>>        Record.push_back((*M)->File->getModificationTime());
>> -      // FIXME: This writes the absolute path for AST files we depend on.
>>        const std::string &FileName = (*M)->FileName;
>>        Record.push_back(FileName.size());
>>        Record.append(FileName.begin(), FileName.end());
>>
>> Modified: cfe/trunk/lib/Serialization/GlobalModuleIndex.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/GlobalModuleIndex.cpp?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Serialization/GlobalModuleIndex.cpp (original)
>> +++ cfe/trunk/lib/Serialization/GlobalModuleIndex.cpp Mon Apr 14 13:00:01
>> 2014
>> @@ -14,6 +14,7 @@
>>  #include "ASTReaderInternals.h"
>>  #include "clang/Basic/FileManager.h"
>>  #include "clang/Basic/OnDiskHashTable.h"
>> +#include "clang/Lex/HeaderSearch.h"
>>  #include "clang/Serialization/ASTBitCodes.h"
>>  #include "clang/Serialization/GlobalModuleIndex.h"
>>  #include "clang/Serialization/Module.h"
>> @@ -203,7 +204,12 @@ GlobalModuleIndex::GlobalModuleIndex(llv
>>        assert(Idx == Record.size() && "More module info?");
>>
>>        // Record this module as an unresolved module.
>> -      UnresolvedModules[llvm::sys::path::stem(Modules[ID].FileName)] =
>> ID;
>> +      // FIXME: this doesn't work correctly for module names containing
>> path
>> +      // separators.
>> +      StringRef ModuleName = llvm::sys::path::stem(Modules[ID].FileName);
>> +      // Remove the -<hash of ModuleMapPath>
>> +      ModuleName = ModuleName.rsplit('-').first;
>> +      UnresolvedModules[ModuleName] = ID;
>>        break;
>>      }
>>
>> @@ -308,7 +314,7 @@ bool GlobalModuleIndex::lookupIdentifier
>>
>>  bool GlobalModuleIndex::loadedModuleFile(ModuleFile *File) {
>>    // Look for the module in the global module index based on the module
>> name.
>> -  StringRef Name = llvm::sys::path::stem(File->FileName);
>> +  StringRef Name = File->ModuleName;
>>    llvm::StringMap<unsigned>::iterator Known =
>> UnresolvedModules.find(Name);
>>    if (Known == UnresolvedModules.end()) {
>>      return true;
>>
>> Modified: cfe/trunk/lib/Serialization/ModuleManager.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ModuleManager.cpp?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/lib/Serialization/ModuleManager.cpp (original)
>> +++ cfe/trunk/lib/Serialization/ModuleManager.cpp Mon Apr 14 13:00:01 2014
>> @@ -11,6 +11,7 @@
>>  //  modules for the ASTReader.
>>  //
>>
>>  //===----------------------------------------------------------------------===//
>> +#include "clang/Lex/HeaderSearch.h"
>>  #include "clang/Lex/ModuleMap.h"
>>  #include "clang/Serialization/GlobalModuleIndex.h"
>>  #include "clang/Serialization/ModuleManager.h"
>> @@ -155,7 +156,7 @@ void ModuleManager::removeModules(Module
>>
>>      FileMgr.invalidateCache((*victim)->File);
>>      if (modMap) {
>> -      StringRef ModuleName = llvm::sys::path::stem((*victim)->FileName);
>> +      StringRef ModuleName = (*victim)->ModuleName;
>>        if (Module *mod = modMap->findModule(ModuleName)) {
>>          mod->setASTFile(0);
>>        }
>> @@ -429,7 +430,7 @@ namespace llvm {
>>      }
>>
>>      std::string getNodeLabel(ModuleFile *M, const ModuleManager&) {
>> -      return llvm::sys::path::stem(M->FileName);
>> +      return M->ModuleName;
>>      }
>>    };
>>  }
>>
>> Modified: cfe/trunk/test/Index/annotate-module.m
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/annotate-module.m?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/Index/annotate-module.m (original)
>> +++ cfe/trunk/test/Index/annotate-module.m Mon Apr 14 13:00:01 2014
>> @@ -44,6 +44,6 @@ int glob;
>>  // RUN: c-index-test -cursor-at=%s:3:11 %s -fmodules-cache-path=%t.cache
>> -fmodules -F %S/../Modules/Inputs \
>>  // RUN:     | FileCheck %s -check-prefix=CHECK-CURSOR
>>
>> -// 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):
>> +// 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):
>>  // CHECK-CURSOR-NEXT: {{.*}}other.h
>>  // CHECK-CURSOR-NEXT: {{.*}}DependsOnModule.h
>>
>> Modified: cfe/trunk/test/Index/pch-depending-on-deleted-module.c
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/pch-depending-on-deleted-module.c?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/Index/pch-depending-on-deleted-module.c (original)
>> +++ cfe/trunk/test/Index/pch-depending-on-deleted-module.c Mon Apr 14
>> 13:00:01 2014
>> @@ -4,10 +4,10 @@
>>  // RUN: mkdir %t
>>
>>  // 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
>> -// RUN: %clang_cc1 -fmodules -fdisable-module-hash
>> -fmodules-cache-path=%t/modules-cache -verify-pch %t/use_LibA.pch
>> +// RUN: %clang_cc1 -fmodules -fdisable-module-hash
>> -fmodules-cache-path=%t/modules-cache -I %S/Inputs/Headers -verify-pch
>> %t/use_LibA.pch
>>  // RUN: rm -f %t/modules-cache/LibA.pcm
>> -// 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
>> -// 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
>> +// 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
>> +// 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
>>
>>  // VERIFY: fatal error: malformed or corrupted AST file: 'Unable to load
>> module
>>  // INDEX: {{^}}Failure: AST deserialization error occurred{{$}}
>>
>> Added:
>> cfe/trunk/test/Modules/Inputs/modules-with-same-name/DependsOnA/DependsOnA.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/modules-with-same-name/DependsOnA/DependsOnA.h?rev=206201&view=auto
>>
>> ==============================================================================
>> ---
>> cfe/trunk/test/Modules/Inputs/modules-with-same-name/DependsOnA/DependsOnA.h
>> (added)
>> +++
>> cfe/trunk/test/Modules/Inputs/modules-with-same-name/DependsOnA/DependsOnA.h
>> Mon Apr 14 13:00:01 2014
>> @@ -0,0 +1 @@
>> + at import A;
>>
>> Added:
>> cfe/trunk/test/Modules/Inputs/modules-with-same-name/DependsOnA/module.modulemap
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/modules-with-same-name/DependsOnA/module.modulemap?rev=206201&view=auto
>>
>> ==============================================================================
>> ---
>> cfe/trunk/test/Modules/Inputs/modules-with-same-name/DependsOnA/module.modulemap
>> (added)
>> +++
>> cfe/trunk/test/Modules/Inputs/modules-with-same-name/DependsOnA/module.modulemap
>> Mon Apr 14 13:00:01 2014
>> @@ -0,0 +1,4 @@
>> +module DependsOnA {
>> +  header "DependsOnA.h"
>> +  export *
>> +}
>>
>> Added: cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/A/a.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/A/a.h?rev=206201&view=auto
>>
>> ==============================================================================
>> --- cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/A/a.h
>> (added)
>> +++ cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/A/a.h Mon
>> Apr 14 13:00:01 2014
>> @@ -0,0 +1 @@
>> +#define FROM_PATH 1
>>
>> Added:
>> cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/A/module.modulemap
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/A/module.modulemap?rev=206201&view=auto
>>
>> ==============================================================================
>> ---
>> cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/A/module.modulemap
>> (added)
>> +++
>> cfe/trunk/test/Modules/Inputs/modules-with-same-name/path1/A/module.modulemap
>> Mon Apr 14 13:00:01 2014
>> @@ -0,0 +1,3 @@
>> +module A {
>> +  header "a.h"
>> +}
>>
>> Added: cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/A/a.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/A/a.h?rev=206201&view=auto
>>
>> ==============================================================================
>> --- cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/A/a.h
>> (added)
>> +++ cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/A/a.h Mon
>> Apr 14 13:00:01 2014
>> @@ -0,0 +1 @@
>> +#define FROM_PATH 2
>>
>> Added:
>> cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/A/module.modulemap
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/A/module.modulemap?rev=206201&view=auto
>>
>> ==============================================================================
>> ---
>> cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/A/module.modulemap
>> (added)
>> +++
>> cfe/trunk/test/Modules/Inputs/modules-with-same-name/path2/A/module.modulemap
>> Mon Apr 14 13:00:01 2014
>> @@ -0,0 +1,3 @@
>> +module A {
>> +  header "a.h"
>> +}
>>
>> Modified: cfe/trunk/test/Modules/dependency-gen-pch.m
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/dependency-gen-pch.m?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/Modules/dependency-gen-pch.m (original)
>> +++ cfe/trunk/test/Modules/dependency-gen-pch.m Mon Apr 14 13:00:01 2014
>> @@ -1,7 +1,7 @@
>>  // RUN: rm -rf %t-mcp
>>  // RUN: mkdir -p %t-mcp
>>
>> -// 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
>> +// 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
>>  // RUN: FileCheck %s < %t.d
>>  // CHECK: dependency-gen-pch.m.o
>>  // CHECK-NEXT: dependency-gen-pch.m
>>
>> Modified: cfe/trunk/test/Modules/diamond-pch.c
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/diamond-pch.c?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/Modules/diamond-pch.c (original)
>> +++ cfe/trunk/test/Modules/diamond-pch.c Mon Apr 14 13:00:01 2014
>> @@ -4,7 +4,7 @@
>>  // RUN: %clang_cc1 -fmodules -x objective-c -emit-module
>> -fmodules-cache-path=%t -fmodule-name=diamond_right %S/Inputs/module.map
>>  // RUN: %clang_cc1 -fmodules -x objective-c -emit-module
>> -fmodules-cache-path=%t -fmodule-name=diamond_bottom %S/Inputs/module.map
>>  // RUN: %clang_cc1 -fmodules -x objective-c -emit-pch
>> -fmodules-cache-path=%t -I %S/Inputs -o %t.pch %S/Inputs/diamond.h
>> -// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t
>> -include-pch %t.pch %s -verify
>> +// RUN: %clang_cc1 -fmodules -x objective-c -fmodules-cache-path=%t
>> -include-pch %t.pch %s -I %S/Inputs -verify
>>  // FIXME: When we have a syntax for modules in C, use that.
>>
>>  void test_diamond(int i, float f, double d, char c) {
>>
>> Modified: cfe/trunk/test/Modules/macro-undef-through-pch.m
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/macro-undef-through-pch.m?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/Modules/macro-undef-through-pch.m (original)
>> +++ cfe/trunk/test/Modules/macro-undef-through-pch.m Mon Apr 14 13:00:01
>> 2014
>> @@ -2,7 +2,9 @@
>>  // RUN: %clang_cc1 -x objective-c-header -fmodules
>> -fmodules-cache-path=%t \
>>  // RUN:            -I%S/Inputs/macro-undef-through-pch -emit-pch \
>>  // RUN:            %S/Inputs/macro-undef-through-pch/foo.h -o %t.pch
>> -// RUN: %clang_cc1 -x objective-c -fmodules -fmodules-cache-path=%t
>> -include-pch %t.pch %s
>> +// RUN: %clang_cc1 -x objective-c -fmodules -fmodules-cache-path=%t \
>> +// RUN:            -I%S/Inputs/macro-undef-through-pch -emit-pch \
>> +// RUN:            -include-pch %t.pch %s
>>
>>  // PR19215
>>  #undef AB
>>
>> Added: cfe/trunk/test/Modules/modules-with-same-name.m
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/modules-with-same-name.m?rev=206201&view=auto
>>
>> ==============================================================================
>> --- cfe/trunk/test/Modules/modules-with-same-name.m (added)
>> +++ cfe/trunk/test/Modules/modules-with-same-name.m Mon Apr 14 13:00:01
>> 2014
>> @@ -0,0 +1,35 @@
>> +// REQUIRES: shell
>> +// RUN: rm -rf %t
>> +
>> +// A from path 1
>> +// 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
>> +
>> +// A from path 2
>> +// 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
>> +
>> +// Confirm that we have two pcm files (one for each 'A').
>> +// RUN: find %t -name "A-*.pcm" | count 2
>> +
>> +// DependsOnA, using A from path 1
>> +// 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
>> +
>> +// Confirm that we have three pcm files (one for each 'A', and one for
>> 'DependsOnA')
>> +// RUN: find %t -name "*.pcm" | count 3
>> +
>> +// DependsOnA, using A from path 2
>> +// 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
>> +
>> +// Confirm that we still have three pcm files, since DependsOnA will be
>> rebuilt
>> +// RUN: find %t -name "*.pcm" | count 3
>> +
>> +#ifdef DIRECT
>> + at import A;
>> +#else
>> + at import DependsOnA;
>> +#endif
>> +
>> +#if FROM_PATH != EXPECTED_PATH
>> +#error "Got the wrong module!"
>> +#endif
>> +
>> +// expected-no-diagnostics
>>
>> Modified: cfe/trunk/test/Modules/prune.m
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/prune.m?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/Modules/prune.m (original)
>> +++ cfe/trunk/test/Modules/prune.m Mon Apr 14 13:00:01 2014
>> @@ -14,33 +14,33 @@
>>  // RUN: %clang_cc1 -DIMPORT_DEPENDS_ON_MODULE
>> -fmodules-ignore-macro=DIMPORT_DEPENDS_ON_MODULE -fmodules -F %S/Inputs
>> -fmodules-cache-path=%t %s -verify
>>  // RUN: %clang_cc1 -DIMPORT_DEPENDS_ON_MODULE
>> -fmodules-ignore-macro=DIMPORT_DEPENDS_ON_MODULE -fmodules -F %S/Inputs
>> -fmodules-cache-path=%t %s -verify
>>  // RUN: ls %t | grep modules.timestamp
>> -// RUN: ls -R %t | grep ^Module.pcm
>> -// RUN: ls -R %t | grep DependsOnModule.pcm
>> +// RUN: ls -R %t | grep ^Module.*pcm
>> +// RUN: ls -R %t | grep DependsOnModule.*pcm
>>
>>  // Set the timestamp back more than two days. We should try to prune,
>>  // but nothing gets pruned because the module files are new enough.
>>  // RUN: touch -m -a -t 201101010000 %t/modules.timestamp
>>  // RUN: %clang_cc1 -fmodules -F %S/Inputs -fmodules-cache-path=%t
>> -fmodules -fmodules-prune-interval=172800 -fmodules-prune-after=345600 %s
>> -verify
>>  // RUN: ls %t | grep modules.timestamp
>> -// RUN: ls -R %t | grep ^Module.pcm
>> -// RUN: ls -R %t | grep DependsOnModule.pcm
>> +// RUN: ls -R %t | grep ^Module.*pcm
>> +// RUN: ls -R %t | grep DependsOnModule.*pcm
>>
>>  // Set the DependsOnModule access time back more than four days.
>>  // This shouldn't prune anything, because the timestamp has been
>> updated, so
>>  // the pruning mechanism won't fire.
>> -// RUN: find %t -name DependsOnModule.pcm | xargs touch -a -t
>> 201101010000
>> +// RUN: find %t -name DependsOnModule*.pcm | xargs touch -a -t
>> 201101010000
>>  // RUN: %clang_cc1 -fmodules -F %S/Inputs -fmodules-cache-path=%t
>> -fmodules -fmodules-prune-interval=172800 -fmodules-prune-after=345600 %s
>> -verify
>>  // RUN: ls %t | grep modules.timestamp
>> -// RUN: ls -R %t | grep ^Module.pcm
>> -// RUN: ls -R %t | grep DependsOnModule.pcm
>> +// RUN: ls -R %t | grep ^Module.*pcm
>> +// RUN: ls -R %t | grep DependsOnModule.*pcm
>>
>>  // Set both timestamp and DependsOnModule.pcm back beyond the cutoff.
>>  // This should trigger pruning, which will remove DependsOnModule but
>> not Module.
>>  // RUN: touch -m -a -t 201101010000 %t/modules.timestamp
>> -// RUN: find %t -name DependsOnModule.pcm | xargs touch -a -t
>> 201101010000
>> +// RUN: find %t -name DependsOnModule..pcm | xargs touch -a -t
>> 201101010000
>>  // RUN: %clang_cc1 -fmodules -F %S/Inputs -fmodules-cache-path=%t
>> -fmodules -fmodules-prune-interval=172800 -fmodules-prune-after=345600 %s
>> -verify
>>  // RUN: ls %t | grep modules.timestamp
>> -// RUN: ls -R %t | grep ^Module.pcm
>> -// RUN: ls -R %t | not grep DependsOnModule.pcm
>> +// RUN: ls -R %t | grep ^Module.*pcm
>> +// RUN: ls -R %t | not grep DependsOnModule.*pcm
>>
>>  // expected-no-diagnostics
>>
>> Modified: cfe/trunk/test/Modules/redecls/main.m
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/redecls/main.m?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/Modules/redecls/main.m (original)
>> +++ cfe/trunk/test/Modules/redecls/main.m Mon Apr 14 13:00:01 2014
>> @@ -3,7 +3,7 @@
>>  // RUN: %clang_cc1 -fmodules -x objective-c -emit-module -fmodule-name=b
>> %S/module.map -fmodules-cache-path=%t.mcp
>>  // RUN: %clang_cc1 -fmodules %s -emit-pch -o %t1.pch
>> -fmodules-cache-path=%t.mcp -I %S
>>  // RUN: %clang_cc1 -fmodules %s -emit-pch -o %t2.pch -include-pch
>> %t1.pch -fmodules-cache-path=%t.mcp -I %S
>> -// RUN: %clang_cc1 -fmodules %s -fsyntax-only -include-pch %t2.pch
>> -fmodules-cache-path=%t.mcp -verify
>> +// RUN: %clang_cc1 -fmodules %s -fsyntax-only -include-pch %t2.pch -I %S
>> -fmodules-cache-path=%t.mcp -verify
>>
>>  #ifndef HEADER1
>>  #define HEADER1
>>
>> Added: cfe/trunk/test/Modules/resolution-change.m
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/resolution-change.m?rev=206201&view=auto
>>
>> ==============================================================================
>> --- cfe/trunk/test/Modules/resolution-change.m (added)
>> +++ cfe/trunk/test/Modules/resolution-change.m Mon Apr 14 13:00:01 2014
>> @@ -0,0 +1,24 @@
>> +// RUN: rm -rf %t
>> +
>> +// Build PCH using A from path 1
>> +// 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
>> +
>> +// Use the PCH with the same header search options; should be fine
>> +// 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
>> +
>> +// Use the PCH with no way to resolve DependsOnA
>> +// 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
>> +// CHECK-NODOA: module 'DependsOnA' imported by AST file '{{.*A.pch}}'
>> not found
>> +
>> +// Use the PCH with no way to resolve A
>> +// 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
>> +// CHECK-NOA: module 'A' imported by AST file '{{.*DependsOnA.*pcm}}'
>> not found
>> +
>> +// Use the PCH and have it resolve the the other A
>> +// 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
>> +// 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.*}})
>> +
>> +#ifndef HEADER
>> +#define HEADER
>> + at import DependsOnA;
>> +#endif
>>
>> Modified: cfe/trunk/test/Modules/system_version.m
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/system_version.m?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/Modules/system_version.m (original)
>> +++ cfe/trunk/test/Modules/system_version.m Mon Apr 14 13:00:01 2014
>> @@ -11,21 +11,21 @@
>>
>>  // Run once with no system version file. We should end up with one
>> module.
>>  // RUN: %clang_cc1 -fmodules-cache-path=%t/cache -fmodules -isysroot %t
>> -I %t/usr/include %s -verify
>> -// RUN: ls -R %t | grep -c ModA.pcm| grep 1
>> +// RUN: ls -R %t | grep -c "ModA.*pcm" | grep 1
>>
>>  // Add a system version file and run again. We should now have two
>>  // module variants.
>>  // RUN: mkdir -p %t/System/Library/CoreServices
>>  // RUN: echo "hello" > %t/System/Library/CoreServices/SystemVersion.plist
>>  // RUN: %clang_cc1 -fmodules-cache-path=%t/cache -fmodules -isysroot %t
>> -I %t/usr/include %s -verify
>> -// RUN: ls -R %t | grep -c ModA.pcm| grep 2
>> +// RUN: ls -R %t | grep -c "ModA.*pcm" | grep 2
>>
>>  // Change the system version file and run again. We should now have three
>>  // module variants.
>>  // RUN: mkdir -p %t/System/Library/CoreServices
>>  // RUN: echo "modules" >
>> %t/System/Library/CoreServices/SystemVersion.plist
>>  // RUN: %clang_cc1 -fmodules-cache-path=%t/cache -fmodules -isysroot %t
>> -I %t/usr/include %s -verify
>> -// RUN: ls -R %t | grep -c ModA.pcm| grep 3
>> +// RUN: ls -R %t | grep -c "ModA.*pcm" | grep 3
>>
>>  // expected-no-diagnostics
>>  @import ModA;
>>
>> Modified: cfe/trunk/test/PCH/modified-module-dependency.m
>> URL:
>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/modified-module-dependency.m?rev=206201&r1=206200&r2=206201&view=diff
>>
>> ==============================================================================
>> --- cfe/trunk/test/PCH/modified-module-dependency.m (original)
>> +++ cfe/trunk/test/PCH/modified-module-dependency.m Mon Apr 14 13:00:01
>> 2014
>> @@ -5,13 +5,13 @@
>>  // RUN: cp %S/modified-module-dependency.module.map %t-dir/module.map
>>
>>  // Precompile prefix.pch.
>> -// 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
>> +// 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
>>
>>  // Modify the dependency.
>>  // RUN: echo ' ' >> %t-dir/test.h
>>
>>  // Run and check the diagnostics.
>> -// 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
>> +// 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
>>  // RUN: FileCheck %s < %t-dir/log
>>
>>  // CHECK: file '[[TEST_H:.*[/\\]test\.h]]' has been modified since the
>> precompiled header '[[PREFIX_PCH:.*/prefix\.pch]]' was built
>>
>>
>> _______________________________________________
>> cfe-commits mailing list
>> cfe-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20141211/bbd14eb9/attachment.html>


More information about the cfe-commits mailing list