Clean up ValidateOutputs

Remove the validateOutputs method from Compiler and replace it with a
static method alongside the traverser. This encapsulates the
ValidateOutputs implementation better.

TEST=angle_unittests
BUG=angleproject:2068

Change-Id: I1788cb9726db41ca35fd0e746f8d48ced7fee74f
Reviewed-on: https://chromium-review.googlesource.com/535477
Commit-Queue: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Jamie Madill <jmadill@chromium.org>
diff --git a/src/compiler/translator/Compiler.cpp b/src/compiler/translator/Compiler.cpp
index 46da806..909bb96 100644
--- a/src/compiler/translator/Compiler.cpp
+++ b/src/compiler/translator/Compiler.cpp
@@ -366,7 +366,10 @@
             PruneEmptyDeclarations(root);
 
         if (success && shaderVersion >= 300 && shaderType == GL_FRAGMENT_SHADER)
-            success = validateOutputs(root);
+        {
+            success = ValidateOutputs(root, getExtensionBehavior(), compileResources.MaxDrawBuffers,
+                                      &mDiagnostics);
+        }
 
         if (success && shouldRunLoopAndIndexingValidation(compileOptions))
             success =
@@ -874,14 +877,6 @@
     return true;
 }
 
-bool TCompiler::validateOutputs(TIntermNode *root)
-{
-    ValidateOutputs validateOutputs(getExtensionBehavior(), compileResources.MaxDrawBuffers);
-    root->traverse(&validateOutputs);
-    validateOutputs.validate(&mDiagnostics);
-    return (mDiagnostics.numErrors() == 0);
-}
-
 bool TCompiler::limitExpressionComplexity(TIntermBlock *root)
 {
     TMaxDepthTraverser traverser(maxExpressionComplexity + 1);
diff --git a/src/compiler/translator/Compiler.h b/src/compiler/translator/Compiler.h
index e66f51a..c09a0c3 100644
--- a/src/compiler/translator/Compiler.h
+++ b/src/compiler/translator/Compiler.h
@@ -133,8 +133,6 @@
     void setResourceString();
     // Return false if the call depth is exceeded.
     bool checkCallDepth();
-    // Returns true if a program has no conflicting or missing fragment outputs
-    bool validateOutputs(TIntermNode *root);
     // Add emulated functions to the built-in function emulator.
     virtual void initBuiltInFunctionEmulator(BuiltInFunctionEmulator *emu,
                                              ShCompileOptions compileOptions){};
diff --git a/src/compiler/translator/ValidateOutputs.cpp b/src/compiler/translator/ValidateOutputs.cpp
index 27ab814..36e339b 100644
--- a/src/compiler/translator/ValidateOutputs.cpp
+++ b/src/compiler/translator/ValidateOutputs.cpp
@@ -3,9 +3,16 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
+// ValidateOutputs validates fragment shader outputs. It checks for conflicting locations,
+// out-of-range locations, that locations are specified when using multiple outputs, and YUV output
+// validity.
 
 #include "compiler/translator/ValidateOutputs.h"
+
+#include <set>
+
 #include "compiler/translator/InfoSink.h"
+#include "compiler/translator/IntermNode.h"
 #include "compiler/translator/ParseContext.h"
 
 namespace sh
@@ -18,9 +25,29 @@
     diagnostics->error(symbol.getLine(), reason, symbol.getSymbol().c_str());
 }
 
-}  // namespace
+class ValidateOutputsTraverser : public TIntermTraverser
+{
+  public:
+    ValidateOutputsTraverser(const TExtensionBehavior &extBehavior, int maxDrawBuffers);
 
-ValidateOutputs::ValidateOutputs(const TExtensionBehavior &extBehavior, int maxDrawBuffers)
+    void validate(TDiagnostics *diagnostics) const;
+
+    void visitSymbol(TIntermSymbol *) override;
+
+  private:
+    int mMaxDrawBuffers;
+    bool mAllowUnspecifiedOutputLocationResolution;
+    bool mUsesFragDepth;
+
+    typedef std::vector<TIntermSymbol *> OutputVector;
+    OutputVector mOutputs;
+    OutputVector mUnspecifiedLocationOutputs;
+    OutputVector mYuvOutputs;
+    std::set<std::string> mVisitedSymbols;
+};
+
+ValidateOutputsTraverser::ValidateOutputsTraverser(const TExtensionBehavior &extBehavior,
+                                                   int maxDrawBuffers)
     : TIntermTraverser(true, false, false),
       mMaxDrawBuffers(maxDrawBuffers),
       mAllowUnspecifiedOutputLocationResolution(
@@ -29,7 +56,7 @@
 {
 }
 
-void ValidateOutputs::visitSymbol(TIntermSymbol *symbol)
+void ValidateOutputsTraverser::visitSymbol(TIntermSymbol *symbol)
 {
     TString name         = symbol->getSymbol();
     TQualifier qualifier = symbol->getQualifier();
@@ -60,7 +87,7 @@
     }
 }
 
-void ValidateOutputs::validate(TDiagnostics *diagnostics) const
+void ValidateOutputsTraverser::validate(TDiagnostics *diagnostics) const
 {
     ASSERT(diagnostics);
     OutputVector validOutputs(mMaxDrawBuffers);
@@ -128,4 +155,18 @@
     }
 }
 
+}  // anonymous namespace
+
+bool ValidateOutputs(TIntermBlock *root,
+                     const TExtensionBehavior &extBehavior,
+                     int maxDrawBuffers,
+                     TDiagnostics *diagnostics)
+{
+    ValidateOutputsTraverser validateOutputs(extBehavior, maxDrawBuffers);
+    root->traverse(&validateOutputs);
+    int numErrorsBefore = diagnostics->numErrors();
+    validateOutputs.validate(diagnostics);
+    return (diagnostics->numErrors() == numErrorsBefore);
+}
+
 }  // namespace sh
diff --git a/src/compiler/translator/ValidateOutputs.h b/src/compiler/translator/ValidateOutputs.h
index c9282d2..e41ccd9 100644
--- a/src/compiler/translator/ValidateOutputs.h
+++ b/src/compiler/translator/ValidateOutputs.h
@@ -3,40 +3,27 @@
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
+// ValidateOutputs validates fragment shader outputs. It checks for conflicting locations,
+// out-of-range locations, that locations are specified when using multiple outputs, and YUV output
+// validity.
+//
 
 #ifndef COMPILER_TRANSLATOR_VALIDATEOUTPUTS_H_
 #define COMPILER_TRANSLATOR_VALIDATEOUTPUTS_H_
 
 #include "compiler/translator/ExtensionBehavior.h"
-#include "compiler/translator/IntermNode.h"
-
-#include <set>
 
 namespace sh
 {
 
-class TInfoSinkBase;
+class TIntermBlock;
+class TDiagnostics;
 
-class ValidateOutputs : public TIntermTraverser
-{
-  public:
-    ValidateOutputs(const TExtensionBehavior &extBehavior, int maxDrawBuffers);
-
-    void validate(TDiagnostics *diagnostics) const;
-
-    void visitSymbol(TIntermSymbol *) override;
-
-  private:
-    int mMaxDrawBuffers;
-    bool mAllowUnspecifiedOutputLocationResolution;
-    bool mUsesFragDepth;
-
-    typedef std::vector<TIntermSymbol *> OutputVector;
-    OutputVector mOutputs;
-    OutputVector mUnspecifiedLocationOutputs;
-    OutputVector mYuvOutputs;
-    std::set<std::string> mVisitedSymbols;
-};
+// Returns true if the shader has no conflicting or otherwise erroneous fragment outputs.
+bool ValidateOutputs(TIntermBlock *root,
+                     const TExtensionBehavior &extBehavior,
+                     int maxDrawBuffers,
+                     TDiagnostics *diagnostics);
 
 }  // namespace sh