[vfs] Don't bail out after a missing -ivfsoverlay file

This make -ivfsoverlay behave more like other fatal errors (e.g. missing
-include file) by skipping the missing file instead of bailing out of
the whole compilation. This makes it possible for libclang to still
provide some functionallity as well as to correctly produce the fatal
error diagnostic (previously we lost the diagnostic in libclang since
there was no TU to tie it to).

rdar://33385423

llvm-svn: 328337
This commit is contained in:
Ben Langmuir 2018-03-23 17:37:27 +00:00
parent a237866faf
commit 005c2e57a6
10 changed files with 48 additions and 22 deletions

View File

@ -289,7 +289,6 @@ enum class BuildPreambleError {
PreambleIsEmpty = 1,
CouldntCreateTempFile,
CouldntCreateTargetInfo,
CouldntCreateVFSOverlay,
BeginSourceFileFailed,
CouldntEmitPCH
};

View File

@ -1354,7 +1354,6 @@ ASTUnit::getMainBufferWithPrecompiledPreamble(
case BuildPreambleError::CouldntCreateTargetInfo:
case BuildPreambleError::BeginSourceFileFailed:
case BuildPreambleError::CouldntEmitPCH:
case BuildPreambleError::CouldntCreateVFSOverlay:
// These erros are more likely to repeat, retry after some period.
PreambleRebuildCounter = DefaultPreambleRebuildInterval;
return nullptr;
@ -1456,8 +1455,6 @@ ASTUnit::create(std::shared_ptr<CompilerInvocation> CI,
ConfigureDiags(Diags, *AST, CaptureDiagnostics);
IntrusiveRefCntPtr<vfs::FileSystem> VFS =
createVFSFromCompilerInvocation(*CI, *Diags);
if (!VFS)
return nullptr;
AST->Diagnostics = Diags;
AST->FileSystemOpts = CI->getFileSystemOpts();
AST->Invocation = std::move(CI);
@ -1735,14 +1732,14 @@ ASTUnit *ASTUnit::LoadFromCommandLine(
// Create the AST unit.
std::unique_ptr<ASTUnit> AST;
AST.reset(new ASTUnit(false));
AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size();
AST->StoredDiagnostics.swap(StoredDiagnostics);
ConfigureDiags(Diags, *AST, CaptureDiagnostics);
AST->Diagnostics = Diags;
AST->FileSystemOpts = CI->getFileSystemOpts();
if (!VFS)
VFS = vfs::getRealFileSystem();
VFS = createVFSFromCompilerInvocation(*CI, *Diags, VFS);
if (!VFS)
return nullptr;
AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
AST->PCMCache = new MemoryBufferCache;
AST->OnlyLocalDecls = OnlyLocalDecls;
@ -1752,8 +1749,6 @@ ASTUnit *ASTUnit::LoadFromCommandLine(
AST->IncludeBriefCommentsInCodeCompletion
= IncludeBriefCommentsInCodeCompletion;
AST->UserFilesAreVolatile = UserFilesAreVolatile;
AST->NumStoredDiagnosticsFromDriver = StoredDiagnostics.size();
AST->StoredDiagnostics.swap(StoredDiagnostics);
AST->Invocation = CI;
if (ForSerialization)
AST->WriterData.reset(new ASTWriterData(*AST->PCMCache));

View File

@ -302,11 +302,9 @@ CompilerInstance::createDiagnostics(DiagnosticOptions *Opts,
FileManager *CompilerInstance::createFileManager() {
if (!hasVirtualFileSystem()) {
if (IntrusiveRefCntPtr<vfs::FileSystem> VFS =
createVFSFromCompilerInvocation(getInvocation(), getDiagnostics()))
setVirtualFileSystem(VFS);
else
return nullptr;
IntrusiveRefCntPtr<vfs::FileSystem> VFS =
createVFSFromCompilerInvocation(getInvocation(), getDiagnostics());
setVirtualFileSystem(VFS);
}
FileMgr = new FileManager(getFileSystemOpts(), VirtualFileSystem);
return FileMgr.get();

View File

@ -3073,16 +3073,15 @@ createVFSFromCompilerInvocation(const CompilerInvocation &CI,
BaseFS->getBufferForFile(File);
if (!Buffer) {
Diags.Report(diag::err_missing_vfs_overlay_file) << File;
return IntrusiveRefCntPtr<vfs::FileSystem>();
continue;
}
IntrusiveRefCntPtr<vfs::FileSystem> FS = vfs::getVFSFromYAML(
std::move(Buffer.get()), /*DiagHandler*/ nullptr, File);
if (!FS.get()) {
if (FS)
Overlay->pushOverlay(FS);
else
Diags.Report(diag::err_invalid_vfs_overlay) << File;
return IntrusiveRefCntPtr<vfs::FileSystem>();
}
Overlay->pushOverlay(FS);
}
return Overlay;
}

View File

@ -303,8 +303,6 @@ llvm::ErrorOr<PrecompiledPreamble> PrecompiledPreamble::Build(
VFS =
createVFSFromCompilerInvocation(Clang->getInvocation(), Diagnostics, VFS);
if (!VFS)
return BuildPreambleError::CouldntCreateVFSOverlay;
// Create a file manager object to provide access to and cache the filesystem.
Clang->setFileManager(new FileManager(Clang->getFileSystemOpts(), VFS));
@ -756,8 +754,6 @@ std::string BuildPreambleErrorCategory::message(int condition) const {
return "Could not create temporary file for PCH";
case BuildPreambleError::CouldntCreateTargetInfo:
return "CreateTargetInfo() return null";
case BuildPreambleError::CouldntCreateVFSOverlay:
return "Could not create VFS Overlay";
case BuildPreambleError::BeginSourceFileFailed:
return "BeginSourceFile() return an error";
case BuildPreambleError::CouldntEmitPCH:

View File

@ -0,0 +1,6 @@
// RUN: c-index-test -test-load-source local %s -ivfsoverlay %t/does-not-exist.yaml &> %t.out
// RUN: FileCheck -check-prefix=STDERR %s < %t.out
// STDERR: fatal error: virtual filesystem overlay file '{{.*}}' not found
// RUN: FileCheck %s < %t.out
// CHECK: missing_vfs.c:[[@LINE+1]]:6: FunctionDecl=foo:[[@LINE+1]]:6
void foo(void);

View File

@ -0,0 +1 @@
// void funcA(void);

View File

@ -0,0 +1,3 @@
module A {
header "a.h"
}

View File

@ -0,0 +1,13 @@
{
'version': 0,
'ignore-non-existent-contents': false,
'roots': [
{ 'name': 'INPUT_DIR', 'type': 'directory',
'contents': [
{ 'name': 'a.h', 'type': 'file',
'external-contents': 'OUT_DIR/a.h'
}
]
}
]
}

View File

@ -0,0 +1,16 @@
// REQUIRES: shell
// RUN: rm -rf %t && mkdir -p %t
// RUN: echo "void funcA(void);" >> %t/a.h
// RUN: not %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/mcp -I %S/Inputs/MissingVFS %s -fsyntax-only -ivfsoverlay %t/vfs.yaml 2>&1 | FileCheck %s -check-prefix=ERROR
// ERROR: virtual filesystem overlay file '{{.*}}' not found
// RUN: find %t/mcp -name "A-*.pcm" | count 1
// RUN: sed -e "s:INPUT_DIR:%S/Inputs:g" -e "s:OUT_DIR:%t:g" %S/Inputs/MissingVFS/vfsoverlay.yaml > %t/vfs.yaml
// RUN: %clang_cc1 -fmodules -fimplicit-module-maps -fmodules-cache-path=%t/mcp -I %S/Inputs/MissingVFS %s -fsyntax-only -ivfsoverlay %t/vfs.yaml
// RUN: find %t/mcp -name "A-*.pcm" | count 1
@import A;
void test(void) {
funcA();
}