2 //Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
5 //Redistribution and use in source and binary forms, with or without
6 //modification, are permitted provided that the following conditions
9 // Redistributions of source code must retain the above copyright
10 // notice, this list of conditions and the following disclaimer.
12 // Redistributions in binary form must reproduce the above
13 // copyright notice, this list of conditions and the following
14 // disclaimer in the documentation and/or other materials provided
15 // with the distribution.
17 // Neither the name of 3Dlabs Inc. Ltd. nor the names of its
18 // contributors may be used to endorse or promote products derived
19 // from this software without specific prior written permission.
21 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 //"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24 //FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25 //COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 //INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27 //BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29 //CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 //LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31 //ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32 //POSSIBILITY OF SUCH DAMAGE.
35 #include "../Include/intermediate.h"
38 // Traverse the intermediate representation tree, and
39 // call a node type specific function for each node.
40 // Done recursively through the member function Traverse().
41 // Node types can be skipped if their function to call is 0,
42 // but their subtree will still be traversed.
43 // Nodes with children can have their whole subtree skipped
44 // if preVisit is turned on and the type specific function
47 // preVisit, postVisit, and rightToLeft control what order
48 // nodes are visited in.
52 // Traversal functions for terminals are straighforward....
54 void TIntermSymbol::traverse(TIntermTraverser
* it
)
57 it
->visitSymbol(this, it
);
60 void TIntermConstantUnion::traverse(TIntermTraverser
* it
)
62 if (it
->visitConstantUnion
)
63 it
->visitConstantUnion(this, it
);
67 // Traverse a binary node.
69 void TIntermBinary::traverse(TIntermTraverser
* it
)
74 // visit the node before children if pre-visiting.
76 if (it
->preVisit
&& it
->visitBinary
)
77 visit
= it
->visitBinary(true, this, it
);
80 // Visit the children, in the right order.
84 if (it
->rightToLeft
) {
99 // Visit the node after the children, if requested and the traversal
100 // hasn't been cancelled yet.
102 if (visit
&& it
->postVisit
&& it
->visitBinary
)
103 it
->visitBinary(false, this, it
);
107 // Traverse a unary node. Same comments in binary node apply here.
109 void TIntermUnary::traverse(TIntermTraverser
* it
)
113 if (it
->preVisit
&& it
->visitUnary
)
114 visit
= it
->visitUnary(true, this, it
);
118 operand
->traverse(it
);
122 if (visit
&& it
->postVisit
&& it
->visitUnary
)
123 it
->visitUnary(false, this, it
);
127 // Traverse an aggregate node. Same comments in binary node apply here.
129 void TIntermAggregate::traverse(TIntermTraverser
* it
)
133 if (it
->preVisit
&& it
->visitAggregate
)
134 visit
= it
->visitAggregate(true, this, it
);
139 TIntermSequence::iterator sit
;
140 if (it
->rightToLeft
) {
141 sit
= sequence
.end();
142 while (sit
!= sequence
.begin()) {
144 (*sit
)->traverse(it
);
147 for (sit
= sequence
.begin(); sit
!= sequence
.end(); ++sit
)
148 (*sit
)->traverse(it
);
154 if (visit
&& it
->postVisit
&& it
->visitAggregate
)
155 it
->visitAggregate(false, this, it
);
159 // Traverse a selection node. Same comments in binary node apply here.
161 void TIntermSelection::traverse(TIntermTraverser
* it
)
165 if (it
->preVisit
&& it
->visitSelection
)
166 visit
= it
->visitSelection(true, this, it
);
170 if (it
->rightToLeft
) {
172 falseBlock
->traverse(it
);
174 trueBlock
->traverse(it
);
175 condition
->traverse(it
);
177 condition
->traverse(it
);
179 trueBlock
->traverse(it
);
181 falseBlock
->traverse(it
);
186 if (visit
&& it
->postVisit
&& it
->visitSelection
)
187 it
->visitSelection(false, this, it
);
191 // Traverse a loop node. Same comments in binary node apply here.
193 void TIntermLoop::traverse(TIntermTraverser
* it
)
197 if (it
->preVisit
&& it
->visitLoop
)
198 visit
= it
->visitLoop(true, this, it
);
202 if (it
->rightToLeft
) {
204 terminal
->traverse(it
);
215 terminal
->traverse(it
);
220 if (visit
&& it
->postVisit
&& it
->visitLoop
)
221 it
->visitLoop(false, this, it
);
225 // Traverse a branch node. Same comments in binary node apply here.
227 void TIntermBranch::traverse(TIntermTraverser
* it
)
231 if (it
->preVisit
&& it
->visitBranch
)
232 visit
= it
->visitBranch(true, this, it
);
234 if (visit
&& expression
) {
236 expression
->traverse(it
);
240 if (visit
&& it
->postVisit
&& it
->visitBranch
)
241 it
->visitBranch(false, this, it
);