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.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@112706 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/tools/bugpoint/ExtractFunction.cpp b/tools/bugpoint/ExtractFunction.cpp
index e9cae15..524f130 100644
--- a/tools/bugpoint/ExtractFunction.cpp
+++ b/tools/bugpoint/ExtractFunction.cpp
@@ -339,15 +339,15 @@
     // 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/tools/bugpoint/OptimizerDriver.cpp b/tools/bugpoint/OptimizerDriver.cpp
index 8f5ab72..3600ca6 100644
--- a/tools/bugpoint/OptimizerDriver.cpp
+++ b/tools/bugpoint/OptimizerDriver.cpp
@@ -58,14 +58,14 @@
   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 @@
     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/tools/llc/llc.cpp b/tools/llc/llc.cpp
index 13fe71b..8bcc2d8 100644
--- a/tools/llc/llc.cpp
+++ b/tools/llc/llc.cpp
@@ -123,9 +123,9 @@
   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 @@
     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 @@
   TargetMachine &Target = *target.get();
 
   // Figure out where we are going to send the output...
-  OwningPtr<formatted_tool_output_file> Out
+  OwningPtr<tool_output_file> Out
     (GetOutputStream(TheTarget->getName(), TheTriple.getOS(), argv[0]));
   if (!Out) return 1;
 
@@ -314,15 +310,18 @@
       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/tools/llvm-as/llvm-as.cpp b/tools/llvm-as/llvm-as.cpp
index 516cec2..1eaa4b3 100644
--- a/tools/llvm-as/llvm-as.cpp
+++ b/tools/llvm-as/llvm-as.cpp
@@ -77,8 +77,8 @@
     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/tools/llvm-dis/llvm-dis.cpp b/tools/llvm-dis/llvm-dis.cpp
index de6ac02..9d36f10 100644
--- a/tools/llvm-dis/llvm-dis.cpp
+++ b/tools/llvm-dis/llvm-dis.cpp
@@ -98,7 +98,7 @@
 
   // 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/tools/llvm-extract/llvm-extract.cpp b/tools/llvm-extract/llvm-extract.cpp
index 319737c..91a59e5 100644
--- a/tools/llvm-extract/llvm-extract.cpp
+++ b/tools/llvm-extract/llvm-extract.cpp
@@ -134,9 +134,9 @@
   }
 
   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/tools/llvm-ld/llvm-ld.cpp b/tools/llvm-ld/llvm-ld.cpp
index e4b2ae5..3bbea9d 100644
--- a/tools/llvm-ld/llvm-ld.cpp
+++ b/tools/llvm-ld/llvm-ld.cpp
@@ -244,7 +244,7 @@
   }
 
   // Write it out
-  WriteBitcodeToFile(M, Out);
+  WriteBitcodeToFile(M, Out.os());
   Out.keep();
 }
 
@@ -432,10 +432,10 @@
   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<lib> and implicitly searches /lib and /usr/lib.
   LibPaths.push_back("/lib");
   LibPaths.push_back("/usr/lib");
@@ -466,9 +466,9 @@
     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/tools/llvm-link/llvm-link.cpp b/tools/llvm-link/llvm-link.cpp
index f487d24..e55d0de 100644
--- a/tools/llvm-link/llvm-link.cpp
+++ b/tools/llvm-link/llvm-link.cpp
@@ -130,9 +130,9 @@
 
   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/tools/llvm-mc/llvm-mc.cpp b/tools/llvm-mc/llvm-mc.cpp
index cf0b346..aef0a3d 100644
--- a/tools/llvm-mc/llvm-mc.cpp
+++ b/tools/llvm-mc/llvm-mc.cpp
@@ -140,7 +140,7 @@
   return 0;
 }
 
-static formatted_tool_output_file *GetOutputStream() {
+static tool_output_file *GetOutputStream() {
   if (OutputFilename == "")
     OutputFilename = "-";
 
@@ -152,9 +152,8 @@
     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 @@
   AsmLexer Lexer(*MAI);
   Lexer.setBuffer(SrcMgr.getMemoryBuffer(0));
 
-  OwningPtr<formatted_tool_output_file> Out(GetOutputStream());
+  OwningPtr<tool_output_file> Out(GetOutputStream());
   if (!Out)
     return 1;
 
@@ -204,44 +203,44 @@
       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 @@
     return 1;
   }
 
-  OwningPtr<formatted_tool_output_file> Out(GetOutputStream());
+  OwningPtr<tool_output_file> Out(GetOutputStream());
   if (!Out)
     return 1;
 
+  formatted_raw_ostream FOS(Out->os());
   OwningPtr<MCStreamer> Str;
 
   if (FileType == OFT_AssemblyFile) {
@@ -303,7 +303,7 @@
     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 @@
     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 @@
     return 1;
   }
   
-  OwningPtr<formatted_tool_output_file> Out(GetOutputStream());
+  OwningPtr<tool_output_file> 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/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp
index 67b1765..671348c 100644
--- a/tools/lto/LTOCodeGenerator.cpp
+++ b/tools/lto/LTOCodeGenerator.cpp
@@ -164,13 +164,13 @@
   }
     
   // 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 @@
     // 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 @@
 }
 
 /// 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 @@
 
     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/tools/lto/LTOCodeGenerator.h b/tools/lto/LTOCodeGenerator.h
index 71593a5..f5b78a6 100644
--- a/tools/lto/LTOCodeGenerator.h
+++ b/tools/lto/LTOCodeGenerator.h
@@ -45,7 +45,7 @@
     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/tools/opt/GraphPrinters.cpp b/tools/opt/GraphPrinters.cpp
index d689a4a..9de7d6a 100644
--- a/tools/opt/GraphPrinters.cpp
+++ b/tools/opt/GraphPrinters.cpp
@@ -31,16 +31,16 @@
   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/tools/opt/opt.cpp b/tools/opt/opt.cpp
index f4ca38f..d837185 100644
--- a/tools/opt/opt.cpp
+++ b/tools/opt/opt.cpp
@@ -359,6 +359,11 @@
 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 @@
   // 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 @@
       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 @@
   // 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.