r220731 - [modules] Load .pcm files specified by -fmodule-file lazily.

NAKAMURA Takumi geek4civic at gmail.com
Mon Oct 27 16:36:39 PDT 2014


2014-10-28 8:01 GMT+09:00 Richard Smith <richard-llvm at metafoo.co.uk>:
> Author: rsmith
> Date: Mon Oct 27 18:01:16 2014
> New Revision: 220731
>
> URL: http://llvm.org/viewvc/llvm-project?rev=220731&view=rev
> Log:
> [modules] Load .pcm files specified by -fmodule-file lazily.
>
> Modified:
>     cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td
>     cfe/trunk/include/clang/Frontend/CompilerInstance.h
>     cfe/trunk/include/clang/Serialization/ASTReader.h
>     cfe/trunk/lib/Frontend/CompilerInstance.cpp
>     cfe/trunk/lib/Frontend/FrontendAction.cpp
>     cfe/trunk/lib/Serialization/ASTReader.cpp
>     cfe/trunk/test/Modules/explicit-build.cpp
>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td?rev=220731&r1=220730&r2=220731&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td (original)
> +++ cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td Mon Oct 27 18:01:16 2014
> @@ -190,8 +190,10 @@ def remark_module_build_done : Remark<"f
>  def err_conflicting_module_names : Error<
>    "conflicting module names specified: '-fmodule-name=%0' and "
>    "'-fmodule-implementation-of %1'">;
> -def err_module_already_loaded : Error<
> -  "module '%0' has already been loaded; cannot load module file '%1'">;
> +def err_conflicting_module_files : Error<
> +  "module '%0' is defined in both '%1' and '%2'">;
> +def err_module_file_not_found : Error<
> +  "file '%0' is not a precompiled module file">, DefaultFatal;
>  def err_module_file_not_module : Error<
>    "AST file '%0' was not built as a module">, DefaultFatal;
>
>
> Modified: cfe/trunk/include/clang/Frontend/CompilerInstance.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CompilerInstance.h?rev=220731&r1=220730&r2=220731&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Frontend/CompilerInstance.h (original)
> +++ cfe/trunk/include/clang/Frontend/CompilerInstance.h Mon Oct 27 18:01:16 2014
> @@ -117,7 +117,10 @@ class CompilerInstance : public ModuleLo
>    /// \brief The set of top-level modules that has already been loaded,
>    /// along with the module map
>    llvm::DenseMap<const IdentifierInfo *, Module *> KnownModules;
> -
> +
> +  /// \brief Module names that have an override for the target file.
> +  llvm::StringMap<std::string> ModuleFileOverrides;
> +
>    /// \brief The location of the module-import keyword for the last module
>    /// import.
>    SourceLocation LastModuleImportLoc;
> @@ -691,7 +694,7 @@ public:
>    // Create module manager.
>    void createModuleManager();
>
> -  ModuleLoadResult loadModuleFile(StringRef FileName, SourceLocation Loc);
> +  bool loadModuleFile(StringRef FileName);
>
>    ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path,
>                                Module::NameVisibilityKind Visibility,
>
> Modified: cfe/trunk/include/clang/Serialization/ASTReader.h
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=220731&r1=220730&r2=220731&view=diff
> ==============================================================================
> --- cfe/trunk/include/clang/Serialization/ASTReader.h (original)
> +++ cfe/trunk/include/clang/Serialization/ASTReader.h Mon Oct 27 18:01:16 2014
> @@ -193,6 +193,13 @@ public:
>                                bool isOverridden) {
>      return true;
>    }
> +
> +  /// \brief Returns true if this \c ASTReaderListener wants to receive the
> +  /// imports of the AST file via \c visitImport, false otherwise.
> +  virtual bool needsImportVisitation() const { return false; }
> +  /// \brief If needsImportVisitation returns \c true, this is called for each
> +  /// AST file imported by this AST file.
> +  virtual void visitImport(StringRef Filename) {}
>  };
>
>  /// \brief Simple wrapper class for chaining listeners.
>
> Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=220731&r1=220730&r2=220731&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)
> +++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Mon Oct 27 18:01:16 2014
> @@ -1257,51 +1257,61 @@ void CompilerInstance::createModuleManag
>    }
>  }
>
> -ModuleLoadResult
> -CompilerInstance::loadModuleFile(StringRef FileName, SourceLocation Loc) {
> -  if (!ModuleManager)
> -    createModuleManager();
> -  if (!ModuleManager)
> -    return ModuleLoadResult();
> -
> -  // Load the module if this is the first time we've been told about this file.
> -  auto *MF = ModuleManager->getModuleManager().lookup(FileName);
> -  if (!MF) {
> -    struct ReadModuleNameListener : ASTReaderListener {
> -      std::function<void(StringRef)> OnRead;
> -      ReadModuleNameListener(std::function<void(StringRef)> F) : OnRead(F) {}
> -      void ReadModuleName(StringRef ModuleName) override { OnRead(ModuleName); }
> -    };
> -
> -    // Register listener to track the modules that are loaded by explicitly
> -    // loading a module file. We suppress any attempts to implicitly load
> -    // module files for any such module.
> -    ASTReader::ListenerScope OnReadModuleName(
> -        *ModuleManager,
> -        llvm::make_unique<ReadModuleNameListener>([&](StringRef ModuleName) {
> -      auto &PP = getPreprocessor();
> -      auto *NameII = PP.getIdentifierInfo(ModuleName);
> -      auto *Module = PP.getHeaderSearchInfo().lookupModule(ModuleName, false);
> -      if (!KnownModules.insert(std::make_pair(NameII, Module)).second)
> -        getDiagnostics().Report(Loc, diag::err_module_already_loaded)
> -            << ModuleName << FileName;
> -    }));
> +bool CompilerInstance::loadModuleFile(StringRef FileName) {
> +  // Helper to recursively read the module names for all modules we're adding.
> +  // We mark these as known and redirect any attempt to load that module to
> +  // the files we were handed.
> +  struct ReadModuleNames : ASTReaderListener {
> +    CompilerInstance &CI;
> +    std::vector<StringRef> ModuleFileStack;
> +    bool Failed;
> +    bool TopFileIsModule;
> +
> +    ReadModuleNames(CompilerInstance &CI)
> +        : CI(CI), Failed(false), TopFileIsModule(false) {}
> +
> +    bool needsImportVisitation() const override { return true; }
> +
> +    void visitImport(StringRef FileName) override {
> +      ModuleFileStack.push_back(FileName);
> +      if (ASTReader::readASTFileControlBlock(FileName, CI.getFileManager(),
> +                                             *this)) {
> +        CI.getDiagnostics().Report(SourceLocation(),
> +                                   diag::err_module_file_not_found)
> +            << FileName;
> +        // FIXME: Produce a note stack explaining how we got here.
> +        Failed = true;
> +      }
> +      ModuleFileStack.pop_back();
> +    }
>
> -    if (ModuleManager->ReadAST(FileName, serialization::MK_ExplicitModule, Loc,
> -                               ASTReader::ARR_None) != ASTReader::Success)
> -      return ModuleLoadResult();
> +    void ReadModuleName(StringRef ModuleName) override {
> +      if (ModuleFileStack.size() == 1)
> +        TopFileIsModule = true;
> +
> +      auto &ModuleFile = CI.ModuleFileOverrides[ModuleName];
> +      if (!ModuleFile.empty() && ModuleFile != ModuleFileStack.back())
> +        CI.getDiagnostics().Report(SourceLocation(),
> +                                   diag::err_conflicting_module_files)
> +            << ModuleName << ModuleFile << ModuleFileStack.back();
> +      ModuleFile = ModuleFileStack.back();
> +    }
> +  } RMN(*this);
>
> -    MF = ModuleManager->getModuleManager().lookup(FileName);
> -    assert(MF && "unexpectedly failed to load module file");
> -  }
> +  RMN.visitImport(FileName);
>
> -  if (MF->ModuleName.empty()) {
> -    getDiagnostics().Report(Loc, diag::err_module_file_not_module)
> +  if (RMN.Failed)
> +    return false;
> +
> +  // If we never found a module name for the top file, then it's not a module,
> +  // it's a PCH or preamble or something.
> +  if (!RMN.TopFileIsModule) {
> +    getDiagnostics().Report(SourceLocation(), diag::err_module_file_not_module)
>        << FileName;
> -    return ModuleLoadResult();
> +    return false;
>    }
> -  auto *Module = PP->getHeaderSearchInfo().lookupModule(MF->ModuleName, false);
> -  return ModuleLoadResult(Module, false);
> +
> +  return true;
>  }
>
>  ModuleLoadResult
> @@ -1349,8 +1359,12 @@ CompilerInstance::loadModule(SourceLocat
>        return ModuleLoadResult();
>      }
>
> +    auto Override = ModuleFileOverrides.find(ModuleName);
> +    bool Explicit = Override != ModuleFileOverrides.end();
> +
>      std::string ModuleFileName =
> -        PP->getHeaderSearchInfo().getModuleFileName(Module);
> +        Explicit ? Override->second
> +                 : PP->getHeaderSearchInfo().getModuleFileName(Module);
>
>      // If we don't already have an ASTReader, create one now.
>      if (!ModuleManager)
> @@ -1366,15 +1380,24 @@ CompilerInstance::loadModule(SourceLocat
>        Listener->attachToASTReader(*ModuleManager);
>
>      // Try to load the module file.
> -    unsigned ARRFlags = ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing;
> +    unsigned ARRFlags =
> +        Explicit ? 0 : ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing;
>      switch (ModuleManager->ReadAST(ModuleFileName,
> -                                   serialization::MK_ImplicitModule, ImportLoc,
> -                                   ARRFlags)) {
> +                                   Explicit ? serialization::MK_ExplicitModule
> +                                            : serialization::MK_ImplicitModule,
> +                                   ImportLoc, ARRFlags)) {
>      case ASTReader::Success:
>        break;
>
>      case ASTReader::OutOfDate:
>      case ASTReader::Missing: {
> +      if (Explicit) {
> +        // ReadAST has already complained for us.
> +        ModuleLoader::HadFatalFailure = true;
> +        KnownModules[Path[0].first] = nullptr;
> +        return ModuleLoadResult();
> +      }
> +
>        // The module file is missing or out-of-date. Build it.
>        assert(Module && "missing module file");
>        // Check whether there is a cycle in the module graph.
>
> Modified: cfe/trunk/lib/Frontend/FrontendAction.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendAction.cpp?rev=220731&r1=220730&r2=220731&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Frontend/FrontendAction.cpp (original)
> +++ cfe/trunk/lib/Frontend/FrontendAction.cpp Mon Oct 27 18:01:16 2014
> @@ -383,16 +383,10 @@ bool FrontendAction::BeginSourceFile(Com
>             "doesn't support modules");
>    }
>
> -  // If we were asked to load any module files, do so now. Don't make any names
> -  // from those modules visible.
> -  for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles) {
> -    // FIXME: Use a better source location here. Perhaps inject something
> -    // into the predefines buffer to represent these module files.
> -    if (!CI.loadModuleFile(ModuleFile,
> -                           CI.getSourceManager().getLocForStartOfFile(
> -                               CI.getSourceManager().getMainFileID())))
> +  // If we were asked to load any module files, do so now.
> +  for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles)
> +    if (!CI.loadModuleFile(ModuleFile))
>        goto failure;
> -  }
>
>    // If there is a layout overrides file, attach an external AST source that
>    // provides the layouts from that file.
>
> Modified: cfe/trunk/lib/Serialization/ASTReader.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=220731&r1=220730&r2=220731&view=diff
> ==============================================================================
> --- cfe/trunk/lib/Serialization/ASTReader.cpp (original)
> +++ cfe/trunk/lib/Serialization/ASTReader.cpp Mon Oct 27 18:01:16 2014
> @@ -4188,6 +4188,7 @@ bool ASTReader::readASTFileControlBlock(
>
>    bool NeedsInputFiles = Listener.needsInputFileVisitation();
>    bool NeedsSystemInputFiles = Listener.needsSystemInputFileVisitation();
> +  bool NeedsImports = Listener.needsImportVisitation();
>    BitstreamCursor InputFilesCursor;
>    if (NeedsInputFiles) {
>      InputFilesCursor = Stream;
> @@ -4305,6 +4306,24 @@ bool ASTReader::readASTFileControlBlock(
>        }
>        break;
>      }
> +
> +    case IMPORTS: {
> +      if (!NeedsImports)
> +        break;
> +
> +      unsigned Idx = 0, N = Record.size();
> +      while (Idx < N) {
> +        // Read information about the AST file.
> +        ModuleKind ImportedKind = (ModuleKind)Record[Idx++];

ImportedKind is unused around here. Would it be skipped, like Idx++ or
Idx +=5,  for now?

> +        Idx += 4; // ImportLoc, Size, ModTime, Signature
> +        unsigned Length = Record[Idx++];
> +        SmallString<128> ImportedFile(Record.begin() + Idx,
> +                                      Record.begin() + Idx + Length);
> +        Idx += Length;
> +        Listener.visitImport(ImportedFile);
> +      }
> +      break;
> +    }
>
>      default:
>        // No other validation to perform.
>
> Modified: cfe/trunk/test/Modules/explicit-build.cpp
> URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/explicit-build.cpp?rev=220731&r1=220730&r2=220731&view=diff
> ==============================================================================
> --- cfe/trunk/test/Modules/explicit-build.cpp (original)
> +++ cfe/trunk/test/Modules/explicit-build.cpp Mon Oct 27 18:01:16 2014
> @@ -2,16 +2,16 @@
>
>  // -------------------------------
>  // Build chained modules A, B, and C
> -// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
>  // RUN:            -fmodule-name=a -emit-module %S/Inputs/explicit-build/module.modulemap -o %t/a.pcm \
>  // RUN:            2>&1 | FileCheck --check-prefix=CHECK-NO-IMPLICIT-BUILD %s --allow-empty
>  //
> -// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
>  // RUN:            -fmodule-file=%t/a.pcm \
>  // RUN:            -fmodule-name=b -emit-module %S/Inputs/explicit-build/module.modulemap -o %t/b.pcm \
>  // RUN:            2>&1 | FileCheck --check-prefix=CHECK-NO-IMPLICIT-BUILD %s --allow-empty
>  //
> -// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
>  // RUN:            -fmodule-file=%t/b.pcm \
>  // RUN:            -fmodule-name=c -emit-module %S/Inputs/explicit-build/module.modulemap -o %t/c.pcm \
>  // RUN:            2>&1 | FileCheck --check-prefix=CHECK-NO-IMPLICIT-BUILD %s --allow-empty
> @@ -20,7 +20,7 @@
>
>  // -------------------------------
>  // Build B with an implicit build of A
> -// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
>  // RUN:            -fmodule-name=b -emit-module %S/Inputs/explicit-build/module.modulemap -o %t/b-not-a.pcm \
>  // RUN:            2>&1 | FileCheck --check-prefix=CHECK-B-NO-A %s
>  //
> @@ -29,123 +29,127 @@
>
>  // -------------------------------
>  // Check that we can use the explicitly-built A, B, and C modules.
> -// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// RUN:            -I%S/Inputs/explicit-build \
>  // RUN:            -fmodule-file=%t/a.pcm \
>  // RUN:            -verify %s -DHAVE_A
>  //
> -// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> -// RUN:            -fmodule-file=%t/a.pcm \
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// RUN:            -I%S/Inputs/explicit-build \
>  // RUN:            -fmodule-map-file=%S/Inputs/explicit-build/module.modulemap \
> +// RUN:            -fmodule-file=%t/a.pcm \
>  // RUN:            -verify %s -DHAVE_A
>  //
> -// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// RUN:            -I%S/Inputs/explicit-build \
>  // RUN:            -fmodule-file=%t/b.pcm \
>  // RUN:            -verify %s -DHAVE_A -DHAVE_B
>  //
> -// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// RUN:            -I%S/Inputs/explicit-build \
>  // RUN:            -fmodule-file=%t/a.pcm \
>  // RUN:            -fmodule-file=%t/b.pcm \
>  // RUN:            -verify %s -DHAVE_A -DHAVE_B
>  //
> -// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// RUN:            -I%S/Inputs/explicit-build \
>  // RUN:            -fmodule-file=%t/a.pcm \
>  // RUN:            -fmodule-file=%t/b.pcm \
>  // RUN:            -fmodule-file=%t/c.pcm \
>  // RUN:            -verify %s -DHAVE_A -DHAVE_B -DHAVE_C
>  //
> -// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
>  // RUN:            -I%S/Inputs/explicit-build \
>  // RUN:            -fmodule-file=%t/a.pcm \
> -// RUN:            -fmodule-file=%t/b.pcm \
>  // RUN:            -fmodule-file=%t/c.pcm \
> -// RUN:            -verify %s -INCLUDE_ALL -DHAVE_A -DHAVE_B -DHAVE_C
> +// RUN:            -verify %s -DHAVE_A -DHAVE_B -DHAVE_C
>
> -#ifdef INCLUDE_ALL
> +#if HAVE_A
>    #include "a.h"
> -  #include "b.h"
> -  #include "c.h"
>    static_assert(a == 1, "");
> +#else
> +  const int use_a = a; // expected-error {{undeclared identifier}}
> +#endif
> +
> +#if HAVE_B
> +  #include "b.h"
>    static_assert(b == 2, "");
> +#else
> +  const int use_b = b; // expected-error {{undeclared identifier}}
> +#endif
> +
> +#if HAVE_C
> +  #include "c.h"
>    static_assert(c == 3, "");
>  #else
> -  const int use_a = a;
> -  #ifndef HAVE_A
> -  // expected-error at -2 {{undeclared identifier}}
> -  #else
> -  // expected-error at -4 {{must be imported from module 'a'}}
> -  // expected-note at Inputs/explicit-build/a.h:* {{here}}
> -  #endif
> -
> -  const int use_b = b;
> -  #ifndef HAVE_B
> -  // expected-error at -2 {{undeclared identifier}}
> -  #else
> -  // expected-error at -4 {{must be imported from module 'b'}}
> -  // expected-note at Inputs/explicit-build/b.h:* {{here}}
> -  #endif
> -
> -  const int use_c = c;
> -  #ifndef HAVE_C
> -  // expected-error at -2 {{undeclared identifier}}
> -  #else
> -  // expected-error at -4 {{must be imported from module 'c'}}
> -  // expected-note at Inputs/explicit-build/c.h:* {{here}}
> -  #endif
> +  const int use_c = c; // expected-error {{undeclared identifier}}
> +#endif
> +
> +#if HAVE_A && HAVE_B && HAVE_C
> +// expected-no-diagnostics
>  #endif
>
>  // -------------------------------
>  // Check that we can use a mixture of implicit and explicit modules.
> -// RUN: not %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// RUN:            -I%S/Inputs/explicit-build \
>  // RUN:            -fmodule-file=%t/b-not-a.pcm \
> -// RUN:            -fmodule-map-file=%S/Inputs/explicit-build/module.modulemap \
> -// RUN:            %s 2>&1 | FileCheck --check-prefix=CHECK-A-AND-B-NO-A %s
> +// RUN:            -verify %s -DHAVE_A -DHAVE_B
>
>  // -------------------------------
> -// Check that mixing an implicit and explicit form of the 'a' module is rejected.
> -// RUN: not %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// Try to use two different flavors of the 'a' module.
> +// RUN: not %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
>  // RUN:            -fmodule-file=%t/a.pcm \
>  // RUN:            -fmodule-file=%t/b-not-a.pcm \
> -// RUN:            %s 2>&1 | FileCheck --check-prefix=CHECK-A-AND-B-NO-A %s
> +// RUN:            %s 2>&1 | FileCheck --check-prefix=CHECK-MULTIPLE-AS %s
>  //
> -// RUN: not %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// RUN: not %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
>  // RUN:            -fmodule-file=%t/a.pcm \
>  // RUN:            -fmodule-file=%t/b-not-a.pcm \
>  // RUN:            -fmodule-map-file=%S/Inputs/explicit-build/module.modulemap \
> -// RUN:            %s 2>&1 | FileCheck --check-prefix=CHECK-A-AND-B-NO-A %s
> +// RUN:            %s 2>&1 | FileCheck --check-prefix=CHECK-MULTIPLE-AS %s
>  //
> -// FIXME: We should load module map files specified on the command line and
> -// module map files in include paths on demand to allow this, and possibly
> -// also the previous case.
> -// CHECK-A-AND-B-NO-A: fatal error: module 'a' {{.*}} is not defined in any loaded module map
> -
> -// -------------------------------
> -// Try to use two different flavors of the 'a' module.
> -// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
>  // RUN:            -fmodule-name=a -emit-module %S/Inputs/explicit-build/module.modulemap -o %t/a-alt.pcm \
>  // RUN:            2>&1 | FileCheck --check-prefix=CHECK-NO-IMPLICIT-BUILD %s --allow-empty
>  //
> -// RUN: not %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// RUN: not %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
>  // RUN:            -fmodule-file=%t/a.pcm \
>  // RUN:            -fmodule-file=%t/a-alt.pcm \
>  // RUN:            -fmodule-map-file=%S/Inputs/explicit-build/module.modulemap \
>  // RUN:            %s 2>&1 | FileCheck --check-prefix=CHECK-MULTIPLE-AS %s
>  //
> -// RUN: not %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// RUN: not %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
>  // RUN:            -fmodule-file=%t/a-alt.pcm \
>  // RUN:            -fmodule-file=%t/a.pcm \
>  // RUN:            -fmodule-map-file=%S/Inputs/explicit-build/module.modulemap \
>  // RUN:            %s 2>&1 | FileCheck --check-prefix=CHECK-MULTIPLE-AS %s
>  //
> -// CHECK-MULTIPLE-AS: error: module 'a' has already been loaded; cannot load module file '{{.*a(-alt)?}}.pcm'
> +// CHECK-MULTIPLE-AS: error: module 'a' is defined in both '{{.*}}/a{{.*}}.pcm' and '{{.*}}/a{{.*}}.pcm'
>
>  // -------------------------------
>  // Try to import a PCH with -fmodule-file=
> -// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
>  // RUN:            -fmodule-name=a -emit-pch %S/Inputs/explicit-build/a.h -o %t/a.pch \
>  // RUN:            2>&1 | FileCheck --check-prefix=CHECK-NO-IMPLICIT-BUILD %s --allow-empty
>  //
> -// RUN: not %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// RUN: not %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
>  // RUN:            -fmodule-file=%t/a.pch \
>  // RUN:            %s 2>&1 | FileCheck --check-prefix=CHECK-A-AS-PCH %s
>  //
>  // CHECK-A-AS-PCH: fatal error: AST file '{{.*}}a.pch' was not built as a module
> +
> +// -------------------------------
> +// Try to import a non-AST file with -fmodule-file=
> +//
> +// RUN: touch %t/not.pcm
> +//
> +// RUN: not %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// RUN:            -fmodule-file=%t/not.pcm \
> +// RUN:            %s 2>&1 | FileCheck --check-prefix=CHECK-BAD-FILE %s
> +//
> +// RUN: not %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \
> +// RUN:            -fmodule-file=%t/nonexistent.pcm \
> +// RUN:            %s 2>&1 | FileCheck --check-prefix=CHECK-BAD-FILE %s
> +//
> +// CHECK-BAD-FILE: fatal error: file '{{.*}}t.pcm' is not a precompiled module file
>
>
> _______________________________________________
> cfe-commits mailing list
> cfe-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits



More information about the cfe-commits mailing list