Don't try to apply ForLoopUnroll to loops it can't handle

ForLoopUnroll should only mark loops that fit the limitations in ESSL
1.00 Appendix A.

BUG=angleproject:1253
TEST=angle_unittests, WebGL conformance tests

Change-Id: I00b0a7d29cd42efea9611d020aa1f873ac04773f
Reviewed-on: https://chromium-review.googlesource.com/317551
Tested-by: Olli Etuaho <oetuaho@nvidia.com>
Reviewed-by: Zhenyao Mo <zmo@chromium.org>
diff --git a/src/compiler/translator/ValidateLimitations.cpp b/src/compiler/translator/ValidateLimitations.cpp
index 4a84fb6..918f125 100644
--- a/src/compiler/translator/ValidateLimitations.cpp
+++ b/src/compiler/translator/ValidateLimitations.cpp
@@ -53,15 +53,37 @@
 
 }  // namespace anonymous
 
-ValidateLimitations::ValidateLimitations(sh::GLenum shaderType,
-                                         TInfoSinkBase &sink)
+ValidateLimitations::ValidateLimitations(sh::GLenum shaderType, TInfoSinkBase *sink)
     : TIntermTraverser(true, false, false),
       mShaderType(shaderType),
       mSink(sink),
-      mNumErrors(0)
+      mNumErrors(0),
+      mValidateIndexing(true),
+      mValidateInnerLoops(true)
 {
 }
 
+// static
+bool ValidateLimitations::IsLimitedForLoop(TIntermLoop *loop)
+{
+    // The shader type doesn't matter in this case.
+    ValidateLimitations validate(GL_FRAGMENT_SHADER, nullptr);
+    validate.mValidateIndexing   = false;
+    validate.mValidateInnerLoops = false;
+    if (!validate.validateLoopType(loop))
+        return false;
+    if (!validate.validateForLoopHeader(loop))
+        return false;
+    TIntermNode *body = loop->getBody();
+    if (body != nullptr)
+    {
+        validate.mLoopStack.push(loop);
+        body->traverse(&validate);
+        validate.mLoopStack.pop();
+    }
+    return (validate.mNumErrors == 0);
+}
+
 bool ValidateLimitations::visitBinary(Visit, TIntermBinary *node)
 {
     // Check if loop index is modified in the loop body.
@@ -72,10 +94,11 @@
     {
       case EOpIndexDirect:
       case EOpIndexIndirect:
-        validateIndexing(node);
-        break;
+          if (mValidateIndexing)
+              validateIndexing(node);
+          break;
       default:
-        break;
+          break;
     }
     return true;
 }
@@ -102,6 +125,9 @@
 
 bool ValidateLimitations::visitLoop(Visit, TIntermLoop *node)
 {
+    if (!mValidateInnerLoops)
+        return true;
+
     if (!validateLoopType(node))
         return false;
 
@@ -123,9 +149,12 @@
 void ValidateLimitations::error(TSourceLoc loc,
                                 const char *reason, const char *token)
 {
-    mSink.prefix(EPrefixError);
-    mSink.location(loc);
-    mSink << "'" << token << "' : " << reason << "\n";
+    if (mSink)
+    {
+        mSink->prefix(EPrefixError);
+        mSink->location(loc);
+        (*mSink) << "'" << token << "' : " << reason << "\n";
+    }
     ++mNumErrors;
 }