From d5826a33a5a7c298a8934541d11cda042028be3b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Fri, 20 Aug 2010 01:07:01 +0000 Subject: Use the new tool_output_file in several tools. This fixes a variety of problems with output files being left behind or output streams being left unclosed. Fix llvm-mc to respect the -o option in all modes, rather than hardcoding outs() in some cases. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@111603 91177308-0d34-0410-b5e6-96231b3b80d8 --- tools/llc/llc.cpp | 33 ++++------ tools/llvm-as/llvm-as.cpp | 14 ++--- tools/llvm-dis/llvm-dis.cpp | 15 ++--- tools/llvm-mc/Disassembler.cpp | 69 ++++++++++---------- tools/llvm-mc/Disassembler.h | 7 ++- tools/llvm-mc/llvm-mc.cpp | 140 ++++++++++++++++++++++------------------- tools/opt/opt.cpp | 20 +++--- 7 files changed, 150 insertions(+), 148 deletions(-) (limited to 'tools') diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp index a7d1fa0311..208d9f75ef 100644 --- a/tools/llc/llc.cpp +++ b/tools/llc/llc.cpp @@ -124,9 +124,9 @@ GetFileNameRoot(const std::string &InputFilename) { return outputFilename; } -static formatted_raw_ostream *GetOutputStream(const char *TargetName, - Triple::OSType OS, - const char *ProgName) { +static formatted_tool_output_file *GetOutputStream(const char *TargetName, + Triple::OSType OS, + const char *ProgName) { // If we don't yet have an output filename, make one. if (OutputFilename.empty()) { if (InputFilename == "-") @@ -172,25 +172,21 @@ static formatted_raw_ostream *GetOutputStream(const char *TargetName, break; } - // Make sure that the Out file gets unlinked from the disk if we get a - // SIGINT - if (OutputFilename != "-") - sys::RemoveFileOnSignal(sys::Path(OutputFilename)); - // Open the file. std::string error; unsigned OpenFlags = 0; if (Binary) OpenFlags |= raw_fd_ostream::F_Binary; - raw_fd_ostream *FDOut = new raw_fd_ostream(OutputFilename.c_str(), error, - OpenFlags); + tool_output_file *FDOut = new tool_output_file(OutputFilename.c_str(), error, + OpenFlags); if (!error.empty()) { errs() << error << '\n'; delete FDOut; return 0; } - formatted_raw_ostream *Out = - new formatted_raw_ostream(*FDOut, formatted_raw_ostream::DELETE_STREAM); + formatted_tool_output_file *Out = + new formatted_tool_output_file(*FDOut, + formatted_raw_ostream::DELETE_STREAM); return Out; } @@ -283,9 +279,9 @@ int main(int argc, char **argv) { TargetMachine &Target = *target.get(); // Figure out where we are going to send the output... - formatted_raw_ostream *Out = GetOutputStream(TheTarget->getName(), - TheTriple.getOS(), argv[0]); - if (Out == 0) return 1; + OwningPtr Out + (GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0])); + if (!Out) return 1; CodeGenOpt::Level OLvl = CodeGenOpt::Default; switch (OptLevel) { @@ -335,16 +331,13 @@ int main(int argc, char **argv) { DisableVerify)) { errs() << argv[0] << ": target does not support generation of this" << " file type!\n"; - delete Out; - // And the Out file is empty and useless, so remove it now. - sys::Path(OutputFilename).eraseFromDisk(); return 1; } PM.run(mod); - // Delete the ostream. - delete Out; + // Declare success. + Out->keep(); return 0; } diff --git a/tools/llvm-as/llvm-as.cpp b/tools/llvm-as/llvm-as.cpp index d39d6c8a31..516cec2d5c 100644 --- a/tools/llvm-as/llvm-as.cpp +++ b/tools/llvm-as/llvm-as.cpp @@ -68,15 +68,10 @@ static void WriteOutputFile(const Module *M) { } } - // 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, - raw_fd_ostream::F_Binary)); + OwningPtr Out + (new tool_output_file(OutputFilename.c_str(), ErrorInfo, + raw_fd_ostream::F_Binary)); if (!ErrorInfo.empty()) { errs() << ErrorInfo << '\n'; exit(1); @@ -84,6 +79,9 @@ static void WriteOutputFile(const Module *M) { if (Force || !CheckBitcodeOutputToConsole(*Out, true)) WriteBitcodeToFile(M, *Out); + + // Declare success. + Out->keep(); } int main(int argc, char **argv) { diff --git a/tools/llvm-dis/llvm-dis.cpp b/tools/llvm-dis/llvm-dis.cpp index b8b1a39384..de6ac02e2c 100644 --- a/tools/llvm-dis/llvm-dis.cpp +++ b/tools/llvm-dis/llvm-dis.cpp @@ -25,7 +25,6 @@ #include "llvm/Support/PrettyStackTrace.h" #include "llvm/Support/raw_ostream.h" #include "llvm/System/Signals.h" -#include using namespace llvm; static cl::opt @@ -88,15 +87,10 @@ int main(int argc, char **argv) { } } - // 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, - raw_fd_ostream::F_Binary)); + OwningPtr + Out(new tool_output_file(OutputFilename.c_str(), ErrorInfo, + raw_fd_ostream::F_Binary)); if (!ErrorInfo.empty()) { errs() << ErrorInfo << '\n'; return 1; @@ -106,6 +100,9 @@ int main(int argc, char **argv) { if (!DontPrint) *Out << *M; + // Declare success. + Out->keep(); + return 0; } diff --git a/tools/llvm-mc/Disassembler.cpp b/tools/llvm-mc/Disassembler.cpp index 7c9d7456f3..13080b481f 100644 --- a/tools/llvm-mc/Disassembler.cpp +++ b/tools/llvm-mc/Disassembler.cpp @@ -53,7 +53,7 @@ public: static bool PrintInsts(const MCDisassembler &DisAsm, MCInstPrinter &Printer, const ByteArrayTy &Bytes, - SourceMgr &SM) { + SourceMgr &SM, raw_ostream &Out) { // Wrap the vector in a MemoryObject. VectorMemoryObject memoryObject(Bytes); @@ -66,8 +66,8 @@ static bool PrintInsts(const MCDisassembler &DisAsm, if (DisAsm.getInstruction(Inst, Size, memoryObject, Index, /*REMOVE*/ nulls())) { - Printer.printInst(&Inst, outs()); - outs() << "\n"; + Printer.printInst(&Inst, Out); + Out << "\n"; } else { SM.PrintMessage(SMLoc::getFromPointer(Bytes[Index].second), "invalid instruction encoding", "warning"); @@ -127,7 +127,8 @@ static bool ByteArrayFromString(ByteArrayTy &ByteArray, } int Disassembler::disassemble(const Target &T, const std::string &Triple, - MemoryBuffer &Buffer) { + MemoryBuffer &Buffer, + raw_ostream &Out) { // Set up disassembler. OwningPtr AsmInfo(T.createAsmInfo(Triple)); @@ -162,7 +163,7 @@ int Disassembler::disassemble(const Target &T, const std::string &Triple, ErrorOccurred |= ByteArrayFromString(ByteArray, Str, SM); if (!ByteArray.empty()) - ErrorOccurred |= PrintInsts(*DisAsm, *IP, ByteArray, SM); + ErrorOccurred |= PrintInsts(*DisAsm, *IP, ByteArray, SM, Out); return ErrorOccurred; } @@ -179,22 +180,24 @@ static int byteArrayReader(uint8_t *B, uint64_t A, void *Arg) { } static int verboseEvaluator(uint64_t *V, unsigned R, void *Arg) { - EDDisassembler &disassembler = *((EDDisassembler *)Arg); + EDDisassembler &disassembler = *(EDDisassembler *)((void **)Arg)[0]; + raw_ostream &Out = *(raw_ostream *)((void **)Arg)[1]; if (const char *regName = disassembler.nameWithRegisterID(R)) - outs() << "[" << regName << "/" << R << "]"; + Out << "[" << regName << "/" << R << "]"; if (disassembler.registerIsStackPointer(R)) - outs() << "(sp)"; + Out << "(sp)"; if (disassembler.registerIsProgramCounter(R)) - outs() << "(pc)"; + Out << "(pc)"; *V = 0; return 0; } int Disassembler::disassembleEnhanced(const std::string &TS, - MemoryBuffer &Buffer) { + MemoryBuffer &Buffer, + raw_ostream &Out) { ByteArrayTy ByteArray; StringRef Str = Buffer.getBuffer(); SourceMgr SM; @@ -259,52 +262,52 @@ int Disassembler::disassembleEnhanced(const std::string &TS, return -1; } - outs() << '['; + Out << '['; int operandIndex = token->operandID(); if (operandIndex >= 0) - outs() << operandIndex << "-"; + Out << operandIndex << "-"; switch (token->type()) { - default: outs() << "?"; break; - case EDToken::kTokenWhitespace: outs() << "w"; break; - case EDToken::kTokenPunctuation: outs() << "p"; break; - case EDToken::kTokenOpcode: outs() << "o"; break; - case EDToken::kTokenLiteral: outs() << "l"; break; - case EDToken::kTokenRegister: outs() << "r"; break; + default: Out << "?"; break; + case EDToken::kTokenWhitespace: Out << "w"; break; + case EDToken::kTokenPunctuation: Out << "p"; break; + case EDToken::kTokenOpcode: Out << "o"; break; + case EDToken::kTokenLiteral: Out << "l"; break; + case EDToken::kTokenRegister: Out << "r"; break; } - outs() << ":" << buf; + Out << ":" << buf; if (token->type() == EDToken::kTokenLiteral) { - outs() << "="; + Out << "="; if (token->literalSign()) - outs() << "-"; + Out << "-"; uint64_t absoluteValue; if (token->literalAbsoluteValue(absoluteValue)) { errs() << "error: Couldn't get the value of a literal token\n"; return -1; } - outs() << absoluteValue; + Out << absoluteValue; } else if (token->type() == EDToken::kTokenRegister) { - outs() << "="; + Out << "="; unsigned regID; if (token->registerID(regID)) { errs() << "error: Couldn't get the ID of a register token\n"; return -1; } - outs() << "r" << regID; + Out << "r" << regID; } - outs() << "]"; + Out << "]"; } - outs() << " "; + Out << " "; if (inst->isBranch()) - outs() << "
"; + Out << "
"; if (inst->isMove()) - outs() << " "; + Out << " "; unsigned numOperands = inst->numOperands(); @@ -314,7 +317,7 @@ int Disassembler::disassembleEnhanced(const std::string &TS, } for (unsigned operandIndex = 0; operandIndex != numOperands; ++operandIndex) { - outs() << operandIndex << ":"; + Out << operandIndex << ":"; EDOperand *operand; if (inst->getOperand(operand, operandIndex)) { @@ -323,12 +326,12 @@ int Disassembler::disassembleEnhanced(const std::string &TS, } uint64_t evaluatedResult; - evaluatedResult = operand->evaluate(evaluatedResult, verboseEvaluator, - disassembler); - outs() << "=" << evaluatedResult << " "; + void *Arg[] = { disassembler, &Out }; + evaluatedResult = operand->evaluate(evaluatedResult, verboseEvaluator, Arg); + Out << "=" << evaluatedResult << " "; } - outs() << '\n'; + Out << '\n'; return 0; } diff --git a/tools/llvm-mc/Disassembler.h b/tools/llvm-mc/Disassembler.h index 3da23965bd..b56f2e9545 100644 --- a/tools/llvm-mc/Disassembler.h +++ b/tools/llvm-mc/Disassembler.h @@ -21,15 +21,18 @@ namespace llvm { class Target; class MemoryBuffer; +class raw_ostream; class Disassembler { public: static int disassemble(const Target &target, const std::string &tripleString, - MemoryBuffer &buffer); + MemoryBuffer &buffer, + raw_ostream &Out); static int disassembleEnhanced(const std::string &tripleString, - MemoryBuffer &buffer); + MemoryBuffer &buffer, + raw_ostream &Out); }; } // namespace llvm diff --git a/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp index 94b11ebe64..77d5a31518 100644 --- a/tools/llvm-mc/llvm-mc.cpp +++ b/tools/llvm-mc/llvm-mc.cpp @@ -27,6 +27,7 @@ #include "llvm/Target/TargetSelect.h" #include "llvm/ADT/OwningPtr.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Support/FileUtilities.h" #include "llvm/Support/FormattedStream.h" #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/MemoryBuffer.h" @@ -139,6 +140,23 @@ static const Target *GetTarget(const char *ProgName) { return 0; } +static formatted_tool_output_file *GetOutputStream() { + if (OutputFilename == "") + OutputFilename = "-"; + + std::string Err; + tool_output_file *Out = new tool_output_file(OutputFilename.c_str(), Err, + raw_fd_ostream::F_Binary); + if (!Err.empty()) { + errs() << Err << '\n'; + delete Out; + return 0; + } + + return new formatted_tool_output_file(*Out, + formatted_raw_ostream::DELETE_STREAM); +} + static int AsLexInput(const char *ProgName) { std::string ErrorMessage; MemoryBuffer *Buffer = MemoryBuffer::getFileOrSTDIN(InputFilename, @@ -171,6 +189,10 @@ static int AsLexInput(const char *ProgName) { AsmLexer Lexer(*MAI); Lexer.setBuffer(SrcMgr.getMemoryBuffer(0)); + OwningPtr Out(GetOutputStream()); + if (!Out) + return 1; + bool Error = false; while (Lexer.Lex().isNot(AsmToken::Eof)) { switch (Lexer.getKind()) { @@ -182,69 +204,51 @@ static int AsLexInput(const char *ProgName) { Error = true; // error already printed. break; case AsmToken::Identifier: - outs() << "identifier: " << Lexer.getTok().getString() << '\n'; + *Out << "identifier: " << Lexer.getTok().getString() << '\n'; break; case AsmToken::String: - outs() << "string: " << Lexer.getTok().getString() << '\n'; + *Out << "string: " << Lexer.getTok().getString() << '\n'; break; case AsmToken::Integer: - outs() << "int: " << Lexer.getTok().getString() << '\n'; + *Out << "int: " << Lexer.getTok().getString() << '\n'; break; - case AsmToken::Amp: outs() << "Amp\n"; break; - case AsmToken::AmpAmp: outs() << "AmpAmp\n"; break; - case AsmToken::Caret: outs() << "Caret\n"; break; - case AsmToken::Colon: outs() << "Colon\n"; break; - case AsmToken::Comma: outs() << "Comma\n"; break; - case AsmToken::Dollar: outs() << "Dollar\n"; break; - case AsmToken::EndOfStatement: outs() << "EndOfStatement\n"; break; - case AsmToken::Eof: outs() << "Eof\n"; break; - case AsmToken::Equal: outs() << "Equal\n"; break; - case AsmToken::EqualEqual: outs() << "EqualEqual\n"; break; - case AsmToken::Exclaim: outs() << "Exclaim\n"; break; - case AsmToken::ExclaimEqual: outs() << "ExclaimEqual\n"; break; - case AsmToken::Greater: outs() << "Greater\n"; break; - case AsmToken::GreaterEqual: outs() << "GreaterEqual\n"; break; - case AsmToken::GreaterGreater: outs() << "GreaterGreater\n"; break; - case AsmToken::LParen: outs() << "LParen\n"; break; - case AsmToken::Less: outs() << "Less\n"; break; - case AsmToken::LessEqual: outs() << "LessEqual\n"; break; - case AsmToken::LessGreater: outs() << "LessGreater\n"; break; - case AsmToken::LessLess: outs() << "LessLess\n"; break; - case AsmToken::Minus: outs() << "Minus\n"; break; - case AsmToken::Percent: outs() << "Percent\n"; break; - case AsmToken::Pipe: outs() << "Pipe\n"; break; - case AsmToken::PipePipe: outs() << "PipePipe\n"; break; - case AsmToken::Plus: outs() << "Plus\n"; break; - case AsmToken::RParen: outs() << "RParen\n"; break; - case AsmToken::Slash: outs() << "Slash\n"; break; - case AsmToken::Star: outs() << "Star\n"; break; - case AsmToken::Tilde: outs() << "Tilde\n"; break; + case AsmToken::Amp: *Out << "Amp\n"; break; + case AsmToken::AmpAmp: *Out << "AmpAmp\n"; break; + case AsmToken::Caret: *Out << "Caret\n"; break; + case AsmToken::Colon: *Out << "Colon\n"; break; + case AsmToken::Comma: *Out << "Comma\n"; break; + case AsmToken::Dollar: *Out << "Dollar\n"; break; + case AsmToken::EndOfStatement: *Out << "EndOfStatement\n"; break; + case AsmToken::Eof: *Out << "Eof\n"; break; + case AsmToken::Equal: *Out << "Equal\n"; break; + case AsmToken::EqualEqual: *Out << "EqualEqual\n"; break; + case AsmToken::Exclaim: *Out << "Exclaim\n"; break; + case AsmToken::ExclaimEqual: *Out << "ExclaimEqual\n"; break; + case AsmToken::Greater: *Out << "Greater\n"; break; + case AsmToken::GreaterEqual: *Out << "GreaterEqual\n"; break; + case AsmToken::GreaterGreater: *Out << "GreaterGreater\n"; break; + case AsmToken::LParen: *Out << "LParen\n"; break; + case AsmToken::Less: *Out << "Less\n"; break; + case AsmToken::LessEqual: *Out << "LessEqual\n"; break; + case AsmToken::LessGreater: *Out << "LessGreater\n"; break; + case AsmToken::LessLess: *Out << "LessLess\n"; break; + case AsmToken::Minus: *Out << "Minus\n"; break; + case AsmToken::Percent: *Out << "Percent\n"; break; + case AsmToken::Pipe: *Out << "Pipe\n"; break; + case AsmToken::PipePipe: *Out << "PipePipe\n"; break; + case AsmToken::Plus: *Out << "Plus\n"; break; + case AsmToken::RParen: *Out << "RParen\n"; break; + case AsmToken::Slash: *Out << "Slash\n"; break; + case AsmToken::Star: *Out << "Star\n"; break; + case AsmToken::Tilde: *Out << "Tilde\n"; break; } } - - return Error; -} - -static formatted_raw_ostream *GetOutputStream() { - if (OutputFilename == "") - OutputFilename = "-"; - // 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 Err; - raw_fd_ostream *Out = new raw_fd_ostream(OutputFilename.c_str(), Err, - raw_fd_ostream::F_Binary); - if (!Err.empty()) { - errs() << Err << '\n'; - delete Out; - return 0; - } - - return new formatted_raw_ostream(*Out, formatted_raw_ostream::DELETE_STREAM); + // Keep output if no errors. + if (Error == 0) Out->keep(); + + return Error; } static int AssembleInput(const char *ProgName) { @@ -277,10 +281,6 @@ static int AssembleInput(const char *ProgName) { assert(MAI && "Unable to create target asm info!"); MCContext Ctx(*MAI); - formatted_raw_ostream *Out = GetOutputStream(); - if (!Out) - return 1; - // FIXME: We shouldn't need to do this (and link in codegen). OwningPtr TM(TheTarget->createTargetMachine(TripleName, "")); @@ -291,6 +291,10 @@ static int AssembleInput(const char *ProgName) { return 1; } + OwningPtr Out(GetOutputStream()); + if (!Out) + return 1; + OwningPtr Str; if (FileType == OFT_AssemblyFile) { @@ -328,11 +332,9 @@ static int AssembleInput(const char *ProgName) { Parser->setTargetParser(*TAP.get()); int Res = Parser->Run(NoInitialTextSection); - delete Out; - // Delete output on errors. - if (Res && OutputFilename != "-") - sys::Path(OutputFilename).eraseFromDisk(); + // Keep output if no errors. + if (Res == 0) Out->keep(); return Res; } @@ -356,10 +358,20 @@ static int DisassembleInput(const char *ProgName, bool Enhanced) { return 1; } + OwningPtr Out(GetOutputStream()); + if (!Out) + return 1; + + int Res; if (Enhanced) - return Disassembler::disassembleEnhanced(TripleName, *Buffer); + Res = Disassembler::disassembleEnhanced(TripleName, *Buffer, *Out); else - return Disassembler::disassemble(*TheTarget, TripleName, *Buffer); + Res = Disassembler::disassemble(*TheTarget, TripleName, *Buffer, *Out); + + // Keep output if no errors. + if (Res == 0) Out->keep(); + + return Res; } diff --git a/tools/opt/opt.cpp b/tools/opt/opt.cpp index b8700685ca..f4ca38fb1a 100644 --- a/tools/opt/opt.cpp +++ b/tools/opt/opt.cpp @@ -385,7 +385,7 @@ int main(int argc, char **argv) { } // Figure out what stream we are supposed to write to... - raw_ostream *Out = 0; + OwningPtr Out; if (NoOutput) { if (!OutputFilename.empty()) errs() << "WARNING: The -o (output filename) option is ignored when\n" @@ -395,17 +395,11 @@ int main(int argc, char **argv) { if (OutputFilename.empty()) OutputFilename = "-"; - // Make sure that the Output file gets unlinked from the disk if we get - // a SIGINT. - if (OutputFilename != "-") - sys::RemoveFileOnSignal(sys::Path(OutputFilename)); - std::string ErrorInfo; - Out = new raw_fd_ostream(OutputFilename.c_str(), ErrorInfo, - raw_fd_ostream::F_Binary); + Out.reset(new tool_output_file(OutputFilename.c_str(), ErrorInfo, + raw_fd_ostream::F_Binary)); if (!ErrorInfo.empty()) { errs() << ErrorInfo << '\n'; - delete Out; return 1; } } @@ -542,7 +536,7 @@ int main(int argc, char **argv) { // Write bitcode or assembly to the output as the last step... if (!NoOutput && !AnalyzeOnly) { if (OutputAssembly) - Passes.add(createPrintModulePass(Out)); + Passes.add(createPrintModulePass(Out.get())); else Passes.add(createBitcodeWriterPass(*Out)); } @@ -550,7 +544,9 @@ int main(int argc, char **argv) { // Now that we have all of the passes ready, run them. Passes.run(*M.get()); - // Delete the raw_fd_ostream. - delete Out; + // Declare success. + if (!NoOutput) + Out->keep(); + return 0; } -- cgit v1.2.3