Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -2988,8 +2988,9 @@ return IntrusiveRefCntPtr(); } - IntrusiveRefCntPtr FS = vfs::getVFSFromYAML( - std::move(Buffer.get()), /*DiagHandler*/ nullptr, File); + IntrusiveRefCntPtr FS = + vfs::getVFSFromYAML(std::move(Buffer.get()), /*DiagHandler*/ nullptr, + File, /*DiagContext*/ nullptr, BaseFS); if (!FS.get()) { Diags.Report(diag::err_invalid_vfs_overlay) << File; return IntrusiveRefCntPtr(); Index: lib/Tooling/Tooling.cpp =================================================================== --- lib/Tooling/Tooling.cpp +++ lib/Tooling/Tooling.cpp @@ -280,6 +280,12 @@ Invocation->getPreprocessorOpts().addRemappedFile(It.getKey(), Input.release()); } + IntrusiveRefCntPtr VirtualFileSystem = + createVFSFromCompilerInvocation(*Invocation, Diagnostics, + Files->getVirtualFileSystem()); + if (Files->getVirtualFileSystem() != VirtualFileSystem) { + Files = new FileManager(Invocation->getFileSystemOpts(), VirtualFileSystem); + } return runInvocation(BinaryName, Compilation.get(), std::move(Invocation), std::move(PCHContainerOps)); } Index: unittests/Tooling/ToolingTest.cpp =================================================================== --- unittests/Tooling/ToolingTest.cpp +++ unittests/Tooling/ToolingTest.cpp @@ -21,6 +21,7 @@ #include "llvm/Support/Path.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Support/TargetSelect.h" +#include "llvm/Support/FormatVariadic.h" #include "gtest/gtest.h" #include #include @@ -171,6 +172,37 @@ EXPECT_TRUE(Invocation.run()); } +TEST(ToolInvocation, TestVfsOverlay) { + llvm::IntrusiveRefCntPtr OverlayFileSystem( + new vfs::OverlayFileSystem(vfs::getRealFileSystem())); + llvm::IntrusiveRefCntPtr InMemoryFileSystem( + new vfs::InMemoryFileSystem); + OverlayFileSystem->pushOverlay(InMemoryFileSystem); + llvm::IntrusiveRefCntPtr Files( + new FileManager(FileSystemOptions(), OverlayFileSystem)); + std::vector Args; + Args.push_back("tool-executable"); + Args.push_back("-ivfsoverlay"); + Args.push_back("overlay.yaml"); + Args.push_back("-fsyntax-only"); + Args.push_back("a.cpp"); + clang::tooling::ToolInvocation Invocation(Args, new SyntaxOnlyAction, + Files.get()); + InMemoryFileSystem->addFile( + "a.cpp", 0, + llvm::MemoryBuffer::getMemBuffer("#include \n")); + std::string OverlayContent = llvm::formatv( + "{{'version': 0,'roots':[{{'name':'{0}','type':'directory'," + "'contents':[{{'name':'a.cpp','type':'file'," + "'external-contents':'b.cpp'}]}]}", + InMemoryFileSystem.get()->getCurrentWorkingDirectory().get()); + InMemoryFileSystem->addFile("overlay.yaml", 0, + llvm::MemoryBuffer::getMemBuffer(OverlayContent)); + InMemoryFileSystem->addFile( + "b.cpp", 0, llvm::MemoryBuffer::getMemBuffer("int main() {}")); + EXPECT_TRUE(Invocation.run()); +} + TEST(ToolInvocation, TestVirtualModulesCompilation) { // FIXME: Currently, this only tests that we don't exit with an error if a // mapped module.map is found on the include path. In the future, expand this