From 005c2e57a658bc18529de5027d52619dc4a2a72c Mon Sep 17 00:00:00 2001 From: Ben Langmuir Date: Fri, 23 Mar 2018 17:37:27 +0000 Subject: [PATCH] [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 --- clang/include/clang/Frontend/PrecompiledPreamble.h | 1 - clang/lib/Frontend/ASTUnit.cpp | 9 ++------- clang/lib/Frontend/CompilerInstance.cpp | 8 +++----- clang/lib/Frontend/CompilerInvocation.cpp | 9 ++++----- clang/lib/Frontend/PrecompiledPreamble.cpp | 4 ---- clang/test/Index/missing_vfs.c | 6 ++++++ clang/test/VFS/Inputs/MissingVFS/a.h | 1 + clang/test/VFS/Inputs/MissingVFS/module.modulemap | 3 +++ clang/test/VFS/Inputs/MissingVFS/vfsoverlay.yaml | 13 +++++++++++++ clang/test/VFS/module_missing_vfs.m | 16 ++++++++++++++++ 10 files changed, 48 insertions(+), 22 deletions(-) create mode 100644 clang/test/Index/missing_vfs.c create mode 100644 clang/test/VFS/Inputs/MissingVFS/a.h create mode 100644 clang/test/VFS/Inputs/MissingVFS/module.modulemap create mode 100644 clang/test/VFS/Inputs/MissingVFS/vfsoverlay.yaml create mode 100644 clang/test/VFS/module_missing_vfs.m diff --git a/clang/include/clang/Frontend/PrecompiledPreamble.h b/clang/include/clang/Frontend/PrecompiledPreamble.h index f1898f5..aa8fb82 100644 --- a/clang/include/clang/Frontend/PrecompiledPreamble.h +++ b/clang/include/clang/Frontend/PrecompiledPreamble.h @@ -289,7 +289,6 @@ enum class BuildPreambleError { PreambleIsEmpty = 1, CouldntCreateTempFile, CouldntCreateTargetInfo, - CouldntCreateVFSOverlay, BeginSourceFileFailed, CouldntEmitPCH }; diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp index cd3664b..1247e82 100644 --- a/clang/lib/Frontend/ASTUnit.cpp +++ b/clang/lib/Frontend/ASTUnit.cpp @@ -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 CI, ConfigureDiags(Diags, *AST, CaptureDiagnostics); IntrusiveRefCntPtr 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 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)); diff --git a/clang/lib/Frontend/CompilerInstance.cpp b/clang/lib/Frontend/CompilerInstance.cpp index bb8b857..a03e5df 100644 --- a/clang/lib/Frontend/CompilerInstance.cpp +++ b/clang/lib/Frontend/CompilerInstance.cpp @@ -302,11 +302,9 @@ CompilerInstance::createDiagnostics(DiagnosticOptions *Opts, FileManager *CompilerInstance::createFileManager() { if (!hasVirtualFileSystem()) { - if (IntrusiveRefCntPtr VFS = - createVFSFromCompilerInvocation(getInvocation(), getDiagnostics())) - setVirtualFileSystem(VFS); - else - return nullptr; + IntrusiveRefCntPtr VFS = + createVFSFromCompilerInvocation(getInvocation(), getDiagnostics()); + setVirtualFileSystem(VFS); } FileMgr = new FileManager(getFileSystemOpts(), VirtualFileSystem); return FileMgr.get(); diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index c9d251f..acbe650 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -3073,16 +3073,15 @@ createVFSFromCompilerInvocation(const CompilerInvocation &CI, BaseFS->getBufferForFile(File); if (!Buffer) { Diags.Report(diag::err_missing_vfs_overlay_file) << File; - return IntrusiveRefCntPtr(); + continue; } IntrusiveRefCntPtr 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(); - } - Overlay->pushOverlay(FS); } return Overlay; } diff --git a/clang/lib/Frontend/PrecompiledPreamble.cpp b/clang/lib/Frontend/PrecompiledPreamble.cpp index d761f6e..ddd7bda 100644 --- a/clang/lib/Frontend/PrecompiledPreamble.cpp +++ b/clang/lib/Frontend/PrecompiledPreamble.cpp @@ -303,8 +303,6 @@ llvm::ErrorOr 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: diff --git a/clang/test/Index/missing_vfs.c b/clang/test/Index/missing_vfs.c new file mode 100644 index 0000000..61aedd4 --- /dev/null +++ b/clang/test/Index/missing_vfs.c @@ -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); diff --git a/clang/test/VFS/Inputs/MissingVFS/a.h b/clang/test/VFS/Inputs/MissingVFS/a.h new file mode 100644 index 0000000..892d837 --- /dev/null +++ b/clang/test/VFS/Inputs/MissingVFS/a.h @@ -0,0 +1 @@ +// void funcA(void); diff --git a/clang/test/VFS/Inputs/MissingVFS/module.modulemap b/clang/test/VFS/Inputs/MissingVFS/module.modulemap new file mode 100644 index 0000000..bbd9d67 --- /dev/null +++ b/clang/test/VFS/Inputs/MissingVFS/module.modulemap @@ -0,0 +1,3 @@ +module A { + header "a.h" +} diff --git a/clang/test/VFS/Inputs/MissingVFS/vfsoverlay.yaml b/clang/test/VFS/Inputs/MissingVFS/vfsoverlay.yaml new file mode 100644 index 0000000..49517a1 --- /dev/null +++ b/clang/test/VFS/Inputs/MissingVFS/vfsoverlay.yaml @@ -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' + } + ] + } + ] +} diff --git a/clang/test/VFS/module_missing_vfs.m b/clang/test/VFS/module_missing_vfs.m new file mode 100644 index 0000000..4c4ee4d --- /dev/null +++ b/clang/test/VFS/module_missing_vfs.m @@ -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(); +} -- 2.7.4