r206309 - Honour -ivfsoverlay in ASTUnit to match clang

Ben Langmuir blangmuir at apple.com
Tue Apr 15 11:16:26 PDT 2014


Author: benlangmuir
Date: Tue Apr 15 13:16:25 2014
New Revision: 206309

URL: http://llvm.org/viewvc/llvm-project?rev=206309&view=rev
Log:
Honour -ivfsoverlay in ASTUnit to match clang

This allows code indexing, etc. to use the VFS in the same way as the
compiler.

Added:
    cfe/trunk/test/Index/Inputs/base_module_needs_vfs.h
    cfe/trunk/test/Index/Inputs/module.map
    cfe/trunk/test/Index/Inputs/module_needs_vfs.h
    cfe/trunk/test/Index/Inputs/vfsoverlay.yaml
    cfe/trunk/test/Index/index-module-with-vfs.m
Modified:
    cfe/trunk/include/clang/Frontend/ASTUnit.h
    cfe/trunk/include/clang/Frontend/CompilerInvocation.h
    cfe/trunk/lib/Frontend/ASTUnit.cpp
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp
    cfe/trunk/lib/Frontend/FrontendAction.cpp
    cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp
    cfe/trunk/tools/libclang/Indexing.cpp

Modified: cfe/trunk/include/clang/Frontend/ASTUnit.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/ASTUnit.h?rev=206309&r1=206308&r2=206309&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/ASTUnit.h (original)
+++ cfe/trunk/include/clang/Frontend/ASTUnit.h Tue Apr 15 13:16:25 2014
@@ -499,7 +499,7 @@ public:
   bool hasSema() const { return (bool)TheSema; }
   Sema &getSema() const { 
     assert(TheSema && "ASTUnit does not have a Sema object!");
-    return *TheSema; 
+    return *TheSema;
   }
   
   const FileManager &getFileManager() const { return *FileMgr; }

Modified: cfe/trunk/include/clang/Frontend/CompilerInvocation.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/CompilerInvocation.h?rev=206309&r1=206308&r2=206309&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/CompilerInvocation.h (original)
+++ cfe/trunk/include/clang/Frontend/CompilerInvocation.h Tue Apr 15 13:16:25 2014
@@ -204,6 +204,14 @@ public:
   /// @}
 };
 
+namespace vfs {
+  class FileSystem;
+}
+
+IntrusiveRefCntPtr<vfs::FileSystem>
+createVFSFromCompilerInvocation(const CompilerInvocation &CI,
+                                DiagnosticsEngine &Diags);
+
 } // end namespace clang
 
 #endif

Modified: cfe/trunk/lib/Frontend/ASTUnit.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/ASTUnit.cpp?rev=206309&r1=206308&r2=206309&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/ASTUnit.cpp (original)
+++ cfe/trunk/lib/Frontend/ASTUnit.cpp Tue Apr 15 13:16:25 2014
@@ -692,7 +692,8 @@ ASTUnit *ASTUnit::LoadFromASTFile(const
   AST->OnlyLocalDecls = OnlyLocalDecls;
   AST->CaptureDiagnostics = CaptureDiagnostics;
   AST->Diagnostics = Diags;
-  AST->FileMgr = new FileManager(FileSystemOpts);
+  IntrusiveRefCntPtr<vfs::FileSystem> VFS = vfs::getRealFileSystem();
+  AST->FileMgr = new FileManager(FileSystemOpts, VFS);
   AST->UserFilesAreVolatile = UserFilesAreVolatile;
   AST->SourceMgr = new SourceManager(AST->getDiagnostics(),
                                      AST->getFileManager(),
@@ -1093,10 +1094,9 @@ bool ASTUnit::Parse(llvm::MemoryBuffer *
          "IR inputs not support here!");
 
   // Configure the various subsystems.
-  // FIXME: Should we retain the previous file manager?
   LangOpts = &Clang->getLangOpts();
   FileSystemOpts = Clang->getFileSystemOpts();
-  FileMgr = new FileManager(FileSystemOpts);
+  // Re-use the existing FileManager
   SourceMgr = new SourceManager(getDiagnostics(), *FileMgr,
                                 UserFilesAreVolatile);
   TheSema.reset();
@@ -1598,9 +1598,14 @@ llvm::MemoryBuffer *ASTUnit::getMainBuff
   TopLevelDecls.clear();
   TopLevelDeclsInPreamble.clear();
   PreambleDiagnostics.clear();
-  
+
+  IntrusiveRefCntPtr<vfs::FileSystem> VFS =
+      createVFSFromCompilerInvocation(Clang->getInvocation(), getDiagnostics());
+  if (!VFS)
+    return nullptr;
+
   // Create a file manager object to provide access to and cache the filesystem.
-  Clang->setFileManager(new FileManager(Clang->getFileSystemOpts()));
+  Clang->setFileManager(new FileManager(Clang->getFileSystemOpts(), VFS));
   
   // Create the source manager.
   Clang->setSourceManager(new SourceManager(getDiagnostics(),
@@ -1758,7 +1763,11 @@ ASTUnit *ASTUnit::create(CompilerInvocat
   AST->Diagnostics = Diags;
   AST->Invocation = CI;
   AST->FileSystemOpts = CI->getFileSystemOpts();
-  AST->FileMgr = new FileManager(AST->FileSystemOpts);
+  IntrusiveRefCntPtr<vfs::FileSystem> VFS =
+      createVFSFromCompilerInvocation(*CI, *Diags);
+  if (!VFS)
+    return nullptr;
+  AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
   AST->UserFilesAreVolatile = UserFilesAreVolatile;
   AST->SourceMgr = new SourceManager(AST->getDiagnostics(), *AST->FileMgr,
                                      UserFilesAreVolatile);
@@ -1781,6 +1790,8 @@ ASTUnit *ASTUnit::LoadFromCompilerInvoca
     // Create the AST unit.
     OwnAST.reset(create(CI, Diags, CaptureDiagnostics, UserFilesAreVolatile));
     AST = OwnAST.get();
+    if (!AST)
+      return nullptr;
   }
   
   if (!ResourceFilesPath.empty()) {
@@ -1950,7 +1961,11 @@ ASTUnit *ASTUnit::LoadFromCompilerInvoca
     = IncludeBriefCommentsInCodeCompletion;
   AST->Invocation = CI;
   AST->FileSystemOpts = CI->getFileSystemOpts();
-  AST->FileMgr = new FileManager(AST->FileSystemOpts);
+  IntrusiveRefCntPtr<vfs::FileSystem> VFS =
+      createVFSFromCompilerInvocation(*CI, *Diags);
+  if (!VFS)
+    return nullptr;
+  AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
   AST->UserFilesAreVolatile = UserFilesAreVolatile;
   
   // Recover resources if we crash before exiting this method.
@@ -2017,7 +2032,11 @@ ASTUnit *ASTUnit::LoadFromCommandLine(
   AST->Diagnostics = Diags;
   Diags = 0; // Zero out now to ease cleanup during crash recovery.
   AST->FileSystemOpts = CI->getFileSystemOpts();
-  AST->FileMgr = new FileManager(AST->FileSystemOpts);
+  IntrusiveRefCntPtr<vfs::FileSystem> VFS =
+      createVFSFromCompilerInvocation(*CI, *Diags);
+  if (!VFS)
+    return nullptr;
+  AST->FileMgr = new FileManager(AST->FileSystemOpts, VFS);
   AST->OnlyLocalDecls = OnlyLocalDecls;
   AST->CaptureDiagnostics = CaptureDiagnostics;
   AST->TUKind = TUKind;

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=206309&r1=206308&r2=206309&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Tue Apr 15 13:16:25 2014
@@ -8,12 +8,12 @@
 //===----------------------------------------------------------------------===//
 
 #include "clang/Frontend/CompilerInvocation.h"
-#include "clang/Basic/Diagnostic.h"
 #include "clang/Basic/FileManager.h"
 #include "clang/Basic/Version.h"
 #include "clang/Driver/DriverDiagnostic.h"
 #include "clang/Driver/Options.h"
 #include "clang/Driver/Util.h"
+#include "clang/Frontend/FrontendDiagnostic.h"
 #include "clang/Frontend/LangStandard.h"
 #include "clang/Frontend/Utils.h"
 #include "clang/Lex/HeaderSearchOptions.h"
@@ -1907,4 +1907,31 @@ void BuryPointer(const void *Ptr) {
     return;
   GraveYard[Idx] = Ptr;
 }
+
+IntrusiveRefCntPtr<vfs::FileSystem>
+createVFSFromCompilerInvocation(const CompilerInvocation &CI,
+                                DiagnosticsEngine &Diags) {
+  if (CI.getHeaderSearchOpts().VFSOverlayFiles.empty())
+    return vfs::getRealFileSystem();
+
+  IntrusiveRefCntPtr<vfs::OverlayFileSystem>
+    Overlay(new vfs::OverlayFileSystem(vfs::getRealFileSystem()));
+  // earlier vfs files are on the bottom
+  for (const std::string &File : CI.getHeaderSearchOpts().VFSOverlayFiles) {
+    std::unique_ptr<llvm::MemoryBuffer> Buffer;
+    if (llvm::errc::success != llvm::MemoryBuffer::getFile(File, Buffer)) {
+      Diags.Report(diag::err_missing_vfs_overlay_file) << File;
+      return IntrusiveRefCntPtr<vfs::FileSystem>();
+    }
+
+    IntrusiveRefCntPtr<vfs::FileSystem> FS =
+        vfs::getVFSFromYAML(Buffer.release(), /*DiagHandler*/0);
+    if (!FS.getPtr()) {
+      Diags.Report(diag::err_invalid_vfs_overlay) << File;
+      return IntrusiveRefCntPtr<vfs::FileSystem>();
+    }
+    Overlay->pushOverlay(FS);
+  }
+  return Overlay;
 }
+} // end namespace clang

Modified: cfe/trunk/lib/Frontend/FrontendAction.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendAction.cpp?rev=206309&r1=206308&r2=206309&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/FrontendAction.cpp (original)
+++ cfe/trunk/lib/Frontend/FrontendAction.cpp Tue Apr 15 13:16:25 2014
@@ -211,30 +211,13 @@ bool FrontendAction::BeginSourceFile(Com
     return true;
   }
 
-  if (!CI.getHeaderSearchOpts().VFSOverlayFiles.empty()) {
-    IntrusiveRefCntPtr<vfs::OverlayFileSystem>
-        Overlay(new vfs::OverlayFileSystem(vfs::getRealFileSystem()));
-    // earlier vfs files are on the bottom
-    const std::vector<std::string> &Files =
-        CI.getHeaderSearchOpts().VFSOverlayFiles;
-    for (std::vector<std::string>::const_iterator I = Files.begin(),
-                                                  E = Files.end();
-         I != E; ++I) {
-      std::unique_ptr<llvm::MemoryBuffer> Buffer;
-      if (llvm::errc::success != llvm::MemoryBuffer::getFile(*I, Buffer)) {
-        CI.getDiagnostics().Report(diag::err_missing_vfs_overlay_file) << *I;
-        goto failure;
-      }
-
-      IntrusiveRefCntPtr<vfs::FileSystem> FS =
-          vfs::getVFSFromYAML(Buffer.release(), /*DiagHandler*/ 0);
-      if (!FS.getPtr()) {
-        CI.getDiagnostics().Report(diag::err_invalid_vfs_overlay) << *I;
-        goto failure;
-      }
-      Overlay->pushOverlay(FS);
-    }
-    CI.setVirtualFileSystem(Overlay);
+  if (!CI.hasVirtualFileSystem()) {
+    if (IntrusiveRefCntPtr<vfs::FileSystem> VFS =
+          createVFSFromCompilerInvocation(CI.getInvocation(),
+                                          CI.getDiagnostics()))
+      CI.setVirtualFileSystem(VFS);
+    else
+      goto failure;
   }
 
   // Set up the file and source managers, if needed.

Added: cfe/trunk/test/Index/Inputs/base_module_needs_vfs.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/Inputs/base_module_needs_vfs.h?rev=206309&view=auto
==============================================================================
--- cfe/trunk/test/Index/Inputs/base_module_needs_vfs.h (added)
+++ cfe/trunk/test/Index/Inputs/base_module_needs_vfs.h Tue Apr 15 13:16:25 2014
@@ -0,0 +1 @@
+void base_module_needs_vfs(void);

Added: cfe/trunk/test/Index/Inputs/module.map
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/Inputs/module.map?rev=206309&view=auto
==============================================================================
--- cfe/trunk/test/Index/Inputs/module.map (added)
+++ cfe/trunk/test/Index/Inputs/module.map Tue Apr 15 13:16:25 2014
@@ -0,0 +1,6 @@
+// See vfsoverlay.yaml
+module ModuleNeedsVFS {
+  header "ModuleNeedsVFS.h"
+  export *
+}
+framework module * { }

Added: cfe/trunk/test/Index/Inputs/module_needs_vfs.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/Inputs/module_needs_vfs.h?rev=206309&view=auto
==============================================================================
--- cfe/trunk/test/Index/Inputs/module_needs_vfs.h (added)
+++ cfe/trunk/test/Index/Inputs/module_needs_vfs.h Tue Apr 15 13:16:25 2014
@@ -0,0 +1,4 @@
+ at import BaseModuleNeedsVFS;
+inline void module_needs_vfs(void) {
+  base_module_needs_vfs();
+}

Added: cfe/trunk/test/Index/Inputs/vfsoverlay.yaml
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/Inputs/vfsoverlay.yaml?rev=206309&view=auto
==============================================================================
--- cfe/trunk/test/Index/Inputs/vfsoverlay.yaml (added)
+++ cfe/trunk/test/Index/Inputs/vfsoverlay.yaml Tue Apr 15 13:16:25 2014
@@ -0,0 +1,18 @@
+{
+  'version': 0,
+  'roots': [
+    { 'name': 'OUT_DIR', 'type': 'directory',
+      'contents': [
+        { 'name': 'module.map', 'type': 'file',
+          'external-contents': 'INPUT_DIR/module.map'
+        },
+        { 'name': 'ModuleNeedsVFS.h', 'type': 'file',
+          'external-contents': 'INPUT_DIR/module_needs_vfs.h'
+        },
+        { 'name': 'BaseModuleNeedsVFS.framework/Headers/BaseModuleNeedsVFS.h', 'type': 'file',
+          'external-contents': 'INPUT_DIR/base_module_needs_vfs.h'
+        },
+      ]
+    }
+  ]
+}

Added: cfe/trunk/test/Index/index-module-with-vfs.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Index/index-module-with-vfs.m?rev=206309&view=auto
==============================================================================
--- cfe/trunk/test/Index/index-module-with-vfs.m (added)
+++ cfe/trunk/test/Index/index-module-with-vfs.m Tue Apr 15 13:16:25 2014
@@ -0,0 +1,26 @@
+// REQUIRES: shell
+ at import ModuleNeedsVFS;
+
+void foo() {
+  module_needs_vfs();
+  base_module_needs_vfs();
+}
+
+// RUN: rm -rf %t.cache
+// RUN: sed -e "s:INPUT_DIR:%S/Inputs:g" -e "s:OUT_DIR:%t:g" %S/Inputs/vfsoverlay.yaml > %t.yaml
+// RUN: c-index-test -index-file %s -fmodules-cache-path=%t.cache -fmodules -F %t -I %t \
+// RUN:              -ivfsoverlay %t.yaml -Xclang -fdisable-module-hash | FileCheck %s
+
+// CHECK: [importedASTFile]: {{.*}}ModuleNeedsVFS.pcm | loc: 2:1 | name: "ModuleNeedsVFS" | isImplicit: 0
+// CHECK: [indexEntityReference]: kind: function | name: module_needs_vfs
+// CHECK: [indexEntityReference]: kind: function | name: base_module_needs_vfs
+
+// RUN: c-index-test -index-tu %t.cache/ModuleNeedsVFS.pcm | FileCheck %s -check-prefix=CHECK-MOD
+
+// CHECK-MOD: [ppIncludedFile]: {{.*}}module_needs_vfs.h 
+// CHECK-MOD: [importedASTFile]: {{.*}}BaseModuleNeedsVFS.pcm
+// CHECK-MOD: [indexEntityReference]: kind: function | name: base_module_needs_vfs
+
+// RUN: c-index-test -index-tu %t.cache/BaseModuleNeedsVFS.pcm | FileCheck %s -check-prefix=CHECK-MOD2
+
+// CHECK-MOD2: [ppIncludedFile]: {{.*}}base_module_needs_vfs.h

Modified: cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp?rev=206309&r1=206308&r2=206309&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp (original)
+++ cfe/trunk/tools/libclang/CIndexCodeCompletion.cpp Tue Apr 15 13:16:25 2014
@@ -249,7 +249,7 @@ namespace {
 /// AllocatedCXCodeCompleteResults outlives the CXTranslationUnit, so we can
 /// not rely on the StringPool in the TU.
 struct AllocatedCXCodeCompleteResults : public CXCodeCompleteResults {
-  AllocatedCXCodeCompleteResults(const FileSystemOptions& FileSystemOpts);
+  AllocatedCXCodeCompleteResults(IntrusiveRefCntPtr<FileManager> FileMgr);
   ~AllocatedCXCodeCompleteResults();
   
   /// \brief Diagnostics produced while performing code completion.
@@ -263,8 +263,6 @@ struct AllocatedCXCodeCompleteResults :
   /// \brief Language options used to adjust source locations.
   LangOptions LangOpts;
 
-  FileSystemOptions FileSystemOpts;
-
   /// \brief File manager, used for diagnostics.
   IntrusiveRefCntPtr<FileManager> FileMgr;
 
@@ -318,20 +316,15 @@ struct AllocatedCXCodeCompleteResults :
 static std::atomic<unsigned> CodeCompletionResultObjects;
   
 AllocatedCXCodeCompleteResults::AllocatedCXCodeCompleteResults(
-                                      const FileSystemOptions& FileSystemOpts)
-  : CXCodeCompleteResults(),
-    DiagOpts(new DiagnosticOptions),
-    Diag(new DiagnosticsEngine(
-                   IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs),
-                   &*DiagOpts)),
-    FileSystemOpts(FileSystemOpts),
-    FileMgr(new FileManager(FileSystemOpts)),
-    SourceMgr(new SourceManager(*Diag, *FileMgr)),
-    CodeCompletionAllocator(new clang::GlobalCodeCompletionAllocator),
-    Contexts(CXCompletionContext_Unknown),
-    ContainerKind(CXCursor_InvalidCode),
-    ContainerIsIncomplete(1)
-{ 
+    IntrusiveRefCntPtr<FileManager> FileMgr)
+    : CXCodeCompleteResults(),
+      DiagOpts(new DiagnosticOptions),
+      Diag(new DiagnosticsEngine(
+          IntrusiveRefCntPtr<DiagnosticIDs>(new DiagnosticIDs), &*DiagOpts)),
+      FileMgr(FileMgr), SourceMgr(new SourceManager(*Diag, *FileMgr)),
+      CodeCompletionAllocator(new clang::GlobalCodeCompletionAllocator),
+      Contexts(CXCompletionContext_Unknown),
+      ContainerKind(CXCursor_InvalidCode), ContainerIsIncomplete(1) {
   if (getenv("LIBCLANG_OBJTRACKING"))
     fprintf(stderr, "+++ %u completion results\n",
             ++CodeCompletionResultObjects);
@@ -709,8 +702,8 @@ void clang_codeCompleteAt_Impl(void *Use
   }
 
   // Parse the resulting source file to find code-completion results.
-  AllocatedCXCodeCompleteResults *Results = 
-        new AllocatedCXCodeCompleteResults(AST->getFileSystemOpts());
+  AllocatedCXCodeCompleteResults *Results = new AllocatedCXCodeCompleteResults(
+      &AST->getFileManager());
   Results->Results = 0;
   Results->NumResults = 0;
   

Modified: cfe/trunk/tools/libclang/Indexing.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/libclang/Indexing.cpp?rev=206309&r1=206308&r2=206309&view=diff
==============================================================================
--- cfe/trunk/tools/libclang/Indexing.cpp (original)
+++ cfe/trunk/tools/libclang/Indexing.cpp Tue Apr 15 13:16:25 2014
@@ -610,6 +610,11 @@ static void clang_indexSourceFile_Impl(v
   ASTUnit *Unit = ASTUnit::create(CInvok.getPtr(), Diags,
                                   CaptureDiagnostics,
                                   /*UserFilesAreVolatile=*/true);
+  if (!Unit) {
+    ITUI->result = CXError_InvalidArguments;
+    return;
+  }
+
   std::unique_ptr<CXTUOwner> CXTU(
       new CXTUOwner(MakeCXTranslationUnit(CXXIdx, Unit)));
 





More information about the cfe-commits mailing list