diff --git a/clang/include/clang/Basic/FileManager.h b/clang/include/clang/Basic/FileManager.h --- a/clang/include/clang/Basic/FileManager.h +++ b/clang/include/clang/Basic/FileManager.h @@ -243,6 +243,10 @@ const FileSystemOptions &getFileSystemOpts() const { return FileSystemOpts; } llvm::vfs::FileSystem &getVirtualFileSystem() const { return *FS; } + llvm::IntrusiveRefCntPtr + getVirtualFileSystemPtr() const { + return FS; + } void setVirtualFileSystem(IntrusiveRefCntPtr FS) { this->FS = std::move(FS); diff --git a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h --- a/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h +++ b/clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h @@ -91,14 +91,13 @@ private: std::shared_ptr PCHContainerOps; - - /// The physical filesystem overlaid by `InMemoryFS`. - llvm::IntrusiveRefCntPtr RealFS; - /// The in-memory filesystem laid on top the physical filesystem in `RealFS`. - llvm::IntrusiveRefCntPtr InMemoryFS; - /// The file system that is used by each worker when scanning for - /// dependencies. This filesystem persists across multiple compiler - /// invocations. + /// The file system to be used during the scan. + /// This is either \c FS passed in the constructor (when performing canonical + /// preprocessing), or \c DepFS (when performing dependency directives scan). + llvm::IntrusiveRefCntPtr BaseFS; + /// When performing dependency directives scan, this is the caching (and + /// dependency-directives-extracting) filesystem overlaid on top of \c FS + /// (passed in the constructor). llvm::IntrusiveRefCntPtr DepFS; ScanningOutputFormat Format; /// Whether to optimize the modules' command-line arguments. diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -209,7 +209,8 @@ // Support for virtual file system overlays on top of the caching // filesystem. FileMgr->setVirtualFileSystem(createVFSFromCompilerInvocation( - ScanInstance.getInvocation(), ScanInstance.getDiagnostics(), DepFS)); + ScanInstance.getInvocation(), ScanInstance.getDiagnostics(), + FileMgr->getVirtualFileSystemPtr())); llvm::IntrusiveRefCntPtr LocalDepFS = DepFS; @@ -324,15 +325,17 @@ PCHContainerOps->registerWriter( std::make_unique()); - auto OverlayFS = - llvm::makeIntrusiveRefCnt(std::move(FS)); - InMemoryFS = llvm::makeIntrusiveRefCnt(); - OverlayFS->pushOverlay(InMemoryFS); - RealFS = OverlayFS; - - if (Service.getMode() == ScanningMode::DependencyDirectivesScan) - DepFS = new DependencyScanningWorkerFilesystem(Service.getSharedCache(), - RealFS); + switch (Service.getMode()) { + case ScanningMode::DependencyDirectivesScan: + DepFS = + new DependencyScanningWorkerFilesystem(Service.getSharedCache(), FS); + BaseFS = DepFS; + break; + case ScanningMode::CanonicalPreprocessing: + DepFS = nullptr; + BaseFS = FS; + break; + } } llvm::Error DependencyScanningWorker::computeDependencies( @@ -386,22 +389,32 @@ DependencyConsumer &Consumer, DiagnosticConsumer &DC, llvm::Optional ModuleName) { // Reset what might have been modified in the previous worker invocation. - RealFS->setCurrentWorkingDirectory(WorkingDirectory); - - FileSystemOptions FSOpts; - FSOpts.WorkingDir = WorkingDirectory.str(); - auto FileMgr = llvm::makeIntrusiveRefCnt(FSOpts, RealFS); + BaseFS->setCurrentWorkingDirectory(WorkingDirectory); Optional> ModifiedCommandLine; + llvm::IntrusiveRefCntPtr ModifiedFS; if (ModuleName) { ModifiedCommandLine = CommandLine; - InMemoryFS->addFile(*ModuleName, 0, llvm::MemoryBuffer::getMemBuffer("")); ModifiedCommandLine->emplace_back(*ModuleName); + + auto OverlayFS = llvm::makeIntrusiveRefCnt( + std::move(BaseFS)); + auto InMemoryFS = + llvm::makeIntrusiveRefCnt(); + InMemoryFS->setCurrentWorkingDirectory(WorkingDirectory); + InMemoryFS->addFile(*ModuleName, 0, llvm::MemoryBuffer::getMemBuffer("")); + OverlayFS->pushOverlay(InMemoryFS); + ModifiedFS = OverlayFS; } const std::vector &FinalCommandLine = ModifiedCommandLine ? *ModifiedCommandLine : CommandLine; + FileSystemOptions FSOpts; + FSOpts.WorkingDir = WorkingDirectory.str(); + auto FileMgr = llvm::makeIntrusiveRefCnt( + FSOpts, ModifiedFS ? ModifiedFS : BaseFS); + std::vector FinalCCommandLine(CommandLine.size(), nullptr); llvm::transform(CommandLine, FinalCCommandLine.begin(), [](const std::string &Str) { return Str.c_str(); });