Unify Diagnostics interface

Use the same kind of interface for reporting preprocessor errors as
for reporting regular compiler errors, and make global errors like
having too many uniforms also go through Diagnostics. Also don't
create std::string objects unnecessarily.

Includes cleanups of some dead code related to reporting errors.

BUG=angleproject:1670
TEST=angle_unittests

Change-Id: I3ee794d32ddeec1826bdf1b76b558f35259f82c0
Reviewed-on: https://chromium-review.googlesource.com/421527
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
diff --git a/src/compiler/translator/CallDAG.cpp b/src/compiler/translator/CallDAG.cpp
index 3ea0fa8..45273a0 100644
--- a/src/compiler/translator/CallDAG.cpp
+++ b/src/compiler/translator/CallDAG.cpp
@@ -9,7 +9,7 @@
 // order.
 
 #include "compiler/translator/CallDAG.h"
-#include "compiler/translator/InfoSink.h"
+#include "compiler/translator/Diagnostics.h"
 
 namespace sh
 {
@@ -19,9 +19,9 @@
 class CallDAG::CallDAGCreator : public TIntermTraverser
 {
   public:
-    CallDAGCreator(TInfoSinkBase *info)
+    CallDAGCreator(TDiagnostics *diagnostics)
         : TIntermTraverser(true, false, true),
-          mCreationInfo(info),
+          mDiagnostics(diagnostics),
           mCurrentFunction(nullptr),
           mCurrentIndex(0)
     {
@@ -38,7 +38,6 @@
                 InitResult result = assignIndicesInternal(&it.second);
                 if (result != INITDAG_SUCCESS)
                 {
-                    *mCreationInfo << "\n";
                     return result;
                 }
             }
@@ -190,6 +189,8 @@
 
         InitResult result = INITDAG_SUCCESS;
 
+        std::stringstream errorStream;
+
         while (!functionsToProcess.empty())
         {
             CreatorFunctionData *function = functionsToProcess.back();
@@ -206,8 +207,8 @@
 
             if (!function->node)
             {
-                *mCreationInfo << "Undefined function '" << function->name
-                               << ")' used in the following call chain:";
+                errorStream << "Undefined function '" << function->name
+                            << ")' used in the following call chain:";
                 result = INITDAG_UNDEFINED;
                 break;
             }
@@ -228,7 +229,7 @@
                 // in the chain printed in the info log.
                 if (callee->visiting)
                 {
-                    *mCreationInfo << "Recursive function call in the following call chain:";
+                    errorStream << "Recursive function call in the following call chain:";
                     result = INITDAG_RECURSION;
                     break;
                 }
@@ -250,18 +251,23 @@
                 {
                     if (!first)
                     {
-                        *mCreationInfo << " -> ";
+                        errorStream << " -> ";
                     }
-                    *mCreationInfo << function->name << ")";
+                    errorStream << function->name << ")";
                     first = false;
                 }
             }
+            if (mDiagnostics)
+            {
+                std::string errorStr = errorStream.str();
+                mDiagnostics->globalError(errorStr.c_str());
+            }
         }
 
         return result;
     }
 
-    TInfoSinkBase *mCreationInfo;
+    TDiagnostics *mDiagnostics;
 
     std::map<TString, CreatorFunctionData> mFunctions;
     CreatorFunctionData *mCurrentFunction;
@@ -318,11 +324,9 @@
     mFunctionIdToIndex.clear();
 }
 
-CallDAG::InitResult CallDAG::init(TIntermNode *root, TInfoSinkBase *info)
+CallDAG::InitResult CallDAG::init(TIntermNode *root, TDiagnostics *diagnostics)
 {
-    ASSERT(info);
-
-    CallDAGCreator creator(info);
+    CallDAGCreator creator(diagnostics);
 
     // Creates the mapping of functions to callees
     root->traverse(&creator);