Refactor a bit & -M bug fixed.

1. Use llvm::tool_output_file instead of llvm::raw_stream. The former
can automatically deleted itself from filesystem once the compilation failed.
2. Fix -M bug which causes segfault previously.
diff --git a/llvm-rs-cc.cpp b/llvm-rs-cc.cpp
index 03fdd45..ec6362e 100644
--- a/llvm-rs-cc.cpp
+++ b/llvm-rs-cc.cpp
@@ -205,7 +205,9 @@
       }
     }
 
-    if (Opts.mOutputType != Slang::OT_Bitcode)
+    if (Opts.mOutputDep &&
+        ((Opts.mOutputType != Slang::OT_Bitcode) &&
+         (Opts.mOutputType != Slang::OT_Dependency)))
       Diags.Report(clang::diag::err_drv_argument_not_allowed_with)
           << Args->getLastArg(OPT_M_Group)->getAsString(*Args)
           << Args->getLastArg(OPT_Output_Type_Group)->getAsString(*Args);
@@ -318,6 +320,7 @@
 static bool ExecuteCompilation(SlangRS &Compiler,
                                const char *InputFile,
                                const char *OutputFile,
+                               const char *BCOutputFile,
                                const char *DepOutputFile,
                                const RSCCOptions &Opts) {
   std::string RealPackageName;
@@ -338,8 +341,7 @@
     if (!Compiler.setDepOutput(DepOutputFile))
       return false;
 
-    if (Opts.mOutputType != Slang::OT_Dependency)
-      Compiler.setDepTargetBC(OutputFile);
+    Compiler.setDepTargetBC(BCOutputFile);
     Compiler.setAdditionalDepTargets(Opts.mAdditionalDepTargets);
 
     if (Compiler.generateDepFile() > 0)
@@ -412,7 +414,8 @@
     return 1;
   }
 
-  const char *InputFile, *OutputFile, *DepOutputFile = NULL;
+  const char *InputFile, *OutputFile, *BCOutputFile = NULL,
+             *DepOutputFile = NULL;
   llvm::OwningPtr<SlangRS> Compiler(new SlangRS(Opts.mTriple, Opts.mCPU,
                                                 Opts.mFeatures));
 
@@ -426,10 +429,17 @@
       else
         DepOutputFile = DetermineOutputFile(Opts.mOutputDepDir, InputFile,
                                             Slang::OT_Dependency, SavedStrings);
+
+      if (Opts.mOutputType == Slang::OT_Bitcode)
+        BCOutputFile = OutputFile;
+      else
+        BCOutputFile = DetermineOutputFile(Opts.mOutputDepDir, InputFile,
+                                           Slang::OT_Bitcode, SavedStrings);
     }
     if (!ExecuteCompilation(*Compiler,
                             InputFile,
                             OutputFile,
+                            BCOutputFile,
                             DepOutputFile,
                             Opts)) {
       llvm::errs() << Compiler->getErrorMessage();
diff --git a/slang.cpp b/slang.cpp
index ba4c861..78428f9 100644
--- a/slang.cpp
+++ b/slang.cpp
@@ -106,6 +106,29 @@
 // bcc.cpp)
 const llvm::StringRef Slang::PragmaMetadataName = "#pragma";
 
+static inline llvm::tool_output_file *OpenOutputFile(const char *OutputFile,
+                                                     unsigned Flags,
+                                                     std::string* Error,
+                                                     clang::Diagnostic* Diag) {
+  assert((OutputFile != NULL) && (Error != NULL) && (Diag != NULL) &&
+         "Invalid parameter!");
+
+  llvm::sys::Path OutputFilePath(OutputFile);
+
+  if (SlangUtils::CreateDirectoryWithParents(OutputFilePath.getDirname(),
+                                             Error)) {
+    llvm::tool_output_file *F =
+          new llvm::tool_output_file(OutputFile, *Error, Flags);
+    if (F != NULL)
+      return F;
+  }
+
+  // Report error here.
+  Diag->Report(clang::diag::err_fe_error_opening) << OutputFile << *Error;
+
+  return NULL;
+}
+
 void Slang::GlobalInitialization() {
   if (!GlobalInitialized) {
     // We only support x86, x64 and ARM target
@@ -289,31 +312,24 @@
 bool Slang::setOutput(const char *OutputFile) {
   llvm::sys::Path OutputFilePath(OutputFile);
   std::string Error;
+  llvm::tool_output_file *OS = NULL;
 
   switch (mOT) {
     case OT_Dependency:
     case OT_Assembly:
     case OT_LLVMAssembly: {
-      if (!SlangUtils::CreateDirectoryWithParents(OutputFilePath.getDirname(),
-                                                  &Error))
-        mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile
-            << Error;
-      mOS.reset(new llvm::tool_output_file(OutputFile, Error, 0));
+      OS = OpenOutputFile(OutputFile, 0, &Error, mDiagnostics.getPtr());
       break;
     }
     case OT_Nothing: {
-      mOS.reset();
       break;
     }
     case OT_Object:
     case OT_Bitcode: {
-      if (!SlangUtils::CreateDirectoryWithParents(OutputFilePath.getDirname(),
-                                                  &Error))
-        mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile
-            << Error;
-      mOS.reset(new llvm::tool_output_file(OutputFile,
-                                           Error,
-                                           llvm::raw_fd_ostream::F_Binary));
+      OS = OpenOutputFile(OutputFile,
+                          llvm::raw_fd_ostream::F_Binary,
+                          &Error,
+                          mDiagnostics.getPtr());
       break;
     }
     default: {
@@ -321,12 +337,10 @@
     }
   }
 
-  if (!Error.empty()) {
-    mOS.reset();
-    mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile
-                                                            << Error;
+  if (!Error.empty())
     return false;
-  }
+
+  mOS.reset(OS);
 
   mOutputFileName = OutputFile;
 
@@ -337,18 +351,9 @@
   llvm::sys::Path OutputFilePath(OutputFile);
   std::string Error;
 
-  if (!SlangUtils::CreateDirectoryWithParents(OutputFilePath.getDirname(),
-                                              &Error))
-    mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile
-        << Error;
-  mDOS.reset(new llvm::raw_fd_ostream(OutputFile, Error, 0));
-
-  if (!Error.empty()) {
-    mDOS.reset();
-    mDiagnostics->Report(clang::diag::err_fe_error_opening) << OutputFile
-                                                            << Error;
+  mDOS.reset(OpenOutputFile(OutputFile, 0, &Error, mDiagnostics.getPtr()));
+  if (!Error.empty() || (mDOS.get() == NULL))
     return false;
-  }
 
   mDepOutputFileName = OutputFile;
 
@@ -361,21 +366,21 @@
   if (mDOS.get() == NULL)
     return 1;
 
-  /* Initialize options for generating dependency file */
+  // Initialize options for generating dependency file
   clang::DependencyOutputOptions DepOpts;
   DepOpts.IncludeSystemHeaders = 1;
   DepOpts.OutputFile = mDepOutputFileName;
   DepOpts.Targets = mAdditionalDepTargets;
   DepOpts.Targets.push_back(mDepTargetBCFileName);
 
-  /* Per-compilation needed initialization */
+  // Per-compilation needed initialization
   createPreprocessor();
   AttachDependencyFileGen(*mPP.get(), DepOpts);
 
-  /* Inform the diagnostic client we are processing a source file */
+  // Inform the diagnostic client we are processing a source file
   mDiagClient->BeginSourceFile(LangOpts, mPP.get());
 
-  /* Go through the source file (no operations necessary) */
+  // Go through the source file (no operations necessary)
   clang::Token Tok;
   mPP->EnterMainSourceFile();
   do {
@@ -384,8 +389,13 @@
 
   mPP->EndSourceFile();
 
-  /* Clean up after compilation */
+  // Declare success if no error
+  if (mDiagnostics->getNumErrors() == 0)
+    mDOS->keep();
+
+  // Clean up after compilation
   mPP.reset();
+  mDOS.reset();
 
   return mDiagnostics->getNumErrors();
 }
@@ -400,7 +410,7 @@
   createPreprocessor();
   createASTContext();
 
-  mBackend.reset(createBackend(CodeGenOpts, mOS.take(), mOT));
+  mBackend.reset(createBackend(CodeGenOpts, mOS.get(), mOT));
 
   // Inform the diagnostic client we are processing a source file
   mDiagClient->BeginSourceFile(LangOpts, mPP.get());
@@ -408,13 +418,18 @@
   // The core of the slang compiler
   ParseAST(*mPP, mBackend.get(), *mASTContext);
 
+  // Inform the diagnostic client we are done with previous source file
+  mDiagClient->EndSourceFile();
+
+  // Declare success if no error
+  if (mDiagnostics->getNumErrors() == 0)
+    mOS->keep();
+
   // The compilation ended, clear
   mBackend.reset();
   mASTContext.reset();
   mPP.reset();
-
-  // Inform the diagnostic client we are done with previous source file
-  mDiagClient->EndSourceFile();
+  mOS.reset();
 
   return mDiagnostics->getNumErrors();
 }
diff --git a/slang.h b/slang.h
index 67f8560..a614135 100644
--- a/slang.h
+++ b/slang.h
@@ -15,7 +15,7 @@
 #include "slang_diagnostic_buffer.h"
 
 namespace llvm {
-  class raw_ostream;
+  class tool_output_file;
 }
 
 namespace clang {
@@ -100,9 +100,9 @@
   OutputType mOT;
 
   // Output stream
-  llvm::OwningPtr<llvm::raw_ostream> mOS;
+  llvm::OwningPtr<llvm::tool_output_file> mOS;
   // Dependency output stream
-  llvm::OwningPtr<llvm::raw_ostream> mDOS;
+  llvm::OwningPtr<llvm::tool_output_file> mDOS;
 
   std::vector<std::string> mIncludePaths;