First attempt to capture parser/translation errors in browser.

Adds a notion of an (optional) error stream to the existing
log and emit streams. If not specified, the log stream is used.
Error messages in parser/translation are sent to this new error
stream.

In the browser compiler server, a separate error (string) stream is
created to capture errors. Method onEndCallBack returns the contents
of the error stream (if non-empty) instead of a generic error message.

BUG= https://code.google.com/p/nativeclient/issues/detail?id=4138
R=jvoung@chromium.org

Review URL: https://codereview.chromium.org/1052833003
diff --git a/src/IceGlobalContext.cpp b/src/IceGlobalContext.cpp
index 1c9e3c4..8de57f3 100644
--- a/src/IceGlobalContext.cpp
+++ b/src/IceGlobalContext.cpp
@@ -213,14 +213,18 @@
   Str << "\n";
 }
 
-GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit,
+GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError,
                              ELFStreamer *ELFStr, const ClFlags &Flags)
     : ConstPool(new ConstantPool()), ErrorStatus(), StrDump(OsDump),
-      StrEmit(OsEmit), Flags(Flags), RNG(Flags.getRandomSeed()), ObjectWriter(),
+      StrEmit(OsEmit), StrError(OsError), Flags(Flags),
+      RNG(Flags.getRandomSeed()), ObjectWriter(),
       OptQ(/*Sequential=*/Flags.isSequential(),
            /*MaxSize=*/Flags.getNumTranslationThreads()),
       // EmitQ is allowed unlimited size.
       EmitQ(/*Sequential=*/Flags.isSequential()) {
+  assert(OsDump && "OsDump is not defined for GlobalContext");
+  assert(OsEmit && "OsEmit is not defined for GlobalContext");
+  assert(OsError && "OsError is not defined for GlobalContext");
   // Make sure thread_local fields are properly initialized before any
   // accesses are made.  Do this here instead of at the start of
   // main() so that all clients (e.g. unit tests) can benefit for
@@ -278,8 +282,8 @@
     if (Func->hasError()) {
       getErrorStatus()->assign(EC_Translation);
       OstreamLocker L(this);
-      getStrDump() << "ICE translation error: " << Func->getFunctionName()
-                   << ": " << Func->getError() << "\n";
+      getStrError() << "ICE translation error: " << Func->getFunctionName()
+                    << ": " << Func->getError() << "\n";
       Item = new EmitterWorkItem(Func->getSequenceNumber());
     } else {
       Func->getAssembler<>()->setInternal(Func->getInternal());