blob: 48d2013cc57df08522e801939e7607f5ba4c0371 [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 {
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//
197// Traverse a loop node. Same comments in binary node apply here.
198//
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700199void TIntermLoop::traverse(TIntermTraverser *it)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000200{
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700201 bool visit = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000202
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700203 if (it->preVisit)
204 visit = it->visitLoop(PreVisit, this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000205
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700206 if (visit)
207 {
Zhenyao Mo7cab38b2013-10-15 12:59:30 -0700208 it->incrementDepth(this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000209
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700210 if (it->rightToLeft)
211 {
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700212 if (mExpr)
213 mExpr->traverse(it);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000214
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700215 if (mBody)
216 mBody->traverse(it);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000217
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700218 if (mCond)
219 mCond->traverse(it);
Zhenyao Mo6cb95f32013-10-03 17:01:52 -0700220
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700221 if (mInit)
222 mInit->traverse(it);
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700223 }
224 else
225 {
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700226 if (mInit)
227 mInit->traverse(it);
Zhenyao Mo6cb95f32013-10-03 17:01:52 -0700228
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700229 if (mCond)
230 mCond->traverse(it);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000231
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700232 if (mBody)
233 mBody->traverse(it);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000234
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700235 if (mExpr)
236 mExpr->traverse(it);
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700237 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000238
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700239 it->decrementDepth();
240 }
241
242 if (visit && it->postVisit)
243 it->visitLoop(PostVisit, this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000244}
245
246//
247// Traverse a branch node. Same comments in binary node apply here.
248//
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700249void TIntermBranch::traverse(TIntermTraverser *it)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000250{
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700251 bool visit = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000252
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700253 if (it->preVisit)
254 visit = it->visitBranch(PreVisit, this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000255
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700256 if (visit && mExpression) {
Zhenyao Mo7cab38b2013-10-15 12:59:30 -0700257 it->incrementDepth(this);
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700258 mExpression->traverse(it);
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700259 it->decrementDepth();
260 }
261
262 if (visit && it->postVisit)
263 it->visitBranch(PostVisit, this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000264}
265
Jamie Madill4cfb1e82014-07-07 12:49:23 -0400266void TIntermRaw::traverse(TIntermTraverser *it)
267{
268 it->visitRaw(this);
269}