diff options
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()); |