]> granicus.if.org Git - clang/commitdiff
[vfs] Don't bail out after a missing -ivfsoverlay file
authorBen Langmuir <blangmuir@apple.com>
Fri, 23 Mar 2018 17:37:27 +0000 (17:37 +0000)
committerBen Langmuir <blangmuir@apple.com>
Fri, 23 Mar 2018 17:37:27 +0000 (17:37 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@328337 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/Frontend/PrecompiledPreamble.h
lib/Frontend/ASTUnit.cpp
lib/Frontend/CompilerInstance.cpp
lib/Frontend/CompilerInvocation.cpp
lib/Frontend/PrecompiledPreamble.cpp
test/Index/missing_vfs.c [new file with mode: 0644]
test/VFS/Inputs/MissingVFS/a.h [new file with mode: 0644]
test/VFS/Inputs/MissingVFS/module.modulemap [new file with mode: 0644]
test/VFS/Inputs/MissingVFS/vfsoverlay.yaml [new file with mode: 0644]
test/VFS/module_missing_vfs.m [new file with mode: 0644]

index f1898f573ff66ded4bf609755f3d7594722dbf9c..aa8fb82f340615135217e3e57dbcdb5a2fa15328 100644 (file)
@@ -289,7 +289,6 @@ enum class BuildPreambleError {
   PreambleIsEmpty = 1,
   CouldntCreateTempFile,
   CouldntCreateTargetInfo,
-  CouldntCreateVFSOverlay,
   BeginSourceFileFailed,
   CouldntEmitPCH
 };
index cd3664bd3fc31fc6476d53efb36775fff62004db..1247e8219ff739bc0226a3cc9078dad85101e015 100644 (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));
index bb8b8572fa730a7500a5c4343e31c2665ee123d7..a03e5df63aa71e5642860ca0dfcef23182db8583 100644 (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();
index c9d251f5b7f06ca9f5224533fa85799b50510c01..acbe650b861822ba44186861c905fc1b67000b85 100644 (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;
 }
index d761f6ee458bfdc844f37a50a3e035af5c0971f5..ddd7bda546fe9b695f96716ff9c5d0176c5a38ae 100644 (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:
diff --git a/test/Index/missing_vfs.c b/test/Index/missing_vfs.c
new file mode 100644 (file)
index 0000000..61aedd4
--- /dev/null
@@ -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/test/VFS/Inputs/MissingVFS/a.h b/test/VFS/Inputs/MissingVFS/a.h
new file mode 100644 (file)
index 0000000..892d837
--- /dev/null
@@ -0,0 +1 @@
+// void funcA(void);
diff --git a/test/VFS/Inputs/MissingVFS/module.modulemap b/test/VFS/Inputs/MissingVFS/module.modulemap
new file mode 100644 (file)
index 0000000..bbd9d67
--- /dev/null
@@ -0,0 +1,3 @@
+module A {
+  header "a.h"
+}
diff --git a/test/VFS/Inputs/MissingVFS/vfsoverlay.yaml b/test/VFS/Inputs/MissingVFS/vfsoverlay.yaml
new file mode 100644 (file)
index 0000000..49517a1
--- /dev/null
@@ -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/test/VFS/module_missing_vfs.m b/test/VFS/module_missing_vfs.m
new file mode 100644 (file)
index 0000000..4c4ee4d
--- /dev/null
@@ -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();
+}