summaryrefslogtreecommitdiffstats
path: root/clang/lib/Frontend/ASTUnit.cpp
diff options
context:
space:
mode:
authorCameron Desrochers <cameron@moodycamel.com>2017-09-11 15:03:23 +0000
committerCameron Desrochers <cameron@moodycamel.com>2017-09-11 15:03:23 +0000
commitb5b48db12ed915d2927ba6dc1f9fbe50b342de04 (patch)
tree1f2b4778d1415c22d1865493411782d98367e700 /clang/lib/Frontend/ASTUnit.cpp
parentb092bd321a072f667dd0984fe2b07c144802b1aa (diff)
downloadbcm5719-llvm-b5b48db12ed915d2927ba6dc1f9fbe50b342de04.tar.gz
bcm5719-llvm-b5b48db12ed915d2927ba6dc1f9fbe50b342de04.zip
[PCH] Allow VFS to be used for tests that generate PCH files
When using a virtual file-system (VFS) and a preamble file (PCH) is generated, it is generated on-disk in the real file-system instead of in the VFS (which makes sense, since the VFS is read-only). However, when subsequently reading the generated PCH, the frontend passes through the VFS it has been given -- resulting in an error and a failed parse (since the VFS doesn't contain the PCH; the real filesystem does). This patch fixes that by detecting when a VFS is being used for a parse that needs to work with a PCH file, and creating an overlay VFS that includes the PCH file from the real file-system. This allows tests to be written which make use of both PCH files and a VFS. Differential Revision: https://reviews.llvm.org/D37474 llvm-svn: 312917
Diffstat (limited to 'clang/lib/Frontend/ASTUnit.cpp')
-rw-r--r--clang/lib/Frontend/ASTUnit.cpp36
1 files changed, 36 insertions, 0 deletions
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index 6efc9e7539e..b644ef81222 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -1009,6 +1009,24 @@ static void checkAndSanitizeDiags(SmallVectorImpl<StoredDiagnostic> &
}
}
+static IntrusiveRefCntPtr<vfs::FileSystem> createVFSOverlayForPreamblePCH(
+ StringRef PCHFilename,
+ IntrusiveRefCntPtr<vfs::FileSystem> RealFS,
+ IntrusiveRefCntPtr<vfs::FileSystem> VFS) {
+ // We want only the PCH file from the real filesystem to be available,
+ // so we create an in-memory VFS with just that and overlay it on top.
+ auto Buf = RealFS->getBufferForFile(PCHFilename);
+ if (!Buf)
+ return VFS;
+ IntrusiveRefCntPtr<vfs::InMemoryFileSystem>
+ PCHFS(new vfs::InMemoryFileSystem());
+ PCHFS->addFile(PCHFilename, 0, std::move(*Buf));
+ IntrusiveRefCntPtr<vfs::OverlayFileSystem>
+ Overlay(new vfs::OverlayFileSystem(VFS));
+ Overlay->pushOverlay(PCHFS);
+ return Overlay;
+}
+
/// Parse the source file into a translation unit using the given compiler
/// invocation, replacing the current translation unit.
///
@@ -1030,6 +1048,24 @@ bool ASTUnit::Parse(std::shared_ptr<PCHContainerOperations> PCHContainerOps,
Clang->setVirtualFileSystem(VFS);
}
+ // Make sure we can access the PCH file even if we're using a VFS
+ if (!VFS && FileMgr)
+ VFS = FileMgr->getVirtualFileSystem();
+ IntrusiveRefCntPtr<vfs::FileSystem> RealFS = vfs::getRealFileSystem();
+ if (OverrideMainBuffer && VFS && RealFS && VFS != RealFS &&
+ !VFS->exists(Preamble->GetPCHPath())) {
+ // We have a slight inconsistency here -- we're using the VFS to
+ // read files, but the PCH was generated in the real file system.
+ VFS = createVFSOverlayForPreamblePCH(Preamble->GetPCHPath(), RealFS, VFS);
+ if (FileMgr) {
+ FileMgr = new FileManager(FileMgr->getFileSystemOpts(), VFS);
+ Clang->setFileManager(FileMgr.get());
+ }
+ else {
+ Clang->setVirtualFileSystem(VFS);
+ }
+ }
+
// Recover resources if we crash before exiting this method.
llvm::CrashRecoveryContextCleanupRegistrar<CompilerInstance>
CICleanup(Clang.get());
OpenPOWER on IntegriCloud