blob: 7a7efb71f5f09118ddb8efcd3cd8c7c6f12f363b [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
Jamie Madillb1a85f42014-08-19 15:23:24 -04007#include "compiler/translator/IntermNode.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 {
Zhenyao Mo7cab38b2013-10-15 12:59:30 -070054 it->incrementDepth(this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000055
Zhenyao Moe88dcaf2013-10-03 16:55:19 -070056 if (it->rightToLeft)
57 {
Zhenyao Moe40d1e92014-07-16 17:40:36 -070058 if (mRight)
59 mRight->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 Moe40d1e92014-07-16 17:40:36 -070064 if (visit && mLeft)
65 mLeft->traverse(it);
Zhenyao Moe88dcaf2013-10-03 16:55:19 -070066 }
67 else
68 {
Zhenyao Moe40d1e92014-07-16 17:40:36 -070069 if (mLeft)
70 mLeft->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
Zhenyao Moe40d1e92014-07-16 17:40:36 -070075 if (visit && mRight)
76 mRight->traverse(it);
Zhenyao Moe88dcaf2013-10-03 16:55:19 -070077 }
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) {
Zhenyao Mo7cab38b2013-10-15 12:59:30 -0700101 it->incrementDepth(this);
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700102 mOperand->traverse(it);
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700103 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 {
Zhenyao Mo7cab38b2013-10-15 12:59:30 -0700122 it->incrementDepth(this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000123
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700124 if (it->rightToLeft)
125 {
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700126 for (TIntermSequence::reverse_iterator sit = mSequence.rbegin();
127 sit != mSequence.rend(); sit++)
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700128 {
129 (*sit)->traverse(it);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000130
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700131 if (visit && it->inVisit)
132 {
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700133 if (*sit != mSequence.front())
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700134 visit = it->visitAggregate(InVisit, this);
135 }
136 }
137 }
138 else
139 {
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700140 for (TIntermSequence::iterator sit = mSequence.begin();
141 sit != mSequence.end(); sit++)
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700142 {
143 (*sit)->traverse(it);
144
145 if (visit && it->inVisit)
146 {
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700147 if (*sit != mSequence.back())
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700148 visit = it->visitAggregate(InVisit, this);
149 }
150 }
151 }
152
153 it->decrementDepth();
154 }
155
156 if (visit && it->postVisit)
157 it->visitAggregate(PostVisit, this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000158}
159
160//
161// Traverse a selection node. Same comments in binary node apply here.
162//
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700163void TIntermSelection::traverse(TIntermTraverser *it)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000164{
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700165 bool visit = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000166
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700167 if (it->preVisit)
168 visit = it->visitSelection(PreVisit, this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000169
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700170 if (visit)
171 {
Zhenyao Mo7cab38b2013-10-15 12:59:30 -0700172 it->incrementDepth(this);
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700173 if (it->rightToLeft)
174 {
175 if (mFalseBlock)
176 mFalseBlock->traverse(it);
177 if (mTrueBlock)
178 mTrueBlock->traverse(it);
179 mCondition->traverse(it);
180 }
181 else
182 {
183 mCondition->traverse(it);
184 if (mTrueBlock)
185 mTrueBlock->traverse(it);
186 if (mFalseBlock)
187 mFalseBlock->traverse(it);
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700188 }
189 it->decrementDepth();
190 }
191
192 if (visit && it->postVisit)
193 it->visitSelection(PostVisit, this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000194}
195
196//
Olli Etuahoa3a36662015-02-17 13:46:51 +0200197// Traverse a switch node. Same comments in binary node apply here.
198//
199void TIntermSwitch::traverse(TIntermTraverser *it)
200{
201 bool visit = true;
202
203 if (it->preVisit)
204 visit = it->visitSwitch(PreVisit, this);
205
206 if (visit)
207 {
208 it->incrementDepth(this);
209 if (it->rightToLeft)
210 {
211 if (mStatementList)
212 mStatementList->traverse(it);
213 if (it->inVisit)
214 visit = it->visitSwitch(InVisit, this);
215 if (visit)
216 mInit->traverse(it);
217 }
218 else
219 {
220 mInit->traverse(it);
221 if (it->inVisit)
222 visit = it->visitSwitch(InVisit, this);
223 if (visit && mStatementList)
224 mStatementList->traverse(it);
225 }
226 it->decrementDepth();
227 }
228
229 if (visit && it->postVisit)
230 it->visitSwitch(PostVisit, this);
231}
232
233//
234// Traverse a switch node. Same comments in binary node apply here.
235//
236void TIntermCase::traverse(TIntermTraverser *it)
237{
238 bool visit = true;
239
240 if (it->preVisit)
241 visit = it->visitCase(PreVisit, this);
242
243 if (visit && mCondition)
244 mCondition->traverse(it);
245
246 if (visit && it->postVisit)
247 it->visitCase(PostVisit, this);
248}
249
250//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000251// Traverse a loop node. Same comments in binary node apply here.
252//
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700253void TIntermLoop::traverse(TIntermTraverser *it)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000254{
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700255 bool visit = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000256
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700257 if (it->preVisit)
258 visit = it->visitLoop(PreVisit, this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000259
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700260 if (visit)
261 {
Zhenyao Mo7cab38b2013-10-15 12:59:30 -0700262 it->incrementDepth(this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000263
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700264 if (it->rightToLeft)
265 {
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700266 if (mExpr)
267 mExpr->traverse(it);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000268
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700269 if (mBody)
270 mBody->traverse(it);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000271
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700272 if (mCond)
273 mCond->traverse(it);
Zhenyao Mo6cb95f32013-10-03 17:01:52 -0700274
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700275 if (mInit)
276 mInit->traverse(it);
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700277 }
278 else
279 {
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700280 if (mInit)
281 mInit->traverse(it);
Zhenyao Mo6cb95f32013-10-03 17:01:52 -0700282
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700283 if (mCond)
284 mCond->traverse(it);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000285
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700286 if (mBody)
287 mBody->traverse(it);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000288
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700289 if (mExpr)
290 mExpr->traverse(it);
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700291 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000292
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700293 it->decrementDepth();
294 }
295
296 if (visit && it->postVisit)
297 it->visitLoop(PostVisit, this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000298}
299
300//
301// Traverse a branch node. Same comments in binary node apply here.
302//
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700303void TIntermBranch::traverse(TIntermTraverser *it)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000304{
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700305 bool visit = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000306
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700307 if (it->preVisit)
308 visit = it->visitBranch(PreVisit, this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000309
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700310 if (visit && mExpression) {
Zhenyao Mo7cab38b2013-10-15 12:59:30 -0700311 it->incrementDepth(this);
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700312 mExpression->traverse(it);
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700313 it->decrementDepth();
314 }
315
316 if (visit && it->postVisit)
317 it->visitBranch(PostVisit, this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000318}
319
Jamie Madill4cfb1e82014-07-07 12:49:23 -0400320void TIntermRaw::traverse(TIntermTraverser *it)
321{
322 it->visitRaw(this);
323}