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);