[This is supporting an RFC which I'll send to cfe-dev and llvm-dev in a bit; a follow up patch has initial adoption in clang::CompilerInstance; marked WIP for now.]
Add `OutputManager` to the `llvm::vfs` namespace to virtualize compiler
The manager is configured with an `OutputBackend`. This patch contains a
number of backends, including:
- NullOutputBackend, for ignoring all backends.
- OnDiskOutputBackend, for writing to disk (the default), initially
based on the logic in `clang::CompilerInstance`.
- InMemoryOutputBackend, for writing to an `InMemoryFileSystem`.
- MirroringOutputBackend, for writing to multiple backends.
- FilteringOutputBackend, for filtering which outputs get written to the
An `OutputBackend` needs to implement `createDestination()`, which
returns a `std::unique_ptr<OutputDestination>`. Typically this is an
associated subclass of `OutputDestination`.
`OutputDestination`s are chained in a linked list (to support
`MirroringOutputBackend`). Each one needs to implement
`storeContentImpl()` (at minimum) in order to store content.
`ContentBuffer` is used to shepherd the content between backends. Some
`OutputDestination`s don't need content to be buffered, and can
implement `takeStreamImpl()` / `storeStreamedContentImpl()` to bypass
it when they're the only destination.
`OutputManager::createOutput()` returns an RAII-managed
- `takeOS()` returns a `std::unique_ptr<raw_pwrite_stream>` for writing
(`getOS()` gives a raw pointer to the stream if it hasn't been taken).
- `close()` commits the file (to disk, in-memory, etc.).
- `erase()` cancels the output, cleaning it up.
- `~Output` effectively calls `erase()` if the output is still "open".
A `ContentBuffer` is initialized with either
`std::unique_ptr<llvm::MemoryBuffer>` or `SmallVectorImpl<char> &&`.
If a destination just needs the bytes, it can call `getBytes()`; if it
wants a `MemoryBuffer`, it can call `takeBuffer()`, which has a variants
depending on whether the destination needs to own the bytes written to.
`OnDiskOutputDestination` has support for writing its bytes to an
mmap'ed region and passing a file-backed buffer on to other