mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 12:41:49 +01:00
[Support] Use outs() in ToolOutputFile
Summary: If the output filename was specified as "-", the ToolOutputFile class would create a brand new raw_ostream object referring to the stdout. This patch changes it to reuse the llvm::outs() singleton. At the moment, this change should be "NFC", but it does enable other enhancements, like the automatic stdout/stderr synchronization as discussed on D80803. I've checked the history, and I did not find any indication that this class *has* to use a brand new stream object instead of outs() -- indeed, it is special-casing "-" in a number of places already, so this change fits the pattern pretty well. I suspect the main reason for the current state of affairs is that the class was originally introduced (r111595, in 2010) as a raw_fd_ostream subclass, which made any other solution impossible. Another potential benefit of this patch is that it makes it possible to move the raw_ostream class out of the business of special-casing "-" for stdout handling. That state of affairs does not seem appropriate because "-" is a valid filename (albeit hard to access with a lot of command line tools) on most systems. Handling "-" in ToolOutputFile seems more appropriate. To make this possible, this patch changes the return type of llvm::outs() and errs() to raw_fd_ostream&. Previously the functions were constructing objects of that type, but returning a generic raw_ostream reference. This makes it possible for new ToolOutputFile and other code to use raw_fd_ostream methods like error() on the outs() object. This does not seem like a bad thing (since stdout is a file descriptor which can be redirected to anywhere, it makes sense to ask it whether the writing was successful or if it supports seeking), and indeed a lot of code was already depending on this fact via the ToolOutputFile "back door". Reviewers: dblaikie, JDevlieghere, MaskRay, jhenderson Subscribers: hiraditya, llvm-commits Tags: #llvm Differential Revision: https://reviews.llvm.org/D81078
This commit is contained in:
parent
64533fe9cc
commit
0d0270ebc8
@ -13,6 +13,7 @@
|
|||||||
#ifndef LLVM_SUPPORT_TOOLOUTPUTFILE_H
|
#ifndef LLVM_SUPPORT_TOOLOUTPUTFILE_H
|
||||||
#define LLVM_SUPPORT_TOOLOUTPUTFILE_H
|
#define LLVM_SUPPORT_TOOLOUTPUTFILE_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/Optional.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
@ -38,8 +39,12 @@ class ToolOutputFile {
|
|||||||
~CleanupInstaller();
|
~CleanupInstaller();
|
||||||
} Installer;
|
} Installer;
|
||||||
|
|
||||||
/// The contained stream. This is intentionally declared after Installer.
|
/// Storage for the stream, if we're owning our own stream. This is
|
||||||
raw_fd_ostream OS;
|
/// intentionally declared after Installer.
|
||||||
|
Optional<raw_fd_ostream> OSHolder;
|
||||||
|
|
||||||
|
/// The actual stream to use.
|
||||||
|
raw_fd_ostream *OS;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/// This constructor's arguments are passed to raw_fd_ostream's
|
/// This constructor's arguments are passed to raw_fd_ostream's
|
||||||
@ -50,7 +55,7 @@ public:
|
|||||||
ToolOutputFile(StringRef Filename, int FD);
|
ToolOutputFile(StringRef Filename, int FD);
|
||||||
|
|
||||||
/// Return the contained raw_fd_ostream.
|
/// Return the contained raw_fd_ostream.
|
||||||
raw_fd_ostream &os() { return OS; }
|
raw_fd_ostream &os() { return *OS; }
|
||||||
|
|
||||||
/// Indicate that the tool's job wrt this output file has been successful and
|
/// Indicate that the tool's job wrt this output file has been successful and
|
||||||
/// the file should not be deleted.
|
/// the file should not be deleted.
|
||||||
|
@ -496,13 +496,13 @@ public:
|
|||||||
void clear_error() { EC = std::error_code(); }
|
void clear_error() { EC = std::error_code(); }
|
||||||
};
|
};
|
||||||
|
|
||||||
/// This returns a reference to a raw_ostream for standard output. Use it like:
|
/// This returns a reference to a raw_fd_ostream for standard output. Use it
|
||||||
/// outs() << "foo" << "bar";
|
/// like: outs() << "foo" << "bar";
|
||||||
raw_ostream &outs();
|
raw_fd_ostream &outs();
|
||||||
|
|
||||||
/// This returns a reference to a raw_ostream for standard error. Use it like:
|
/// This returns a reference to a raw_fd_ostream for standard error. Use it
|
||||||
/// errs() << "foo" << "bar";
|
/// like: errs() << "foo" << "bar";
|
||||||
raw_ostream &errs();
|
raw_fd_ostream &errs();
|
||||||
|
|
||||||
/// This returns a reference to a raw_ostream which simply discards output.
|
/// This returns a reference to a raw_ostream which simply discards output.
|
||||||
raw_ostream &nulls();
|
raw_ostream &nulls();
|
||||||
|
@ -15,31 +15,45 @@
|
|||||||
#include "llvm/Support/Signals.h"
|
#include "llvm/Support/Signals.h"
|
||||||
using namespace llvm;
|
using namespace llvm;
|
||||||
|
|
||||||
|
static bool isStdout(StringRef Filename) { return Filename == "-"; }
|
||||||
|
|
||||||
ToolOutputFile::CleanupInstaller::CleanupInstaller(StringRef Filename)
|
ToolOutputFile::CleanupInstaller::CleanupInstaller(StringRef Filename)
|
||||||
: Filename(std::string(Filename)), Keep(false) {
|
: Filename(std::string(Filename)), Keep(false) {
|
||||||
// Arrange for the file to be deleted if the process is killed.
|
// Arrange for the file to be deleted if the process is killed.
|
||||||
if (Filename != "-")
|
if (!isStdout(Filename))
|
||||||
sys::RemoveFileOnSignal(Filename);
|
sys::RemoveFileOnSignal(Filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolOutputFile::CleanupInstaller::~CleanupInstaller() {
|
ToolOutputFile::CleanupInstaller::~CleanupInstaller() {
|
||||||
|
if (isStdout(Filename))
|
||||||
|
return;
|
||||||
|
|
||||||
// Delete the file if the client hasn't told us not to.
|
// Delete the file if the client hasn't told us not to.
|
||||||
if (!Keep && Filename != "-")
|
if (!Keep)
|
||||||
sys::fs::remove(Filename);
|
sys::fs::remove(Filename);
|
||||||
|
|
||||||
// Ok, the file is successfully written and closed, or deleted. There's no
|
// Ok, the file is successfully written and closed, or deleted. There's no
|
||||||
// further need to clean it up on signals.
|
// further need to clean it up on signals.
|
||||||
if (Filename != "-")
|
sys::DontRemoveFileOnSignal(Filename);
|
||||||
sys::DontRemoveFileOnSignal(Filename);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolOutputFile::ToolOutputFile(StringRef Filename, std::error_code &EC,
|
ToolOutputFile::ToolOutputFile(StringRef Filename, std::error_code &EC,
|
||||||
sys::fs::OpenFlags Flags)
|
sys::fs::OpenFlags Flags)
|
||||||
: Installer(Filename), OS(Filename, EC, Flags) {
|
: Installer(Filename) {
|
||||||
|
if (isStdout(Filename)) {
|
||||||
|
OS = &outs();
|
||||||
|
EC = std::error_code();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
OSHolder.emplace(Filename, EC, Flags);
|
||||||
|
OS = OSHolder.getPointer();
|
||||||
// If open fails, no cleanup is needed.
|
// If open fails, no cleanup is needed.
|
||||||
if (EC)
|
if (EC)
|
||||||
Installer.Keep = true;
|
Installer.Keep = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolOutputFile::ToolOutputFile(StringRef Filename, int FD)
|
ToolOutputFile::ToolOutputFile(StringRef Filename, int FD)
|
||||||
: Installer(Filename), OS(FD, true) {}
|
: Installer(Filename) {
|
||||||
|
OSHolder.emplace(FD, true);
|
||||||
|
OS = OSHolder.getPointer();
|
||||||
|
}
|
||||||
|
@ -864,9 +864,7 @@ void raw_fd_ostream::anchor() {}
|
|||||||
// outs(), errs(), nulls()
|
// outs(), errs(), nulls()
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
/// outs() - This returns a reference to a raw_ostream for standard output.
|
raw_fd_ostream &llvm::outs() {
|
||||||
/// Use it like: outs() << "foo" << "bar";
|
|
||||||
raw_ostream &llvm::outs() {
|
|
||||||
// Set buffer settings to model stdout behavior.
|
// Set buffer settings to model stdout behavior.
|
||||||
std::error_code EC;
|
std::error_code EC;
|
||||||
static raw_fd_ostream S("-", EC, sys::fs::OF_None);
|
static raw_fd_ostream S("-", EC, sys::fs::OF_None);
|
||||||
@ -874,9 +872,7 @@ raw_ostream &llvm::outs() {
|
|||||||
return S;
|
return S;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// errs() - This returns a reference to a raw_ostream for standard error.
|
raw_fd_ostream &llvm::errs() {
|
||||||
/// Use it like: errs() << "foo" << "bar";
|
|
||||||
raw_ostream &llvm::errs() {
|
|
||||||
// Set standard error to be unbuffered by default.
|
// Set standard error to be unbuffered by default.
|
||||||
static raw_fd_ostream S(STDERR_FILENO, false, true);
|
static raw_fd_ostream S(STDERR_FILENO, false, true);
|
||||||
return S;
|
return S;
|
||||||
|
@ -75,6 +75,7 @@ add_llvm_unittest(SupportTests
|
|||||||
ThreadPool.cpp
|
ThreadPool.cpp
|
||||||
Threading.cpp
|
Threading.cpp
|
||||||
TimerTest.cpp
|
TimerTest.cpp
|
||||||
|
ToolOutputFileTest.cpp
|
||||||
TypeNameTest.cpp
|
TypeNameTest.cpp
|
||||||
TypeTraitsTest.cpp
|
TypeTraitsTest.cpp
|
||||||
TrailingObjectsTest.cpp
|
TrailingObjectsTest.cpp
|
||||||
|
22
unittests/Support/ToolOutputFileTest.cpp
Normal file
22
unittests/Support/ToolOutputFileTest.cpp
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
//===- ToolOutputFileTest.cpp - ToolOutputFile tests ----------------------===//
|
||||||
|
//
|
||||||
|
// 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
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "llvm/Support/ToolOutputFile.h"
|
||||||
|
#include "llvm/Support/FileSystem.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
|
||||||
|
using namespace llvm;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
TEST(ToolOutputFileTest, DashOpensOuts) {
|
||||||
|
std::error_code EC;
|
||||||
|
EXPECT_EQ(&ToolOutputFile("-", EC, sys::fs::OF_None).os(), &outs());
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
Loading…
x
Reference in New Issue
Block a user