Improvement to the AST traversal infrastructure.
Note: This affects any downstream consumers of glslang's traverser. Let me know if there are any issues. Essentially, you will need to change the functions that were pointed to into overriding base-class members instead. See the examples in this check in. git-svn-id: https://cvs.khronos.org/svn/repos/ogl/trunk/ecosystem/public/sdk/tools/glslang@24740 e7fa87d3-cd2b-0410-9028-fcbf551c1848
This commit is contained in:
parent
4f9aebf659
commit
a9819921b3
8 changed files with 361 additions and 350 deletions
|
|
@ -55,6 +55,17 @@ namespace glslang {
|
|||
class TOutputTraverser : public TIntermTraverser {
|
||||
public:
|
||||
TOutputTraverser(TInfoSink& i) : infoSink(i) { }
|
||||
|
||||
virtual bool visitBinary(TVisit, TIntermBinary* node);
|
||||
virtual bool visitUnary(TVisit, TIntermUnary* node);
|
||||
virtual bool visitAggregate(TVisit, TIntermAggregate* node);
|
||||
virtual bool visitSelection(TVisit, TIntermSelection* node);
|
||||
virtual void visitConstantUnion(TIntermConstantUnion* node);
|
||||
virtual void visitSymbol(TIntermSymbol* node);
|
||||
virtual bool visitLoop(TVisit, TIntermLoop* node);
|
||||
virtual bool visitBranch(TVisit, TIntermBranch* node);
|
||||
virtual bool visitSwitch(TVisit, TIntermSwitch* node);
|
||||
|
||||
TInfoSink& infoSink;
|
||||
};
|
||||
|
||||
|
|
@ -85,12 +96,11 @@ void OutputTreeText(TInfoSink& infoSink, const TIntermNode* node, const int dept
|
|||
// return false.
|
||||
//
|
||||
|
||||
bool OutputBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it)
|
||||
bool TOutputTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)
|
||||
{
|
||||
TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
|
||||
TInfoSink& out = oit->infoSink;
|
||||
TInfoSink& out = infoSink;
|
||||
|
||||
OutputTreeText(out, node, oit->depth);
|
||||
OutputTreeText(out, node, depth);
|
||||
|
||||
switch (node->getOp()) {
|
||||
case EOpAssign: out.debug << "move second child to first child"; break;
|
||||
|
|
@ -152,12 +162,11 @@ bool OutputBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it
|
|||
return true;
|
||||
}
|
||||
|
||||
bool OutputUnary(bool /* preVisit */, TIntermUnary* node, TIntermTraverser* it)
|
||||
bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
|
||||
{
|
||||
TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
|
||||
TInfoSink& out = oit->infoSink;
|
||||
TInfoSink& out = infoSink;
|
||||
|
||||
OutputTreeText(out, node, oit->depth);
|
||||
OutputTreeText(out, node, depth);
|
||||
|
||||
switch (node->getOp()) {
|
||||
case EOpNegative: out.debug << "Negate value"; break;
|
||||
|
|
@ -261,17 +270,16 @@ bool OutputUnary(bool /* preVisit */, TIntermUnary* node, TIntermTraverser* it)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool OutputAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverser* it)
|
||||
bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node)
|
||||
{
|
||||
TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
|
||||
TInfoSink& out = oit->infoSink;
|
||||
TInfoSink& out = infoSink;
|
||||
|
||||
if (node->getOp() == EOpNull) {
|
||||
out.debug.message(EPrefixError, "node is still EOpNull!");
|
||||
return true;
|
||||
}
|
||||
|
||||
OutputTreeText(out, node, oit->depth);
|
||||
OutputTreeText(out, node, depth);
|
||||
|
||||
switch (node->getOp()) {
|
||||
case EOpSequence: out.debug << "Sequence\n"; return true;
|
||||
|
|
@ -368,36 +376,35 @@ bool OutputAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTravers
|
|||
return true;
|
||||
}
|
||||
|
||||
bool OutputSelection(bool /* preVisit */, TIntermSelection* node, TIntermTraverser* it)
|
||||
bool TOutputTraverser::visitSelection(TVisit /* visit */, TIntermSelection* node)
|
||||
{
|
||||
TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
|
||||
TInfoSink& out = oit->infoSink;
|
||||
TInfoSink& out = infoSink;
|
||||
|
||||
OutputTreeText(out, node, oit->depth);
|
||||
OutputTreeText(out, node, depth);
|
||||
|
||||
out.debug << "Test condition and select";
|
||||
out.debug << " (" << node->getCompleteString() << ")\n";
|
||||
|
||||
++oit->depth;
|
||||
++depth;
|
||||
|
||||
OutputTreeText(oit->infoSink, node, oit->depth);
|
||||
OutputTreeText(out, node, depth);
|
||||
out.debug << "Condition\n";
|
||||
node->getCondition()->traverse(it);
|
||||
node->getCondition()->traverse(this);
|
||||
|
||||
OutputTreeText(oit->infoSink, node, oit->depth);
|
||||
if (node->getTrueBlock()) {
|
||||
out.debug << "true case\n";
|
||||
node->getTrueBlock()->traverse(it);
|
||||
} else
|
||||
out.debug << "true case is null\n";
|
||||
OutputTreeText(out, node, depth);
|
||||
if (node->getTrueBlock()) {
|
||||
out.debug << "true case\n";
|
||||
node->getTrueBlock()->traverse(this);
|
||||
} else
|
||||
out.debug << "true case is null\n";
|
||||
|
||||
if (node->getFalseBlock()) {
|
||||
OutputTreeText(oit->infoSink, node, oit->depth);
|
||||
OutputTreeText(out, node, depth);
|
||||
out.debug << "false case\n";
|
||||
node->getFalseBlock()->traverse(it);
|
||||
node->getFalseBlock()->traverse(this);
|
||||
}
|
||||
|
||||
--oit->depth;
|
||||
--depth;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -454,78 +461,72 @@ void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const TConstU
|
|||
}
|
||||
}
|
||||
|
||||
void OutputConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it)
|
||||
void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node)
|
||||
{
|
||||
TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
|
||||
OutputTreeText(infoSink, node, depth);
|
||||
infoSink.debug << "Constant:\n";
|
||||
|
||||
OutputTreeText(oit->infoSink, node, oit->depth);
|
||||
oit->infoSink.debug << "Constant:\n";
|
||||
|
||||
OutputConstantUnion(oit->infoSink, node, node->getConstArray(), oit->depth + 1);
|
||||
OutputConstantUnion(infoSink, node, node->getConstArray(), depth + 1);
|
||||
}
|
||||
|
||||
void OutputSymbol(TIntermSymbol* node, TIntermTraverser* it)
|
||||
void TOutputTraverser::visitSymbol(TIntermSymbol* node)
|
||||
{
|
||||
TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
|
||||
|
||||
OutputTreeText(oit->infoSink, node, oit->depth);
|
||||
OutputTreeText(infoSink, node, depth);
|
||||
|
||||
const int maxSize = GlslangMaxTypeLength + GlslangMaxTokenLength;
|
||||
char buf[maxSize];
|
||||
snprintf(buf, maxSize, "'%s' (%s)\n",
|
||||
node->getName().c_str(),
|
||||
node->getCompleteString().c_str());
|
||||
oit->infoSink.debug << buf;
|
||||
infoSink.debug << buf;
|
||||
|
||||
if (! node->getConstArray().empty())
|
||||
OutputConstantUnion(oit->infoSink, node, node->getConstArray(), oit->depth + 1);
|
||||
OutputConstantUnion(infoSink, node, node->getConstArray(), depth + 1);
|
||||
}
|
||||
|
||||
bool OutputLoop(bool /* preVisit */, TIntermLoop* node, TIntermTraverser* it)
|
||||
bool TOutputTraverser::visitLoop(TVisit /* visit */, TIntermLoop* node)
|
||||
{
|
||||
TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
|
||||
TInfoSink& out = oit->infoSink;
|
||||
TInfoSink& out = infoSink;
|
||||
|
||||
OutputTreeText(out, node, oit->depth);
|
||||
OutputTreeText(out, node, depth);
|
||||
|
||||
out.debug << "Loop with condition ";
|
||||
if (! node->testFirst())
|
||||
out.debug << "not ";
|
||||
out.debug << "tested first\n";
|
||||
|
||||
++oit->depth;
|
||||
++depth;
|
||||
|
||||
OutputTreeText(oit->infoSink, node, oit->depth);
|
||||
OutputTreeText(infoSink, node, depth);
|
||||
if (node->getTest()) {
|
||||
out.debug << "Loop Condition\n";
|
||||
node->getTest()->traverse(it);
|
||||
node->getTest()->traverse(this);
|
||||
} else
|
||||
out.debug << "No loop condition\n";
|
||||
|
||||
OutputTreeText(oit->infoSink, node, oit->depth);
|
||||
OutputTreeText(infoSink, node, depth);
|
||||
if (node->getBody()) {
|
||||
out.debug << "Loop Body\n";
|
||||
node->getBody()->traverse(it);
|
||||
node->getBody()->traverse(this);
|
||||
} else
|
||||
out.debug << "No loop body\n";
|
||||
|
||||
if (node->getTerminal()) {
|
||||
OutputTreeText(oit->infoSink, node, oit->depth);
|
||||
OutputTreeText(infoSink, node, depth);
|
||||
out.debug << "Loop Terminal Expression\n";
|
||||
node->getTerminal()->traverse(it);
|
||||
node->getTerminal()->traverse(this);
|
||||
}
|
||||
|
||||
--oit->depth;
|
||||
--depth;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OutputBranch(bool /* previsit*/, TIntermBranch* node, TIntermTraverser* it)
|
||||
bool TOutputTraverser::visitBranch(TVisit /* visit*/, TIntermBranch* node)
|
||||
{
|
||||
TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
|
||||
TInfoSink& out = oit->infoSink;
|
||||
TInfoSink& out = infoSink;
|
||||
|
||||
OutputTreeText(out, node, oit->depth);
|
||||
OutputTreeText(out, node, depth);
|
||||
|
||||
switch (node->getFlowOp()) {
|
||||
case EOpKill: out.debug << "Branch: Kill"; break;
|
||||
|
|
@ -539,35 +540,34 @@ bool OutputBranch(bool /* previsit*/, TIntermBranch* node, TIntermTraverser* it)
|
|||
|
||||
if (node->getExpression()) {
|
||||
out.debug << " with expression\n";
|
||||
++oit->depth;
|
||||
node->getExpression()->traverse(it);
|
||||
--oit->depth;
|
||||
++depth;
|
||||
node->getExpression()->traverse(this);
|
||||
--depth;
|
||||
} else
|
||||
out.debug << "\n";
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool OutputSwitch(bool /* preVisit */, TIntermSwitch* node, TIntermTraverser* it)
|
||||
bool TOutputTraverser::visitSwitch(TVisit /* visit */, TIntermSwitch* node)
|
||||
{
|
||||
TOutputTraverser* oit = static_cast<TOutputTraverser*>(it);
|
||||
TInfoSink& out = oit->infoSink;
|
||||
TInfoSink& out = infoSink;
|
||||
|
||||
OutputTreeText(out, node, oit->depth);
|
||||
OutputTreeText(out, node, depth);
|
||||
out.debug << "switch\n";
|
||||
|
||||
OutputTreeText(out, node, oit->depth);
|
||||
OutputTreeText(out, node, depth);
|
||||
out.debug << "condition\n";
|
||||
++oit->depth;
|
||||
node->getCondition()->traverse(it);
|
||||
++depth;
|
||||
node->getCondition()->traverse(this);
|
||||
|
||||
--oit->depth;
|
||||
OutputTreeText(out, node, oit->depth);
|
||||
--depth;
|
||||
OutputTreeText(out, node, depth);
|
||||
out.debug << "body\n";
|
||||
++oit->depth;
|
||||
node->getBody()->traverse(it);
|
||||
++depth;
|
||||
node->getBody()->traverse(this);
|
||||
|
||||
--oit->depth;
|
||||
--depth;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
|
@ -621,16 +621,6 @@ void TIntermediate::output(TInfoSink& infoSink, bool tree)
|
|||
|
||||
TOutputTraverser it(infoSink);
|
||||
|
||||
it.visitAggregate = OutputAggregate;
|
||||
it.visitBinary = OutputBinary;
|
||||
it.visitConstantUnion = OutputConstantUnion;
|
||||
it.visitSelection = OutputSelection;
|
||||
it.visitSymbol = OutputSymbol;
|
||||
it.visitUnary = OutputUnary;
|
||||
it.visitLoop = OutputLoop;
|
||||
it.visitBranch = OutputBranch;
|
||||
it.visitSwitch = OutputSwitch;
|
||||
|
||||
treeRoot->traverse(&it);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue