//===----------------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// /// /// \file /// This file contains the declarations of the concrete VirtualOutputBackend /// classes, which are the implementation for different output style and /// functions. This file contains: /// * NullOutputBackend: discard all outputs written. /// * OnDiskOutputBackend: write output to disk, with support for common output /// types, like append, or atomic update. /// * FilteringOutputBackend: filer some output paths to underlying output /// backend. /// * MirrorOutputBackend: mirror output to two output backends. /// //===----------------------------------------------------------------------===// #ifndef LLVM_SUPPORT_VIRTUALOUTPUTBACKENDS_H #define LLVM_SUPPORT_VIRTUALOUTPUTBACKENDS_H #include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/Support/VirtualOutputBackend.h" #include "llvm/Support/VirtualOutputConfig.h" namespace llvm::vfs { /// Create a backend that ignores all output. LLVM_ABI IntrusiveRefCntPtr makeNullOutputBackend(); /// Make a backend where \a OutputBackend::createFile() forwards to /// \p UnderlyingBackend when \p Filter is true, and otherwise returns a /// \a NullOutput. LLVM_ABI IntrusiveRefCntPtr makeFilteringOutputBackend( IntrusiveRefCntPtr UnderlyingBackend, std::function)> Filter); /// Create a backend that forwards \a OutputBackend::createFile() to both \p /// Backend1 and \p Backend2. Writing to such backend will create identical /// outputs using two different backends. LLVM_ABI IntrusiveRefCntPtr makeMirroringOutputBackend(IntrusiveRefCntPtr Backend1, IntrusiveRefCntPtr Backend2); /// A helper class for proxying another backend, with the default /// implementation to forward to the underlying backend. class ProxyOutputBackend : public OutputBackend { LLVM_ABI void anchor() override; protected: // Require subclass to implement cloneImpl(). // // IntrusiveRefCntPtr cloneImpl() const override; Expected> createFileImpl(StringRef Path, std::optional Config) override { OutputFile File; if (Error E = UnderlyingBackend->createFile(Path, Config).moveInto(File)) return std::move(E); return File.takeImpl(); } OutputBackend &getUnderlyingBackend() const { return *UnderlyingBackend; } public: ProxyOutputBackend(IntrusiveRefCntPtr UnderlyingBackend) : UnderlyingBackend(std::move(UnderlyingBackend)) { assert(this->UnderlyingBackend && "Expected non-null backend"); } private: IntrusiveRefCntPtr UnderlyingBackend; }; /// An output backend that creates files on disk, wrapping APIs in sys::fs. class OnDiskOutputBackend : public OutputBackend { LLVM_ABI void anchor() override; protected: IntrusiveRefCntPtr cloneImpl() const override { return clone(); } LLVM_ABI Expected> createFileImpl(StringRef Path, std::optional Config) override; public: /// Resolve an absolute path. Error makeAbsolute(SmallVectorImpl &Path) const; /// On disk output settings. struct OutputSettings { /// Register output files to be deleted if a signal is received. Also /// enabled for outputs with \a OutputConfig::getDiscardOnSignal(). bool RemoveOnSignal = true; /// Use temporary files. Also enabled for outputs with \a /// OutputConfig::getAtomicWrite(). bool UseTemporaries = true; // Default configuration for this backend. OutputConfig DefaultConfig; }; IntrusiveRefCntPtr clone() const { auto Clone = makeIntrusiveRefCnt(); Clone->Settings = Settings; return Clone; } OnDiskOutputBackend() = default; /// Settings for this backend. /// /// Access is not thread-safe. OutputSettings Settings; }; } // namespace llvm::vfs #endif // LLVM_SUPPORT_VIRTUALOUTPUTBACKENDS_H