diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td index fc3ca62113e5dace4133b6a055e29bdfb04b78d8..605736f0763d2d4c782cb7564c62c0505ae2c2a3 100644 --- a/include/clang/Basic/DiagnosticCommonKinds.td +++ b/include/clang/Basic/DiagnosticCommonKinds.td @@ -194,9 +194,8 @@ def err_unable_to_make_temp : Error< "unable to make temporary file: %0">; // Modules -def err_module_file_conflict : Error<"module '%0' found in both '%1' and '%2'">; def err_module_format_unhandled : Error< - "no handler registered for module format '%0'">; + "no handler registered for module format '%0'">, DefaultFatal; // TransformActions // TODO: Use a custom category name to distinguish rewriter errors. diff --git a/include/clang/Basic/DiagnosticFrontendKinds.td b/include/clang/Basic/DiagnosticFrontendKinds.td index f4ab4800c9e79551f15efb20b09e5be1ccad51d1..21058aa0bb05e1b71c44f0df8ceec0e5c71da504 100644 --- a/include/clang/Basic/DiagnosticFrontendKinds.td +++ b/include/clang/Basic/DiagnosticFrontendKinds.td @@ -194,16 +194,6 @@ def remark_module_build_done : Remark<"finished building module '%0'">, def err_conflicting_module_names : Error< "conflicting module names specified: '-fmodule-name=%0' and " "'-fmodule-implementation-of %1'">; -def err_conflicting_module_files : Error< - "module '%0' is defined in both '%1' and '%2'">; -def err_module_file_not_found : Error< - "module file '%0' not found">, DefaultFatal; -def err_module_file_invalid : Error< - "file '%0' is not a valid precompiled module file">, DefaultFatal; -def note_module_file_imported_by : Note< - "imported by %select{|module '%2' in }1'%0'">; -def err_module_file_not_module : Error< - "AST file '%0' was not built as a module">, DefaultFatal; def err_missing_vfs_overlay_file : Error< "virtual filesystem overlay file '%0' not found">, DefaultFatal; diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td index 796027ea628bf9c5d62cdd222028a7b8de218bdc..bd81c8041fafac2365282c513c52fead70e9fb42 100644 --- a/include/clang/Basic/DiagnosticSerializationKinds.td +++ b/include/clang/Basic/DiagnosticSerializationKinds.td @@ -53,6 +53,20 @@ def err_pch_different_branch : Error< def err_pch_with_compiler_errors : Error< "PCH file contains compiler errors">; +def err_module_file_conflict : Error< + "module '%0' is defined in both '%1' and '%2'">, DefaultFatal; +def err_module_file_not_found : Error< + "%select{PCH|module|AST}0 file '%1' not found%select{|: %3}2">, DefaultFatal; +def err_module_file_out_of_date : Error< + "%select{PCH|module|AST}0 file '%1' is out of date and " + "needs to be rebuilt%select{|: %3}2">, DefaultFatal; +def err_module_file_invalid : Error< + "file '%1' is not a valid precompiled %select{PCH|module|AST}0 file">, DefaultFatal; +def note_module_file_imported_by : Note< + "imported by %select{|module '%2' in }1'%0'">; +def err_module_file_not_module : Error< + "AST file '%0' was not built as a module">, DefaultFatal; + def err_imported_module_not_found : Error< "module '%0' in AST file '%1' (imported by AST file '%2') " "is not defined in any loaded module map file; " @@ -82,9 +96,6 @@ def err_pch_pp_detailed_record : Error< "'-detailed-preprocessing-record' but %select{precompiled header was not " "built with it|it is not present on the command line}0">; -def err_not_a_pch_file : Error< - "'%0' does not appear to be a precompiled header file">, DefaultFatal; - def err_module_odr_violation_missing_decl : Error< "%q0 from module '%1' is not present in definition of %q2" "%select{ in module '%4'| provided earlier}3">, NoSFINAE; diff --git a/lib/CodeGen/ObjectFilePCHContainerOperations.cpp b/lib/CodeGen/ObjectFilePCHContainerOperations.cpp index e09b2857a37fa9fe7c5fa0d94e443fc63d39ab8a..d0e857be3ca2a19405849eabf509a4ee6b047214 100644 --- a/lib/CodeGen/ObjectFilePCHContainerOperations.cpp +++ b/lib/CodeGen/ObjectFilePCHContainerOperations.cpp @@ -58,7 +58,7 @@ public: const std::string &OutputFileName, raw_pwrite_stream *OS, std::shared_ptr<PCHBuffer> Buffer) - : Diags(diags), HeaderSearchOpts(HSO), PreprocessorOpts(PPO), + : Diags(diags), Ctx(nullptr), HeaderSearchOpts(HSO), PreprocessorOpts(PPO), TargetOpts(TO), LangOpts(LO), OS(OS), Buffer(Buffer) { // The debug info output isn't affected by CodeModel and // ThreadModel, but the backend expects them to be nonempty. @@ -71,6 +71,11 @@ public: virtual ~PCHContainerGenerator() {} void Initialize(ASTContext &Context) override { + if (Ctx) { + assert(Ctx == &Context); + return; + } + Ctx = &Context; VMContext.reset(new llvm::LLVMContext()); M.reset(new llvm::Module(MainFileName, *VMContext)); diff --git a/lib/Frontend/CompilerInstance.cpp b/lib/Frontend/CompilerInstance.cpp index 5133ffc2726bcea214032fbf61056c52f9961ebe..7d9efd4e9be0646ab0e943b3c31a52219138b08e 100644 --- a/lib/Frontend/CompilerInstance.cpp +++ b/lib/Frontend/CompilerInstance.cpp @@ -1261,8 +1261,10 @@ void CompilerInstance::createModuleManager() { getASTContext().setExternalSource(ModuleManager); if (hasSema()) ModuleManager->InitializeSema(getSema()); - if (hasASTConsumer()) + if (hasASTConsumer()) { + getASTConsumer().Initialize(getASTContext()); ModuleManager->StartTranslationUnit(&getASTConsumer()); + } if (TheDependencyFileGenerator) TheDependencyFileGenerator->AttachToASTReader(*ModuleManager); @@ -1284,86 +1286,44 @@ bool CompilerInstance::loadModuleFile(StringRef FileName) { // the files we were handed. struct ReadModuleNames : ASTReaderListener { CompilerInstance &CI; - std::vector<StringRef> ModuleFileStack; - std::vector<StringRef> ModuleNameStack; - bool Failed; - bool TopFileIsModule; - - ReadModuleNames(CompilerInstance &CI) - : CI(CI), Failed(false), TopFileIsModule(false) {} - - bool needsImportVisitation() const override { return true; } + llvm::SmallVector<IdentifierInfo*, 8> LoadedModules; - void visitImport(StringRef FileName) override { - if (!CI.ExplicitlyLoadedModuleFiles.insert(FileName).second) { - if (ModuleFileStack.size() == 0) - TopFileIsModule = true; - return; - } + ReadModuleNames(CompilerInstance &CI) : CI(CI) {} - ModuleFileStack.push_back(FileName); - ModuleNameStack.push_back(StringRef()); - if (ASTReader::readASTFileControlBlock(FileName, CI.getFileManager(), - CI.getPCHContainerReader(), - *this)) { - CI.getDiagnostics().Report( - SourceLocation(), CI.getFileManager().getBufferForFile(FileName) - ? diag::err_module_file_invalid - : diag::err_module_file_not_found) - << FileName; - for (int I = ModuleFileStack.size() - 2; I >= 0; --I) - CI.getDiagnostics().Report(SourceLocation(), - diag::note_module_file_imported_by) - << ModuleFileStack[I] - << !ModuleNameStack[I].empty() << ModuleNameStack[I]; - Failed = true; - } - ModuleNameStack.pop_back(); - ModuleFileStack.pop_back(); + void ReadModuleName(StringRef ModuleName) override { + LoadedModules.push_back( + CI.getPreprocessor().getIdentifierInfo(ModuleName)); } - void ReadModuleName(StringRef ModuleName) override { - if (ModuleFileStack.size() == 1) - TopFileIsModule = true; - ModuleNameStack.back() = ModuleName; - - auto &ModuleFile = CI.ModuleFileOverrides[ModuleName]; - if (!ModuleFile.empty() && - CI.getFileManager().getFile(ModuleFile) != - CI.getFileManager().getFile(ModuleFileStack.back())) - CI.getDiagnostics().Report(SourceLocation(), - diag::err_conflicting_module_files) - << ModuleName << ModuleFile << ModuleFileStack.back(); - ModuleFile = ModuleFileStack.back(); + void registerAll() { + for (auto *II : LoadedModules) { + CI.KnownModules[II] = CI.getPreprocessor() + .getHeaderSearchInfo() + .getModuleMap() + .findModule(II->getName()); + } + LoadedModules.clear(); } - } RMN(*this); + }; // If we don't already have an ASTReader, create one now. if (!ModuleManager) createModuleManager(); - // Tell the module manager about this module file. - if (getModuleManager()->getModuleManager().addKnownModuleFile(FileName)) { - getDiagnostics().Report(SourceLocation(), diag::err_module_file_not_found) - << FileName; - return false; - } - - // Build our mapping of module names to module files from this file - // and its imports. - RMN.visitImport(FileName); - - if (RMN.Failed) - return false; + auto Listener = llvm::make_unique<ReadModuleNames>(*this); + auto &ListenerRef = *Listener; + ASTReader::ListenerScope ReadModuleNamesListener(*ModuleManager, + std::move(Listener)); - // 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; + // Try to load the module file. + if (ModuleManager->ReadAST(FileName, serialization::MK_ExplicitModule, + SourceLocation(), ASTReader::ARR_None) + != ASTReader::Success) return false; - } + // We successfully loaded the module file; remember the set of provided + // modules so that we don't try to load implicit modules for them. + ListenerRef.registerAll(); return true; } @@ -1412,6 +1372,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, return ModuleLoadResult(); } + // FIXME: Rmove ModuleFileOverrides auto Override = ModuleFileOverrides.find(ModuleName); bool Explicit = Override != ModuleFileOverrides.end(); @@ -1507,7 +1468,7 @@ CompilerInstance::loadModule(SourceLocation ImportLoc, case ASTReader::ConfigurationMismatch: case ASTReader::HadErrors: ModuleLoader::HadFatalFailure = true; - // FIXME: The ASTReader will already have complained, but can we showhorn + // FIXME: The ASTReader will already have complained, but can we shoehorn // that diagnostic information into a more useful form? KnownModules[Path[0].first] = nullptr; return ModuleLoadResult(); diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index ff771fd00a3b09ef2d9271f2d4ea3e884e5975f5..29a935c9099818abf64bbf5d6e915b6dc16c4fa2 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -2029,6 +2029,21 @@ void ASTReader::ResolveImportedPath(std::string &Filename, StringRef Prefix) { Filename.assign(Buffer.begin(), Buffer.end()); } +static bool isDiagnosedResult(ASTReader::ASTReadResult ARR, unsigned Caps) { + switch (ARR) { + case ASTReader::Failure: return true; + case ASTReader::Missing: return !(Caps & ASTReader::ARR_Missing); + case ASTReader::OutOfDate: return !(Caps & ASTReader::ARR_OutOfDate); + case ASTReader::VersionMismatch: return !(Caps & ASTReader::ARR_VersionMismatch); + case ASTReader::ConfigurationMismatch: + return !(Caps & ASTReader::ARR_ConfigurationMismatch); + case ASTReader::HadErrors: return true; + case ASTReader::Success: return false; + } + + llvm_unreachable("unknown ASTReadResult"); +} + ASTReader::ASTReadResult ASTReader::ReadControlBlock(ModuleFile &F, SmallVectorImpl<ImportedModule> &Loaded, @@ -2064,8 +2079,9 @@ ASTReader::ReadControlBlock(ModuleFile &F, PP.getHeaderSearchInfo().getHeaderSearchOpts(); // All user input files reside at the index range [0, NumUserInputs), and - // system input files reside at [NumUserInputs, NumInputs). - if (!DisableValidation) { + // system input files reside at [NumUserInputs, NumInputs). For explicitly + // loaded module files, ignore missing inputs. + if (!DisableValidation && F.Kind != MK_ExplicitModule) { bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0; // If we are reading a module, we will create a verification timestamp, @@ -2181,10 +2197,23 @@ ASTReader::ReadControlBlock(ModuleFile &F, ASTFileSignature StoredSignature = Record[Idx++]; auto ImportedFile = ReadPath(F, Record, Idx); + // If our client can't cope with us being out of date, we can't cope with + // our dependency being missing. + unsigned Capabilities = ClientLoadCapabilities; + if ((ClientLoadCapabilities & ARR_OutOfDate) == 0) + Capabilities &= ~ARR_Missing; + // Load the AST file. - switch(ReadASTCore(ImportedFile, ImportedKind, ImportLoc, &F, Loaded, - StoredSize, StoredModTime, StoredSignature, - ClientLoadCapabilities)) { + auto Result = ReadASTCore(ImportedFile, ImportedKind, ImportLoc, &F, + Loaded, StoredSize, StoredModTime, + StoredSignature, Capabilities); + + // If we diagnosed a problem, produce a backtrace. + if (isDiagnosedResult(Result, Capabilities)) + Diag(diag::note_module_file_imported_by) + << F.FileName << !F.ModuleName.empty() << F.ModuleName; + + switch (Result) { case Failure: return Failure; // If we have to ignore the dependency, we'll have to ignore this too. case Missing: @@ -3152,11 +3181,18 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F, const FileEntry *ModMap = M ? Map.getModuleMapFileForUniquing(M) : nullptr; if (!ModMap) { assert(ImportedBy && "top-level import should be verified"); - if ((ClientLoadCapabilities & ARR_Missing) == 0) - Diag(diag::err_imported_module_not_found) << F.ModuleName << F.FileName - << ImportedBy->FileName - << F.ModuleMapPath; - return Missing; + if ((ClientLoadCapabilities & ARR_OutOfDate) == 0) { + if (auto *ASTFE = M ? M->getASTFile() : nullptr) + // This module was defined by an imported (explicit) module. + Diag(diag::err_module_file_conflict) << F.ModuleName << F.FileName + << ASTFE->getName(); + else + // This module was built with a different module map. + Diag(diag::err_imported_module_not_found) + << F.ModuleName << F.FileName << ImportedBy->FileName + << F.ModuleMapPath; + } + return OutOfDate; } assert(M->Name == F.ModuleName && "found module with different name"); @@ -3557,6 +3593,20 @@ static bool startsWithASTFileMagic(BitstreamCursor &Stream) { Stream.Read(8) == 'H'; } +static unsigned moduleKindForDiagnostic(ModuleKind Kind) { + switch (Kind) { + case MK_PCH: + return 0; // PCH + case MK_ImplicitModule: + case MK_ExplicitModule: + return 1; // module + case MK_MainFile: + case MK_Preamble: + return 2; // main source file + } + llvm_unreachable("unknown module kind"); +} + ASTReader::ASTReadResult ASTReader::ReadASTCore(StringRef FileName, ModuleKind Type, @@ -3589,11 +3639,9 @@ ASTReader::ReadASTCore(StringRef FileName, return Missing; // Otherwise, return an error. - { - std::string Msg = "Unable to load module \"" + FileName.str() + "\": " - + ErrorStr; - Error(Msg); - } + Diag(diag::err_module_file_not_found) << moduleKindForDiagnostic(Type) + << FileName << ErrorStr.empty() + << ErrorStr; return Failure; case ModuleManager::OutOfDate: @@ -3603,11 +3651,9 @@ ASTReader::ReadASTCore(StringRef FileName, return OutOfDate; // Otherwise, return an error. - { - std::string Msg = "Unable to load module \"" + FileName.str() + "\": " - + ErrorStr; - Error(Msg); - } + Diag(diag::err_module_file_out_of_date) << moduleKindForDiagnostic(Type) + << FileName << ErrorStr.empty() + << ErrorStr; return Failure; } @@ -3628,7 +3674,8 @@ ASTReader::ReadASTCore(StringRef FileName, // Sniff for the signature. if (!startsWithASTFileMagic(Stream)) { - Diag(diag::err_not_a_pch_file) << FileName; + Diag(diag::err_module_file_invalid) << moduleKindForDiagnostic(Type) + << FileName; return Failure; } @@ -3661,6 +3708,18 @@ ASTReader::ReadASTCore(StringRef FileName, HaveReadControlBlock = true; switch (ReadControlBlock(F, Loaded, ImportedBy, ClientLoadCapabilities)) { case Success: + // Check that we didn't try to load a non-module AST file as a module. + // + // FIXME: Should we also perform the converse check? Loading a module as + // a PCH file sort of works, but it's a bit wonky. + if ((Type == MK_ImplicitModule || Type == MK_ExplicitModule) && + F.ModuleName.empty()) { + auto Result = (Type == MK_ImplicitModule) ? OutOfDate : Failure; + if (Result != OutOfDate || + (ClientLoadCapabilities & ARR_OutOfDate) == 0) + Diag(diag::err_module_file_not_module) << FileName; + return Result; + } break; case Failure: return Failure; @@ -3690,8 +3749,6 @@ ASTReader::ReadASTCore(StringRef FileName, break; } } - - return Success; } void ASTReader::InitializeContext() { diff --git a/test/Index/pch-depending-on-deleted-module.c b/test/Index/pch-depending-on-deleted-module.c index a0fbaf559fcadc78445c8c1fd548a8681370c78c..8efa66a32373c4cf987b925e42726aeb3190c666 100644 --- a/test/Index/pch-depending-on-deleted-module.c +++ b/test/Index/pch-depending-on-deleted-module.c @@ -9,6 +9,6 @@ // RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -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 -fimplicit-module-maps -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 +// VERIFY: fatal error: module file '{{.*}}LibA.pcm' not found // INDEX: {{^}}Failure: AST deserialization error occurred{{$}} diff --git a/test/Modules/dependency-gen.modulemap b/test/Modules/dependency-gen.modulemap index ba109c2be4025552f0a584e6250346865481fd85..ace1177a3e5b5022485b56ca9ff548bd3d72a35c 100644 --- a/test/Modules/dependency-gen.modulemap +++ b/test/Modules/dependency-gen.modulemap @@ -1,10 +1,10 @@ // RUN: cd %S // RUN: rm -rf %t // -// RUN: %clang_cc1 -I. -x c++ -fmodule-name=test -fmodules -emit-module -fno-validate-pch -fmodules-strict-decluse %s -dependency-file - -MT implicit.pcm -o %t/implicit.pcm -fmodules-cache-path=%t -fmodule-map-file-home-is-cwd | FileCheck %s +// RUN: %clang_cc1 -I. -x c++ -fmodule-name=test -fmodules -emit-module -fno-validate-pch -fmodules-strict-decluse %s -dependency-file - -MT implicit.pcm -o %t/implicit.pcm -fmodules-cache-path=%t -fmodule-map-file-home-is-cwd | FileCheck %s --check-prefix=IMPLICIT // // RUN: %clang_cc1 -I. -x c++ -fmodule-name=test-base -fmodules -emit-module -fno-validate-pch -fmodules-strict-decluse Inputs/dependency-gen-base.modulemap -o %t/base.pcm -fmodule-map-file-home-is-cwd -// RUN: %clang_cc1 -I. -x c++ -fmodule-name=test -fmodules -emit-module -fno-validate-pch -fmodules-strict-decluse -fmodule-file=%t/base.pcm %s -dependency-file - -MT explicit.pcm -o %t/explicit.pcm -fmodules-cache-path=%t -fmodule-map-file-home-is-cwd | FileCheck %s +// RUN: %clang_cc1 -I. -x c++ -fmodule-name=test -fmodules -emit-module -fno-validate-pch -fmodules-strict-decluse -fmodule-file=%t/base.pcm %s -dependency-file - -MT explicit.pcm -o %t/explicit.pcm -fmodules-cache-path=%t -fmodule-map-file-home-is-cwd | FileCheck %s --check-prefix=EXPLICIT module "test" { export * header "Inputs/dependency-gen.h" @@ -14,10 +14,30 @@ module "test" { extern module "test-base2" "Inputs/dependency-gen-base2.modulemap" extern module "test-base" "Inputs/dependency-gen-base.modulemap" -// CHECK-DAG: {{[/\\]}}dependency-gen.modulemap -// CHECK-DAG: {{ |\.[/\\]}}Inputs{{[/\\]}}dependency-gen-base.modulemap -// CHECK-DAG: {{ |\.[/\\]}}Inputs{{[/\\]}}dependency-gen-base2.modulemap +// For implicit use of a module via the module cache, the input files +// referenced by the .pcm are also dependencies of this build. +// +// IMPLICIT-DAG: {{[/\\]}}dependency-gen.modulemap +// IMPLICIT-DAG: {{ |\.[/\\]}}Inputs{{[/\\]}}dependency-gen-base.modulemap +// IMPLICIT-DAG: {{ |\.[/\\]}}Inputs{{[/\\]}}dependency-gen-base2.modulemap +// IMPLICIT-DAG: {{ |\.[/\\]}}Inputs{{[/\\]}}dependency-gen.h +// IMPLICIT-DAG: {{ |\.[/\\]}}Inputs{{[/\\]}}dependency-gen-included.h +// IMPLICIT-DAG: {{ |\.[/\\]}}Inputs{{[/\\]}}dependency-gen-included2.h -// CHECK-DAG: {{ |\.[/\\]}}Inputs{{[/\\]}}dependency-gen.h -// CHECK-DAG: {{ |\.[/\\]}}Inputs{{[/\\]}}dependency-gen-included.h -// CHECK-DAG: {{ |\.[/\\]}}Inputs{{[/\\]}}dependency-gen-included2.h +// For an explicit use of a module via -fmodule-file=, the other module maps +// and included headers are not dependencies of this target (they are instead +// dependencies of the explicitly-specified .pcm input). +// +// FIXME: We should avoid loading the other referenced module maps (we already +// have a parsed copy of their contents from the .pcm file) and thus not list +// them here. +// +// FIXME: We should list a dependency on the explicitly specified .pcm files +// (whether or not -module-file-deps is specified on the command line). +// +// EXPLICIT-FIXME-NOT: dependency-gen- +// EXPLICIT-FIXME: {{.*}}/base.pcm +// +// EXPLICIT: {{^}}explicit.pcm: +// EXPLICIT: {{.*}}/dependency-gen.modulemap +// EXPLICIT: {{ |\.[/\\]}}Inputs{{[/\\]}}dependency-gen.h diff --git a/test/Modules/explicit-build-missing-files.cpp b/test/Modules/explicit-build-missing-files.cpp new file mode 100644 index 0000000000000000000000000000000000000000..2ea157b934c0bceb3f1818b64d29d580035b4cb7 --- /dev/null +++ b/test/Modules/explicit-build-missing-files.cpp @@ -0,0 +1,21 @@ +// RUN: rm -rf %t +// RUN: mkdir %t +// RUN: echo 'extern int a;' > %t/a.h +// RUN: echo 'extern int b;' > %t/b.h +// RUN: echo 'module a { header "a.h" header "b.h" }' > %t/modulemap + +// We lazily check that the files referenced by an explicitly-specified .pcm +// file exist. Test this by removing files and ensuring that the compilation +// still succeeds. +// +// RUN: %clang_cc1 -fmodules -I %t -emit-module -fmodule-name=a -x c++ %t/modulemap -o %t/a.pcm +// RUN: %clang_cc1 -fmodules -I %t -fmodule-file=%t/a.pcm %s +// RUN: rm %t/modulemap +// RUN: %clang_cc1 -fmodules -I %t -fmodule-file=%t/a.pcm %s +// RUN: rm %t/b.h +// RUN: %clang_cc1 -fmodules -I %t -fmodule-file=%t/a.pcm %s +// RUN: rm %t/a.h +// RUN: %clang_cc1 -fmodules -I %t -fmodule-file=%t/a.pcm %s -verify + +#include "a.h" // expected-error {{file not found}} +int x = b; diff --git a/test/Modules/explicit-build.cpp b/test/Modules/explicit-build.cpp index 01aa5dc68bf8d0fbd3b8d0e5025d0593281af7be..4f125810558735f53bc05e0ddcf6d2261433532e 100644 --- a/test/Modules/explicit-build.cpp +++ b/test/Modules/explicit-build.cpp @@ -179,6 +179,7 @@ // CHECK-NO-FILE-INDIRECT: error: module file '{{.*}}a.pcm' not found // CHECK-NO-FILE-INDIRECT-NEXT: note: imported by module 'b' in '{{.*}}b.pcm' // CHECK-NO-FILE-INDIRECT-NEXT: note: imported by module 'c' in '{{.*}}c.pcm' +// CHECK-NO-FILE-INDIRECT-NOT: note: // ------------------------------- // Check that we don't get upset if B's timestamp is newer than C's. @@ -198,4 +199,6 @@ // RUN: -fmodule-file=%t/c.pcm \ // RUN: %s -DHAVE_A -DHAVE_B -DHAVE_C 2>&1 | FileCheck --check-prefix=CHECK-MISMATCHED-B %s // -// CHECK-MISMATCHED-B: fatal error: malformed or corrupted AST file: {{.*}}b.pcm": module file out of date +// CHECK-MISMATCHED-B: fatal error: module file '{{.*}}b.pcm' is out of date and needs to be rebuilt +// CHECK-MISMATCHED-B-NEXT: note: imported by module 'c' +// CHECK-MISMATCHED-B-NOT: note: diff --git a/test/Modules/fatal-module-loader-error.m b/test/Modules/fatal-module-loader-error.m index 99a42c2aff4206ef9a55c371212b99e24cd550db..6e6131e00010159b301923e0bf14afbf41fac8a2 100644 --- a/test/Modules/fatal-module-loader-error.m +++ b/test/Modules/fatal-module-loader-error.m @@ -8,13 +8,13 @@ #ifdef IMPLICIT -// expected-error@+1{{does not appear to be}} +// expected-error@+1{{Module.pcm' is not a valid precompiled module file}} #import <Module/Module.h> #pragma clang __debug crash; #else -// expected-error@+1{{does not appear to be}} +// expected-error@+1{{Module.pcm' is not a valid precompiled module file}} @import Module; #pragma clang __debug crash; diff --git a/test/Modules/relative-dep-gen.cpp b/test/Modules/relative-dep-gen.cpp index 5fbfcfa38149e61b36b749a1f547043ed98f1ebc..d82b5a18b1ebe73d41d46d8dd4255ae158df3bbb 100644 --- a/test/Modules/relative-dep-gen.cpp +++ b/test/Modules/relative-dep-gen.cpp @@ -25,6 +25,6 @@ // CHECK-BUILD: Inputs/relative-dep-gen-1.h // CHECK-BUILD: Inputs/relative-dep-gen-2.h // CHECK-USE: use.o: -// CHECK-USE: Inputs/relative-dep-gen{{(-cwd)?}}.modulemap -// CHECK-USE: relative-dep-gen.cpp -// CHECK-USE: Inputs/relative-dep-gen-1.h +// CHECK-USE-DAG: Inputs/relative-dep-gen{{(-cwd)?}}.modulemap +// CHECK-USE-DAG: relative-dep-gen.cpp +// CHECK-USE-DAG: Inputs/relative-dep-gen-1.h