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