r220731 - [modules] Load .pcm files specified by -fmodule-file lazily.
Richard Smith
richard-llvm at metafoo.co.uk
Mon Oct 27 16:01:16 PDT 2014
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++];
+ 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
More information about the cfe-commits
mailing list