blob: 0e345d2e37c5bb7ca42929e5851ab27415aa83f4 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
2// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
Geoff Lang17732822013-08-29 13:46:49 -04007#include "compiler/translator/intermediate.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00008
9//
10// Traverse the intermediate representation tree, and
11// call a node type specific function for each node.
12// Done recursively through the member function Traverse().
13// Node types can be skipped if their function to call is 0,
14// but their subtree will still be traversed.
15// Nodes with children can have their whole subtree skipped
16// if preVisit is turned on and the type specific function
17// returns false.
18//
19// preVisit, postVisit, and rightToLeft control what order
20// nodes are visited in.
21//
22
23//
24// Traversal functions for terminals are straighforward....
25//
Zhenyao Moe88dcaf2013-10-03 16:55:19 -070026void TIntermSymbol::traverse(TIntermTraverser *it)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000027{
Zhenyao Moe88dcaf2013-10-03 16:55:19 -070028 it->visitSymbol(this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000029}
30
Zhenyao Moe88dcaf2013-10-03 16:55:19 -070031void TIntermConstantUnion::traverse(TIntermTraverser *it)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000032{
Zhenyao Moe88dcaf2013-10-03 16:55:19 -070033 it->visitConstantUnion(this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000034}
35
36//
37// Traverse a binary node.
38//
Zhenyao Moe88dcaf2013-10-03 16:55:19 -070039void TIntermBinary::traverse(TIntermTraverser *it)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000040{
Zhenyao Moe88dcaf2013-10-03 16:55:19 -070041 bool visit = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000042
Zhenyao Moe88dcaf2013-10-03 16:55:19 -070043 //
44 // visit the node before children if pre-visiting.
45 //
46 if (it->preVisit)
47 visit = it->visitBinary(PreVisit, this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000048
Zhenyao Moe88dcaf2013-10-03 16:55:19 -070049 //
50 // Visit the children, in the right order.
51 //
52 if (visit)
53 {
54 it->incrementDepth();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000055
Zhenyao Moe88dcaf2013-10-03 16:55:19 -070056 if (it->rightToLeft)
57 {
58 if (right)
59 right->traverse(it);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000060
Zhenyao Moe88dcaf2013-10-03 16:55:19 -070061 if (it->inVisit)
62 visit = it->visitBinary(InVisit, this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000063
Zhenyao Moe88dcaf2013-10-03 16:55:19 -070064 if (visit && left)
65 left->traverse(it);
66 }
67 else
68 {
69 if (left)
70 left->traverse(it);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000071
Zhenyao Moe88dcaf2013-10-03 16:55:19 -070072 if (it->inVisit)
73 visit = it->visitBinary(InVisit, this);
74
75 if (visit && right)
76 right->traverse(it);
77 }
78
79 it->decrementDepth();
80 }
81
82 //
83 // Visit the node after the children, if requested and the traversal
84 // hasn't been cancelled yet.
85 //
86 if (visit && it->postVisit)
87 it->visitBinary(PostVisit, this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000088}
89
90//
91// Traverse a unary node. Same comments in binary node apply here.
92//
Zhenyao Moe88dcaf2013-10-03 16:55:19 -070093void TIntermUnary::traverse(TIntermTraverser *it)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000094{
Zhenyao Moe88dcaf2013-10-03 16:55:19 -070095 bool visit = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000096
Zhenyao Moe88dcaf2013-10-03 16:55:19 -070097 if (it->preVisit)
98 visit = it->visitUnary(PreVisit, this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000099
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700100 if (visit) {
101 it->incrementDepth();
102 operand->traverse(it);
103 it->decrementDepth();
104 }
105
106 if (visit && it->postVisit)
107 it->visitUnary(PostVisit, this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000108}
109
110//
111// Traverse an aggregate node. Same comments in binary node apply here.
112//
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700113void TIntermAggregate::traverse(TIntermTraverser *it)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000114{
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700115 bool visit = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000116
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700117 if (it->preVisit)
118 visit = it->visitAggregate(PreVisit, this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000119
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700120 if (visit)
121 {
122 it->incrementDepth();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000123
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700124 if (it->rightToLeft)
125 {
126 for (TIntermSequence::reverse_iterator sit = sequence.rbegin(); sit != sequence.rend(); sit++)
127 {
128 (*sit)->traverse(it);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000129
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700130 if (visit && it->inVisit)
131 {
132 if (*sit != sequence.front())
133 visit = it->visitAggregate(InVisit, this);
134 }
135 }
136 }
137 else
138 {
139 for (TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++)
140 {
141 (*sit)->traverse(it);
142
143 if (visit && it->inVisit)
144 {
145 if (*sit != sequence.back())
146 visit = it->visitAggregate(InVisit, this);
147 }
148 }
149 }
150
151 it->decrementDepth();
152 }
153
154 if (visit && it->postVisit)
155 it->visitAggregate(PostVisit, this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000156}
157
158//
159// Traverse a selection node. Same comments in binary node apply here.
160//
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700161void TIntermSelection::traverse(TIntermTraverser *it)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000162{
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700163 bool visit = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000164
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700165 if (it->preVisit)
166 visit = it->visitSelection(PreVisit, this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000167
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700168 if (visit) {
169 it->incrementDepth();
170 if (it->rightToLeft) {
171 if (falseBlock)
172 falseBlock->traverse(it);
173 if (trueBlock)
174 trueBlock->traverse(it);
175 condition->traverse(it);
176 } else {
177 condition->traverse(it);
178 if (trueBlock)
179 trueBlock->traverse(it);
180 if (falseBlock)
181 falseBlock->traverse(it);
182 }
183 it->decrementDepth();
184 }
185
186 if (visit && it->postVisit)
187 it->visitSelection(PostVisit, this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000188}
189
190//
191// Traverse a loop node. Same comments in binary node apply here.
192//
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700193void TIntermLoop::traverse(TIntermTraverser *it)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000194{
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700195 bool visit = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000196
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700197 if (it->preVisit)
198 visit = it->visitLoop(PreVisit, this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000199
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700200 if (visit)
201 {
202 it->incrementDepth();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000203
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700204 if (it->rightToLeft)
205 {
206 if (expr)
207 expr->traverse(it);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000208
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700209 if (body)
210 body->traverse(it);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000211
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700212 if (cond)
213 cond->traverse(it);
Zhenyao Mo6cb95f32013-10-03 17:01:52 -0700214
215 if (init)
216 init->traverse(it);
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700217 }
218 else
219 {
Zhenyao Mo6cb95f32013-10-03 17:01:52 -0700220 if (init)
221 init->traverse(it);
222
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700223 if (cond)
224 cond->traverse(it);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000225
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700226 if (body)
227 body->traverse(it);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000228
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700229 if (expr)
230 expr->traverse(it);
231 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000232
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700233 it->decrementDepth();
234 }
235
236 if (visit && it->postVisit)
237 it->visitLoop(PostVisit, this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000238}
239
240//
241// Traverse a branch node. Same comments in binary node apply here.
242//
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700243void TIntermBranch::traverse(TIntermTraverser *it)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000244{
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700245 bool visit = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000246
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700247 if (it->preVisit)
248 visit = it->visitBranch(PreVisit, this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000249
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700250 if (visit && expression) {
251 it->incrementDepth();
252 expression->traverse(it);
253 it->decrementDepth();
254 }
255
256 if (visit && it->postVisit)
257 it->visitBranch(PostVisit, this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000258}
259