diff --git a/glslang/Include/intermediate.h b/glslang/Include/intermediate.h index b73083a7..e65dd92d 100644 --- a/glslang/Include/intermediate.h +++ b/glslang/Include/intermediate.h @@ -643,6 +643,13 @@ protected: 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 @@ -653,43 +660,65 @@ protected: // // 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()) + 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() { } - 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) {} + 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; } - 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 getMaxDepth() const { return maxDepth; } - int depth; - bool preVisit; - bool postVisit; - bool rightToLeft; + 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 path; }; } // end namespace glslang diff --git a/glslang/Include/revision.h b/glslang/Include/revision.h index 457b857e..56a62233 100644 --- a/glslang/Include/revision.h +++ b/glslang/Include/revision.h @@ -9,5 +9,5 @@ // source have to figure out how to create revision.h just to get a build // going. However, if it is not updated, it can be a version behind. -#define GLSLANG_REVISION "24692" -#define GLSLANG_DATE "2014/01/08 16:25:18" +#define GLSLANG_REVISION "24738" +#define GLSLANG_DATE "2014/01/10 14:25:05" diff --git a/glslang/MachineIndependent/IntermTraverse.cpp b/glslang/MachineIndependent/IntermTraverse.cpp index f609ff72..28f8da8c 100644 --- a/glslang/MachineIndependent/IntermTraverse.cpp +++ b/glslang/MachineIndependent/IntermTraverse.cpp @@ -1,6 +1,7 @@ // //Copyright (C) 2002-2005 3Dlabs Inc. Ltd. //Copyright (C) 2013 LunarG, Inc. +//Copyright (c) 2002-2010 The ANGLE Project Authors. // //All rights reserved. // @@ -62,122 +63,138 @@ void TIntermMethod::traverse(TIntermTraverser* it) // 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 (visit) { - ++it->depth; - TIntermSequence::iterator sit; + if (it->preVisit) + visit = it->visitAggregate(EvPreVisit, this); + + if (visit) { + it->incrementDepth(this); + 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); @@ -191,65 +208,71 @@ void TIntermSelection::traverse(TIntermTraverser* 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); } // @@ -259,11 +282,11 @@ void TIntermSwitch::traverse(TIntermTraverser* it) { 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); @@ -271,11 +294,11 @@ void TIntermSwitch::traverse(TIntermTraverser* 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 diff --git a/glslang/MachineIndependent/RemoveTree.cpp b/glslang/MachineIndependent/RemoveTree.cpp index ee72a728..a4fa551c 100644 --- a/glslang/MachineIndependent/RemoveTree.cpp +++ b/glslang/MachineIndependent/RemoveTree.cpp @@ -42,85 +42,75 @@ 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); } diff --git a/glslang/MachineIndependent/intermOut.cpp b/glslang/MachineIndependent/intermOut.cpp index 0a997536..64febdb1 100644 --- a/glslang/MachineIndependent/intermOut.cpp +++ b/glslang/MachineIndependent/intermOut.cpp @@ -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(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(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(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(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(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(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(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(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(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); } diff --git a/glslang/MachineIndependent/limits.cpp b/glslang/MachineIndependent/limits.cpp index 0c660a87..137c051b 100644 --- a/glslang/MachineIndependent/limits.cpp +++ b/glslang/MachineIndependent/limits.cpp @@ -63,7 +63,13 @@ namespace glslang { class TInductiveTraverser : public TIntermTraverser { public: - TInductiveTraverser(int id, TSymbolTable& st) : loopId(id), symbolTable(st), bad(false) { } + TInductiveTraverser(int id, TSymbolTable& st) + : loopId(id), symbolTable(st), bad(false) { } + + virtual bool visitBinary(TVisit, TIntermBinary* node); + virtual bool visitUnary(TVisit, TIntermUnary* node); + virtual bool visitAggregate(TVisit, TIntermAggregate* node); + int loopId; // unique ID of the symbol that's the loop inductive variable TSymbolTable& symbolTable; bool bad; @@ -71,49 +77,43 @@ public: }; // check binary operations for those modifying the loop index -bool InductiveBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it) +bool TInductiveTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node) { - TInductiveTraverser* oit = static_cast(it); - if (node->modifiesState() && node->getLeft()->getAsSymbolNode() && - node->getLeft()->getAsSymbolNode()->getId() == oit->loopId) { - oit->bad = true; - oit->badLoc = node->getLoc(); + node->getLeft()->getAsSymbolNode()->getId() == loopId) { + bad = true; + badLoc = node->getLoc(); } return true; } // check unary operations for those modifying the loop index -bool InductiveUnary(bool /* preVisit */, TIntermUnary* node, TIntermTraverser* it) +bool TInductiveTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node) { - TInductiveTraverser* oit = static_cast(it); - if (node->modifiesState() && node->getOperand()->getAsSymbolNode() && - node->getOperand()->getAsSymbolNode()->getId() == oit->loopId) { - oit->bad = true; - oit->badLoc = node->getLoc(); + node->getOperand()->getAsSymbolNode()->getId() == loopId) { + bad = true; + badLoc = node->getLoc(); } return true; } // check function calls for arguments modifying the loop index -bool InductiveAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverser* it) +bool TInductiveTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node) { - TInductiveTraverser* oit = static_cast(it); - if (node->getOp() == EOpFunctionCall) { // see if an out or inout argument is the loop index const TIntermSequence& args = node->getSequence(); for (size_t i = 0; i < args.size(); ++i) { - if (args[i]->getAsSymbolNode() && args[i]->getAsSymbolNode()->getId() == oit->loopId) { - TSymbol* function = oit->symbolTable.find(node->getName()); + if (args[i]->getAsSymbolNode() && args[i]->getAsSymbolNode()->getId() == loopId) { + TSymbol* function = symbolTable.find(node->getName()); const TType* type = (*function->getAsFunction())[i].type; if (type->getQualifier().storage == EvqOut || type->getQualifier().storage == EvqInOut) { - oit->bad = true; - oit->badLoc = node->getLoc(); + bad = true; + badLoc = node->getLoc(); } } } @@ -132,10 +132,6 @@ void TParseContext::inductiveLoopBodyCheck(TIntermNode* body, int loopId, TSymbo if (! body) return; - it.visitAggregate = InductiveAggregate; - it.visitBinary = InductiveBinary; - it.visitUnary = InductiveUnary; - body->traverse(&it); if (it.bad) @@ -151,30 +147,28 @@ void TParseContext::inductiveLoopBodyCheck(TIntermNode* body, int loopId, TSymbo class TIndexTraverser : public TIntermTraverser { public: TIndexTraverser(const TIdSetType& ids) : inductiveLoopIds(ids), bad(false) { } + virtual void visitSymbol(TIntermSymbol* symbol); + virtual bool visitAggregate(TVisit, TIntermAggregate* node); const TIdSetType& inductiveLoopIds; bool bad; TSourceLoc badLoc; }; // make sure symbols are inductive-loop indexes -void IndexSymbol(TIntermSymbol* symbol, TIntermTraverser* it) +void TIndexTraverser::visitSymbol(TIntermSymbol* symbol) { - TIndexTraverser* oit = static_cast(it); - - if (oit->inductiveLoopIds.find(symbol->getId()) == oit->inductiveLoopIds.end()) { - oit->bad = true; - oit->badLoc = symbol->getLoc(); + if (inductiveLoopIds.find(symbol->getId()) == inductiveLoopIds.end()) { + bad = true; + badLoc = symbol->getLoc(); } } // check for function calls, assuming they are bad; spec. doesn't really say -bool IndexAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverser* it) +bool TIndexTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node) { - TIndexTraverser* oit = static_cast(it); - if (node->getOp() == EOpFunctionCall) { - oit->bad = true; - oit->badLoc = node->getLoc(); + bad = true; + badLoc = node->getLoc(); } return true; @@ -187,9 +181,6 @@ void TParseContext::constantIndexExpressionCheck(TIntermNode* index) { TIndexTraverser it(inductiveLoopIds); - it.visitSymbol = IndexSymbol; - it.visitAggregate = IndexAggregate; - index->traverse(&it); if (it.bad) diff --git a/glslang/MachineIndependent/parseConst.cpp b/glslang/MachineIndependent/parseConst.cpp index 342fca51..ac643b68 100644 --- a/glslang/MachineIndependent/parseConst.cpp +++ b/glslang/MachineIndependent/parseConst.cpp @@ -43,9 +43,14 @@ namespace glslang { 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; @@ -59,32 +64,30 @@ public: int matrixRows; }; -bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverser* it) +bool TConstTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node) { - TConstTraverser* oit = static_cast(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(); } } @@ -92,55 +95,54 @@ bool ParseAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverse 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(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++; @@ -148,12 +150,12 @@ void ParseConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it) } 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]; @@ -166,16 +168,16 @@ void ParseConstantUnion(TIntermConstantUnion* node, TIntermTraverser* it) } 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++; @@ -192,9 +194,6 @@ bool TIntermediate::parseConstTree(TIntermNode* root, TConstUnionArray unionArra TConstTraverser it(unionArray, singleConstantParam, constructorType, t); - it.visitAggregate = ParseAggregate; - it.visitConstantUnion = ParseConstantUnion; - root->traverse(&it); if (it.error) return true; diff --git a/glslang/MachineIndependent/reflection.cpp b/glslang/MachineIndependent/reflection.cpp index 53f2d52e..164ced57 100644 --- a/glslang/MachineIndependent/reflection.cpp +++ b/glslang/MachineIndependent/reflection.cpp @@ -78,6 +78,11 @@ class TLiveTraverser : public TIntermTraverser { public: TLiveTraverser(const TIntermediate& i, TReflection& r) : intermediate(i), reflection(r) { } + virtual bool visitAggregate(TVisit, TIntermAggregate* node); + virtual bool visitBinary(TVisit, TIntermBinary* node); + virtual void visitSymbol(TIntermSymbol* base); + virtual bool visitSelection(TVisit, TIntermSelection* node); + // Track live funtions as well as uniforms, so that we don't visit dead functions // and only visit each function once. void addFunctionCall(TIntermAggregate* call) @@ -712,34 +717,28 @@ public: const int TLiveTraverser::baseAlignmentVec4Std140 = 16; -namespace { - // // Implement the traversal functions of interest. // // To catch which function calls are not dead, and hence which functions must be visited. -bool LiveAggregate(bool /* preVisit */, TIntermAggregate* node, TIntermTraverser* it) +bool TLiveTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node) { - TLiveTraverser* oit = static_cast(it); - if (node->getOp() == EOpFunctionCall) - oit->addFunctionCall(node); + addFunctionCall(node); return true; // traverse this subtree } // To catch dereferenced aggregates that must be reflected. // This catches them at the highest level possible in the tree. -bool LiveBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it) +bool TLiveTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node) { - TLiveTraverser* oit = static_cast(it); - switch (node->getOp()) { case EOpIndexDirect: case EOpIndexIndirect: case EOpIndexDirectStruct: - oit->addDereferencedUniform(node); + addDereferencedUniform(node); break; default: break; @@ -751,34 +750,28 @@ bool LiveBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it) } // To reflect non-dereferenced objects. -void LiveSymbol(TIntermSymbol* base, TIntermTraverser* it) +void TLiveTraverser::visitSymbol(TIntermSymbol* base) { - TLiveTraverser* oit = static_cast(it); - if (base->getQualifier().storage == EvqUniform) - oit->addUniform(*base); + addUniform(*base); } // To prune semantically dead paths. -bool LiveSelection(bool /* preVisit */, TIntermSelection* node, TIntermTraverser* it) +bool TLiveTraverser::visitSelection(TVisit /* visit */, TIntermSelection* node) { - TLiveTraverser* oit = static_cast(it); - TIntermConstantUnion* constant = node->getCondition()->getAsConstantUnion(); if (constant) { // cull the path that is dead if (constant->getConstArray()[0].getBConst() == true && node->getTrueBlock()) - node->getTrueBlock()->traverse(it); + node->getTrueBlock()->traverse(this); if (constant->getConstArray()[0].getBConst() == false && node->getFalseBlock()) - node->getFalseBlock()->traverse(it); + node->getFalseBlock()->traverse(this); return false; // don't traverse any more, we did it all above } else return true; // traverse the whole subtree } -} // end anonymous namespace - // // Implement TReflection methods. // @@ -792,10 +785,6 @@ bool TReflection::addStage(EShLanguage, const TIntermediate& intermediate) return false; TLiveTraverser it(intermediate, *this); - it.visitSymbol = LiveSymbol; - it.visitSelection = LiveSelection; - it.visitBinary = LiveBinary; - it.visitAggregate = LiveAggregate; // put main() on functions to process it.pushFunction("main(");