OSDN Git Service

Subzero: Fix asm (non-ELF) output files.
authorJim Stichnoth <stichnot@chromium.org>
Tue, 28 Apr 2015 21:12:20 +0000 (14:12 -0700)
committerJim Stichnoth <stichnot@chromium.org>
Tue, 28 Apr 2015 21:12:20 +0000 (14:12 -0700)
In an earlier version of Subzero, the text output stream object was
stack-allocated within main.  A later refactoring moved its allocation
into a helper function, but it was still being stack-allocated, which
was bad when the helper function returned.

This change allocates the object via "new", which fixes that problem,
but reveals another problem: the raw_ostream object for some reason
doesn't finish writing everything to disk and yielding a truncated
output file.  This is solved in the style of the ELF streamer, by
using raw_fd_ostream instead.

BUG= none
R=kschimpf@google.com

Review URL: https://codereview.chromium.org/1111603003

src/IceBrowserCompileServer.h
src/IceCompileServer.cpp
src/IceGlobalContext.h

index a34a03d..1f663c3 100644 (file)
@@ -75,9 +75,7 @@ public:
     ELFStream.reset(nullptr);
   }
 
-  StringStream &getErrorStream() {
-    return *ErrorStream;
-  }
+  StringStream &getErrorStream() { return *ErrorStream; }
 
 private:
   class StringStream {
@@ -85,6 +83,7 @@ private:
     StringStream() : StrBuf(Buffer) {}
     const IceString &getContents() { return StrBuf.str(); }
     Ostream &getStream() { return StrBuf; }
+
   private:
     std::string Buffer;
     llvm::raw_string_ostream StrBuf;
index cf398d4..25b8092 100644 (file)
@@ -30,13 +30,13 @@ namespace Ice {
 
 namespace {
 
-std::unique_ptr<Ostream> getStream(const IceString &Filename) {
-  std::ofstream Ofs;
-  if (Filename != "-") {
-    Ofs.open(Filename.c_str(), std::ofstream::out);
-    return std::unique_ptr<Ostream>(new llvm::raw_os_ostream(Ofs));
-  } else {
+std::unique_ptr<Ostream> makeStream(const IceString &Filename,
+                                    std::error_code &EC) {
+  if (Filename == "-") {
     return std::unique_ptr<Ostream>(new llvm::raw_os_ostream(std::cout));
+  } else {
+    return std::unique_ptr<Ostream>(
+        new llvm::raw_fd_ostream(Filename, EC, llvm::sys::fs::F_None));
   }
 }
 
@@ -55,7 +55,11 @@ void CLCompileServer::run() {
   ClFlags::getParsedClFlags(Flags);
   ClFlags::getParsedClFlagsExtra(ExtraFlags);
 
-  std::unique_ptr<Ostream> Ls = getStream(ExtraFlags.getLogFilename());
+  std::error_code EC;
+  std::unique_ptr<Ostream> Ls = makeStream(ExtraFlags.getLogFilename(), EC);
+  if (EC) {
+    llvm::report_fatal_error("Unable to open log file");
+  }
   Ls->SetUnbuffered();
   std::unique_ptr<Ostream> Os;
   std::unique_ptr<ELFStreamer> ELFStr;
@@ -65,7 +69,6 @@ void CLCompileServer::run() {
       *Ls << "Error: writing binary ELF to stdout is unsupported\n";
       return transferErrorCode(getReturnValue(ExtraFlags, Ice::EC_Args));
     }
-    std::error_code EC;
     std::unique_ptr<llvm::raw_fd_ostream> FdOs(new llvm::raw_fd_ostream(
         ExtraFlags.getOutputFilename(), EC, llvm::sys::fs::F_None));
     if (EC) {
@@ -81,7 +84,12 @@ void CLCompileServer::run() {
   } break;
   case FT_Asm:
   case FT_Iasm: {
-    Os = getStream(ExtraFlags.getOutputFilename());
+    Os = makeStream(ExtraFlags.getOutputFilename(), EC);
+    if (EC) {
+      *Ls << "Failed to open output file: " << ExtraFlags.getOutputFilename()
+          << ":\n" << EC.message() << "\n";
+      return transferErrorCode(getReturnValue(ExtraFlags, Ice::EC_Args));
+    }
     Os->SetUnbuffered();
   } break;
   }
@@ -96,8 +104,8 @@ void CLCompileServer::run() {
     return transferErrorCode(getReturnValue(ExtraFlags, Ice::EC_Bitcode));
   }
 
-  Ctx.reset(new GlobalContext(Ls.get(), Os.get(), Ls.get(), ELFStr.get(),
-                              Flags));
+  Ctx.reset(
+      new GlobalContext(Ls.get(), Os.get(), Ls.get(), ELFStr.get(), Flags));
   if (Ctx->getFlags().getNumTranslationThreads() != 0) {
     std::thread CompileThread([this, &ExtraFlags, &InputStream]() {
       Ctx->initParserThread();
index a1fd133..9fb997c 100644 (file)
@@ -420,8 +420,8 @@ private:
   // StrLock is a global lock on the dump and emit output streams.
   typedef std::mutex StrLockType;
   StrLockType StrLock;
-  Ostream *StrDump; // Stream for dumping / diagnostics
-  Ostream *StrEmit; // Stream for code emission
+  Ostream *StrDump;  // Stream for dumping / diagnostics
+  Ostream *StrEmit;  // Stream for code emission
   Ostream *StrError; // Stream for logging errors.
 
   ICE_CACHELINE_BOUNDARY;