Replaced TIntermLoop::testFirst with TIntermLoop::loopType to clearly indicate which type of loop it is. In some cases it is not possble to differentiate between a for-loop and while-loop.
BUG=48
Review URL: http://codereview.appspot.com/3123041

git-svn-id: https://angleproject.googlecode.com/svn/trunk@482 736b8ea6-26fd-11df-bfd4-992fa37f6226
diff --git a/src/compiler/Intermediate.cpp b/src/compiler/Intermediate.cpp
index edb3460..4591cfb 100644
--- a/src/compiler/Intermediate.cpp
+++ b/src/compiler/Intermediate.cpp
@@ -603,9 +603,9 @@
 //
 // Create loop nodes.
 //
-TIntermNode* TIntermediate::addLoop(TIntermNode *init, TIntermNode* body, TIntermTyped* test, TIntermTyped* terminal, bool testFirst, TSourceLoc line)
+TIntermNode* TIntermediate::addLoop(TLoopType type, TIntermNode* init, TIntermTyped* cond, TIntermTyped* expr, TIntermNode* body, TSourceLoc line)
 {
-    TIntermNode* node = new TIntermLoop(init, body, test, terminal, testFirst);
+    TIntermNode* node = new TIntermLoop(type, init, cond, expr, body);
     node->setLine(line);
 
     return node;
diff --git a/src/compiler/OutputGLSL.cpp b/src/compiler/OutputGLSL.cpp
index d2a325c..23476f2 100644
--- a/src/compiler/OutputGLSL.cpp
+++ b/src/compiler/OutputGLSL.cpp
@@ -612,23 +612,32 @@
 
     incrementDepth();
     // Loop header.
-    if (node->testFirst())  // for loop
+    TLoopType loopType = node->getType();
+    if (loopType == ELoopFor)  // for loop
     {
         out << "for (";
         if (node->getInit())
             node->getInit()->traverse(this);
         out << "; ";
 
-        if (node->getTest())
-            node->getTest()->traverse(this);
+        if (node->getCondition())
+            node->getCondition()->traverse(this);
         out << "; ";
 
-        if (node->getTerminal())
-            node->getTerminal()->traverse(this);
+        if (node->getExpression())
+            node->getExpression()->traverse(this);
+        out << ")\n";
+    }
+    else if (loopType == ELoopWhile)  // while loop
+    {
+        out << "while (";
+        ASSERT(node->getCondition() != NULL);
+        node->getCondition()->traverse(this);
         out << ")\n";
     }
     else  // do-while loop
     {
+        ASSERT(loopType == ELoopDoWhile);
         out << "do\n";
     }
 
@@ -636,11 +645,11 @@
     visitCodeBlock(node->getBody());
 
     // Loop footer.
-    if (!node->testFirst())  // while loop
+    if (loopType == ELoopDoWhile)  // do-while loop
     {
         out << "while (";
-        ASSERT(node->getTest() != NULL);
-        node->getTest()->traverse(this);
+        ASSERT(node->getCondition() != NULL);
+        node->getCondition()->traverse(this);
         out << ");\n";
     }
     decrementDepth();
diff --git a/src/compiler/OutputHLSL.cpp b/src/compiler/OutputHLSL.cpp
index 77ea944..aa51ba1 100644
--- a/src/compiler/OutputHLSL.cpp
+++ b/src/compiler/OutputHLSL.cpp
@@ -1425,7 +1425,7 @@
 
     TInfoSinkBase &out = mBody;
 
-    if (!node->testFirst())
+    if (node->getType() == ELoopDoWhile)
     {
         out << "do\n"
                "{\n";
@@ -1437,14 +1437,14 @@
             mUnfoldSelect->traverse(node->getInit());
         }
         
-        if (node->getTest())
+        if (node->getCondition())
         {
-            mUnfoldSelect->traverse(node->getTest());
+            mUnfoldSelect->traverse(node->getCondition());
         }
         
-        if (node->getTerminal())
+        if (node->getExpression())
         {
-            mUnfoldSelect->traverse(node->getTerminal());
+            mUnfoldSelect->traverse(node->getExpression());
         }
 
         out << "for(";
@@ -1456,16 +1456,16 @@
 
         out << "; ";
 
-        if (node->getTest())
+        if (node->getCondition())
         {
-            node->getTest()->traverse(this);
+            node->getCondition()->traverse(this);
         }
 
         out << "; ";
 
-        if (node->getTerminal())
+        if (node->getExpression())
         {
-            node->getTerminal()->traverse(this);
+            node->getExpression()->traverse(this);
         }
 
         out << ")\n"
@@ -1479,11 +1479,11 @@
 
     out << "}\n";
 
-    if (!node->testFirst())
+    if (node->getType() == ELoopDoWhile)
     {
         out << "while(\n";
 
-        node->getTest()->traverse(this);
+        node->getCondition()->traverse(this);
 
         out << ")";
     }
@@ -1598,9 +1598,9 @@
     }
 
     // Parse comparator and limit value
-    if (index != NULL && node->getTest())
+    if (index != NULL && node->getCondition())
     {
-        TIntermBinary *test = node->getTest()->getAsBinaryNode();
+        TIntermBinary *test = node->getCondition()->getAsBinaryNode();
         
         if (test && test->getLeft()->getAsSymbolNode()->getId() == index->getId())
         {
@@ -1618,10 +1618,10 @@
     }
 
     // Parse increment
-    if (index != NULL && comparator != EOpNull && node->getTerminal())
+    if (index != NULL && comparator != EOpNull && node->getExpression())
     {
-        TIntermBinary *binaryTerminal = node->getTerminal()->getAsBinaryNode();
-        TIntermUnary *unaryTerminal = node->getTerminal()->getAsUnaryNode();
+        TIntermBinary *binaryTerminal = node->getExpression()->getAsBinaryNode();
+        TIntermUnary *unaryTerminal = node->getExpression()->getAsUnaryNode();
         
         if (binaryTerminal)
         {
diff --git a/src/compiler/glslang.y b/src/compiler/glslang.y
index 208c2d7..5eae4b5 100644
--- a/src/compiler/glslang.y
+++ b/src/compiler/glslang.y
@@ -1854,19 +1854,19 @@
 iteration_statement
     : WHILE LEFT_PAREN { context->symbolTable.push(); ++context->loopNestingLevel; } condition RIGHT_PAREN statement_no_new_scope {
         context->symbolTable.pop();
-        $$ = context->intermediate.addLoop(0, $6, $4, 0, true, $1.line);
+        $$ = context->intermediate.addLoop(ELoopWhile, 0, $4, 0, $6, $1.line);
         --context->loopNestingLevel;
     }
     | DO { ++context->loopNestingLevel; } statement WHILE LEFT_PAREN expression RIGHT_PAREN SEMICOLON {
         if (context->boolErrorCheck($8.line, $6))
             context->recover();
 
-        $$ = context->intermediate.addLoop(0, $3, $6, 0, false, $4.line);
+        $$ = context->intermediate.addLoop(ELoopDoWhile, 0, $6, 0, $3, $4.line);
         --context->loopNestingLevel;
     }
     | FOR LEFT_PAREN { context->symbolTable.push(); ++context->loopNestingLevel; } for_init_statement for_rest_statement RIGHT_PAREN statement_no_new_scope {
         context->symbolTable.pop();
-        $$ = context->intermediate.addLoop($4, $7, reinterpret_cast<TIntermTyped*>($5.node1), reinterpret_cast<TIntermTyped*>($5.node2), true, $1.line);
+        $$ = context->intermediate.addLoop(ELoopFor, $4, reinterpret_cast<TIntermTyped*>($5.node1), reinterpret_cast<TIntermTyped*>($5.node2), $7, $1.line);
         --context->loopNestingLevel;
     }
     ;
diff --git a/src/compiler/glslang_tab.cpp b/src/compiler/glslang_tab.cpp
index f11df85..d00c7a3 100644
--- a/src/compiler/glslang_tab.cpp
+++ b/src/compiler/glslang_tab.cpp
@@ -4211,7 +4211,7 @@
 
     {
         context->symbolTable.pop();
-        (yyval.interm.intermNode) = context->intermediate.addLoop(0, (yyvsp[(6) - (6)].interm.intermNode), (yyvsp[(4) - (6)].interm.intermTypedNode), 0, true, (yyvsp[(1) - (6)].lex).line);
+        (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopWhile, 0, (yyvsp[(4) - (6)].interm.intermTypedNode), 0, (yyvsp[(6) - (6)].interm.intermNode), (yyvsp[(1) - (6)].lex).line);
         --context->loopNestingLevel;
     ;}
     break;
@@ -4227,7 +4227,7 @@
         if (context->boolErrorCheck((yyvsp[(8) - (8)].lex).line, (yyvsp[(6) - (8)].interm.intermTypedNode)))
             context->recover();
 
-        (yyval.interm.intermNode) = context->intermediate.addLoop(0, (yyvsp[(3) - (8)].interm.intermNode), (yyvsp[(6) - (8)].interm.intermTypedNode), 0, false, (yyvsp[(4) - (8)].lex).line);
+        (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopDoWhile, 0, (yyvsp[(6) - (8)].interm.intermTypedNode), 0, (yyvsp[(3) - (8)].interm.intermNode), (yyvsp[(4) - (8)].lex).line);
         --context->loopNestingLevel;
     ;}
     break;
@@ -4241,7 +4241,7 @@
 
     {
         context->symbolTable.pop();
-        (yyval.interm.intermNode) = context->intermediate.addLoop((yyvsp[(4) - (7)].interm.intermNode), (yyvsp[(7) - (7)].interm.intermNode), reinterpret_cast<TIntermTyped*>((yyvsp[(5) - (7)].interm.nodePair).node1), reinterpret_cast<TIntermTyped*>((yyvsp[(5) - (7)].interm.nodePair).node2), true, (yyvsp[(1) - (7)].lex).line);
+        (yyval.interm.intermNode) = context->intermediate.addLoop(ELoopFor, (yyvsp[(4) - (7)].interm.intermNode), reinterpret_cast<TIntermTyped*>((yyvsp[(5) - (7)].interm.nodePair).node1), reinterpret_cast<TIntermTyped*>((yyvsp[(5) - (7)].interm.nodePair).node2), (yyvsp[(7) - (7)].interm.intermNode), (yyvsp[(1) - (7)].lex).line);
         --context->loopNestingLevel;
     ;}
     break;
diff --git a/src/compiler/intermOut.cpp b/src/compiler/intermOut.cpp
index 7d49828..798a69a 100644
--- a/src/compiler/intermOut.cpp
+++ b/src/compiler/intermOut.cpp
@@ -345,16 +345,16 @@
     OutputTreeText(out, node, depth);
 
     out << "Loop with condition ";
-    if (! node->testFirst())
+    if (node->getType() == ELoopDoWhile)
         out << "not ";
     out << "tested first\n";
 
     ++depth;
 
     OutputTreeText(sink, node, depth);
-    if (node->getTest()) {
+    if (node->getCondition()) {
         out << "Loop Condition\n";
-        node->getTest()->traverse(this);
+        node->getCondition()->traverse(this);
     } else
         out << "No loop condition\n";
 
@@ -365,10 +365,10 @@
     } else
         out << "No loop body\n";
 
-    if (node->getTerminal()) {
+    if (node->getExpression()) {
         OutputTreeText(sink, node, depth);
         out << "Loop Terminal Expression\n";
-        node->getTerminal()->traverse(this);
+        node->getExpression()->traverse(this);
     }
 
     --depth;
diff --git a/src/compiler/intermediate.h b/src/compiler/intermediate.h
index dd269e1..1b08d73 100644
--- a/src/compiler/intermediate.h
+++ b/src/compiler/intermediate.h
@@ -262,30 +262,38 @@
 //
 // Handle for, do-while, and while loops.
 //
+enum TLoopType {
+    ELoopFor,
+    ELoopWhile,
+    ELoopDoWhile,
+};
+
 class TIntermLoop : public TIntermNode {
 public:
-    TIntermLoop(TIntermNode *init, TIntermNode* aBody, TIntermTyped* aTest, TIntermTyped* aTerminal, bool testFirst) : 
-            init(init),
-            body(aBody),
-            test(aTest),
-            terminal(aTerminal),
-            first(testFirst) { }
+    TIntermLoop(TLoopType aType,
+                TIntermNode *aInit, TIntermTyped* aCond, TIntermTyped* aExpr,
+                TIntermNode* aBody) :
+            type(aType),
+            init(aInit),
+            cond(aCond),
+            expr(aExpr),
+            body(aBody) { }
 
     virtual TIntermLoop* getAsLoopNode() { return this; }
     virtual void traverse(TIntermTraverser*);
 
-    TIntermNode *getInit() { return init; }
-    TIntermNode *getBody() { return body; }
-    TIntermTyped *getTest() { return test; }
-    TIntermTyped *getTerminal() { return terminal; }
-    bool testFirst() { return first; }
+    TLoopType getType() const { return type; }
+    TIntermNode* getInit() { return init; }
+    TIntermTyped* getCondition() { return cond; }
+    TIntermTyped* getExpression() { return expr; }
+    TIntermNode* getBody() { return body; }
 
 protected:
-    TIntermNode *init;
-    TIntermNode *body;       // code to loop over
-    TIntermTyped *test;      // exit condition associated with loop, could be 0 for 'for' loops
-    TIntermTyped *terminal;  // exists for for-loops
-    bool first;              // true for while and for, not for do-while
+    TLoopType type;
+    TIntermNode* init;  // for-loop initialization
+    TIntermTyped* cond; // loop exit condition
+    TIntermTyped* expr; // for-loop expression
+    TIntermNode* body;  // loop body
 };
 
 //
diff --git a/src/compiler/localintermediate.h b/src/compiler/localintermediate.h
index 4ea6ff5..56890bd 100644
--- a/src/compiler/localintermediate.h
+++ b/src/compiler/localintermediate.h
@@ -40,7 +40,7 @@
     TIntermConstantUnion* addConstantUnion(ConstantUnion*, const TType&, TSourceLoc);
     TIntermTyped* promoteConstantUnion(TBasicType, TIntermConstantUnion*) ;
     bool parseConstTree(TSourceLoc, TIntermNode*, ConstantUnion*, TOperator, TSymbolTable&, TType, bool singleConstantParam = false);        
-    TIntermNode* addLoop(TIntermNode*, TIntermNode*, TIntermTyped*, TIntermTyped*, bool testFirst, TSourceLoc);
+    TIntermNode* addLoop(TLoopType, TIntermNode*, TIntermTyped*, TIntermTyped*, TIntermNode*, TSourceLoc);
     TIntermBranch* addBranch(TOperator, TSourceLoc);
     TIntermBranch* addBranch(TOperator, TIntermTyped*, TSourceLoc);
     TIntermTyped* addSwizzle(TVectorFields&, TSourceLoc);