From ec080467f5b322441055de1f6cd4f08edc23d7df Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 11 Sep 2009 20:46:33 +0000 Subject: [PATCH] Fix llvm-extract's "writing bitcode to a terminal" warning, which wasn't working. To support this, add an is_displayed() function to raw_ostream, and generalize Process::StandardOutIsDisplayed and friends in order to support it. Also, call RemoveFileOnSignal before creating a file instead of after, so that the file isn't left behind if the program is interrupted between when the file is created and RemoveFileOnSignal is called. While here, add a -S to llvm-extract and port it to IRReader so that it supports assembly input. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@81568 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/CommandGuide/llvm-extract.pod | 4 ++++ include/llvm/Support/raw_ostream.h | 7 ++++++ include/llvm/System/Process.h | 5 ++++ lib/Support/SystemUtils.cpp | 3 +-- lib/Support/raw_ostream.cpp | 4 ++++ lib/System/Unix/Process.inc | 20 ++++++---------- lib/System/Win32/Process.inc | 10 +++++--- tools/llvm-as/llvm-as.cpp | 13 +++++------ tools/llvm-dis/llvm-dis.cpp | 12 +++++----- tools/llvm-extract/Makefile | 2 +- tools/llvm-extract/llvm-extract.cpp | 36 ++++++++++++++++------------- tools/opt/opt.cpp | 8 +++---- 12 files changed, 72 insertions(+), 52 deletions(-) diff --git a/docs/CommandGuide/llvm-extract.pod b/docs/CommandGuide/llvm-extract.pod index c3bc019c6b8..b62e8ae312b 100644 --- a/docs/CommandGuide/llvm-extract.pod +++ b/docs/CommandGuide/llvm-extract.pod @@ -45,6 +45,10 @@ Print a summary of command line options. Specify the output filename. If filename is "-" (the default), then B sends its output to standard output. +=item B<-S> + +Write output in LLVM intermediate language (instead of bitcode). + =back =head1 EXIT STATUS diff --git a/include/llvm/Support/raw_ostream.h b/include/llvm/Support/raw_ostream.h index a01d4cdb040..dbad40ca91c 100644 --- a/include/llvm/Support/raw_ostream.h +++ b/include/llvm/Support/raw_ostream.h @@ -240,6 +240,11 @@ public: /// outputting colored text, or before program exit. virtual raw_ostream &resetColor() { return *this; } + /// This function determines if this stream is connected to a "tty" or + /// "console" window. That is, the output would be displayed to the user + /// rather than being put on a pipe or stored in a file. + virtual bool is_displayed() const { return false; } + //===--------------------------------------------------------------------===// // Subclass Interface //===--------------------------------------------------------------------===// @@ -370,6 +375,8 @@ public: virtual raw_ostream &changeColor(enum Colors colors, bool bold=false, bool bg=false); virtual raw_ostream &resetColor(); + + virtual bool is_displayed() const; }; /// raw_stdout_ostream - This is a stream that always prints to stdout. diff --git a/include/llvm/System/Process.h b/include/llvm/System/Process.h index 11dbf759a6c..010499acd4b 100644 --- a/include/llvm/System/Process.h +++ b/include/llvm/System/Process.h @@ -94,6 +94,11 @@ namespace sys { /// the user rather than being put on a pipe or stored in a file. static bool StandardErrIsDisplayed(); + /// This function determines if the given file descriptor is connected to + /// a "tty" or "console" window. That is, the output would be displayed to + /// the user rather than being put on a pipe or stored in a file. + static bool FileDescriptorIsDisplayed(int fd); + /// This function determines the number of columns in the window /// if standard output is connected to a "tty" or "console" /// window. If standard output is not connected to a tty or diff --git a/lib/Support/SystemUtils.cpp b/lib/Support/SystemUtils.cpp index 3d3649eaeba..299032f1871 100644 --- a/lib/Support/SystemUtils.cpp +++ b/lib/Support/SystemUtils.cpp @@ -20,8 +20,7 @@ using namespace llvm; bool llvm::CheckBitcodeOutputToConsole(raw_ostream &stream_to_check, bool print_warning) { - if (&stream_to_check == &outs() && - sys::Process::StandardOutIsDisplayed()) { + if (stream_to_check.is_displayed()) { if (print_warning) { errs() << "WARNING: You're attempting to print out a bitcode file.\n" << "This is inadvisable as it may cause display problems. If\n" diff --git a/lib/Support/raw_ostream.cpp b/lib/Support/raw_ostream.cpp index a229efde6ea..2cb37712872 100644 --- a/lib/Support/raw_ostream.cpp +++ b/lib/Support/raw_ostream.cpp @@ -454,6 +454,10 @@ raw_ostream &raw_fd_ostream::resetColor() { return *this; } +bool raw_fd_ostream::is_displayed() const { + return sys::Process::FileDescriptorIsDisplayed(FD); +} + //===----------------------------------------------------------------------===// // raw_stdout/err_ostream //===----------------------------------------------------------------------===// diff --git a/lib/System/Unix/Process.inc b/lib/System/Unix/Process.inc index 774783f8ad0..d7155852bf2 100644 --- a/lib/System/Unix/Process.inc +++ b/lib/System/Unix/Process.inc @@ -179,26 +179,20 @@ void Process::PreventCoreFiles() { } bool Process::StandardInIsUserInput() { -#if HAVE_ISATTY - return isatty(0); -#else - // If we don't have isatty, just return false. - return false; -#endif + return FileDescriptorIsDisplayed(STDIN_FILENO); } bool Process::StandardOutIsDisplayed() { -#if HAVE_ISATTY - return isatty(1); -#else - // If we don't have isatty, just return false. - return false; -#endif + return FileDescriptorIsDisplayed(STDOUT_FILENO); } bool Process::StandardErrIsDisplayed() { + return FileDescriptorIsDisplayed(STDERR_FILENO); +} + +bool Process::FileDescriptorIsDisplayed(int fd) { #if HAVE_ISATTY - return isatty(2); + return isatty(fd); #else // If we don't have isatty, just return false. return false; diff --git a/lib/System/Win32/Process.inc b/lib/System/Win32/Process.inc index cfbe33c85a2..feb0806116e 100644 --- a/lib/System/Win32/Process.inc +++ b/lib/System/Win32/Process.inc @@ -120,15 +120,19 @@ void Process::PreventCoreFiles() { } bool Process::StandardInIsUserInput() { - return GetFileType((HANDLE)_get_osfhandle(0)) == FILE_TYPE_CHAR; + return FileDescriptorIsDisplayed(0); } bool Process::StandardOutIsDisplayed() { - return GetFileType((HANDLE)_get_osfhandle(1)) == FILE_TYPE_CHAR; + return FileDescriptorIsDisplayed(1); } bool Process::StandardErrIsDisplayed() { - return GetFileType((HANDLE)_get_osfhandle(2)) == FILE_TYPE_CHAR; + return FileDescriptorIsDisplayed(2); +} + +bool Process::FileDescriptorIsDisplayed(int fd) { + return GetFileType((HANDLE)_get_osfhandle(fd)) == FILE_TYPE_CHAR; } unsigned Process::StandardOutColumns() { diff --git a/tools/llvm-as/llvm-as.cpp b/tools/llvm-as/llvm-as.cpp index 9027cfc3cf2..d510297aa35 100644 --- a/tools/llvm-as/llvm-as.cpp +++ b/tools/llvm-as/llvm-as.cpp @@ -94,7 +94,12 @@ int main(int argc, char **argv) { OutputFilename += ".bc"; } } - + + // Make sure that the Out file gets unlinked from the disk if we get a + // SIGINT. + if (OutputFilename != "-") + sys::RemoveFileOnSignal(sys::Path(OutputFilename)); + std::string ErrorInfo; std::auto_ptr Out (new raw_fd_ostream(OutputFilename.c_str(), ErrorInfo, @@ -103,12 +108,6 @@ int main(int argc, char **argv) { errs() << ErrorInfo << '\n'; return 1; } - - - // Make sure that the Out file gets unlinked from the disk if we get a - // SIGINT. - if (OutputFilename != "-") - sys::RemoveFileOnSignal(sys::Path(OutputFilename)); if (!DisableOutput) if (Force || !CheckBitcodeOutputToConsole(*Out, true)) diff --git a/tools/llvm-dis/llvm-dis.cpp b/tools/llvm-dis/llvm-dis.cpp index 89073c08843..43bde53599c 100644 --- a/tools/llvm-dis/llvm-dis.cpp +++ b/tools/llvm-dis/llvm-dis.cpp @@ -89,7 +89,12 @@ int main(int argc, char **argv) { OutputFilename = IFN+".ll"; } } - + + // Make sure that the Out file gets unlinked from the disk if we get a + // SIGINT. + if (OutputFilename != "-") + sys::RemoveFileOnSignal(sys::Path(OutputFilename)); + std::string ErrorInfo; std::auto_ptr Out(new raw_fd_ostream(OutputFilename.c_str(), ErrorInfo, @@ -99,11 +104,6 @@ int main(int argc, char **argv) { return 1; } - // Make sure that the Out file gets unlinked from the disk if we get a - // SIGINT. - if (OutputFilename != "-") - sys::RemoveFileOnSignal(sys::Path(OutputFilename)); - // All that llvm-dis does is write the assembly to a file. if (!DontPrint) { PassManager Passes; diff --git a/tools/llvm-extract/Makefile b/tools/llvm-extract/Makefile index 2ef88415c6a..5672aa3299a 100644 --- a/tools/llvm-extract/Makefile +++ b/tools/llvm-extract/Makefile @@ -10,7 +10,7 @@ LEVEL = ../.. TOOLNAME = llvm-extract -LINK_COMPONENTS := ipo bitreader bitwriter +LINK_COMPONENTS := ipo bitreader bitwriter asmparser # This tool has no plugins, optimize startup time. TOOL_NO_EXPORTS = 1 diff --git a/tools/llvm-extract/llvm-extract.cpp b/tools/llvm-extract/llvm-extract.cpp index 543d01f9103..517244f55ba 100644 --- a/tools/llvm-extract/llvm-extract.cpp +++ b/tools/llvm-extract/llvm-extract.cpp @@ -15,10 +15,12 @@ #include "llvm/LLVMContext.h" #include "llvm/Module.h" #include "llvm/PassManager.h" +#include "llvm/Assembly/PrintModulePass.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/Transforms/IPO.h" #include "llvm/Target/TargetData.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/IRReader.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/PrettyStackTrace.h" @@ -57,6 +59,10 @@ static cl::opt ExtractGlobal("glob", cl::desc("Specify global to extract"), cl::init(""), cl::value_desc("global")); +static cl::opt +OutputAssembly("S", + cl::desc("Write output as LLVM assembly"), cl::Hidden); + int main(int argc, char **argv) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(); @@ -66,19 +72,12 @@ int main(int argc, char **argv) { llvm_shutdown_obj Y; // Call llvm_shutdown() on exit. cl::ParseCommandLineOptions(argc, argv, "llvm extractor\n"); + SMDiagnostic Err; std::auto_ptr M; - - MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename); - if (Buffer == 0) { - errs() << argv[0] << ": Error reading file '" + InputFilename + "'\n"; - return 1; - } else { - M.reset(ParseBitcodeFile(Buffer, Context)); - } - delete Buffer; - + M.reset(ParseIRFile(InputFilename, Err, Context)); + if (M.get() == 0) { - errs() << argv[0] << ": bitcode didn't read correctly.\n"; + Err.Print(argv[0], errs()); return 1; } @@ -111,17 +110,22 @@ int main(int argc, char **argv) { Passes.add(createDeadTypeEliminationPass()); // Remove dead types... Passes.add(createStripDeadPrototypesPass()); // Remove dead func decls + // Make sure that the Output file gets unlinked from the disk if we get a + // SIGINT + sys::RemoveFileOnSignal(sys::Path(OutputFilename)); + std::string ErrorInfo; - std::auto_ptr - Out(new raw_fd_ostream(OutputFilename.c_str(), ErrorInfo, - raw_fd_ostream::F_Binary)); + raw_fd_ostream Out(OutputFilename.c_str(), ErrorInfo, + raw_fd_ostream::F_Binary); if (!ErrorInfo.empty()) { errs() << ErrorInfo << '\n'; return 1; } - if (Force || !CheckBitcodeOutputToConsole(*Out, true)) - Passes.add(createBitcodeWriterPass(*Out)); + if (OutputAssembly) + Passes.add(createPrintModulePass(&Out)); + else if (Force || !CheckBitcodeOutputToConsole(Out, true)) + Passes.add(createBitcodeWriterPass(Out)); Passes.run(*M.get()); diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index e4700667122..fe0e03649dd 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -362,6 +362,10 @@ int main(int argc, char **argv) { // FIXME: outs() is not binary! raw_ostream *Out = &outs(); // Default to printing to stdout... if (OutputFilename != "-") { + // Make sure that the Output file gets unlinked from the disk if we get a + // SIGINT + sys::RemoveFileOnSignal(sys::Path(OutputFilename)); + std::string ErrorInfo; Out = new raw_fd_ostream(OutputFilename.c_str(), ErrorInfo, raw_fd_ostream::F_Binary); @@ -370,10 +374,6 @@ int main(int argc, char **argv) { delete Out; return 1; } - - // Make sure that the Output file gets unlinked from the disk if we get a - // SIGINT - sys::RemoveFileOnSignal(sys::Path(OutputFilename)); } // If the output is set to be emitted to standard out, and standard out is a