32void ProxyOutputBackend::anchor() {}
33void OnDiskOutputBackend::anchor() {}
38 return const_cast<NullOutputBackend *
>(
this);
41 createFileImpl(
StringRef Path, std::optional<OutputConfig>)
override {
42 return std::make_unique<NullOutputFileImpl>();
55 std::optional<OutputConfig> Config)
override {
58 return std::make_unique<NullOutputFileImpl>();
63 getUnderlyingBackend().clone(),
Filter);
66 FilteringOutputBackend(
77 std::move(UnderlyingBackend), std::move(
Filter));
94 Error discard()
final {
96 return joinErrors(F1->discard(), F2->discard());
100 void write_impl(
const char *Ptr,
size_t Size)
override {
104 void pwrite_impl(
const char *Ptr,
size_t Size, uint64_t
Offset)
override {
109 uint64_t current_pos()
const override {
return F1->getOS().tell(); }
110 size_t preferred_buffer_size()
const override {
111 return PreferredBufferSize;
113 void reserveExtraSpace(uint64_t ExtraSize)
override {
114 F1->getOS().reserveExtraSpace(ExtraSize);
115 F2->getOS().reserveExtraSpace(ExtraSize);
117 bool is_displayed()
const override {
118 return F1->getOS().is_displayed() && F2->getOS().is_displayed();
120 bool has_colors()
const override {
121 return F1->getOS().has_colors() && F2->getOS().has_colors();
123 void enable_colors(
bool enable)
override {
125 F1->getOS().enable_colors(enable);
126 F2->getOS().enable_colors(enable);
129 MirroringOutput(std::unique_ptr<OutputFileImpl> F1,
130 std::unique_ptr<OutputFileImpl> F2)
131 : PreferredBufferSize(std::max(F1->getOS().GetBufferSize(),
132 F1->getOS().GetBufferSize())),
133 F1(std::move(F1)), F2(std::move(F2)) {}
135 size_t PreferredBufferSize;
136 std::unique_ptr<OutputFileImpl> F1;
137 std::unique_ptr<OutputFileImpl> F2;
139 struct MirroringOutputBackend :
public ProxyOutputBackend1,
140 public ProxyOutputBackend2 {
143 std::optional<OutputConfig> Config)
override {
144 std::unique_ptr<OutputFileImpl> File1;
145 std::unique_ptr<OutputFileImpl> File2;
147 ProxyOutputBackend1::createFileImpl(Path, Config).moveInto(File1))
150 ProxyOutputBackend2::createFileImpl(Path, Config).moveInto(File2))
151 return joinErrors(std::move(E), File1->discard());
156 return std::move(File2);
160 return std::move(File1);
162 return std::make_unique<MirroringOutput>(std::move(File1),
169 ProxyOutputBackend1::getUnderlyingBackend().clone(),
170 ProxyOutputBackend2::getUnderlyingBackend().clone()));
172 void Retain()
const { ProxyOutputBackend1::Retain(); }
173 void Release()
const { ProxyOutputBackend1::Release(); }
177 : ProxyOutputBackend1(std::move(Backend1)),
178 ProxyOutputBackend2(std::move(Backend2)) {}
181 assert(Backend1 &&
"Expected actual backend");
182 assert(Backend2 &&
"Expected actual backend");
185 std::move(Backend2)));
194 Config->setNoAtomicWrite();
196 Config->setNoDiscardOnSignal();
203 Error keep()
override;
204 Error discard()
override;
205 raw_pwrite_stream &getOS()
override {
206 assert(FileOS &&
"Expected valid file");
220 Error tryToCreateTemporary(std::optional<int> &FD);
222 Error initializeFile(std::optional<int> &FD);
223 Error initializeStream();
226 OnDiskOutputFile(StringRef OutputPath, std::optional<OutputConfig> Config,
227 const OnDiskOutputBackend::OutputSettings &Settings)
229 OutputPath(OutputPath.str()) {}
232 const std::string OutputPath;
233 std::optional<std::string> TempPath;
234 std::optional<raw_fd_ostream> FileOS;
235 std::optional<buffer_ostream> BufferOS;
242 return handleErrors(CreateFile(), [&](std::unique_ptr<ECError> EC) {
243 if (EC->convertToErrorCode() != std::errc::no_such_file_or_directory ||
244 Config.getNoImplyCreateDirectories())
245 return Error(std::move(EC));
258 else if (Config.getText())
262 if (Config.getAppend() && !Config.getAtomicWrite())
268Error OnDiskOutputFile::tryToCreateTemporary(std::optional<int> &FD) {
276 SmallString<128> ModelPath =
277 StringRef(OutputPath).drop_back(OutputExtension.
size());
278 ModelPath +=
"-%%%%%%%%";
279 ModelPath += OutputExtension;
284 SmallString<128> UniquePath;
286 if (std::error_code EC =
290 if (Config.getDiscardOnSignal())
293 TempPath = UniquePath.
str().
str();
299Error OnDiskOutputFile::initializeFile(std::optional<int> &FD) {
302 assert(OutputPath !=
"-" &&
"Unexpected request for FD of stdout");
307 if (Config.getAtomicWrite()) {
308 sys::fs::file_status
Status;
312 Config.setNoAtomicWrite();
322 std::make_error_code(std::errc::operation_not_permitted));
328 if (Config.getAtomicWrite())
341 if (Config.getDiscardOnSignal())
347Error OnDiskOutputFile::initializeStream() {
351 if (OutputPath ==
"-") {
353 FileOS.emplace(OutputPath, EC);
357 std::optional<int> FD;
358 if (
Error E = initializeFile(FD))
360 FileOS.emplace(*FD,
true);
364 if (!FileOS->supportsSeeking() && !Config.getText())
365 BufferOS.emplace(*FileOS);
371enum class FileDifference : uint8_t {
383static Expected<FileDifference>
386 return FileDifference::IdenticalFile;
406 return FileDifference::DifferentContents;
414 return FileDifference::DifferentContents;
417 if (*SourceSize != *DestSize)
418 return FileDifference::DifferentContents;
421 if (*SourceSize == 0)
422 return FileDifference::SameContents;
426 std::error_code SourceRegionErr;
433 std::error_code DestRegionErr;
436 *DestSize, 0, DestRegionErr);
439 return FileDifference::DifferentContents;
443 return FileDifference::DifferentContents;
445 return FileDifference::SameContents;
448Error OnDiskOutputFile::reset() {
457 std::error_code
EC = FileOS->error();
459 FileOS->clear_error();
464Error OnDiskOutputFile::keep() {
467 if (
auto E = reset())
472 if (Config.getDiscardOnSignal())
480 if (Config.getAppend() && OutputPath !=
"-") {
489 llvm::LockFileManager Lock(OutputPath);
491 if (
Error Err = Lock.tryLock().moveInto(Owned)) {
496 OutputPath, std::make_error_code(std::errc::no_lock_available));
504 Out << (*Content)->getBuffer();
514 switch (Lock.waitForUnlockFor(std::chrono::seconds(256))) {
534 if (Config.getOnlyIfDifferent()) {
537 return Result.takeError();
539 case FileDifference::IdenticalFile:
543 case FileDifference::SameContents:
548 case FileDifference::DifferentContents:
570Error OnDiskOutputFile::discard() {
574 if (
auto E = reset())
578 if (OutputPath ==
"-")
581 auto discardPath = [&](StringRef
Path) {
591 discardPath(*TempPath));
603 std::optional<OutputConfig> Config) {
614 auto File = std::make_unique<OnDiskOutputFile>(Path, Config,
Settings);
618 return std::move(
File);
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file defines the scope_exit class, which executes user-defined cleanup logic at scope exit.
static Error createDirectoriesOnDemand(StringRef OutputPath, OutputConfig Config, llvm::function_ref< Error()> CreateFile)
static Expected< FileDifference > areFilesDifferent(const llvm::Twine &Source, const llvm::Twine &Destination)
static sys::fs::OpenFlags generateFlagsFromConfig(OutputConfig Config)
static OutputConfig applySettings(std::optional< OutputConfig > &&Config, const OnDiskOutputBackend::OutputSettings &Settings)
This file contains the declarations of the concrete VirtualOutputBackend classes, which are the imple...
This file contains the declarations of the OutputConfig class.
This file contains the declarations of the OutputError class.
Represents either an error or a value T.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
Tagged union holding either a T or a Error.
Error takeError()
Take ownership of the stored error.
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
static ErrorOr< std::unique_ptr< MemoryBuffer > > getFile(const Twine &Filename, bool IsText=false, bool RequiresNullTerminator=true, bool IsVolatile=false, std::optional< Align > Alignment=std::nullopt)
Open the specified file as a MemoryBuffer, returning a new MemoryBuffer if successful,...
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
StringRef str() const
Explicit conversion to StringRef.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Represent a constant reference to a string, i.e.
std::string str() const
Get the contents as an std::string.
constexpr size_t size() const
Get the string size.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
An efficient, type-erasing, non-owning reference to a callable.
raw_ostream & write(unsigned char C)
virtual void enable_colors(bool enable)
An abstract base class for streams implementations that also support a pwrite operation.
This class represents a memory mapped file.
@ readonly
May only access map via const_data as read only.
LLVM_ABI const char * const_data() const
Get a const view of the data.
Expected< std::unique_ptr< OutputFileImpl > > createFileImpl(StringRef Path, std::optional< OutputConfig > Config) override
Create a file for Path.
OutputSettings Settings
Settings for this backend.
Error makeAbsolute(SmallVectorImpl< char > &Path) const
Resolve an absolute path.
Interface for virtualized outputs.
A helper class for proxying another backend, with the default implementation to forward to the underl...
ProxyOutputBackend(IntrusiveRefCntPtr< OutputBackend > UnderlyingBackend)
Expected< std::unique_ptr< OutputFileImpl > > createFileImpl(StringRef Path, std::optional< OutputConfig > Config) override
Create a file for Path.
The result of a status operation.
LLVM_ABI bool is_regular_file(const basic_file_status &status)
Does status represent a regular file?
LLVM_ABI std::error_code closeFile(file_t &F)
Close the file object.
LLVM_ABI std::error_code rename(const Twine &from, const Twine &to)
Rename from to to.
bool can_write(const Twine &Path)
Can we write this file?
LLVM_ABI bool exists(const basic_file_status &status)
Does file exist?
@ OF_Text
The file should be opened in text mode on platforms like z/OS that make this distinction.
@ OF_TextWithCRLF
The file should be opened in text mode and use a carriage linefeed '\r '.
@ OF_Append
The file should be opened in append mode.
LLVM_ABI std::error_code createUniqueFile(const Twine &Model, int &ResultFD, SmallVectorImpl< char > &ResultPath, OpenFlags Flags=OF_None, unsigned Mode=all_read|all_write)
Create a uniquely named file.
LLVM_ABI std::error_code remove(const Twine &path, bool IgnoreNonExisting=true)
Remove path.
@ CD_CreateAlways
CD_CreateAlways - When opening a file:
std::error_code openFileForWrite(const Twine &Name, int &ResultFD, CreationDisposition Disp=CD_CreateAlways, OpenFlags Flags=OF_None, unsigned Mode=0666)
Opens the file with the given name in a write-only or read-write mode, returning its open file descri...
LLVM_ABI Expected< file_t > openNativeFileForRead(const Twine &Name, OpenFlags Flags=OF_None, SmallVectorImpl< char > *RealPath=nullptr)
Opens the file with the given name in a read-only mode, returning its open file descriptor.
LLVM_ABI std::error_code create_directories(const Twine &path, bool IgnoreExisting=true, perms Perms=owner_all|group_all)
Create all the non-existent directories in path.
LLVM_ABI std::error_code make_absolute(SmallVectorImpl< char > &path)
Make path an absolute path.
LLVM_ABI std::error_code copy_file(const Twine &From, const Twine &To)
Copy the contents of From to To.
LLVM_ABI std::error_code status(const Twine &path, file_status &result, bool follow=true)
Get file status as if by POSIX stat().
LLVM_ABI bool equivalent(file_status A, file_status B)
Do file_status's represent the same thing?
std::error_code file_size(const Twine &Path, uint64_t &Result)
Get file size.
LLVM_ABI StringRef parent_path(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get parent path.
LLVM_ABI StringRef extension(StringRef path LLVM_LIFETIME_BOUND, Style style=Style::native)
Get extension.
ScopedSetting scopedDisable()
LLVM_ABI void DontRemoveFileOnSignal(StringRef Filename)
This function removes a file from the list of files to be removed on signal delivery.
LLVM_ABI bool RemoveFileOnSignal(StringRef Filename, std::string *ErrMsg=nullptr)
This function registers signal handlers to ensure that if a signal gets delivered that the named file...
Error convertToOutputError(const Twine &OutputPath, std::error_code EC)
Return Error::success() or use OutputPath to create an OutputError, depending on EC.
LLVM_ABI IntrusiveRefCntPtr< OutputBackend > makeNullOutputBackend()
Create a backend that ignores all output.
LLVM_ABI IntrusiveRefCntPtr< OutputBackend > makeFilteringOutputBackend(IntrusiveRefCntPtr< OutputBackend > UnderlyingBackend, std::function< bool(StringRef, std::optional< OutputConfig >)> Filter)
Make a backend where OutputBackend::createFile() forwards to UnderlyingBackend when Filter is true,...
LLVM_ABI IntrusiveRefCntPtr< OutputBackend > makeMirroringOutputBackend(IntrusiveRefCntPtr< OutputBackend > Backend1, IntrusiveRefCntPtr< OutputBackend > Backend2)
Create a backend that forwards OutputBackend::createFile() to both Backend1 and Backend2.
Error convertToTempFileOutputError(const Twine &TempPath, const Twine &OutputPath, std::error_code EC)
Return Error::success() or use TempPath and OutputPath to create a TempFileOutputError,...
This is an optimization pass for GlobalISel generic memory operations.
bool errorToBool(Error Err)
Helper for converting an Error to a bool.
scope_exit(Callable) -> scope_exit< Callable >
Error handleErrors(Error E, HandlerTs &&... Hs)
Pass the ErrorInfo(s) contained in E to their respective handlers.
IntrusiveRefCntPtr< T > makeIntrusiveRefCnt(Args &&...A)
Factory function for creating intrusive ref counted pointers.
Error joinErrors(Error E1, Error E2)
Concatenate errors.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ Success
The lock was released successfully.
@ OwnerDied
Owner died while holding the lock.
@ Timeout
Reached timeout while waiting for the owner to release the lock.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI Error errorCodeToError(std::error_code EC)
Helper for converting an std::error_code to a Error.
LLVM_ABI std::error_code errorToErrorCode(Error Err)
Helper for converting an ECError to a std::error_code.
void consumeError(Error Err)
Consume a Error without doing anything.
OutputConfig DefaultConfig
bool RemoveOnSignal
Register output files to be deleted if a signal is received.
bool UseTemporaries
Use temporary files.
Full configuration for an output for use by the OutputBackend.
constexpr bool getTextWithCRLF() const