blob: 09d52e20406771b87a3a22274107e51affa4c8e9 [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"
Olli Etuahod4f303e2015-05-20 17:09:06 +03008#include "compiler/translator/InfoSink.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00009
Olli Etuaho27446bd2015-08-10 14:59:53 +030010void TIntermSymbol::traverse(TIntermTraverser *it)
11{
12 it->traverseSymbol(this);
13}
14
15void TIntermRaw::traverse(TIntermTraverser *it)
16{
17 it->traverseRaw(this);
18}
19
20void TIntermConstantUnion::traverse(TIntermTraverser *it)
21{
22 it->traverseConstantUnion(this);
23}
24
25void TIntermBinary::traverse(TIntermTraverser *it)
26{
27 it->traverseBinary(this);
28}
29
30void TIntermUnary::traverse(TIntermTraverser *it)
31{
32 it->traverseUnary(this);
33}
34
35void TIntermSelection::traverse(TIntermTraverser *it)
36{
37 it->traverseSelection(this);
38}
39
40void TIntermSwitch::traverse(TIntermTraverser *it)
41{
42 it->traverseSwitch(this);
43}
44
45void TIntermCase::traverse(TIntermTraverser *it)
46{
47 it->traverseCase(this);
48}
49
50void TIntermAggregate::traverse(TIntermTraverser *it)
51{
52 it->traverseAggregate(this);
53}
54
55void TIntermLoop::traverse(TIntermTraverser *it)
56{
57 it->traverseLoop(this);
58}
59
60void TIntermBranch::traverse(TIntermTraverser *it)
61{
62 it->traverseBranch(this);
63}
64
Olli Etuaho56eea882015-05-18 12:41:03 +030065void TIntermTraverser::pushParentBlock(TIntermAggregate *node)
66{
Olli Etuaho64f0be92015-06-03 17:38:34 +030067 mParentBlockStack.push_back(ParentBlock(node, 0));
Olli Etuaho56eea882015-05-18 12:41:03 +030068}
69
70void TIntermTraverser::incrementParentBlockPos()
71{
Olli Etuaho64f0be92015-06-03 17:38:34 +030072 ++mParentBlockStack.back().pos;
Olli Etuaho56eea882015-05-18 12:41:03 +030073}
74
75void TIntermTraverser::popParentBlock()
76{
77 ASSERT(!mParentBlockStack.empty());
78 mParentBlockStack.pop_back();
79}
80
81void TIntermTraverser::insertStatementsInParentBlock(const TIntermSequence &insertions)
82{
83 ASSERT(!mParentBlockStack.empty());
84 NodeInsertMultipleEntry insert(mParentBlockStack.back().node, mParentBlockStack.back().pos, insertions);
85 mInsertions.push_back(insert);
86}
87
Olli Etuahoa4aa4e32015-06-04 15:54:30 +030088TIntermSymbol *TIntermTraverser::createTempSymbol(const TType &type, TQualifier qualifier)
Olli Etuahod4f303e2015-05-20 17:09:06 +030089{
90 // Each traversal uses at most one temporary variable, so the index stays the same within a single traversal.
91 TInfoSinkBase symbolNameOut;
92 ASSERT(mTemporaryIndex != nullptr);
93 symbolNameOut << "s" << (*mTemporaryIndex);
94 TString symbolName = symbolNameOut.c_str();
95
96 TIntermSymbol *node = new TIntermSymbol(0, symbolName, type);
97 node->setInternal(true);
Olli Etuahoa4aa4e32015-06-04 15:54:30 +030098 node->getTypePointer()->setQualifier(qualifier);
Olli Etuahod4f303e2015-05-20 17:09:06 +030099 return node;
100}
101
Olli Etuahoa4aa4e32015-06-04 15:54:30 +0300102TIntermSymbol *TIntermTraverser::createTempSymbol(const TType &type)
103{
104 return createTempSymbol(type, EvqTemporary);
105}
106
Olli Etuaho4f1af782015-05-25 11:55:07 +0300107TIntermAggregate *TIntermTraverser::createTempDeclaration(const TType &type)
108{
109 TIntermAggregate *tempDeclaration = new TIntermAggregate(EOpDeclaration);
110 tempDeclaration->getSequence()->push_back(createTempSymbol(type));
111 return tempDeclaration;
112}
Olli Etuahod4f303e2015-05-20 17:09:06 +0300113
Olli Etuahoa4aa4e32015-06-04 15:54:30 +0300114TIntermAggregate *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer, TQualifier qualifier)
Olli Etuahod4f303e2015-05-20 17:09:06 +0300115{
116 ASSERT(initializer != nullptr);
Olli Etuahoa4aa4e32015-06-04 15:54:30 +0300117 TIntermSymbol *tempSymbol = createTempSymbol(initializer->getType(), qualifier);
Olli Etuahod4f303e2015-05-20 17:09:06 +0300118 TIntermAggregate *tempDeclaration = new TIntermAggregate(EOpDeclaration);
119 TIntermBinary *tempInit = new TIntermBinary(EOpInitialize);
120 tempInit->setLeft(tempSymbol);
121 tempInit->setRight(initializer);
122 tempInit->setType(tempSymbol->getType());
123 tempDeclaration->getSequence()->push_back(tempInit);
124 return tempDeclaration;
125}
126
Olli Etuahoa4aa4e32015-06-04 15:54:30 +0300127TIntermAggregate *TIntermTraverser::createTempInitDeclaration(TIntermTyped *initializer)
128{
129 return createTempInitDeclaration(initializer, EvqTemporary);
130}
131
Olli Etuahod4f303e2015-05-20 17:09:06 +0300132TIntermBinary *TIntermTraverser::createTempAssignment(TIntermTyped *rightNode)
133{
134 ASSERT(rightNode != nullptr);
135 TIntermSymbol *tempSymbol = createTempSymbol(rightNode->getType());
136 TIntermBinary *assignment = new TIntermBinary(EOpAssign);
137 assignment->setLeft(tempSymbol);
138 assignment->setRight(rightNode);
139 assignment->setType(tempSymbol->getType());
140 return assignment;
141}
142
143void TIntermTraverser::useTemporaryIndex(unsigned int *temporaryIndex)
144{
145 mTemporaryIndex = temporaryIndex;
146}
147
148void TIntermTraverser::nextTemporaryIndex()
149{
150 ASSERT(mTemporaryIndex != nullptr);
151 ++(*mTemporaryIndex);
152}
153
Olli Etuahoa26ad582015-08-04 13:51:47 +0300154void TIntermTraverser::addToFunctionMap(const TString &name, TIntermSequence *paramSequence)
155{
156 mFunctionMap[name] = paramSequence;
157}
158
159bool TIntermTraverser::isInFunctionMap(const TIntermAggregate *callNode) const
160{
161 ASSERT(callNode->getOp() == EOpFunctionCall || callNode->getOp() == EOpInternalFunctionCall);
162 return (mFunctionMap.find(callNode->getName()) != mFunctionMap.end());
163}
164
165TIntermSequence *TIntermTraverser::getFunctionParameters(const TIntermAggregate *callNode)
166{
167 ASSERT(isInFunctionMap(callNode));
168 return mFunctionMap[callNode->getName()];
169}
170
171void TIntermTraverser::setInFunctionCallOutParameter(bool inOutParameter)
172{
173 mInFunctionCallOutParameter = inOutParameter;
174}
175
Olli Etuaho8afe1e12015-08-05 18:00:01 +0300176bool TIntermTraverser::isInFunctionCallOutParameter() const
177{
178 return mInFunctionCallOutParameter;
179}
180
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000181//
182// Traverse the intermediate representation tree, and
183// call a node type specific function for each node.
184// Done recursively through the member function Traverse().
185// Node types can be skipped if their function to call is 0,
186// but their subtree will still be traversed.
187// Nodes with children can have their whole subtree skipped
188// if preVisit is turned on and the type specific function
189// returns false.
190//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000191
192//
193// Traversal functions for terminals are straighforward....
194//
Olli Etuaho27446bd2015-08-10 14:59:53 +0300195void TIntermTraverser::traverseSymbol(TIntermSymbol *node)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000196{
Olli Etuaho27446bd2015-08-10 14:59:53 +0300197 visitSymbol(node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000198}
199
Olli Etuaho27446bd2015-08-10 14:59:53 +0300200void TIntermTraverser::traverseConstantUnion(TIntermConstantUnion *node)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000201{
Olli Etuaho27446bd2015-08-10 14:59:53 +0300202 visitConstantUnion(node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000203}
204
205//
206// Traverse a binary node.
207//
Olli Etuaho27446bd2015-08-10 14:59:53 +0300208void TIntermTraverser::traverseBinary(TIntermBinary *node)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000209{
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700210 bool visit = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000211
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700212 //
213 // visit the node before children if pre-visiting.
214 //
Olli Etuaho27446bd2015-08-10 14:59:53 +0300215 if (preVisit)
216 visit = visitBinary(PreVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000217
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700218 //
219 // Visit the children, in the right order.
220 //
221 if (visit)
222 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300223 incrementDepth(node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000224
Olli Etuaho8afe1e12015-08-05 18:00:01 +0300225 // Some binary operations like indexing can be inside an expression which must be an
226 // l-value.
Olli Etuaho27446bd2015-08-10 14:59:53 +0300227 bool parentOperatorRequiresLValue = operatorRequiresLValue();
228 bool parentInFunctionCallOutParameter = isInFunctionCallOutParameter();
229 if (node->isAssignment())
Olli Etuahoa26ad582015-08-04 13:51:47 +0300230 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300231 ASSERT(!isLValueRequiredHere());
232 setOperatorRequiresLValue(true);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300233 }
234
Olli Etuaho27446bd2015-08-10 14:59:53 +0300235 if (node->getLeft())
236 node->getLeft()->traverse(this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000237
Olli Etuaho27446bd2015-08-10 14:59:53 +0300238 if (inVisit)
239 visit = visitBinary(InVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000240
Olli Etuaho27446bd2015-08-10 14:59:53 +0300241 if (node->isAssignment())
242 setOperatorRequiresLValue(false);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300243
Olli Etuaho8afe1e12015-08-05 18:00:01 +0300244 // Index is not required to be an l-value even when the surrounding expression is required
245 // to be an l-value.
Olli Etuaho27446bd2015-08-10 14:59:53 +0300246 TOperator op = node->getOp();
247 if (op == EOpIndexDirect || op == EOpIndexDirectInterfaceBlock ||
248 op == EOpIndexDirectStruct || op == EOpIndexIndirect)
Olli Etuaho8afe1e12015-08-05 18:00:01 +0300249 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300250 setOperatorRequiresLValue(false);
251 setInFunctionCallOutParameter(false);
Olli Etuaho8afe1e12015-08-05 18:00:01 +0300252 }
253
Olli Etuaho27446bd2015-08-10 14:59:53 +0300254 if (visit && node->getRight())
255 node->getRight()->traverse(this);
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700256
Olli Etuaho27446bd2015-08-10 14:59:53 +0300257 setOperatorRequiresLValue(parentOperatorRequiresLValue);
258 setInFunctionCallOutParameter(parentInFunctionCallOutParameter);
Olli Etuaho8afe1e12015-08-05 18:00:01 +0300259
Olli Etuaho27446bd2015-08-10 14:59:53 +0300260 decrementDepth();
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700261 }
262
263 //
264 // Visit the node after the children, if requested and the traversal
265 // hasn't been cancelled yet.
266 //
Olli Etuaho27446bd2015-08-10 14:59:53 +0300267 if (visit && postVisit)
268 visitBinary(PostVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000269}
270
271//
272// Traverse a unary node. Same comments in binary node apply here.
273//
Olli Etuaho27446bd2015-08-10 14:59:53 +0300274void TIntermTraverser::traverseUnary(TIntermUnary *node)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000275{
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700276 bool visit = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000277
Olli Etuaho27446bd2015-08-10 14:59:53 +0300278 if (preVisit)
279 visit = visitUnary(PreVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000280
Olli Etuahoa26ad582015-08-04 13:51:47 +0300281 if (visit)
282 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300283 incrementDepth(node);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300284
Olli Etuaho27446bd2015-08-10 14:59:53 +0300285 ASSERT(!operatorRequiresLValue());
286 switch (node->getOp())
Olli Etuahoa26ad582015-08-04 13:51:47 +0300287 {
288 case EOpPostIncrement:
289 case EOpPostDecrement:
290 case EOpPreIncrement:
291 case EOpPreDecrement:
Olli Etuaho27446bd2015-08-10 14:59:53 +0300292 setOperatorRequiresLValue(true);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300293 break;
294 default:
295 break;
296 }
297
Olli Etuaho27446bd2015-08-10 14:59:53 +0300298 node->getOperand()->traverse(this);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300299
Olli Etuaho27446bd2015-08-10 14:59:53 +0300300 setOperatorRequiresLValue(false);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300301
Olli Etuaho27446bd2015-08-10 14:59:53 +0300302 decrementDepth();
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700303 }
304
Olli Etuaho27446bd2015-08-10 14:59:53 +0300305 if (visit && postVisit)
306 visitUnary(PostVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000307}
308
309//
310// Traverse an aggregate node. Same comments in binary node apply here.
311//
Olli Etuaho27446bd2015-08-10 14:59:53 +0300312void TIntermTraverser::traverseAggregate(TIntermAggregate *node)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000313{
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700314 bool visit = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000315
Olli Etuaho27446bd2015-08-10 14:59:53 +0300316 TIntermSequence *sequence = node->getSequence();
317 switch (node->getOp())
Olli Etuahoa26ad582015-08-04 13:51:47 +0300318 {
319 case EOpFunction:
320 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300321 TIntermAggregate *params = sequence->front()->getAsAggregate();
Olli Etuahoa26ad582015-08-04 13:51:47 +0300322 ASSERT(params != nullptr);
323 ASSERT(params->getOp() == EOpParameters);
Olli Etuaho27446bd2015-08-10 14:59:53 +0300324 addToFunctionMap(node->getName(), params->getSequence());
Olli Etuahoa26ad582015-08-04 13:51:47 +0300325 break;
326 }
327 case EOpPrototype:
Olli Etuaho27446bd2015-08-10 14:59:53 +0300328 addToFunctionMap(node->getName(), sequence);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300329 break;
330 default:
331 break;
332 }
333
Olli Etuaho27446bd2015-08-10 14:59:53 +0300334 if (preVisit)
335 visit = visitAggregate(PreVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000336
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700337 if (visit)
338 {
Olli Etuahoa26ad582015-08-04 13:51:47 +0300339 bool inFunctionMap = false;
Olli Etuaho27446bd2015-08-10 14:59:53 +0300340 if (node->getOp() == EOpFunctionCall)
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700341 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300342 inFunctionMap = isInFunctionMap(node);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300343 if (!inFunctionMap)
Olli Etuaho64f0be92015-06-03 17:38:34 +0300344 {
Olli Etuahoa26ad582015-08-04 13:51:47 +0300345 // The function is not user-defined - it is likely built-in texture function.
346 // Assume that those do not have out parameters.
Olli Etuaho27446bd2015-08-10 14:59:53 +0300347 setInFunctionCallOutParameter(false);
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700348 }
349 }
350
Olli Etuaho27446bd2015-08-10 14:59:53 +0300351 incrementDepth(node);
Olli Etuaho56eea882015-05-18 12:41:03 +0300352
Olli Etuahoa26ad582015-08-04 13:51:47 +0300353 if (inFunctionMap)
354 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300355 TIntermSequence *params = getFunctionParameters(node);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300356 TIntermSequence::iterator paramIter = params->begin();
Olli Etuaho27446bd2015-08-10 14:59:53 +0300357 for (auto *child : *sequence)
Olli Etuahoa26ad582015-08-04 13:51:47 +0300358 {
359 ASSERT(paramIter != params->end());
360 TQualifier qualifier = (*paramIter)->getAsTyped()->getQualifier();
Olli Etuaho27446bd2015-08-10 14:59:53 +0300361 setInFunctionCallOutParameter(qualifier == EvqOut || qualifier == EvqInOut);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300362
Olli Etuaho27446bd2015-08-10 14:59:53 +0300363 child->traverse(this);
364 if (visit && inVisit)
Olli Etuahoa26ad582015-08-04 13:51:47 +0300365 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300366 if (child != sequence->back())
367 visit = visitAggregate(InVisit, node);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300368 }
369
370 ++paramIter;
371 }
372
Olli Etuaho27446bd2015-08-10 14:59:53 +0300373 setInFunctionCallOutParameter(false);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300374 }
375 else
376 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300377 if (node->getOp() == EOpSequence)
378 pushParentBlock(node);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300379
Olli Etuaho27446bd2015-08-10 14:59:53 +0300380 for (auto *child : *sequence)
Olli Etuahoa26ad582015-08-04 13:51:47 +0300381 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300382 child->traverse(this);
383 if (visit && inVisit)
Olli Etuahoa26ad582015-08-04 13:51:47 +0300384 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300385 if (child != sequence->back())
386 visit = visitAggregate(InVisit, node);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300387 }
388
Olli Etuaho27446bd2015-08-10 14:59:53 +0300389 if (node->getOp() == EOpSequence)
390 incrementParentBlockPos();
Olli Etuahoa26ad582015-08-04 13:51:47 +0300391 }
392
Olli Etuaho27446bd2015-08-10 14:59:53 +0300393 if (node->getOp() == EOpSequence)
394 popParentBlock();
Olli Etuahoa26ad582015-08-04 13:51:47 +0300395 }
396
Olli Etuaho27446bd2015-08-10 14:59:53 +0300397 decrementDepth();
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700398 }
399
Olli Etuaho27446bd2015-08-10 14:59:53 +0300400 if (visit && postVisit)
401 visitAggregate(PostVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000402}
403
404//
405// Traverse a selection node. Same comments in binary node apply here.
406//
Olli Etuaho27446bd2015-08-10 14:59:53 +0300407void TIntermTraverser::traverseSelection(TIntermSelection *node)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000408{
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700409 bool visit = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000410
Olli Etuaho27446bd2015-08-10 14:59:53 +0300411 if (preVisit)
412 visit = visitSelection(PreVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000413
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700414 if (visit)
415 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300416 incrementDepth(node);
417 node->getCondition()->traverse(this);
418 if (node->getTrueBlock())
419 node->getTrueBlock()->traverse(this);
420 if (node->getFalseBlock())
421 node->getFalseBlock()->traverse(this);
422 decrementDepth();
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700423 }
424
Olli Etuaho27446bd2015-08-10 14:59:53 +0300425 if (visit && postVisit)
426 visitSelection(PostVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000427}
428
429//
Olli Etuahoa3a36662015-02-17 13:46:51 +0200430// Traverse a switch node. Same comments in binary node apply here.
431//
Olli Etuaho27446bd2015-08-10 14:59:53 +0300432void TIntermTraverser::traverseSwitch(TIntermSwitch *node)
Olli Etuahoa3a36662015-02-17 13:46:51 +0200433{
434 bool visit = true;
435
Olli Etuaho27446bd2015-08-10 14:59:53 +0300436 if (preVisit)
437 visit = visitSwitch(PreVisit, node);
Olli Etuahoa3a36662015-02-17 13:46:51 +0200438
439 if (visit)
440 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300441 incrementDepth(node);
442 node->getInit()->traverse(this);
443 if (inVisit)
444 visit = visitSwitch(InVisit, node);
445 if (visit && node->getStatementList())
446 node->getStatementList()->traverse(this);
447 decrementDepth();
Olli Etuahoa3a36662015-02-17 13:46:51 +0200448 }
449
Olli Etuaho27446bd2015-08-10 14:59:53 +0300450 if (visit && postVisit)
451 visitSwitch(PostVisit, node);
Olli Etuahoa3a36662015-02-17 13:46:51 +0200452}
453
454//
Olli Etuaho27446bd2015-08-10 14:59:53 +0300455// Traverse a case node. Same comments in binary node apply here.
Olli Etuahoa3a36662015-02-17 13:46:51 +0200456//
Olli Etuaho27446bd2015-08-10 14:59:53 +0300457void TIntermTraverser::traverseCase(TIntermCase *node)
Olli Etuahoa3a36662015-02-17 13:46:51 +0200458{
459 bool visit = true;
460
Olli Etuaho27446bd2015-08-10 14:59:53 +0300461 if (preVisit)
462 visit = visitCase(PreVisit, node);
Olli Etuahoa3a36662015-02-17 13:46:51 +0200463
Olli Etuaho27446bd2015-08-10 14:59:53 +0300464 if (visit && node->getCondition())
465 node->getCondition()->traverse(this);
Olli Etuahoa3a36662015-02-17 13:46:51 +0200466
Olli Etuaho27446bd2015-08-10 14:59:53 +0300467 if (visit && postVisit)
468 visitCase(PostVisit, node);
Olli Etuahoa3a36662015-02-17 13:46:51 +0200469}
470
471//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000472// Traverse a loop node. Same comments in binary node apply here.
473//
Olli Etuaho27446bd2015-08-10 14:59:53 +0300474void TIntermTraverser::traverseLoop(TIntermLoop *node)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000475{
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700476 bool visit = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000477
Olli Etuaho27446bd2015-08-10 14:59:53 +0300478 if (preVisit)
479 visit = visitLoop(PreVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000480
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700481 if (visit)
482 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300483 incrementDepth(node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000484
Olli Etuaho27446bd2015-08-10 14:59:53 +0300485 if (node->getInit())
486 node->getInit()->traverse(this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000487
Olli Etuaho27446bd2015-08-10 14:59:53 +0300488 if (node->getCondition())
489 node->getCondition()->traverse(this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000490
Olli Etuaho27446bd2015-08-10 14:59:53 +0300491 if (node->getBody())
492 node->getBody()->traverse(this);
Zhenyao Mo6cb95f32013-10-03 17:01:52 -0700493
Olli Etuaho27446bd2015-08-10 14:59:53 +0300494 if (node->getExpression())
495 node->getExpression()->traverse(this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000496
Olli Etuaho27446bd2015-08-10 14:59:53 +0300497 decrementDepth();
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700498 }
499
Olli Etuaho27446bd2015-08-10 14:59:53 +0300500 if (visit && postVisit)
501 visitLoop(PostVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000502}
503
504//
505// Traverse a branch node. Same comments in binary node apply here.
506//
Olli Etuaho27446bd2015-08-10 14:59:53 +0300507void TIntermTraverser::traverseBranch(TIntermBranch *node)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000508{
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700509 bool visit = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000510
Olli Etuaho27446bd2015-08-10 14:59:53 +0300511 if (preVisit)
512 visit = visitBranch(PreVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000513
Olli Etuaho27446bd2015-08-10 14:59:53 +0300514 if (visit && node->getExpression())
515 {
516 incrementDepth(node);
517 node->getExpression()->traverse(this);
518 decrementDepth();
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700519 }
520
Olli Etuaho27446bd2015-08-10 14:59:53 +0300521 if (visit && postVisit)
522 visitBranch(PostVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000523}
524
Olli Etuaho27446bd2015-08-10 14:59:53 +0300525void TIntermTraverser::traverseRaw(TIntermRaw *node)
Jamie Madill4cfb1e82014-07-07 12:49:23 -0400526{
Olli Etuaho27446bd2015-08-10 14:59:53 +0300527 visitRaw(node);
Jamie Madill4cfb1e82014-07-07 12:49:23 -0400528}