<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Mon, Oct 27, 2014 at 4:36 PM, NAKAMURA Takumi <span dir="ltr"><<a href="mailto:geek4civic@gmail.com" target="_blank">geek4civic@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">2014-10-28 8:01 GMT+09:00 Richard Smith <<a href="mailto:richard-llvm@metafoo.co.uk">richard-llvm@metafoo.co.uk</a>>:<br>
> Author: rsmith<br>
> Date: Mon Oct 27 18:01:16 2014<br>
> New Revision: 220731<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=220731&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=220731&view=rev</a><br>
> Log:<br>
> [modules] Load .pcm files specified by -fmodule-file lazily.<br>
><br>
> Modified:<br>
>     cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td<br>
>     cfe/trunk/include/clang/Frontend/CompilerInstance.h<br>
>     cfe/trunk/include/clang/Serialization/ASTReader.h<br>
>     cfe/trunk/lib/Frontend/CompilerInstance.cpp<br>
>     cfe/trunk/lib/Frontend/FrontendAction.cpp<br>
>     cfe/trunk/lib/Serialization/ASTReader.cpp<br>
>     cfe/trunk/test/Modules/explicit-build.cpp<br>
><br>
> Modified: cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td?rev=220731&r1=220730&r2=220731&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td?rev=220731&r1=220730&r2=220731&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td (original)<br>
> +++ cfe/trunk/include/clang/Basic/DiagnosticFrontendKinds.td Mon Oct 27 18:01:16 2014<br>
> @@ -190,8 +190,10 @@ def remark_module_build_done : Remark<"f<br>
>  def err_conflicting_module_names : Error<<br>
>    "conflicting module names specified: '-fmodule-name=%0' and "<br>
>    "'-fmodule-implementation-of %1'">;<br>
> -def err_module_already_loaded : Error<<br>
> -  "module '%0' has already been loaded; cannot load module file '%1'">;<br>
> +def err_conflicting_module_files : Error<<br>
> +  "module '%0' is defined in both '%1' and '%2'">;<br>
> +def err_module_file_not_found : Error<<br>
> +  "file '%0' is not a precompiled module file">, DefaultFatal;<br>
>  def err_module_file_not_module : Error<<br>
>    "AST file '%0' was not built as a module">, DefaultFatal;<br>
><br>
><br>
> Modified: cfe/trunk/include/clang/Frontend/CompilerInstance.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CompilerInstance.h?rev=220731&r1=220730&r2=220731&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CompilerInstance.h?rev=220731&r1=220730&r2=220731&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/Frontend/CompilerInstance.h (original)<br>
> +++ cfe/trunk/include/clang/Frontend/CompilerInstance.h Mon Oct 27 18:01:16 2014<br>
> @@ -117,7 +117,10 @@ class CompilerInstance : public ModuleLo<br>
>    /// \brief The set of top-level modules that has already been loaded,<br>
>    /// along with the module map<br>
>    llvm::DenseMap<const IdentifierInfo *, Module *> KnownModules;<br>
> -<br>
> +<br>
> +  /// \brief Module names that have an override for the target file.<br>
> +  llvm::StringMap<std::string> ModuleFileOverrides;<br>
> +<br>
>    /// \brief The location of the module-import keyword for the last module<br>
>    /// import.<br>
>    SourceLocation LastModuleImportLoc;<br>
> @@ -691,7 +694,7 @@ public:<br>
>    // Create module manager.<br>
>    void createModuleManager();<br>
><br>
> -  ModuleLoadResult loadModuleFile(StringRef FileName, SourceLocation Loc);<br>
> +  bool loadModuleFile(StringRef FileName);<br>
><br>
>    ModuleLoadResult loadModule(SourceLocation ImportLoc, ModuleIdPath Path,<br>
>                                Module::NameVisibilityKind Visibility,<br>
><br>
> Modified: cfe/trunk/include/clang/Serialization/ASTReader.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=220731&r1=220730&r2=220731&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTReader.h?rev=220731&r1=220730&r2=220731&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/include/clang/Serialization/ASTReader.h (original)<br>
> +++ cfe/trunk/include/clang/Serialization/ASTReader.h Mon Oct 27 18:01:16 2014<br>
> @@ -193,6 +193,13 @@ public:<br>
>                                bool isOverridden) {<br>
>      return true;<br>
>    }<br>
> +<br>
> +  /// \brief Returns true if this \c ASTReaderListener wants to receive the<br>
> +  /// imports of the AST file via \c visitImport, false otherwise.<br>
> +  virtual bool needsImportVisitation() const { return false; }<br>
> +  /// \brief If needsImportVisitation returns \c true, this is called for each<br>
> +  /// AST file imported by this AST file.<br>
> +  virtual void visitImport(StringRef Filename) {}<br>
>  };<br>
><br>
>  /// \brief Simple wrapper class for chaining listeners.<br>
><br>
> Modified: cfe/trunk/lib/Frontend/CompilerInstance.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=220731&r1=220730&r2=220731&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInstance.cpp?rev=220731&r1=220730&r2=220731&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/Frontend/CompilerInstance.cpp (original)<br>
> +++ cfe/trunk/lib/Frontend/CompilerInstance.cpp Mon Oct 27 18:01:16 2014<br>
> @@ -1257,51 +1257,61 @@ void CompilerInstance::createModuleManag<br>
>    }<br>
>  }<br>
><br>
> -ModuleLoadResult<br>
> -CompilerInstance::loadModuleFile(StringRef FileName, SourceLocation Loc) {<br>
> -  if (!ModuleManager)<br>
> -    createModuleManager();<br>
> -  if (!ModuleManager)<br>
> -    return ModuleLoadResult();<br>
> -<br>
> -  // Load the module if this is the first time we've been told about this file.<br>
> -  auto *MF = ModuleManager->getModuleManager().lookup(FileName);<br>
> -  if (!MF) {<br>
> -    struct ReadModuleNameListener : ASTReaderListener {<br>
> -      std::function<void(StringRef)> OnRead;<br>
> -      ReadModuleNameListener(std::function<void(StringRef)> F) : OnRead(F) {}<br>
> -      void ReadModuleName(StringRef ModuleName) override { OnRead(ModuleName); }<br>
> -    };<br>
> -<br>
> -    // Register listener to track the modules that are loaded by explicitly<br>
> -    // loading a module file. We suppress any attempts to implicitly load<br>
> -    // module files for any such module.<br>
> -    ASTReader::ListenerScope OnReadModuleName(<br>
> -        *ModuleManager,<br>
> -        llvm::make_unique<ReadModuleNameListener>([&](StringRef ModuleName) {<br>
> -      auto &PP = getPreprocessor();<br>
> -      auto *NameII = PP.getIdentifierInfo(ModuleName);<br>
> -      auto *Module = PP.getHeaderSearchInfo().lookupModule(ModuleName, false);<br>
> -      if (!KnownModules.insert(std::make_pair(NameII, Module)).second)<br>
> -        getDiagnostics().Report(Loc, diag::err_module_already_loaded)<br>
> -            << ModuleName << FileName;<br>
> -    }));<br>
> +bool CompilerInstance::loadModuleFile(StringRef FileName) {<br>
> +  // Helper to recursively read the module names for all modules we're adding.<br>
> +  // We mark these as known and redirect any attempt to load that module to<br>
> +  // the files we were handed.<br>
> +  struct ReadModuleNames : ASTReaderListener {<br>
> +    CompilerInstance &CI;<br>
> +    std::vector<StringRef> ModuleFileStack;<br>
> +    bool Failed;<br>
> +    bool TopFileIsModule;<br>
> +<br>
> +    ReadModuleNames(CompilerInstance &CI)<br>
> +        : CI(CI), Failed(false), TopFileIsModule(false) {}<br>
> +<br>
> +    bool needsImportVisitation() const override { return true; }<br>
> +<br>
> +    void visitImport(StringRef FileName) override {<br>
> +      ModuleFileStack.push_back(FileName);<br>
> +      if (ASTReader::readASTFileControlBlock(FileName, CI.getFileManager(),<br>
> +                                             *this)) {<br>
> +        CI.getDiagnostics().Report(SourceLocation(),<br>
> +                                   diag::err_module_file_not_found)<br>
> +            << FileName;<br>
> +        // FIXME: Produce a note stack explaining how we got here.<br>
> +        Failed = true;<br>
> +      }<br>
> +      ModuleFileStack.pop_back();<br>
> +    }<br>
><br>
> -    if (ModuleManager->ReadAST(FileName, serialization::MK_ExplicitModule, Loc,<br>
> -                               ASTReader::ARR_None) != ASTReader::Success)<br>
> -      return ModuleLoadResult();<br>
> +    void ReadModuleName(StringRef ModuleName) override {<br>
> +      if (ModuleFileStack.size() == 1)<br>
> +        TopFileIsModule = true;<br>
> +<br>
> +      auto &ModuleFile = CI.ModuleFileOverrides[ModuleName];<br>
> +      if (!ModuleFile.empty() && ModuleFile != ModuleFileStack.back())<br>
> +        CI.getDiagnostics().Report(SourceLocation(),<br>
> +                                   diag::err_conflicting_module_files)<br>
> +            << ModuleName << ModuleFile << ModuleFileStack.back();<br>
> +      ModuleFile = ModuleFileStack.back();<br>
> +    }<br>
> +  } RMN(*this);<br>
><br>
> -    MF = ModuleManager->getModuleManager().lookup(FileName);<br>
> -    assert(MF && "unexpectedly failed to load module file");<br>
> -  }<br>
> +  RMN.visitImport(FileName);<br>
><br>
> -  if (MF->ModuleName.empty()) {<br>
> -    getDiagnostics().Report(Loc, diag::err_module_file_not_module)<br>
> +  if (RMN.Failed)<br>
> +    return false;<br>
> +<br>
> +  // If we never found a module name for the top file, then it's not a module,<br>
> +  // it's a PCH or preamble or something.<br>
> +  if (!RMN.TopFileIsModule) {<br>
> +    getDiagnostics().Report(SourceLocation(), diag::err_module_file_not_module)<br>
>        << FileName;<br>
> -    return ModuleLoadResult();<br>
> +    return false;<br>
>    }<br>
> -  auto *Module = PP->getHeaderSearchInfo().lookupModule(MF->ModuleName, false);<br>
> -  return ModuleLoadResult(Module, false);<br>
> +<br>
> +  return true;<br>
>  }<br>
><br>
>  ModuleLoadResult<br>
> @@ -1349,8 +1359,12 @@ CompilerInstance::loadModule(SourceLocat<br>
>        return ModuleLoadResult();<br>
>      }<br>
><br>
> +    auto Override = ModuleFileOverrides.find(ModuleName);<br>
> +    bool Explicit = Override != ModuleFileOverrides.end();<br>
> +<br>
>      std::string ModuleFileName =<br>
> -        PP->getHeaderSearchInfo().getModuleFileName(Module);<br>
> +        Explicit ? Override->second<br>
> +                 : PP->getHeaderSearchInfo().getModuleFileName(Module);<br>
><br>
>      // If we don't already have an ASTReader, create one now.<br>
>      if (!ModuleManager)<br>
> @@ -1366,15 +1380,24 @@ CompilerInstance::loadModule(SourceLocat<br>
>        Listener->attachToASTReader(*ModuleManager);<br>
><br>
>      // Try to load the module file.<br>
> -    unsigned ARRFlags = ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing;<br>
> +    unsigned ARRFlags =<br>
> +        Explicit ? 0 : ASTReader::ARR_OutOfDate | ASTReader::ARR_Missing;<br>
>      switch (ModuleManager->ReadAST(ModuleFileName,<br>
> -                                   serialization::MK_ImplicitModule, ImportLoc,<br>
> -                                   ARRFlags)) {<br>
> +                                   Explicit ? serialization::MK_ExplicitModule<br>
> +                                            : serialization::MK_ImplicitModule,<br>
> +                                   ImportLoc, ARRFlags)) {<br>
>      case ASTReader::Success:<br>
>        break;<br>
><br>
>      case ASTReader::OutOfDate:<br>
>      case ASTReader::Missing: {<br>
> +      if (Explicit) {<br>
> +        // ReadAST has already complained for us.<br>
> +        ModuleLoader::HadFatalFailure = true;<br>
> +        KnownModules[Path[0].first] = nullptr;<br>
> +        return ModuleLoadResult();<br>
> +      }<br>
> +<br>
>        // The module file is missing or out-of-date. Build it.<br>
>        assert(Module && "missing module file");<br>
>        // Check whether there is a cycle in the module graph.<br>
><br>
> Modified: cfe/trunk/lib/Frontend/FrontendAction.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendAction.cpp?rev=220731&r1=220730&r2=220731&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendAction.cpp?rev=220731&r1=220730&r2=220731&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/Frontend/FrontendAction.cpp (original)<br>
> +++ cfe/trunk/lib/Frontend/FrontendAction.cpp Mon Oct 27 18:01:16 2014<br>
> @@ -383,16 +383,10 @@ bool FrontendAction::BeginSourceFile(Com<br>
>             "doesn't support modules");<br>
>    }<br>
><br>
> -  // If we were asked to load any module files, do so now. Don't make any names<br>
> -  // from those modules visible.<br>
> -  for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles) {<br>
> -    // FIXME: Use a better source location here. Perhaps inject something<br>
> -    // into the predefines buffer to represent these module files.<br>
> -    if (!CI.loadModuleFile(ModuleFile,<br>
> -                           CI.getSourceManager().getLocForStartOfFile(<br>
> -                               CI.getSourceManager().getMainFileID())))<br>
> +  // If we were asked to load any module files, do so now.<br>
> +  for (const auto &ModuleFile : CI.getFrontendOpts().ModuleFiles)<br>
> +    if (!CI.loadModuleFile(ModuleFile))<br>
>        goto failure;<br>
> -  }<br>
><br>
>    // If there is a layout overrides file, attach an external AST source that<br>
>    // provides the layouts from that file.<br>
><br>
> Modified: cfe/trunk/lib/Serialization/ASTReader.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=220731&r1=220730&r2=220731&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReader.cpp?rev=220731&r1=220730&r2=220731&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/lib/Serialization/ASTReader.cpp (original)<br>
> +++ cfe/trunk/lib/Serialization/ASTReader.cpp Mon Oct 27 18:01:16 2014<br>
> @@ -4188,6 +4188,7 @@ bool ASTReader::readASTFileControlBlock(<br>
><br>
>    bool NeedsInputFiles = Listener.needsInputFileVisitation();<br>
>    bool NeedsSystemInputFiles = Listener.needsSystemInputFileVisitation();<br>
> +  bool NeedsImports = Listener.needsImportVisitation();<br>
>    BitstreamCursor InputFilesCursor;<br>
>    if (NeedsInputFiles) {<br>
>      InputFilesCursor = Stream;<br>
> @@ -4305,6 +4306,24 @@ bool ASTReader::readASTFileControlBlock(<br>
>        }<br>
>        break;<br>
>      }<br>
> +<br>
> +    case IMPORTS: {<br>
> +      if (!NeedsImports)<br>
> +        break;<br>
> +<br>
> +      unsigned Idx = 0, N = Record.size();<br>
> +      while (Idx < N) {<br>
> +        // Read information about the AST file.<br>
> +        ModuleKind ImportedKind = (ModuleKind)Record[Idx++];<br>
<br>
</div></div>ImportedKind is unused around here. Would it be skipped, like Idx++ or<br>
Idx +=5,  for now?</blockquote><div><br></div><div>Thanks, already fixed.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="HOEnZb"><div class="h5">
> +        Idx += 4; // ImportLoc, Size, ModTime, Signature<br>
> +        unsigned Length = Record[Idx++];<br>
> +        SmallString<128> ImportedFile(Record.begin() + Idx,<br>
> +                                      Record.begin() + Idx + Length);<br>
> +        Idx += Length;<br>
> +        Listener.visitImport(ImportedFile);<br>
> +      }<br>
> +      break;<br>
> +    }<br>
><br>
>      default:<br>
>        // No other validation to perform.<br>
><br>
> Modified: cfe/trunk/test/Modules/explicit-build.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/explicit-build.cpp?rev=220731&r1=220730&r2=220731&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/explicit-build.cpp?rev=220731&r1=220730&r2=220731&view=diff</a><br>
> ==============================================================================<br>
> --- cfe/trunk/test/Modules/explicit-build.cpp (original)<br>
> +++ cfe/trunk/test/Modules/explicit-build.cpp Mon Oct 27 18:01:16 2014<br>
> @@ -2,16 +2,16 @@<br>
><br>
>  // -------------------------------<br>
>  // Build chained modules A, B, and C<br>
> -// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
>  // RUN:            -fmodule-name=a -emit-module %S/Inputs/explicit-build/module.modulemap -o %t/a.pcm \<br>
>  // RUN:            2>&1 | FileCheck --check-prefix=CHECK-NO-IMPLICIT-BUILD %s --allow-empty<br>
>  //<br>
> -// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
>  // RUN:            -fmodule-file=%t/a.pcm \<br>
>  // RUN:            -fmodule-name=b -emit-module %S/Inputs/explicit-build/module.modulemap -o %t/b.pcm \<br>
>  // RUN:            2>&1 | FileCheck --check-prefix=CHECK-NO-IMPLICIT-BUILD %s --allow-empty<br>
>  //<br>
> -// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
>  // RUN:            -fmodule-file=%t/b.pcm \<br>
>  // RUN:            -fmodule-name=c -emit-module %S/Inputs/explicit-build/module.modulemap -o %t/c.pcm \<br>
>  // RUN:            2>&1 | FileCheck --check-prefix=CHECK-NO-IMPLICIT-BUILD %s --allow-empty<br>
> @@ -20,7 +20,7 @@<br>
><br>
>  // -------------------------------<br>
>  // Build B with an implicit build of A<br>
> -// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
>  // RUN:            -fmodule-name=b -emit-module %S/Inputs/explicit-build/module.modulemap -o %t/b-not-a.pcm \<br>
>  // RUN:            2>&1 | FileCheck --check-prefix=CHECK-B-NO-A %s<br>
>  //<br>
> @@ -29,123 +29,127 @@<br>
><br>
>  // -------------------------------<br>
>  // Check that we can use the explicitly-built A, B, and C modules.<br>
> -// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// RUN:            -I%S/Inputs/explicit-build \<br>
>  // RUN:            -fmodule-file=%t/a.pcm \<br>
>  // RUN:            -verify %s -DHAVE_A<br>
>  //<br>
> -// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> -// RUN:            -fmodule-file=%t/a.pcm \<br>
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// RUN:            -I%S/Inputs/explicit-build \<br>
>  // RUN:            -fmodule-map-file=%S/Inputs/explicit-build/module.modulemap \<br>
> +// RUN:            -fmodule-file=%t/a.pcm \<br>
>  // RUN:            -verify %s -DHAVE_A<br>
>  //<br>
> -// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// RUN:            -I%S/Inputs/explicit-build \<br>
>  // RUN:            -fmodule-file=%t/b.pcm \<br>
>  // RUN:            -verify %s -DHAVE_A -DHAVE_B<br>
>  //<br>
> -// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// RUN:            -I%S/Inputs/explicit-build \<br>
>  // RUN:            -fmodule-file=%t/a.pcm \<br>
>  // RUN:            -fmodule-file=%t/b.pcm \<br>
>  // RUN:            -verify %s -DHAVE_A -DHAVE_B<br>
>  //<br>
> -// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// RUN:            -I%S/Inputs/explicit-build \<br>
>  // RUN:            -fmodule-file=%t/a.pcm \<br>
>  // RUN:            -fmodule-file=%t/b.pcm \<br>
>  // RUN:            -fmodule-file=%t/c.pcm \<br>
>  // RUN:            -verify %s -DHAVE_A -DHAVE_B -DHAVE_C<br>
>  //<br>
> -// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
>  // RUN:            -I%S/Inputs/explicit-build \<br>
>  // RUN:            -fmodule-file=%t/a.pcm \<br>
> -// RUN:            -fmodule-file=%t/b.pcm \<br>
>  // RUN:            -fmodule-file=%t/c.pcm \<br>
> -// RUN:            -verify %s -INCLUDE_ALL -DHAVE_A -DHAVE_B -DHAVE_C<br>
> +// RUN:            -verify %s -DHAVE_A -DHAVE_B -DHAVE_C<br>
><br>
> -#ifdef INCLUDE_ALL<br>
> +#if HAVE_A<br>
>    #include "a.h"<br>
> -  #include "b.h"<br>
> -  #include "c.h"<br>
>    static_assert(a == 1, "");<br>
> +#else<br>
> +  const int use_a = a; // expected-error {{undeclared identifier}}<br>
> +#endif<br>
> +<br>
> +#if HAVE_B<br>
> +  #include "b.h"<br>
>    static_assert(b == 2, "");<br>
> +#else<br>
> +  const int use_b = b; // expected-error {{undeclared identifier}}<br>
> +#endif<br>
> +<br>
> +#if HAVE_C<br>
> +  #include "c.h"<br>
>    static_assert(c == 3, "");<br>
>  #else<br>
> -  const int use_a = a;<br>
> -  #ifndef HAVE_A<br>
> -  // expected-error@-2 {{undeclared identifier}}<br>
> -  #else<br>
> -  // expected-error@-4 {{must be imported from module 'a'}}<br>
> -  // expected-note@Inputs/explicit-build/a.h:* {{here}}<br>
> -  #endif<br>
> -<br>
> -  const int use_b = b;<br>
> -  #ifndef HAVE_B<br>
> -  // expected-error@-2 {{undeclared identifier}}<br>
> -  #else<br>
> -  // expected-error@-4 {{must be imported from module 'b'}}<br>
> -  // expected-note@Inputs/explicit-build/b.h:* {{here}}<br>
> -  #endif<br>
> -<br>
> -  const int use_c = c;<br>
> -  #ifndef HAVE_C<br>
> -  // expected-error@-2 {{undeclared identifier}}<br>
> -  #else<br>
> -  // expected-error@-4 {{must be imported from module 'c'}}<br>
> -  // expected-note@Inputs/explicit-build/c.h:* {{here}}<br>
> -  #endif<br>
> +  const int use_c = c; // expected-error {{undeclared identifier}}<br>
> +#endif<br>
> +<br>
> +#if HAVE_A && HAVE_B && HAVE_C<br>
> +// expected-no-diagnostics<br>
>  #endif<br>
><br>
>  // -------------------------------<br>
>  // Check that we can use a mixture of implicit and explicit modules.<br>
> -// RUN: not %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// RUN:            -I%S/Inputs/explicit-build \<br>
>  // RUN:            -fmodule-file=%t/b-not-a.pcm \<br>
> -// RUN:            -fmodule-map-file=%S/Inputs/explicit-build/module.modulemap \<br>
> -// RUN:            %s 2>&1 | FileCheck --check-prefix=CHECK-A-AND-B-NO-A %s<br>
> +// RUN:            -verify %s -DHAVE_A -DHAVE_B<br>
><br>
>  // -------------------------------<br>
> -// Check that mixing an implicit and explicit form of the 'a' module is rejected.<br>
> -// RUN: not %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// Try to use two different flavors of the 'a' module.<br>
> +// RUN: not %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
>  // RUN:            -fmodule-file=%t/a.pcm \<br>
>  // RUN:            -fmodule-file=%t/b-not-a.pcm \<br>
> -// RUN:            %s 2>&1 | FileCheck --check-prefix=CHECK-A-AND-B-NO-A %s<br>
> +// RUN:            %s 2>&1 | FileCheck --check-prefix=CHECK-MULTIPLE-AS %s<br>
>  //<br>
> -// RUN: not %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// RUN: not %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
>  // RUN:            -fmodule-file=%t/a.pcm \<br>
>  // RUN:            -fmodule-file=%t/b-not-a.pcm \<br>
>  // RUN:            -fmodule-map-file=%S/Inputs/explicit-build/module.modulemap \<br>
> -// RUN:            %s 2>&1 | FileCheck --check-prefix=CHECK-A-AND-B-NO-A %s<br>
> +// RUN:            %s 2>&1 | FileCheck --check-prefix=CHECK-MULTIPLE-AS %s<br>
>  //<br>
> -// FIXME: We should load module map files specified on the command line and<br>
> -// module map files in include paths on demand to allow this, and possibly<br>
> -// also the previous case.<br>
> -// CHECK-A-AND-B-NO-A: fatal error: module 'a' {{.*}} is not defined in any loaded module map<br>
> -<br>
> -// -------------------------------<br>
> -// Try to use two different flavors of the 'a' module.<br>
> -// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
>  // RUN:            -fmodule-name=a -emit-module %S/Inputs/explicit-build/module.modulemap -o %t/a-alt.pcm \<br>
>  // RUN:            2>&1 | FileCheck --check-prefix=CHECK-NO-IMPLICIT-BUILD %s --allow-empty<br>
>  //<br>
> -// RUN: not %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// RUN: not %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
>  // RUN:            -fmodule-file=%t/a.pcm \<br>
>  // RUN:            -fmodule-file=%t/a-alt.pcm \<br>
>  // RUN:            -fmodule-map-file=%S/Inputs/explicit-build/module.modulemap \<br>
>  // RUN:            %s 2>&1 | FileCheck --check-prefix=CHECK-MULTIPLE-AS %s<br>
>  //<br>
> -// RUN: not %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// RUN: not %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
>  // RUN:            -fmodule-file=%t/a-alt.pcm \<br>
>  // RUN:            -fmodule-file=%t/a.pcm \<br>
>  // RUN:            -fmodule-map-file=%S/Inputs/explicit-build/module.modulemap \<br>
>  // RUN:            %s 2>&1 | FileCheck --check-prefix=CHECK-MULTIPLE-AS %s<br>
>  //<br>
> -// CHECK-MULTIPLE-AS: error: module 'a' has already been loaded; cannot load module file '{{.*a(-alt)?}}.pcm'<br>
> +// CHECK-MULTIPLE-AS: error: module 'a' is defined in both '{{.*}}/a{{.*}}.pcm' and '{{.*}}/a{{.*}}.pcm'<br>
><br>
>  // -------------------------------<br>
>  // Try to import a PCH with -fmodule-file=<br>
> -// RUN: %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// RUN: %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
>  // RUN:            -fmodule-name=a -emit-pch %S/Inputs/explicit-build/a.h -o %t/a.pch \<br>
>  // RUN:            2>&1 | FileCheck --check-prefix=CHECK-NO-IMPLICIT-BUILD %s --allow-empty<br>
>  //<br>
> -// RUN: not %clang_cc1 -x c++ -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// RUN: not %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
>  // RUN:            -fmodule-file=%t/a.pch \<br>
>  // RUN:            %s 2>&1 | FileCheck --check-prefix=CHECK-A-AS-PCH %s<br>
>  //<br>
>  // CHECK-A-AS-PCH: fatal error: AST file '{{.*}}a.pch' was not built as a module<br>
> +<br>
> +// -------------------------------<br>
> +// Try to import a non-AST file with -fmodule-file=<br>
> +//<br>
> +// RUN: touch %t/not.pcm<br>
> +//<br>
> +// RUN: not %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// RUN:            -fmodule-file=%t/not.pcm \<br>
> +// RUN:            %s 2>&1 | FileCheck --check-prefix=CHECK-BAD-FILE %s<br>
> +//<br>
> +// RUN: not %clang_cc1 -x c++ -std=c++11 -fmodules -fmodules-cache-path=%t -Rmodule-build -fno-modules-error-recovery \<br>
> +// RUN:            -fmodule-file=%t/nonexistent.pcm \<br>
> +// RUN:            %s 2>&1 | FileCheck --check-prefix=CHECK-BAD-FILE %s<br>
> +//<br>
> +// CHECK-BAD-FILE: fatal error: file '{{.*}}t.pcm' is not a precompiled module file<br>
><br>
><br>
> _______________________________________________<br>
> cfe-commits mailing list<br>
> <a href="mailto:cfe-commits@cs.uiuc.edu">cfe-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits</a><br>
</div></div></blockquote></div><br></div></div>