TIntermAggregate* body;
};
+enum TVisit
+{
+ EvPreVisit,
+ EvInVisit,
+ EvPostVisit
+};
+
//
// For traversing the tree. User should derive from this,
// put their traversal specific data in it, and then pass
//
// Explicitly set postVisit to true if you want post visiting, otherwise,
// filled in methods will only be called at pre-visit time (before processing
-// the subtree).
+// the subtree). Similary for inVisit for in-order visiting of nodes with
+// multiple children.
//
-// If you only want post-visits, explicitly turn off preVisit and turn on postVisit.
+// If you only want post-visits, explicitly turn off preVisit (and inVisit)
+// and turn on postVisit.
//
class TIntermTraverser {
public:
- POOL_ALLOCATOR_NEW_DELETE(GetThreadPoolAllocator())
-
- TIntermTraverser() :
- visitSymbol(0),
- visitConstantUnion(0),
- visitBinary(0),
- visitUnary(0),
- visitSelection(0),
- visitAggregate(0),
- visitLoop(0),
- visitBranch(0),
- visitSwitch(0),
- depth(0),
- preVisit(true),
- postVisit(false),
- rightToLeft(false) {}
-
- void (*visitSymbol)(TIntermSymbol*, TIntermTraverser*);
- void (*visitConstantUnion)(TIntermConstantUnion*, TIntermTraverser*);
- bool (*visitBinary)(bool preVisit, TIntermBinary*, TIntermTraverser*);
- bool (*visitUnary)(bool preVisit, TIntermUnary*, TIntermTraverser*);
- bool (*visitSelection)(bool preVisit, TIntermSelection*, TIntermTraverser*);
- bool (*visitAggregate)(bool preVisit, TIntermAggregate*, TIntermTraverser*);
- bool (*visitLoop)(bool preVisit, TIntermLoop*, TIntermTraverser*);
- bool (*visitBranch)(bool preVisit, TIntermBranch*, TIntermTraverser*);
- bool (*visitSwitch)(bool preVisit, TIntermSwitch*, TIntermTraverser*);
-
- int depth;
- bool preVisit;
- bool postVisit;
- bool rightToLeft;
+ POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator())
+ TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
+ preVisit(preVisit),
+ inVisit(inVisit),
+ postVisit(postVisit),
+ rightToLeft(rightToLeft),
+ depth(0),
+ maxDepth(0) { }
+ virtual ~TIntermTraverser() { }
+
+ virtual void visitSymbol(TIntermSymbol*) { }
+ virtual void visitConstantUnion(TIntermConstantUnion*) { }
+ virtual bool visitBinary(TVisit visit, TIntermBinary*) { return true; }
+ virtual bool visitUnary(TVisit visit, TIntermUnary*) { return true; }
+ virtual bool visitSelection(TVisit visit, TIntermSelection*) { return true; }
+ virtual bool visitAggregate(TVisit visit, TIntermAggregate*) { return true; }
+ virtual bool visitLoop(TVisit visit, TIntermLoop*) { return true; }
+ virtual bool visitBranch(TVisit visit, TIntermBranch*) { return true; }
+ virtual bool visitSwitch(TVisit, TIntermSwitch* node) { return true; }
+
+ int getMaxDepth() const { return maxDepth; }
+
+ void incrementDepth(TIntermNode *current)
+ {
+ depth++;
+ maxDepth = std::max(maxDepth, depth);
+ path.push_back(current);
+ }
+
+ void decrementDepth()
+ {
+ depth--;
+ path.pop_back();
+ }
+
+ TIntermNode *getParentNode()
+ {
+ return path.size() == 0 ? NULL : path.back();
+ }
+
+ const bool preVisit;
+ const bool inVisit;
+ const bool postVisit;
+ const bool rightToLeft;
+
+protected:
+ int depth;
+ int maxDepth;
+
+ // All the nodes from root to the current node's parent during traversing.
+ TVector<TIntermNode *> path;
};
} // end namespace glslang
// source have to figure out how to create revision.h just to get a build\r
// going. However, if it is not updated, it can be a version behind.\r
\r
-#define GLSLANG_REVISION "24692"\r
-#define GLSLANG_DATE "2014/01/08 16:25:18"\r
+#define GLSLANG_REVISION "24738"\r
+#define GLSLANG_DATE "2014/01/10 14:25:05"\r
//
//Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
//Copyright (C) 2013 LunarG, Inc.
+//Copyright (c) 2002-2010 The ANGLE Project Authors.
//
//All rights reserved.
//
// TODO: 4.3 functionality: some .length() will stay as methods
}
-void TIntermSymbol::traverse(TIntermTraverser* it)
+void TIntermSymbol::traverse(TIntermTraverser *it)
{
- if (it->visitSymbol)
- it->visitSymbol(this, it);
+ it->visitSymbol(this);
}
-void TIntermConstantUnion::traverse(TIntermTraverser* it)
+void TIntermConstantUnion::traverse(TIntermTraverser *it)
{
- if (it->visitConstantUnion)
- it->visitConstantUnion(this, it);
+ it->visitConstantUnion(this);
}
//
// Traverse a binary node.
//
-void TIntermBinary::traverse(TIntermTraverser* it)
+void TIntermBinary::traverse(TIntermTraverser *it)
{
bool visit = true;
//
// visit the node before children if pre-visiting.
//
- if (it->preVisit && it->visitBinary)
- visit = it->visitBinary(true, this, it);
-
+ if (it->preVisit)
+ visit = it->visitBinary(EvPreVisit, this);
+
//
// Visit the children, in the right order.
//
if (visit) {
- ++it->depth;
+ it->incrementDepth(this);
+
if (it->rightToLeft) {
if (right)
right->traverse(it);
- if (left)
+
+ if (it->inVisit)
+ visit = it->visitBinary(EvInVisit, this);
+
+ if (visit && left)
left->traverse(it);
} else {
if (left)
left->traverse(it);
- if (right)
+
+ if (it->inVisit)
+ visit = it->visitBinary(EvInVisit, this);
+
+ if (visit && right)
right->traverse(it);
}
- --it->depth;
+
+ it->decrementDepth();
}
//
// Visit the node after the children, if requested and the traversal
// hasn't been cancelled yet.
//
- if (visit && it->postVisit && it->visitBinary)
- it->visitBinary(false, this, it);
+ if (visit && it->postVisit)
+ it->visitBinary(EvPostVisit, this);
}
//
// Traverse a unary node. Same comments in binary node apply here.
//
-void TIntermUnary::traverse(TIntermTraverser* it)
+void TIntermUnary::traverse(TIntermTraverser *it)
{
bool visit = true;
- if (it->preVisit && it->visitUnary)
- visit = it->visitUnary(true, this, it);
+ if (it->preVisit)
+ visit = it->visitUnary(EvPreVisit, this);
if (visit) {
- ++it->depth;
+ it->incrementDepth(this);
operand->traverse(it);
- --it->depth;
+ it->decrementDepth();
}
-
- if (visit && it->postVisit && it->visitUnary)
- it->visitUnary(false, this, it);
+
+ if (visit && it->postVisit)
+ it->visitUnary(EvPostVisit, this);
}
//
// Traverse an aggregate node. Same comments in binary node apply here.
//
-void TIntermAggregate::traverse(TIntermTraverser* it)
+void TIntermAggregate::traverse(TIntermTraverser *it)
{
bool visit = true;
-
- if (it->preVisit && it->visitAggregate)
- visit = it->visitAggregate(true, this, it);
-
+
+ if (it->preVisit)
+ visit = it->visitAggregate(EvPreVisit, this);
+
if (visit) {
- ++it->depth;
+ it->incrementDepth(this);
- TIntermSequence::iterator sit;
if (it->rightToLeft) {
- sit = sequence.end();
- while (sit != sequence.begin()) {
- --sit;
+ for (TIntermSequence::reverse_iterator sit = sequence.rbegin(); sit != sequence.rend(); sit++) {
(*sit)->traverse(it);
+
+ if (visit && it->inVisit) {
+ if (*sit != sequence.front())
+ visit = it->visitAggregate(EvInVisit, this);
+ }
}
} else {
- for (sit = sequence.begin(); sit != sequence.end(); ++sit)
+ for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++) {
(*sit)->traverse(it);
+
+ if (visit && it->inVisit) {
+ if (*sit != sequence.back())
+ visit = it->visitAggregate(EvInVisit, this);
+ }
+ }
}
-
- --it->depth;
+
+ it->decrementDepth();
}
- if (visit && it->postVisit && it->visitAggregate)
- it->visitAggregate(false, this, it);
+ if (visit && it->postVisit)
+ it->visitAggregate(EvPostVisit, this);
}
//
// Traverse a selection node. Same comments in binary node apply here.
//
-void TIntermSelection::traverse(TIntermTraverser* it)
+void TIntermSelection::traverse(TIntermTraverser *it)
{
bool visit = true;
- if (it->preVisit && it->visitSelection)
- visit = it->visitSelection(true, this, it);
-
+ if (it->preVisit)
+ visit = it->visitSelection(EvPreVisit, this);
+
if (visit) {
- ++it->depth;
+ it->incrementDepth(this);
if (it->rightToLeft) {
if (falseBlock)
falseBlock->traverse(it);
if (falseBlock)
falseBlock->traverse(it);
}
- --it->depth;
+ it->decrementDepth();
}
- if (visit && it->postVisit && it->visitSelection)
- it->visitSelection(false, this, it);
+ if (visit && it->postVisit)
+ it->visitSelection(EvPostVisit, this);
}
//
// Traverse a loop node. Same comments in binary node apply here.
//
-void TIntermLoop::traverse(TIntermTraverser* it)
+void TIntermLoop::traverse(TIntermTraverser *it)
{
bool visit = true;
- if (it->preVisit && it->visitLoop)
- visit = it->visitLoop(true, this, it);
-
+ if (it->preVisit)
+ visit = it->visitLoop(EvPreVisit, this);
+
if (visit) {
- ++it->depth;
+ it->incrementDepth(this);
+
if (it->rightToLeft) {
if (terminal)
terminal->traverse(it);
+
if (body)
body->traverse(it);
+
if (test)
test->traverse(it);
} else {
if (test)
test->traverse(it);
+
if (body)
body->traverse(it);
+
if (terminal)
terminal->traverse(it);
}
- --it->depth;
+
+ it->decrementDepth();
}
- if (visit && it->postVisit && it->visitLoop)
- it->visitLoop(false, this, it);
+ if (visit && it->postVisit)
+ it->visitLoop(EvPostVisit, this);
}
//
// Traverse a branch node. Same comments in binary node apply here.
//
-void TIntermBranch::traverse(TIntermTraverser* it)
+void TIntermBranch::traverse(TIntermTraverser *it)
{
bool visit = true;
- if (it->preVisit && it->visitBranch)
- visit = it->visitBranch(true, this, it);
-
+ if (it->preVisit)
+ visit = it->visitBranch(EvPreVisit, this);
+
if (visit && expression) {
- ++it->depth;
+ it->incrementDepth(this);
expression->traverse(it);
- --it->depth;
+ it->decrementDepth();
}
- if (visit && it->postVisit && it->visitBranch)
- it->visitBranch(false, this, it);
+ if (visit && it->postVisit)
+ it->visitBranch(EvPostVisit, this);
}
//
{
bool visit = true;
- if (it->preVisit && it->visitSwitch)
- visit = it->visitSwitch(true, this, it);
-
+ if (it->preVisit)
+ visit = it->visitSwitch(EvPreVisit, this);
+
if (visit) {
- ++it->depth;
+ it->incrementDepth(this);
if (it->rightToLeft) {
body->traverse(it);
condition->traverse(it);
condition->traverse(it);
body->traverse(it);
}
- --it->depth;
+ it->decrementDepth();
}
- if (visit && it->postVisit && it->visitSwitch)
- it->visitSwitch(false, this, it);
+ if (visit && it->postVisit)
+ it->visitSwitch(EvPostVisit, this);
}
} // end namespace glslang
//
// Code to recursively delete the intermediate tree.
//
+struct TRemoveTraverser : TIntermTraverser {
+ TRemoveTraverser() : TIntermTraverser(false, false, true, false) {}
-void RemoveSymbol(TIntermSymbol* node, TIntermTraverser* it)
-{
- delete node;
-}
+ virtual void visitSymbol(TIntermSymbol* node)
+ {
+ delete node;
+ }
-bool RemoveBinary(bool /*preVisit*/ , TIntermBinary* node, TIntermTraverser*)
-{
- delete node;
+ virtual bool visitBinary(TVisit /* visit*/ , TIntermBinary* node)
+ {
+ delete node;
- return true;
-}
+ return true;
+ }
-bool RemoveUnary(bool /*preVisit */, TIntermUnary* node, TIntermTraverser*)
-{
- delete node;
+ virtual bool visitUnary(TVisit /* visit */, TIntermUnary* node)
+ {
+ delete node;
- return true;
-}
+ return true;
+ }
-bool RemoveAggregate(bool /*preVisit*/ , TIntermAggregate* node, TIntermTraverser*)
-{
- delete node;
+ virtual bool visitAggregate(TVisit /* visit*/ , TIntermAggregate* node)
+ {
+ delete node;
- return true;
-}
+ return true;
+ }
-bool RemoveSelection(bool /*preVisit*/ , TIntermSelection* node, TIntermTraverser*)
-{
- delete node;
+ virtual bool visitSelection(TVisit /* visit*/ , TIntermSelection* node)
+ {
+ delete node;
- return true;
-}
+ return true;
+ }
-bool RemoveSwitch(bool /*preVisit*/ , TIntermSwitch* node, TIntermTraverser*)
-{
- delete node;
+ virtual bool visitSwitch(TVisit /* visit*/ , TIntermSwitch* node)
+ {
+ delete node;
- return true;
-}
+ return true;
+ }
-void RemoveConstantUnion(TIntermConstantUnion* node, TIntermTraverser*)
-{
- delete node;
-}
+ virtual void visitConstantUnion(TIntermConstantUnion* node)
+ {
+ delete node;
+ }
-bool RemoveLoop(bool /*preVisit*/ , TIntermLoop* node, TIntermTraverser*)
-{
- delete node;
+ virtual bool visitLoop(TVisit /* visit*/ , TIntermLoop* node)
+ {
+ delete node;
- return true;
-}
+ return true;
+ }
-bool RemoveBranch(bool /*preVisit*/ , TIntermBranch* node, TIntermTraverser*)
-{
- delete node;
+ virtual bool visitBranch(TVisit /* visit*/ , TIntermBranch* node)
+ {
+ delete node;
- return true;
-}
+ return true;
+ }
+};
//
// Entry point.
//
void RemoveAllTreeNodes(TIntermNode* root)
{
- TIntermTraverser it;
-
- it.visitSymbol = RemoveSymbol;
- it.visitConstantUnion = RemoveConstantUnion;
- it.visitBinary = RemoveBinary;
- it.visitUnary = RemoveUnary;
- it.visitAggregate = RemoveAggregate;
- it.visitSelection = RemoveSelection;
- it.visitLoop = RemoveLoop;
- it.visitBranch = RemoveBranch;
- it.visitSwitch = RemoveSwitch;
-
- it.preVisit = false;
- it.postVisit = true;
+ TRemoveTraverser it;
root->traverse(&it);
}
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;
};
// 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;
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;
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;
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;
}
}
}
-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;
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;
}
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);
}
\r
class TInductiveTraverser : public TIntermTraverser {\r
public:\r
- TInductiveTraverser(int id, TSymbolTable& st) : loopId(id), symbolTable(st), bad(false) { }\r
+ TInductiveTraverser(int id, TSymbolTable& st)\r
+ : loopId(id), symbolTable(st), bad(false) { }\r
+\r
+ virtual bool visitBinary(TVisit, TIntermBinary* node);\r
+ virtual bool visitUnary(TVisit, TIntermUnary* node);\r
+ virtual bool visitAggregate(TVisit, TIntermAggregate* node);\r
+\r
int loopId; // unique ID of the symbol that's the loop inductive variable\r
TSymbolTable& symbolTable;\r
bool bad;\r
};\r
\r
// check binary operations for those modifying the loop index\r
-bool InductiveBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it)\r
+bool TInductiveTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)\r
{\r
- TInductiveTraverser* oit = static_cast<TInductiveTraverser*>(it);\r
-\r
if (node->modifiesState() && node->getLeft()->getAsSymbolNode() && \r
- node->getLeft()->getAsSymbolNode()->getId() == oit->loopId) {\r
- oit->bad = true;\r
- oit->badLoc = node->getLoc();\r
+ node->getLeft()->getAsSymbolNode()->getId() == loopId) {\r
+ bad = true;\r
+ badLoc = node->getLoc();\r
}\r
\r
return true;\r
}\r
\r
// check unary operations for those modifying the loop index\r
-bool InductiveUnary(bool /* preVisit */, TIntermUnary* node, TIntermTraverser* it)\r
+bool TInductiveTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)\r
{\r
- TInductiveTraverser* oit = static_cast<TInductiveTraverser*>(it);\r
-\r
if (node->modifiesState() && node->getOperand()->getAsSymbolNode() && \r
- node->getOperand()->getAsSymbolNode()->getId() == oit->loopId) {\r
- oit->bad = true;\r
- oit->badLoc = node->getLoc();\r
+ node->getOperand()->getAsSymbolNode()->getId() == loopId) {\r
+ bad = true;\r
+ badLoc = node->getLoc();\r
}\r
\r
return true;\r
}\r
\r
// check function calls for arguments modifying the loop index\r
-bool InductiveAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverser* it)\r
+bool TInductiveTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node)\r
{\r
- TInductiveTraverser* oit = static_cast<TInductiveTraverser*>(it);\r
-\r
if (node->getOp() == EOpFunctionCall) {\r
// see if an out or inout argument is the loop index\r
const TIntermSequence& args = node->getSequence();\r
for (size_t i = 0; i < args.size(); ++i) {\r
- if (args[i]->getAsSymbolNode() && args[i]->getAsSymbolNode()->getId() == oit->loopId) {\r
- TSymbol* function = oit->symbolTable.find(node->getName());\r
+ if (args[i]->getAsSymbolNode() && args[i]->getAsSymbolNode()->getId() == loopId) {\r
+ TSymbol* function = symbolTable.find(node->getName());\r
const TType* type = (*function->getAsFunction())[i].type;\r
if (type->getQualifier().storage == EvqOut ||\r
type->getQualifier().storage == EvqInOut) {\r
- oit->bad = true;\r
- oit->badLoc = node->getLoc();\r
+ bad = true;\r
+ badLoc = node->getLoc();\r
}\r
}\r
}\r
if (! body)\r
return;\r
\r
- it.visitAggregate = InductiveAggregate;\r
- it.visitBinary = InductiveBinary;\r
- it.visitUnary = InductiveUnary;\r
-\r
body->traverse(&it);\r
\r
if (it.bad)\r
class TIndexTraverser : public TIntermTraverser {\r
public:\r
TIndexTraverser(const TIdSetType& ids) : inductiveLoopIds(ids), bad(false) { }\r
+ virtual void visitSymbol(TIntermSymbol* symbol);\r
+ virtual bool visitAggregate(TVisit, TIntermAggregate* node);\r
const TIdSetType& inductiveLoopIds;\r
bool bad;\r
TSourceLoc badLoc;\r
};\r
\r
// make sure symbols are inductive-loop indexes\r
-void IndexSymbol(TIntermSymbol* symbol, TIntermTraverser* it)\r
+void TIndexTraverser::visitSymbol(TIntermSymbol* symbol)\r
{\r
- TIndexTraverser* oit = static_cast<TIndexTraverser*>(it);\r
-\r
- if (oit->inductiveLoopIds.find(symbol->getId()) == oit->inductiveLoopIds.end()) {\r
- oit->bad = true;\r
- oit->badLoc = symbol->getLoc();\r
+ if (inductiveLoopIds.find(symbol->getId()) == inductiveLoopIds.end()) {\r
+ bad = true;\r
+ badLoc = symbol->getLoc();\r
}\r
}\r
\r
// check for function calls, assuming they are bad; spec. doesn't really say\r
-bool IndexAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverser* it)\r
+bool TIndexTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node)\r
{\r
- TIndexTraverser* oit = static_cast<TIndexTraverser*>(it);\r
-\r
if (node->getOp() == EOpFunctionCall) {\r
- oit->bad = true;\r
- oit->badLoc = node->getLoc();\r
+ bad = true;\r
+ badLoc = node->getLoc();\r
}\r
\r
return true;\r
{\r
TIndexTraverser it(inductiveLoopIds);\r
\r
- it.visitSymbol = IndexSymbol;\r
- it.visitAggregate = IndexAggregate;\r
-\r
index->traverse(&it);\r
\r
if (it.bad)\r
class TConstTraverser : public TIntermTraverser {
public:
- TConstTraverser(const TConstUnionArray& cUnion, bool singleConstParam, TOperator constructType, const TType& t) : unionArray(cUnion), type(t),
+ TConstTraverser(const TConstUnionArray& cUnion, bool singleConstParam, TOperator constructType, const TType& t)
+ : unionArray(cUnion), type(t),
constructorType(constructType), singleConstantParam(singleConstParam), error(false), isMatrix(false),
matrixCols(0), matrixRows(0) { index = 0; tOp = EOpNull; }
+
+ virtual void visitConstantUnion(TIntermConstantUnion* node);
+ virtual bool visitAggregate(TVisit, TIntermAggregate* node);
+
int index;
TConstUnionArray unionArray;
TOperator tOp;
int matrixRows;
};
-bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverser* it)
+bool TConstTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node)
{
- TConstTraverser* oit = static_cast<TConstTraverser*>(it);
-
if (! node->isConstructor() && node->getOp() != EOpComma) {
- oit->error = true;
+ error = true;
return false;
}
if (node->getSequence().size() == 0) {
- oit->error = true;
+ error = true;
return false;
}
bool flag = node->getSequence().size() == 1 && node->getSequence()[0]->getAsTyped()->getAsConstantUnion();
if (flag) {
- oit->singleConstantParam = true;
- oit->constructorType = node->getOp();
- oit->size = node->getType().getObjectSize();
+ singleConstantParam = true;
+ constructorType = node->getOp();
+ size = node->getType().getObjectSize();
if (node->getType().isMatrix()) {
- oit->isMatrix = true;
- oit->matrixCols = node->getType().getMatrixCols();
- oit->matrixRows = node->getType().getMatrixRows();
+ isMatrix = true;
+ matrixCols = node->getType().getMatrixCols();
+ matrixRows = node->getType().getMatrixRows();
}
}
p != node->getSequence().end(); p++) {
if (node->getOp() == EOpComma)
- oit->index = 0;
+ index = 0;
- (*p)->traverse(oit);
+ (*p)->traverse(this);
}
if (flag)
{
- oit->singleConstantParam = false;
- oit->constructorType = EOpNull;
- oit->size = 0;
- oit->isMatrix = false;
- oit->matrixCols = 0;
- oit->matrixRows = 0;
+ singleConstantParam = false;
+ constructorType = EOpNull;
+ size = 0;
+ isMatrix = false;
+ matrixCols = 0;
+ matrixRows = 0;
}
return false;
}
-void ParseConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it)
+void TConstTraverser::visitConstantUnion(TIntermConstantUnion* node)
{
- TConstTraverser* oit = static_cast<TConstTraverser*>(it);
- TConstUnionArray leftUnionArray(oit->unionArray);
- int instanceSize = oit->type.getObjectSize();
+ TConstUnionArray leftUnionArray(unionArray);
+ int instanceSize = type.getObjectSize();
- if (oit->index >= instanceSize)
+ if (index >= instanceSize)
return;
- if (! oit->singleConstantParam) {
- int size = node->getType().getObjectSize();
+ if (! singleConstantParam) {
+ int rightUnionSize = node->getType().getObjectSize();
const TConstUnionArray& rightUnionArray = node->getConstArray();
- for (int i = 0; i < size; i++) {
- if (oit->index >= instanceSize)
+ for (int i = 0; i < rightUnionSize; i++) {
+ if (index >= instanceSize)
return;
- leftUnionArray[oit->index] = rightUnionArray[i];
+ leftUnionArray[index] = rightUnionArray[i];
- oit->index++;
+ index++;
}
} else {
- int endIndex = oit->index + oit->size;
+ int endIndex = index + size;
const TConstUnionArray& rightUnionArray = node->getConstArray();
- if (! oit->isMatrix) {
+ if (! isMatrix) {
int count = 0;
- for (int i = oit->index; i < endIndex; i++) {
+ for (int i = index; i < endIndex; i++) {
if (i >= instanceSize)
return;
leftUnionArray[i] = rightUnionArray[count];
- (oit->index)++;
+ (index)++;
if (node->getType().getObjectSize() > 1)
count++;
} else {
// constructing a matrix, but from what?
if (node->isMatrix()) {
- // Matrix from a matrix; oit has the outer matrix, node is the argument matrix.
+ // Matrix from a matrix; this has the outer matrix, node is the argument matrix.
// Traverse the outer, potentially bigger matrix, fill in missing pieces with the
// identity matrix.
- for (int c = 0; c < oit->matrixCols; ++c) {
- for (int r = 0; r < oit->matrixRows; ++r) {
- int targetOffset = oit->index + c * oit->matrixRows + r;
+ for (int c = 0; c < matrixCols; ++c) {
+ for (int r = 0; r < matrixRows; ++r) {
+ int targetOffset = index + c * matrixRows + r;
if (r < node->getType().getMatrixRows() && c < node->getType().getMatrixCols()) {
int srcOffset = c * node->getType().getMatrixRows() + r;
leftUnionArray[targetOffset] = rightUnionArray[srcOffset];
} else {
// matrix from vector
int count = 0;
- int index = oit->index;
- for (int i = index; i < endIndex; i++) {
+ const int startIndex = index;
+ for (int i = startIndex; i < endIndex; i++) {
if (i >= instanceSize)
return;
- if (i == index || (i - index) % (oit->matrixRows + 1) == 0 )
+ if (i == startIndex || (i - startIndex) % (matrixRows + 1) == 0 )
leftUnionArray[i] = rightUnionArray[count];
else
leftUnionArray[i].setDConst(0.0);
- oit->index++;
+ index++;
if (node->getType().getObjectSize() > 1)
count++;
TConstTraverser it(unionArray, singleConstantParam, constructorType, t);
- it.visitAggregate = ParseAggregate;
- it.visitConstantUnion = ParseConstantUnion;
-
root->traverse(&it);
if (it.error)
return true;
public:\r
TLiveTraverser(const TIntermediate& i, TReflection& r) : intermediate(i), reflection(r) { }\r
\r
+ virtual bool visitAggregate(TVisit, TIntermAggregate* node);\r
+ virtual bool visitBinary(TVisit, TIntermBinary* node);\r
+ virtual void visitSymbol(TIntermSymbol* base);\r
+ virtual bool visitSelection(TVisit, TIntermSelection* node);\r
+\r
// Track live funtions as well as uniforms, so that we don't visit dead functions\r
// and only visit each function once.\r
void addFunctionCall(TIntermAggregate* call)\r
\r
const int TLiveTraverser::baseAlignmentVec4Std140 = 16;\r
\r
-namespace {\r
-\r
//\r
// Implement the traversal functions of interest.\r
//\r
\r
// To catch which function calls are not dead, and hence which functions must be visited.\r
-bool LiveAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverser* it)\r
+bool TLiveTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node)\r
{\r
- TLiveTraverser* oit = static_cast<TLiveTraverser*>(it);\r
-\r
if (node->getOp() == EOpFunctionCall)\r
- oit->addFunctionCall(node);\r
+ addFunctionCall(node);\r
\r
return true; // traverse this subtree\r
}\r
\r
// To catch dereferenced aggregates that must be reflected.\r
// This catches them at the highest level possible in the tree.\r
-bool LiveBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it)\r
+bool TLiveTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)\r
{\r
- TLiveTraverser* oit = static_cast<TLiveTraverser*>(it);\r
-\r
switch (node->getOp()) {\r
case EOpIndexDirect:\r
case EOpIndexIndirect:\r
case EOpIndexDirectStruct:\r
- oit->addDereferencedUniform(node);\r
+ addDereferencedUniform(node);\r
break;\r
default:\r
break;\r
}\r
\r
// To reflect non-dereferenced objects.\r
-void LiveSymbol(TIntermSymbol* base, TIntermTraverser* it)\r
+void TLiveTraverser::visitSymbol(TIntermSymbol* base)\r
{\r
- TLiveTraverser* oit = static_cast<TLiveTraverser*>(it);\r
-\r
if (base->getQualifier().storage == EvqUniform)\r
- oit->addUniform(*base);\r
+ addUniform(*base);\r
}\r
\r
// To prune semantically dead paths.\r
-bool LiveSelection(bool /* preVisit */, TIntermSelection* node, TIntermTraverser* it)\r
+bool TLiveTraverser::visitSelection(TVisit /* visit */, TIntermSelection* node)\r
{\r
- TLiveTraverser* oit = static_cast<TLiveTraverser*>(it);\r
-\r
TIntermConstantUnion* constant = node->getCondition()->getAsConstantUnion();\r
if (constant) {\r
// cull the path that is dead\r
if (constant->getConstArray()[0].getBConst() == true && node->getTrueBlock())\r
- node->getTrueBlock()->traverse(it);\r
+ node->getTrueBlock()->traverse(this);\r
if (constant->getConstArray()[0].getBConst() == false && node->getFalseBlock())\r
- node->getFalseBlock()->traverse(it);\r
+ node->getFalseBlock()->traverse(this);\r
\r
return false; // don't traverse any more, we did it all above\r
} else\r
return true; // traverse the whole subtree\r
}\r
\r
-} // end anonymous namespace\r
-\r
//\r
// Implement TReflection methods.\r
//\r
return false;\r
\r
TLiveTraverser it(intermediate, *this);\r
- it.visitSymbol = LiveSymbol;\r
- it.visitSelection = LiveSelection;\r
- it.visitBinary = LiveBinary;\r
- it.visitAggregate = LiveAggregate;\r
\r
// put main() on functions to process\r
it.pushFunction("main(");\r