From a2233f28014b92c31905f3bf9c084422d42fd648 Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 1 Sep 2010 14:20:41 +0000 Subject: [PATCH] Make tool_output_file's raw_ostream instance a member variable instead of a base class. This makes it possible to unregister the file from FilesToRemove when the file is done. Also, this eliminates the need for formatted_tool_output_file. llvm-svn: 112706 --- llvm/include/llvm/Support/FormattedStream.h | 36 --------- llvm/include/llvm/Support/raw_ostream.h | 32 ++++++-- llvm/lib/Support/FormattedStream.cpp | 3 - llvm/lib/Support/raw_ostream.cpp | 32 ++++---- llvm/tools/bugpoint/ExtractFunction.cpp | 10 +-- llvm/tools/bugpoint/OptimizerDriver.cpp | 16 ++-- llvm/tools/llc/llc.cpp | 33 ++++---- llvm/tools/llvm-as/llvm-as.cpp | 4 +- llvm/tools/llvm-dis/llvm-dis.cpp | 2 +- llvm/tools/llvm-extract/llvm-extract.cpp | 6 +- llvm/tools/llvm-ld/llvm-ld.cpp | 12 +-- llvm/tools/llvm-link/llvm-link.cpp | 6 +- llvm/tools/llvm-mc/llvm-mc.cpp | 86 ++++++++++----------- llvm/tools/lto/LTOCodeGenerator.cpp | 25 +++--- llvm/tools/lto/LTOCodeGenerator.h | 2 +- llvm/tools/opt/GraphPrinters.cpp | 8 +- llvm/tools/opt/opt.cpp | 21 +++-- llvm/utils/FileUpdate/FileUpdate.cpp | 2 +- llvm/utils/TableGen/TableGen.cpp | 70 ++++++++--------- 19 files changed, 198 insertions(+), 208 deletions(-) diff --git a/llvm/include/llvm/Support/FormattedStream.h b/llvm/include/llvm/Support/FormattedStream.h index db02580323f6..58a18851687c 100644 --- a/llvm/include/llvm/Support/FormattedStream.h +++ b/llvm/include/llvm/Support/FormattedStream.h @@ -19,14 +19,10 @@ namespace llvm { - class formatted_tool_output_file; - /// formatted_raw_ostream - Formatted raw_fd_ostream to handle /// asm-specific constructs. /// class formatted_raw_ostream : public raw_ostream { - friend class formatted_tool_output_file; - public: /// DELETE_STREAM - Tell the destructor to delete the held stream. /// @@ -140,38 +136,6 @@ namespace llvm } }; - /// formatted_tool_output_file - This is a subclass of formatted_raw_ostream - /// for use when the underlying stream is a tool_output_file. It exposes - /// keep() and several other member functions. - class formatted_tool_output_file : public formatted_raw_ostream { - private: - tool_output_file &get_tool_output_file() const { - return *static_cast(TheStream); - } - - public: - formatted_tool_output_file(tool_output_file &Stream, bool Delete = false) - : formatted_raw_ostream(Stream, Delete) {} - - formatted_tool_output_file() {} - - ~formatted_tool_output_file(); - - void setStream(tool_output_file &Stream, bool Delete = false) { - return formatted_raw_ostream::setStream(Stream, Delete); - } - - void keep() { return get_tool_output_file().keep(); } - bool has_error() const { return get_tool_output_file().has_error(); } - void clear_error() { return get_tool_output_file().clear_error(); } - void close() { - // The inner stream is unbuffered; flush the outer stream's buffer. - flush(); - // The inner stream can close its file descriptor now. - return get_tool_output_file().close(); - } - }; - /// fouts() - This returns a reference to a formatted_raw_ostream for /// standard output. Use it like: fouts() << "foo" << "bar"; formatted_raw_ostream &fouts(); diff --git a/llvm/include/llvm/Support/raw_ostream.h b/llvm/include/llvm/Support/raw_ostream.h index 3c2a8b10201d..39bdbd804c27 100644 --- a/llvm/include/llvm/Support/raw_ostream.h +++ b/llvm/include/llvm/Support/raw_ostream.h @@ -475,23 +475,43 @@ public: ~raw_null_ostream(); }; -/// tool_output_file - This class behaves like a raw_fd_ostream but adds a +/// tool_output_file - This class contains a raw_fd_ostream and adds a /// few extra features commonly needed for compiler-like tool output files: /// - The file is automatically deleted if the process is killed. /// - The file is automatically deleted when the tool_output_file /// object is destroyed unless the client calls keep(). -class tool_output_file : public raw_fd_ostream { - std::string Filename; - bool Keep; +class tool_output_file { + /// Installer - This class is declared before the raw_fd_ostream so that + /// it is constructed before the raw_fd_ostream is constructed and + /// destructed after the raw_fd_ostream is destructed. It installs + /// cleanups in its constructor and uninstalls them in its destructor. + class CleanupInstaller { + /// Filename - The name of the file. + std::string Filename; + public: + /// Keep - The flag which indicates whether we should not delete the file. + bool Keep; + + explicit CleanupInstaller(const char *filename); + ~CleanupInstaller(); + } Installer; + + /// OS - The contained stream. This is intentionally declared after + /// Installer. + raw_fd_ostream OS; + public: + /// tool_output_file - This constructor's arguments are passed to + /// to raw_fd_ostream's constructor. tool_output_file(const char *filename, std::string &ErrorInfo, unsigned Flags = 0); - ~tool_output_file(); + /// os - Return the contained raw_fd_ostream. + raw_fd_ostream &os() { return OS; } /// keep - Indicate that the tool's job wrt this output file has been /// successful and the file should not be deleted. - void keep() { Keep = true; } + void keep() { Installer.Keep = true; } }; } // end llvm namespace diff --git a/llvm/lib/Support/FormattedStream.cpp b/llvm/lib/Support/FormattedStream.cpp index 77bdfab22076..c72b5a1751b4 100644 --- a/llvm/lib/Support/FormattedStream.cpp +++ b/llvm/lib/Support/FormattedStream.cpp @@ -98,6 +98,3 @@ formatted_raw_ostream &llvm::fdbgs() { static formatted_raw_ostream S(dbgs()); return S; } - -/// ~formatted_tool_output_file - Out-of-line destructor. -formatted_tool_output_file::~formatted_tool_output_file() {} diff --git a/llvm/lib/Support/raw_ostream.cpp b/llvm/lib/Support/raw_ostream.cpp index 371dc8b25563..dba46df36256 100644 --- a/llvm/lib/Support/raw_ostream.cpp +++ b/llvm/lib/Support/raw_ostream.cpp @@ -670,25 +670,29 @@ uint64_t raw_null_ostream::current_pos() const { // tool_output_file //===----------------------------------------------------------------------===// -/// SetupRemoveOnSignal - This is a helper for tool_output_file's constructor -/// to allow the signal handlers to be installed before constructing the -/// base class raw_fd_ostream. -static const char *SetupRemoveOnSignal(const char *Filename) { +tool_output_file::CleanupInstaller::CleanupInstaller(const char *filename) + : Filename(filename), Keep(false) { // Arrange for the file to be deleted if the process is killed. - if (strcmp(Filename, "-") != 0) + if (Filename != "-") sys::RemoveFileOnSignal(sys::Path(Filename)); - return Filename; } -tool_output_file::tool_output_file(const char *filename, std::string &ErrorInfo, - unsigned Flags) - : raw_fd_ostream(SetupRemoveOnSignal(filename), ErrorInfo, Flags), - Filename(filename), - Keep(!ErrorInfo.empty() /* If open fails, no cleanup is needed. */) { -} - -tool_output_file::~tool_output_file() { +tool_output_file::CleanupInstaller::~CleanupInstaller() { // Delete the file if the client hasn't told us not to. if (!Keep && Filename != "-") sys::Path(Filename).eraseFromDisk(); + + // Ok, the file is successfully written and closed, or deleted. There's no + // further need to clean it up on signals. + if (Filename != "-") + sys::DontRemoveFileOnSignal(sys::Path(Filename)); +} + +tool_output_file::tool_output_file(const char *filename, std::string &ErrorInfo, + unsigned Flags) + : Installer(filename), + OS(filename, ErrorInfo, Flags) { + // If open fails, no cleanup is needed. + if (!ErrorInfo.empty()) + Installer.Keep = true; } diff --git a/llvm/tools/bugpoint/ExtractFunction.cpp b/llvm/tools/bugpoint/ExtractFunction.cpp index e9cae15ef550..524f130ba751 100644 --- a/llvm/tools/bugpoint/ExtractFunction.cpp +++ b/llvm/tools/bugpoint/ExtractFunction.cpp @@ -339,15 +339,15 @@ Module *BugDriver::ExtractMappedBlocksFromModule(const // If the BB doesn't have a name, give it one so we have something to key // off of. if (!BB->hasName()) BB->setName("tmpbb"); - BlocksToNotExtractFile << BB->getParent()->getNameStr() << " " - << BB->getName() << "\n"; + BlocksToNotExtractFile.os() << BB->getParent()->getNameStr() << " " + << BB->getName() << "\n"; } - BlocksToNotExtractFile.close(); - if (BlocksToNotExtractFile.has_error()) { + BlocksToNotExtractFile.os().close(); + if (BlocksToNotExtractFile.os().has_error()) { errs() << "Error writing list of blocks to not extract: " << ErrorInfo << "\n"; EmitProgressBitcode(M, "basicblockextractfail", true); - BlocksToNotExtractFile.clear_error(); + BlocksToNotExtractFile.os().clear_error(); return 0; } BlocksToNotExtractFile.keep(); diff --git a/llvm/tools/bugpoint/OptimizerDriver.cpp b/llvm/tools/bugpoint/OptimizerDriver.cpp index 8f5ab722f025..3600ca6a81e3 100644 --- a/llvm/tools/bugpoint/OptimizerDriver.cpp +++ b/llvm/tools/bugpoint/OptimizerDriver.cpp @@ -58,14 +58,14 @@ bool BugDriver::writeProgramToFile(const std::string &Filename, tool_output_file Out(Filename.c_str(), ErrInfo, raw_fd_ostream::F_Binary); if (ErrInfo.empty()) { - WriteBitcodeToFile(M, Out); - Out.close(); - if (!Out.has_error()) { + WriteBitcodeToFile(M, Out.os()); + Out.os().close(); + if (!Out.os().has_error()) { Out.keep(); return false; } } - Out.clear_error(); + Out.os().clear_error(); return true; } @@ -140,11 +140,11 @@ bool BugDriver::runPasses(Module *Program, errs() << "Error opening bitcode file: " << inputFilename.str() << "\n"; return 1; } - WriteBitcodeToFile(Program, InFile); - InFile.close(); - if (InFile.has_error()) { + WriteBitcodeToFile(Program, InFile.os()); + InFile.os().close(); + if (InFile.os().has_error()) { errs() << "Error writing bitcode file: " << inputFilename.str() << "\n"; - InFile.clear_error(); + InFile.os().clear_error(); return 1; } InFile.keep(); diff --git a/llvm/tools/llc/llc.cpp b/llvm/tools/llc/llc.cpp index 13fe71b10986..8bcc2d8d27e9 100644 --- a/llvm/tools/llc/llc.cpp +++ b/llvm/tools/llc/llc.cpp @@ -123,9 +123,9 @@ GetFileNameRoot(const std::string &InputFilename) { return outputFilename; } -static formatted_tool_output_file *GetOutputStream(const char *TargetName, - Triple::OSType OS, - const char *ProgName) { +static 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 == "-") @@ -183,11 +183,7 @@ static formatted_tool_output_file *GetOutputStream(const char *TargetName, return 0; } - formatted_tool_output_file *Out = - new formatted_tool_output_file(*FDOut, - formatted_raw_ostream::DELETE_STREAM); - - return Out; + return FDOut; } // main - Entry point for the llc compiler. @@ -278,7 +274,7 @@ int main(int argc, char **argv) { TargetMachine &Target = *target.get(); // Figure out where we are going to send the output... - OwningPtr Out + OwningPtr Out (GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0])); if (!Out) return 1; @@ -314,15 +310,18 @@ int main(int argc, char **argv) { Target.setMCRelaxAll(true); } - // Ask the target to add backend passes as necessary. - if (Target.addPassesToEmitFile(PM, *Out, FileType, OLvl, - NoVerify)) { - errs() << argv[0] << ": target does not support generation of this" - << " file type!\n"; - return 1; - } + { + formatted_raw_ostream FOS(Out->os()); - PM.run(mod); + // Ask the target to add backend passes as necessary. + if (Target.addPassesToEmitFile(PM, FOS, FileType, OLvl, NoVerify)) { + errs() << argv[0] << ": target does not support generation of this" + << " file type!\n"; + return 1; + } + + PM.run(mod); + } // Declare success. Out->keep(); diff --git a/llvm/tools/llvm-as/llvm-as.cpp b/llvm/tools/llvm-as/llvm-as.cpp index 516cec2d5c9a..1eaa4b3bea44 100644 --- a/llvm/tools/llvm-as/llvm-as.cpp +++ b/llvm/tools/llvm-as/llvm-as.cpp @@ -77,8 +77,8 @@ static void WriteOutputFile(const Module *M) { exit(1); } - if (Force || !CheckBitcodeOutputToConsole(*Out, true)) - WriteBitcodeToFile(M, *Out); + if (Force || !CheckBitcodeOutputToConsole(Out->os(), true)) + WriteBitcodeToFile(M, Out->os()); // Declare success. Out->keep(); diff --git a/llvm/tools/llvm-dis/llvm-dis.cpp b/llvm/tools/llvm-dis/llvm-dis.cpp index de6ac02e2c25..9d36f1055c89 100644 --- a/llvm/tools/llvm-dis/llvm-dis.cpp +++ b/llvm/tools/llvm-dis/llvm-dis.cpp @@ -98,7 +98,7 @@ int main(int argc, char **argv) { // All that llvm-dis does is write the assembly to a file. if (!DontPrint) - *Out << *M; + Out->os() << *M; // Declare success. Out->keep(); diff --git a/llvm/tools/llvm-extract/llvm-extract.cpp b/llvm/tools/llvm-extract/llvm-extract.cpp index 319737c54bcc..91a59e5a56da 100644 --- a/llvm/tools/llvm-extract/llvm-extract.cpp +++ b/llvm/tools/llvm-extract/llvm-extract.cpp @@ -134,9 +134,9 @@ int main(int argc, char **argv) { } if (OutputAssembly) - Passes.add(createPrintModulePass(&Out)); - else if (Force || !CheckBitcodeOutputToConsole(Out, true)) - Passes.add(createBitcodeWriterPass(Out)); + Passes.add(createPrintModulePass(&Out.os())); + else if (Force || !CheckBitcodeOutputToConsole(Out.os(), true)) + Passes.add(createBitcodeWriterPass(Out.os())); Passes.run(*M.get()); diff --git a/llvm/tools/llvm-ld/llvm-ld.cpp b/llvm/tools/llvm-ld/llvm-ld.cpp index e4b2ae5d673c..3bbea9dc7287 100644 --- a/llvm/tools/llvm-ld/llvm-ld.cpp +++ b/llvm/tools/llvm-ld/llvm-ld.cpp @@ -244,7 +244,7 @@ void GenerateBitcode(Module* M, const std::string& FileName) { } // Write it out - WriteBitcodeToFile(M, Out); + WriteBitcodeToFile(M, Out.os()); Out.keep(); } @@ -432,10 +432,10 @@ static void EmitShellScript(char **argv, Module *M) { if (!ErrorInfo.empty()) PrintAndExit(ErrorInfo, M); - Out2 << "#!/bin/sh\n"; + Out2.os() << "#!/bin/sh\n"; // Allow user to setenv LLVMINTERP if lli is not in their PATH. - Out2 << "lli=${LLVMINTERP-lli}\n"; - Out2 << "exec $lli \\\n"; + Out2.os() << "lli=${LLVMINTERP-lli}\n"; + Out2.os() << "exec $lli \\\n"; // gcc accepts -l and implicitly searches /lib and /usr/lib. LibPaths.push_back("/lib"); LibPaths.push_back("/usr/lib"); @@ -466,9 +466,9 @@ static void EmitShellScript(char **argv, Module *M) { if (FullLibraryPath.isEmpty()) FullLibraryPath = sys::Path::FindLibrary(*i); if (!FullLibraryPath.isEmpty()) - Out2 << " -load=" << FullLibraryPath.str() << " \\\n"; + Out2.os() << " -load=" << FullLibraryPath.str() << " \\\n"; } - Out2 << " " << BitcodeOutputFilename << " ${1+\"$@\"}\n"; + Out2.os() << " " << BitcodeOutputFilename << " ${1+\"$@\"}\n"; Out2.keep(); } diff --git a/llvm/tools/llvm-link/llvm-link.cpp b/llvm/tools/llvm-link/llvm-link.cpp index f487d2452df2..e55d0de0f9b5 100644 --- a/llvm/tools/llvm-link/llvm-link.cpp +++ b/llvm/tools/llvm-link/llvm-link.cpp @@ -130,9 +130,9 @@ int main(int argc, char **argv) { if (Verbose) errs() << "Writing bitcode...\n"; if (OutputAssembly) { - Out << *Composite; - } else if (Force || !CheckBitcodeOutputToConsole(Out, true)) - WriteBitcodeToFile(Composite.get(), Out); + Out.os() << *Composite; + } else if (Force || !CheckBitcodeOutputToConsole(Out.os(), true)) + WriteBitcodeToFile(Composite.get(), Out.os()); // Declare success. Out.keep(); diff --git a/llvm/tools/llvm-mc/llvm-mc.cpp b/llvm/tools/llvm-mc/llvm-mc.cpp index cf0b346c3a54..aef0a3dffa45 100644 --- a/llvm/tools/llvm-mc/llvm-mc.cpp +++ b/llvm/tools/llvm-mc/llvm-mc.cpp @@ -140,7 +140,7 @@ static const Target *GetTarget(const char *ProgName) { return 0; } -static formatted_tool_output_file *GetOutputStream() { +static tool_output_file *GetOutputStream() { if (OutputFilename == "") OutputFilename = "-"; @@ -152,9 +152,8 @@ static formatted_tool_output_file *GetOutputStream() { delete Out; return 0; } - - return new formatted_tool_output_file(*Out, - formatted_raw_ostream::DELETE_STREAM); + + return Out; } static int AsLexInput(const char *ProgName) { @@ -189,7 +188,7 @@ static int AsLexInput(const char *ProgName) { AsmLexer Lexer(*MAI); Lexer.setBuffer(SrcMgr.getMemoryBuffer(0)); - OwningPtr Out(GetOutputStream()); + OwningPtr Out(GetOutputStream()); if (!Out) return 1; @@ -204,44 +203,44 @@ static int AsLexInput(const char *ProgName) { Error = true; // error already printed. break; case AsmToken::Identifier: - *Out << "identifier: " << Lexer.getTok().getString() << '\n'; + Out->os() << "identifier: " << Lexer.getTok().getString() << '\n'; break; case AsmToken::String: - *Out << "string: " << Lexer.getTok().getString() << '\n'; + Out->os() << "string: " << Lexer.getTok().getString() << '\n'; break; case AsmToken::Integer: - *Out << "int: " << Lexer.getTok().getString() << '\n'; + Out->os() << "int: " << Lexer.getTok().getString() << '\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; + case AsmToken::Amp: Out->os() << "Amp\n"; break; + case AsmToken::AmpAmp: Out->os() << "AmpAmp\n"; break; + case AsmToken::Caret: Out->os() << "Caret\n"; break; + case AsmToken::Colon: Out->os() << "Colon\n"; break; + case AsmToken::Comma: Out->os() << "Comma\n"; break; + case AsmToken::Dollar: Out->os() << "Dollar\n"; break; + case AsmToken::EndOfStatement: Out->os() << "EndOfStatement\n"; break; + case AsmToken::Eof: Out->os() << "Eof\n"; break; + case AsmToken::Equal: Out->os() << "Equal\n"; break; + case AsmToken::EqualEqual: Out->os() << "EqualEqual\n"; break; + case AsmToken::Exclaim: Out->os() << "Exclaim\n"; break; + case AsmToken::ExclaimEqual: Out->os() << "ExclaimEqual\n"; break; + case AsmToken::Greater: Out->os() << "Greater\n"; break; + case AsmToken::GreaterEqual: Out->os() << "GreaterEqual\n"; break; + case AsmToken::GreaterGreater: Out->os() << "GreaterGreater\n"; break; + case AsmToken::LParen: Out->os() << "LParen\n"; break; + case AsmToken::Less: Out->os() << "Less\n"; break; + case AsmToken::LessEqual: Out->os() << "LessEqual\n"; break; + case AsmToken::LessGreater: Out->os() << "LessGreater\n"; break; + case AsmToken::LessLess: Out->os() << "LessLess\n"; break; + case AsmToken::Minus: Out->os() << "Minus\n"; break; + case AsmToken::Percent: Out->os() << "Percent\n"; break; + case AsmToken::Pipe: Out->os() << "Pipe\n"; break; + case AsmToken::PipePipe: Out->os() << "PipePipe\n"; break; + case AsmToken::Plus: Out->os() << "Plus\n"; break; + case AsmToken::RParen: Out->os() << "RParen\n"; break; + case AsmToken::Slash: Out->os() << "Slash\n"; break; + case AsmToken::Star: Out->os() << "Star\n"; break; + case AsmToken::Tilde: Out->os() << "Tilde\n"; break; } } @@ -291,10 +290,11 @@ static int AssembleInput(const char *ProgName) { return 1; } - OwningPtr Out(GetOutputStream()); + OwningPtr Out(GetOutputStream()); if (!Out) return 1; + formatted_raw_ostream FOS(Out->os()); OwningPtr Str; if (FileType == OFT_AssemblyFile) { @@ -303,7 +303,7 @@ static int AssembleInput(const char *ProgName) { MCCodeEmitter *CE = 0; if (ShowEncoding) CE = TheTarget->createCodeEmitter(*TM, Ctx); - Str.reset(createAsmStreamer(Ctx, *Out, + Str.reset(createAsmStreamer(Ctx, FOS, TM->getTargetData()->isLittleEndian(), /*asmverbose*/true, IP, CE, ShowInst)); } else if (FileType == OFT_Null) { @@ -313,7 +313,7 @@ static int AssembleInput(const char *ProgName) { MCCodeEmitter *CE = TheTarget->createCodeEmitter(*TM, Ctx); TargetAsmBackend *TAB = TheTarget->createAsmBackend(TripleName); Str.reset(TheTarget->createObjectStreamer(TripleName, Ctx, *TAB, - *Out, CE, RelaxAll)); + FOS, CE, RelaxAll)); } if (EnableLogging) { @@ -359,15 +359,15 @@ static int DisassembleInput(const char *ProgName, bool Enhanced) { return 1; } - OwningPtr Out(GetOutputStream()); + OwningPtr Out(GetOutputStream()); if (!Out) return 1; int Res; if (Enhanced) - Res = Disassembler::disassembleEnhanced(TripleName, *Buffer, *Out); + Res = Disassembler::disassembleEnhanced(TripleName, *Buffer, Out->os()); else - Res = Disassembler::disassemble(*TheTarget, TripleName, *Buffer, *Out); + Res = Disassembler::disassemble(*TheTarget, TripleName, *Buffer, Out->os()); // Keep output if no errors. if (Res == 0) Out->keep(); diff --git a/llvm/tools/lto/LTOCodeGenerator.cpp b/llvm/tools/lto/LTOCodeGenerator.cpp index 67b17657872c..671348c8333b 100644 --- a/llvm/tools/lto/LTOCodeGenerator.cpp +++ b/llvm/tools/lto/LTOCodeGenerator.cpp @@ -164,13 +164,13 @@ bool LTOCodeGenerator::writeMergedModules(const char *path, } // write bitcode to it - WriteBitcodeToFile(_linker.getModule(), Out); - Out.close(); + WriteBitcodeToFile(_linker.getModule(), Out.os()); + Out.os().close(); - if (Out.has_error()) { + if (Out.os().has_error()) { errMsg = "could not write bitcode file: "; errMsg += path; - Out.clear_error(); + Out.os().clear_error(); return true; } @@ -190,14 +190,13 @@ const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg) // generate assembly code bool genResult = false; { - tool_output_file asmFD(uniqueAsmPath.c_str(), errMsg); - formatted_tool_output_file asmFile(asmFD); + tool_output_file asmFile(uniqueAsmPath.c_str(), errMsg); if (!errMsg.empty()) return NULL; - genResult = this->generateAssemblyCode(asmFile, errMsg); - asmFile.close(); - if (asmFile.has_error()) { - asmFile.clear_error(); + genResult = this->generateAssemblyCode(asmFile.os(), errMsg); + asmFile.os().close(); + if (asmFile.os().has_error()) { + asmFile.os().clear_error(); return NULL; } asmFile.keep(); @@ -368,7 +367,7 @@ void LTOCodeGenerator::applyScopeRestrictions() { } /// Optimize merged modules using various IPO passes -bool LTOCodeGenerator::generateAssemblyCode(formatted_raw_ostream& out, +bool LTOCodeGenerator::generateAssemblyCode(raw_ostream& out, std::string& errMsg) { if ( this->determineTarget(errMsg) ) @@ -403,7 +402,9 @@ bool LTOCodeGenerator::generateAssemblyCode(formatted_raw_ostream& out, codeGenPasses->add(new TargetData(*_target->getTargetData())); - if (_target->addPassesToEmitFile(*codeGenPasses, out, + formatted_raw_ostream Out(out); + + if (_target->addPassesToEmitFile(*codeGenPasses, Out, TargetMachine::CGFT_AssemblyFile, CodeGenOpt::Aggressive)) { errMsg = "target file type not supported"; diff --git a/llvm/tools/lto/LTOCodeGenerator.h b/llvm/tools/lto/LTOCodeGenerator.h index 71593a5039bb..f5b78a608a99 100644 --- a/llvm/tools/lto/LTOCodeGenerator.h +++ b/llvm/tools/lto/LTOCodeGenerator.h @@ -45,7 +45,7 @@ struct LTOCodeGenerator { const void* compile(size_t* length, std::string& errMsg); void setCodeGenDebugOptions(const char *opts); private: - bool generateAssemblyCode(llvm::formatted_raw_ostream& out, + bool generateAssemblyCode(llvm::raw_ostream& out, std::string& errMsg); bool assemble(const std::string& asmPath, const std::string& objPath, std::string& errMsg); diff --git a/llvm/tools/opt/GraphPrinters.cpp b/llvm/tools/opt/GraphPrinters.cpp index d689a4a1dae2..9de7d6ac5459 100644 --- a/llvm/tools/opt/GraphPrinters.cpp +++ b/llvm/tools/opt/GraphPrinters.cpp @@ -31,16 +31,16 @@ static void WriteGraphToFile(raw_ostream &O, const std::string &GraphName, tool_output_file F(Filename.c_str(), ErrInfo); if (ErrInfo.empty()) { - WriteGraph(F, GT); - F.close(); - if (!F.has_error()) { + WriteGraph(F.os(), GT); + F.os().close(); + if (!F.os().has_error()) { O << "\n"; F.keep(); return; } } - F.clear_error(); O << " error opening file for writing!\n"; + F.os().clear_error(); } diff --git a/llvm/tools/opt/opt.cpp b/llvm/tools/opt/opt.cpp index f4ca38fb1ac0..d83718517918 100644 --- a/llvm/tools/opt/opt.cpp +++ b/llvm/tools/opt/opt.cpp @@ -359,6 +359,11 @@ void AddStandardLinkPasses(PassManagerBase &PM) { int main(int argc, char **argv) { sys::PrintStackTraceOnErrorSignal(); llvm::PrettyStackTraceProgram X(argc, argv); + + if (AnalyzeOnly && NoOutput) { + errs() << argv[0] << ": analyze mode conflicts with no-output mode.\n"; + return 1; + } // Enable debug stream buffering. EnableDebugBuffering = true; @@ -408,7 +413,7 @@ int main(int argc, char **argv) { // console, print out a warning message and refuse to do it. We don't // impress anyone by spewing tons of binary goo to a terminal. if (!Force && !NoOutput && !AnalyzeOnly && !OutputAssembly) - if (CheckBitcodeOutputToConsole(*Out, !Quiet)) + if (CheckBitcodeOutputToConsole(Out->os(), !Quiet)) NoOutput = true; // Create a PassManager to hold and optimize the collection of passes we are @@ -484,19 +489,19 @@ int main(int argc, char **argv) { if (AnalyzeOnly) { switch (Kind) { case PT_BasicBlock: - Passes.add(new BasicBlockPassPrinter(PassInf, *Out)); + Passes.add(new BasicBlockPassPrinter(PassInf, Out->os())); break; case PT_Loop: - Passes.add(new LoopPassPrinter(PassInf, *Out)); + Passes.add(new LoopPassPrinter(PassInf, Out->os())); break; case PT_Function: - Passes.add(new FunctionPassPrinter(PassInf, *Out)); + Passes.add(new FunctionPassPrinter(PassInf, Out->os())); break; case PT_CallGraphSCC: - Passes.add(new CallGraphSCCPassPrinter(PassInf, *Out)); + Passes.add(new CallGraphSCCPassPrinter(PassInf, Out->os())); break; default: - Passes.add(new ModulePassPrinter(PassInf, *Out)); + Passes.add(new ModulePassPrinter(PassInf, Out->os())); break; } } @@ -536,9 +541,9 @@ 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.get())); + Passes.add(createPrintModulePass(&Out->os())); else - Passes.add(createBitcodeWriterPass(*Out)); + Passes.add(createBitcodeWriterPass(Out->os())); } // Now that we have all of the passes ready, run them. diff --git a/llvm/utils/FileUpdate/FileUpdate.cpp b/llvm/utils/FileUpdate/FileUpdate.cpp index 8377aea79e84..2cf366fa55f8 100644 --- a/llvm/utils/FileUpdate/FileUpdate.cpp +++ b/llvm/utils/FileUpdate/FileUpdate.cpp @@ -78,7 +78,7 @@ int main(int argc, char **argv) { return 1; } - OutStream.write(In->getBufferStart(), In->getBufferSize()); + OutStream.os().write(In->getBufferStart(), In->getBufferSize()); // Declare success. OutStream.keep(); diff --git a/llvm/utils/TableGen/TableGen.cpp b/llvm/utils/TableGen/TableGen.cpp index a544e1d7120e..5e3e2829b87f 100644 --- a/llvm/utils/TableGen/TableGen.cpp +++ b/llvm/utils/TableGen/TableGen.cpp @@ -226,109 +226,109 @@ int main(int argc, char **argv) { try { switch (Action) { case PrintRecords: - Out << Records; // No argument, dump all contents + Out.os() << Records; // No argument, dump all contents break; case GenEmitter: - CodeEmitterGen(Records).run(Out); + CodeEmitterGen(Records).run(Out.os()); break; case GenRegisterEnums: - RegisterInfoEmitter(Records).runEnums(Out); + RegisterInfoEmitter(Records).runEnums(Out.os()); break; case GenRegister: - RegisterInfoEmitter(Records).run(Out); + RegisterInfoEmitter(Records).run(Out.os()); break; case GenRegisterHeader: - RegisterInfoEmitter(Records).runHeader(Out); + RegisterInfoEmitter(Records).runHeader(Out.os()); break; case GenInstrEnums: - InstrEnumEmitter(Records).run(Out); + InstrEnumEmitter(Records).run(Out.os()); break; case GenInstrs: - InstrInfoEmitter(Records).run(Out); + InstrInfoEmitter(Records).run(Out.os()); break; case GenCallingConv: - CallingConvEmitter(Records).run(Out); + CallingConvEmitter(Records).run(Out.os()); break; case GenAsmWriter: - AsmWriterEmitter(Records).run(Out); + AsmWriterEmitter(Records).run(Out.os()); break; case GenARMDecoder: - ARMDecoderEmitter(Records).run(Out); + ARMDecoderEmitter(Records).run(Out.os()); break; case GenAsmMatcher: - AsmMatcherEmitter(Records).run(Out); + AsmMatcherEmitter(Records).run(Out.os()); break; case GenClangAttrClasses: - ClangAttrClassEmitter(Records).run(Out); + ClangAttrClassEmitter(Records).run(Out.os()); break; case GenClangAttrImpl: - ClangAttrImplEmitter(Records).run(Out); + ClangAttrImplEmitter(Records).run(Out.os()); break; case GenClangAttrList: - ClangAttrListEmitter(Records).run(Out); + ClangAttrListEmitter(Records).run(Out.os()); break; case GenClangAttrPCHRead: - ClangAttrPCHReadEmitter(Records).run(Out); + ClangAttrPCHReadEmitter(Records).run(Out.os()); break; case GenClangAttrPCHWrite: - ClangAttrPCHWriteEmitter(Records).run(Out); + ClangAttrPCHWriteEmitter(Records).run(Out.os()); break; case GenClangDiagsDefs: - ClangDiagsDefsEmitter(Records, ClangComponent).run(Out); + ClangDiagsDefsEmitter(Records, ClangComponent).run(Out.os()); break; case GenClangDiagGroups: - ClangDiagGroupsEmitter(Records).run(Out); + ClangDiagGroupsEmitter(Records).run(Out.os()); break; case GenClangDeclNodes: - ClangASTNodesEmitter(Records, "Decl", "Decl").run(Out); - ClangDeclContextEmitter(Records).run(Out); + ClangASTNodesEmitter(Records, "Decl", "Decl").run(Out.os()); + ClangDeclContextEmitter(Records).run(Out.os()); break; case GenClangStmtNodes: - ClangASTNodesEmitter(Records, "Stmt", "").run(Out); + ClangASTNodesEmitter(Records, "Stmt", "").run(Out.os()); break; case GenDisassembler: - DisassemblerEmitter(Records).run(Out); + DisassemblerEmitter(Records).run(Out.os()); break; case GenOptParserDefs: - OptParserEmitter(Records, true).run(Out); + OptParserEmitter(Records, true).run(Out.os()); break; case GenOptParserImpl: - OptParserEmitter(Records, false).run(Out); + OptParserEmitter(Records, false).run(Out.os()); break; case GenDAGISel: - DAGISelEmitter(Records).run(Out); + DAGISelEmitter(Records).run(Out.os()); break; case GenFastISel: - FastISelEmitter(Records).run(Out); + FastISelEmitter(Records).run(Out.os()); break; case GenSubtarget: - SubtargetEmitter(Records).run(Out); + SubtargetEmitter(Records).run(Out.os()); break; case GenIntrinsic: - IntrinsicEmitter(Records).run(Out); + IntrinsicEmitter(Records).run(Out.os()); break; case GenTgtIntrinsic: - IntrinsicEmitter(Records, true).run(Out); + IntrinsicEmitter(Records, true).run(Out.os()); break; case GenLLVMCConf: - LLVMCConfigurationEmitter(Records).run(Out); + LLVMCConfigurationEmitter(Records).run(Out.os()); break; case GenEDInfo: - EDEmitter(Records).run(Out); + EDEmitter(Records).run(Out.os()); break; case GenArmNeon: - NeonEmitter(Records).run(Out); + NeonEmitter(Records).run(Out.os()); break; case GenArmNeonSema: - NeonEmitter(Records).runHeader(Out); + NeonEmitter(Records).runHeader(Out.os()); break; case PrintEnums: { std::vector Recs = Records.getAllDerivedDefinitions(Class); for (unsigned i = 0, e = Recs.size(); i != e; ++i) - Out << Recs[i]->getName() << ", "; - Out << "\n"; + Out.os() << Recs[i]->getName() << ", "; + Out.os() << "\n"; break; } default: