Improvement to the AST traversal infrastructure.
authorJohn Kessenich <cepheus@frii.com>
Sat, 11 Jan 2014 19:29:55 +0000 (19:29 +0000)
committerJohn Kessenich <cepheus@frii.com>
Sat, 11 Jan 2014 19:29:55 +0000 (19:29 +0000)
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

glslang/Include/intermediate.h
glslang/Include/revision.h
glslang/MachineIndependent/IntermTraverse.cpp
glslang/MachineIndependent/RemoveTree.cpp
glslang/MachineIndependent/intermOut.cpp
glslang/MachineIndependent/limits.cpp
glslang/MachineIndependent/parseConst.cpp
glslang/MachineIndependent/reflection.cpp

index b73083a..e65dd92 100644 (file)
@@ -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())
-
-    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
index 457b857..56a6223 100644 (file)
@@ -9,5 +9,5 @@
 // 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
index f609ff7..28f8da8 100644 (file)
@@ -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(TIntermTraverserit)
+void TIntermSymbol::traverse(TIntermTraverser *it)
 {
-    if (it->visitSymbol)
-        it->visitSymbol(this, it);
+    it->visitSymbol(this);
 }
 
-void TIntermConstantUnion::traverse(TIntermTraverserit)
+void TIntermConstantUnion::traverse(TIntermTraverser *it)
 {
-    if (it->visitConstantUnion)
-        it->visitConstantUnion(this, it);
+    it->visitConstantUnion(this);
 }
 
 //
 // Traverse a binary node.
 //
-void TIntermBinary::traverse(TIntermTraverserit)
+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(TIntermTraverserit)
+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(TIntermTraverserit)
+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(TIntermTraverserit)
+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(TIntermTraverserit)
+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(TIntermTraverserit)
+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
index ee72a72..a4fa551 100644 (file)
@@ -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);
 }
index 0a99753..64febdb 100644 (file)
@@ -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);
 }
 
index 0c660a8..137c051 100644 (file)
@@ -63,7 +63,13 @@ namespace glslang {
 \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
@@ -71,49 +77,43 @@ public:
 };\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
@@ -132,10 +132,6 @@ void TParseContext::inductiveLoopBodyCheck(TIntermNode* body, int loopId, TSymbo
     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
@@ -151,30 +147,28 @@ void TParseContext::inductiveLoopBodyCheck(TIntermNode* body, int loopId, TSymbo
 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
@@ -187,9 +181,6 @@ void TParseContext::constantIndexExpressionCheck(TIntermNode* index)
 {\r
     TIndexTraverser it(inductiveLoopIds);\r
 \r
-    it.visitSymbol = IndexSymbol;\r
-    it.visitAggregate = IndexAggregate;\r
-\r
     index->traverse(&it);\r
 \r
     if (it.bad)\r
index 342fca5..ac643b6 100644 (file)
@@ -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<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();
         }
     }       
 
@@ -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<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++;
@@ -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;
index 53f2d52..164ced5 100644 (file)
@@ -78,6 +78,11 @@ class TLiveTraverser : public TIntermTraverser {
 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
@@ -712,34 +717,28 @@ public:
 \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
@@ -751,34 +750,28 @@ bool LiveBinary(bool /* preVisit */, TIntermBinary* node, TIntermTraverser* it)
 }\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
@@ -792,10 +785,6 @@ bool TReflection::addStage(EShLanguage, const TIntermediate& intermediate)
         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