Unroll for-loop if sampler array uses loop index as its index.

If inside a for-loop, sampler array index is the loop index, Mac cg compiler will crash.  This CL unroll the loop in such situation.  The behavior is:
1) If the for-loop index is a float, we reject the shader.
2) If it is an integer, we unroll the for-loop.

Things that should be done in the future are:
1) Add line number macros.
2) Add a limit to unroll iteration count.

anglebug=94
Review URL: http://codereview.appspot.com/4331048

git-svn-id: https://angleproject.googlecode.com/svn/trunk@606 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/compiler/OutputGLSL.cpp b/src/compiler/OutputGLSL.cpp
index 23476f2..3224dfd 100644
--- a/src/compiler/OutputGLSL.cpp
+++ b/src/compiler/OutputGLSL.cpp
@@ -1,5 +1,5 @@
 //
-// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
+// Copyright (c) 2002-2011 The ANGLE Project Authors. All rights reserved.
 // Use of this source code is governed by a BSD-style license that can be
 // found in the LICENSE file.
 //
@@ -195,7 +195,10 @@
 void TOutputGLSL::visitSymbol(TIntermSymbol* node)
 {
     TInfoSinkBase& out = objSink();
-    out << node->getSymbol();
+    if (mLoopUnroll.NeedsToReplaceSymbolWithValue(node))
+        out << mLoopUnroll.GetLoopIndexValue(node);
+    else
+        out << node->getSymbol();
 
     if (mDeclaringVariables && node->getType().isArray())
         out << arrayBrackets(node->getType());
@@ -615,18 +618,20 @@
     TLoopType loopType = node->getType();
     if (loopType == ELoopFor)  // for loop
     {
-        out << "for (";
-        if (node->getInit())
-            node->getInit()->traverse(this);
-        out << "; ";
+        if (!node->getUnrollFlag()) {
+            out << "for (";
+            if (node->getInit())
+                node->getInit()->traverse(this);
+            out << "; ";
 
-        if (node->getCondition())
-            node->getCondition()->traverse(this);
-        out << "; ";
+            if (node->getCondition())
+                node->getCondition()->traverse(this);
+            out << "; ";
 
-        if (node->getExpression())
-            node->getExpression()->traverse(this);
-        out << ")\n";
+            if (node->getExpression())
+                node->getExpression()->traverse(this);
+            out << ")\n";
+        }
     }
     else if (loopType == ELoopWhile)  // while loop
     {
@@ -642,7 +647,22 @@
     }
 
     // Loop body.
-    visitCodeBlock(node->getBody());
+    if (node->getUnrollFlag())
+    {
+        TLoopIndexInfo indexInfo;
+        mLoopUnroll.FillLoopIndexInfo(node, indexInfo);
+        mLoopUnroll.Push(indexInfo);
+        while (mLoopUnroll.SatisfiesLoopCondition())
+        {
+            visitCodeBlock(node->getBody());
+            mLoopUnroll.Step();
+        }
+        mLoopUnroll.Pop();
+    }
+    else
+    {
+        visitCodeBlock(node->getBody());
+    }
 
     // Loop footer.
     if (loopType == ELoopDoWhile)  // do-while loop