Edit

kc3-lang/angle/src/compiler/translator/IntermTraverse.cpp

Branch :

  • Show log

    Commit

  • Author : Zhenyao Mo
    Date : 2013-10-15 12:59:30
    Hash : 7cab38b5
    Message : Add an option to unfold short circuiting in AST. We replace "a || b" with "a ? true : b", "a && b" with "a ? b : false". This is to work around short circuiting bug in Mac drivers. ANGLEBUG=482 TEST=webgl conformance tests R=alokp@chromium.org, kbr@chromium.org Review URL: https://codereview.appspot.com/14529048 Conflicts: src/build_angle.gypi src/compiler/translator/Compiler.cpp Change-Id: Ic2384a97d58f54294efcb3a012deb2007a9fc658 Reviewed-on: https://chromium-review.googlesource.com/178996 Reviewed-by: Jamie Madill <jmadill@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org> Tested-by: Shannon Woods <shannonwoods@chromium.org>

  • src/compiler/translator/IntermTraverse.cpp
  • //
    // Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
    // Use of this source code is governed by a BSD-style license that can be
    // found in the LICENSE file.
    //
    
    #include "compiler/translator/intermediate.h"
    
    //
    // Traverse the intermediate representation tree, and
    // call a node type specific function for each node.
    // Done recursively through the member function Traverse().
    // Node types can be skipped if their function to call is 0,
    // but their subtree will still be traversed.
    // Nodes with children can have their whole subtree skipped
    // if preVisit is turned on and the type specific function
    // returns false.
    //
    // preVisit, postVisit, and rightToLeft control what order
    // nodes are visited in.
    //
    
    //
    // Traversal functions for terminals are straighforward....
    //
    void TIntermSymbol::traverse(TIntermTraverser *it)
    {
        it->visitSymbol(this);
    }
    
    void TIntermConstantUnion::traverse(TIntermTraverser *it)
    {
        it->visitConstantUnion(this);
    }
    
    //
    // Traverse a binary node.
    //
    void TIntermBinary::traverse(TIntermTraverser *it)
    {
        bool visit = true;
    
        //
        // visit the node before children if pre-visiting.
        //
        if (it->preVisit)
            visit = it->visitBinary(PreVisit, this);
    
        //
        // Visit the children, in the right order.
        //
        if (visit)
        {
            it->incrementDepth(this);
    
            if (it->rightToLeft)
            {
                if (right)
                    right->traverse(it);
    
                if (it->inVisit)
                    visit = it->visitBinary(InVisit, this);
    
                if (visit && left)
                    left->traverse(it);
            }
            else
            {
                if (left)
                    left->traverse(it);
    
                if (it->inVisit)
                    visit = it->visitBinary(InVisit, this);
    
                if (visit && right)
                    right->traverse(it);
            }
    
            it->decrementDepth();
        }
    
        //
        // Visit the node after the children, if requested and the traversal
        // hasn't been cancelled yet.
        //
        if (visit && it->postVisit)
            it->visitBinary(PostVisit, this);
    }
    
    //
    // Traverse a unary node.  Same comments in binary node apply here.
    //
    void TIntermUnary::traverse(TIntermTraverser *it)
    {
        bool visit = true;
    
        if (it->preVisit)
            visit = it->visitUnary(PreVisit, this);
    
        if (visit) {
            it->incrementDepth(this);
            operand->traverse(it);
            it->decrementDepth();
        }
    
        if (visit && it->postVisit)
            it->visitUnary(PostVisit, this);
    }
    
    //
    // Traverse an aggregate node.  Same comments in binary node apply here.
    //
    void TIntermAggregate::traverse(TIntermTraverser *it)
    {
        bool visit = true;
    
        if (it->preVisit)
            visit = it->visitAggregate(PreVisit, this);
    
        if (visit)
        {
            it->incrementDepth(this);
    
            if (it->rightToLeft)
            {
                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(InVisit, this);
                    }
                }
            }
            else
            {
                for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++)
                {
                    (*sit)->traverse(it);
    
                    if (visit && it->inVisit)
                    {
                        if (*sit != sequence.back())
                            visit = it->visitAggregate(InVisit, this);
                    }
                }
            }
    
            it->decrementDepth();
        }
    
        if (visit && it->postVisit)
            it->visitAggregate(PostVisit, this);
    }
    
    //
    // Traverse a selection node.  Same comments in binary node apply here.
    //
    void TIntermSelection::traverse(TIntermTraverser *it)
    {
        bool visit = true;
    
        if (it->preVisit)
            visit = it->visitSelection(PreVisit, this);
    
        if (visit) {
            it->incrementDepth(this);
            if (it->rightToLeft) {
                if (falseBlock)
                    falseBlock->traverse(it);
                if (trueBlock)
                    trueBlock->traverse(it);
                condition->traverse(it);
            } else {
                condition->traverse(it);
                if (trueBlock)
                    trueBlock->traverse(it);
                if (falseBlock)
                    falseBlock->traverse(it);
            }
            it->decrementDepth();
        }
    
        if (visit && it->postVisit)
            it->visitSelection(PostVisit, this);
    }
    
    //
    // Traverse a loop node.  Same comments in binary node apply here.
    //
    void TIntermLoop::traverse(TIntermTraverser *it)
    {
        bool visit = true;
    
        if (it->preVisit)
            visit = it->visitLoop(PreVisit, this);
    
        if (visit)
        {
            it->incrementDepth(this);
    
            if (it->rightToLeft)
            {
                if (expr)
                    expr->traverse(it);
    
                if (body)
                    body->traverse(it);
    
                if (cond)
                    cond->traverse(it);
    
                if (init)
                    init->traverse(it);
            }
            else
            {
                if (init)
                    init->traverse(it);
    
                if (cond)
                    cond->traverse(it);
    
                if (body)
                    body->traverse(it);
    
                if (expr)
                    expr->traverse(it);
            }
    
            it->decrementDepth();
        }
    
        if (visit && it->postVisit)
            it->visitLoop(PostVisit, this);
    }
    
    //
    // Traverse a branch node.  Same comments in binary node apply here.
    //
    void TIntermBranch::traverse(TIntermTraverser *it)
    {
        bool visit = true;
    
        if (it->preVisit)
            visit = it->visitBranch(PreVisit, this);
    
        if (visit && expression) {
            it->incrementDepth(this);
            expression->traverse(it);
            it->decrementDepth();
        }
    
        if (visit && it->postVisit)
            it->visitBranch(PostVisit, this);
    }