Commit d88b7736 by alokp@chromium.org

Do not write extraneous semi-colons - some glsl compilers are do not like that…

Do not write extraneous semi-colons - some glsl compilers are do not like that even though it is so easy to ignore. Review URL: http://codereview.appspot.com/1301041 git-svn-id: https://angleproject.googlecode.com/svn/trunk@317 736b8ea6-26fd-11df-bfd4-992fa37f6226
parent 90033b9e
......@@ -46,12 +46,30 @@ TString arrayBrackets(const TType& type)
out << "[" << type.getArraySize() << "]";
return TString(out.c_str());
}
bool isSingleStatement(TIntermNode* node) {
const TIntermAggregate* aggregate = node->getAsAggregate();
if (aggregate != NULL)
{
if ((aggregate->getOp() == EOpFunction) ||
(aggregate->getOp() == EOpSequence))
return false;
}
else if (node->getAsSelectionNode() != NULL)
{
return false;
}
else if (node->getAsLoopNode() != NULL)
{
return false;
}
return true;
}
} // namespace
TOutputGLSL::TOutputGLSL(TInfoSinkBase& objSink)
: TIntermTraverser(true, true, true),
mObjSink(objSink),
mScopeSequences(false),
mDeclaringVariables(false)
{
}
......@@ -390,23 +408,17 @@ bool TOutputGLSL::visitSelection(Visit visit, TIntermSelection* node)
{
out << "if (";
node->getCondition()->traverse(this);
out << ") {\n";
out << ")\n";
incrementDepth();
if (node->getTrueBlock())
{
node->getTrueBlock()->traverse(this);
}
out << ";\n}";
visitCodeBlock(node->getTrueBlock());
if (node->getFalseBlock())
{
out << " else {\n";
node->getFalseBlock()->traverse(this);
out << ";\n}";
out << "else\n";
visitCodeBlock(node->getFalseBlock());
}
decrementDepth();
out << "\n";
}
return false;
}
......@@ -417,23 +429,29 @@ bool TOutputGLSL::visitAggregate(Visit visit, TIntermAggregate* node)
TInfoSinkBase& out = objSink();
switch (node->getOp())
{
case EOpSequence:
if (visit == PreVisit)
{
if (mScopeSequences)
out << "{\n";
}
else if (visit == InVisit)
{
out << ";\n";
}
else if (visit == PostVisit)
case EOpSequence: {
// Scope the sequences except when at the global scope.
if (depth > 0) out << "{\n";
incrementDepth();
const TIntermSequence& sequence = node->getSequence();
for (TIntermSequence::const_iterator iter = sequence.begin();
iter != sequence.end(); ++iter)
{
out << ";\n";
if (mScopeSequences)
out << "}\n";
TIntermNode* node = *iter;
ASSERT(node != NULL);
node->traverse(this);
if (isSingleStatement(node))
out << ";\n";
}
decrementDepth();
// Scope the sequences except when at the global scope.
if (depth > 0) out << "}\n";
visitChildren = false;
break;
}
case EOpPrototype: {
// Function declaration.
ASSERT(visit == PreVisit);
......@@ -454,6 +472,7 @@ bool TOutputGLSL::visitAggregate(Visit visit, TIntermAggregate* node)
TString functionName = TFunction::unmangleName(node->getName());
out << returnType << " " << functionName;
incrementDepth();
// Function definition node contains one or two children nodes
// representing function parameters and function body. The latter
// is not present in case of empty function bodies.
......@@ -470,20 +489,8 @@ bool TOutputGLSL::visitAggregate(Visit visit, TIntermAggregate* node)
// Traverse function body.
TIntermAggregate* body = ++seqIter != sequence.end() ?
(*seqIter)->getAsAggregate() : NULL;
if (body != NULL)
{
ASSERT(body->getOp() == EOpSequence);
// Sequences are scoped with {} inside function body so that
// variables are declared in the correct scope.
mScopeSequences = true;
body->traverse(this);
mScopeSequences = false;
}
else
{
// Empty function body.
out << "{}\n";
}
visitCodeBlock(body);
decrementDepth();
// Fully processed; no need to visit children.
visitChildren = false;
......@@ -602,6 +609,7 @@ bool TOutputGLSL::visitLoop(Visit visit, TIntermLoop* node)
{
TInfoSinkBase& out = objSink();
incrementDepth();
// Loop header.
if (node->testFirst()) // for loop
{
......@@ -616,29 +624,25 @@ bool TOutputGLSL::visitLoop(Visit visit, TIntermLoop* node)
if (node->getTerminal())
node->getTerminal()->traverse(this);
out << ") {\n";
out << ")\n";
}
else // do-while loop
{
out << "do {\n";
out << "do\n";
}
// Loop body.
if (node->getBody())
node->getBody()->traverse(this);
visitCodeBlock(node->getBody());
// Loop footer.
if (node->testFirst()) // for loop
{
out << "}\n";
}
else // do-while loop
if (!node->testFirst()) // while loop
{
out << "} while (";
out << "while (";
ASSERT(node->getTest() != NULL);
node->getTest()->traverse(this);
out << ");\n";
}
decrementDepth();
// No need to visit children. They have been already processed in
// this function.
......@@ -660,3 +664,19 @@ bool TOutputGLSL::visitBranch(Visit visit, TIntermBranch* node)
return true;
}
void TOutputGLSL::visitCodeBlock(TIntermNode* node) {
TInfoSinkBase &out = objSink();
if (node != NULL)
{
node->traverse(this);
// Single statements not part of a sequence need to be terminated
// with semi-colon.
if (isSingleStatement(node))
out << ";\n";
}
else
{
out << "{\n}\n"; // Empty code block.
}
}
......@@ -33,9 +33,10 @@ protected:
virtual bool visitLoop(Visit visit, TIntermLoop* node);
virtual bool visitBranch(Visit visit, TIntermBranch* node);
void visitCodeBlock(TIntermNode* node);
private:
TInfoSinkBase& mObjSink;
bool mScopeSequences;
bool mDeclaringVariables;
// Structs are declared as the tree is traversed. This set contains all
......
......@@ -192,6 +192,7 @@ class TIntermConstantUnion;
class TIntermSelection;
class TIntermTyped;
class TIntermSymbol;
class TIntermLoop;
class TInfoSink;
//
......@@ -205,13 +206,14 @@ public:
virtual TSourceLoc getLine() const { return line; }
virtual void setLine(TSourceLoc l) { line = l; }
virtual void traverse(TIntermTraverser*) = 0;
virtual TIntermTyped* getAsTyped() { return 0; }
virtual TIntermConstantUnion* getAsConstantUnion() { return 0; }
virtual TIntermAggregate* getAsAggregate() { return 0; }
virtual TIntermBinary* getAsBinaryNode() { return 0; }
virtual TIntermUnary* getAsUnaryNode() { return 0; }
virtual TIntermTyped* getAsTyped() { return 0; }
virtual TIntermConstantUnion* getAsConstantUnion() { return 0; }
virtual TIntermAggregate* getAsAggregate() { return 0; }
virtual TIntermBinary* getAsBinaryNode() { return 0; }
virtual TIntermUnary* getAsUnaryNode() { return 0; }
virtual TIntermSelection* getAsSelectionNode() { return 0; }
virtual TIntermSymbol* getAsSymbolNode() { return 0; }
virtual TIntermSymbol* getAsSymbolNode() { return 0; }
virtual TIntermLoop* getAsLoopNode() { return 0; }
virtual ~TIntermNode() { }
protected:
TSourceLoc line;
......@@ -264,6 +266,7 @@ public:
test(aTest),
terminal(aTerminal),
first(testFirst) { }
virtual TIntermLoop* getAsLoopNode() { return this; }
virtual void traverse(TIntermTraverser*);
TIntermNode *getInit() { return init; }
TIntermNode *getBody() { return body; }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment