diff options
author | Cameron Desrochers <cameron@moodycamel.com> | 2017-09-11 15:03:23 +0000 |
---|---|---|
committer | Cameron Desrochers <cameron@moodycamel.com> | 2017-09-11 15:03:23 +0000 |
commit | b5b48db12ed915d2927ba6dc1f9fbe50b342de04 (patch) | |
tree | 1f2b4778d1415c22d1865493411782d98367e700 /clang/lib/Frontend/ASTUnit.cpp | |
parent | b092bd321a072f667dd0984fe2b07c144802b1aa (diff) | |
download | bcm5719-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.cpp | 36 |
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()); |