| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309 |
- //
- // Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
- // Copyright (C) 2013 LunarG, Inc.
- // Copyright (c) 2002-2010 The ANGLE Project Authors.
- //
- // All rights reserved.
- //
- // Redistribution and use in source and binary forms, with or without
- // modification, are permitted provided that the following conditions
- // are met:
- //
- // Redistributions of source code must retain the above copyright
- // notice, this list of conditions and the following disclaimer.
- //
- // Redistributions in binary form must reproduce the above
- // copyright notice, this list of conditions and the following
- // disclaimer in the documentation and/or other materials provided
- // with the distribution.
- //
- // Neither the name of 3Dlabs Inc. Ltd. nor the names of its
- // contributors may be used to endorse or promote products derived
- // from this software without specific prior written permission.
- //
- // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
- // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
- // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
- // POSSIBILITY OF SUCH DAMAGE.
- //
- #include "../Include/intermediate.h"
- namespace glslang {
- //
- // 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 straightforward....
- //
- void TIntermMethod::traverse(TIntermTraverser*)
- {
- // Tree should always resolve all methods as a non-method.
- }
- void TIntermSymbol::traverse(TIntermTraverser *it)
- {
- it->visitSymbol(this);
- }
- void TIntermConstantUnion::traverse(TIntermTraverser *it)
- {
- it->visitConstantUnion(this);
- }
- const TString& TIntermSymbol::getAccessName() const {
- if (getBasicType() == EbtBlock)
- return getType().getTypeName();
- else
- return getName();
- }
- //
- // 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(EvPreVisit, 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(EvInVisit, this);
- if (visit && left)
- left->traverse(it);
- } else {
- if (left)
- left->traverse(it);
- if (it->inVisit)
- visit = it->visitBinary(EvInVisit, this);
- if (visit && right)
- right->traverse(it);
- }
- it->decrementDepth();
- }
- //
- // Visit the node after the children, if requested and the traversal
- // hasn't been canceled yet.
- //
- if (visit && it->postVisit)
- it->visitBinary(EvPostVisit, 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(EvPreVisit, this);
- if (visit) {
- it->incrementDepth(this);
- operand->traverse(it);
- it->decrementDepth();
- }
- if (visit && it->postVisit)
- it->visitUnary(EvPostVisit, 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(EvPreVisit, 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(EvInVisit, 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(EvInVisit, this);
- }
- }
- }
- it->decrementDepth();
- }
- if (visit && it->postVisit)
- it->visitAggregate(EvPostVisit, 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(EvPreVisit, 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(EvPostVisit, 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(EvPreVisit, this);
- if (visit) {
- 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->decrementDepth();
- }
- if (visit && it->postVisit)
- it->visitLoop(EvPostVisit, 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(EvPreVisit, this);
- if (visit && expression) {
- it->incrementDepth(this);
- expression->traverse(it);
- it->decrementDepth();
- }
- if (visit && it->postVisit)
- it->visitBranch(EvPostVisit, this);
- }
- //
- // Traverse a switch node.
- //
- void TIntermSwitch::traverse(TIntermTraverser* it)
- {
- bool visit = true;
- if (it->preVisit)
- visit = it->visitSwitch(EvPreVisit, this);
- if (visit) {
- it->incrementDepth(this);
- if (it->rightToLeft) {
- body->traverse(it);
- condition->traverse(it);
- } else {
- condition->traverse(it);
- body->traverse(it);
- }
- it->decrementDepth();
- }
- if (visit && it->postVisit)
- it->visitSwitch(EvPostVisit, this);
- }
- } // end namespace glslang
|