blob: d39e779fa7557ba80f928182955cce742c2966d8 [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 Etuaho3fc93372015-08-11 14:50:59 +0300154void TLValueTrackingTraverser::addToFunctionMap(const TString &name, TIntermSequence *paramSequence)
Olli Etuahoa26ad582015-08-04 13:51:47 +0300155{
156 mFunctionMap[name] = paramSequence;
157}
158
Olli Etuaho3fc93372015-08-11 14:50:59 +0300159bool TLValueTrackingTraverser::isInFunctionMap(const TIntermAggregate *callNode) const
Olli Etuahoa26ad582015-08-04 13:51:47 +0300160{
161 ASSERT(callNode->getOp() == EOpFunctionCall || callNode->getOp() == EOpInternalFunctionCall);
162 return (mFunctionMap.find(callNode->getName()) != mFunctionMap.end());
163}
164
Olli Etuaho3fc93372015-08-11 14:50:59 +0300165TIntermSequence *TLValueTrackingTraverser::getFunctionParameters(const TIntermAggregate *callNode)
Olli Etuahoa26ad582015-08-04 13:51:47 +0300166{
167 ASSERT(isInFunctionMap(callNode));
168 return mFunctionMap[callNode->getName()];
169}
170
Olli Etuaho3fc93372015-08-11 14:50:59 +0300171void TLValueTrackingTraverser::setInFunctionCallOutParameter(bool inOutParameter)
Olli Etuahoa26ad582015-08-04 13:51:47 +0300172{
173 mInFunctionCallOutParameter = inOutParameter;
174}
175
Olli Etuaho3fc93372015-08-11 14:50:59 +0300176bool TLValueTrackingTraverser::isInFunctionCallOutParameter() const
Olli Etuaho8afe1e12015-08-05 18:00:01 +0300177{
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 Etuaho3fc93372015-08-11 14:50:59 +0300225 if (node->getLeft())
226 node->getLeft()->traverse(this);
227
228 if (inVisit)
229 visit = visitBinary(InVisit, node);
230
231 if (visit && node->getRight())
232 node->getRight()->traverse(this);
233
234 decrementDepth();
235 }
236
237 //
238 // Visit the node after the children, if requested and the traversal
239 // hasn't been cancelled yet.
240 //
241 if (visit && postVisit)
242 visitBinary(PostVisit, node);
243}
244
245void TLValueTrackingTraverser::traverseBinary(TIntermBinary *node)
246{
247 bool visit = true;
248
249 //
250 // visit the node before children if pre-visiting.
251 //
252 if (preVisit)
253 visit = visitBinary(PreVisit, node);
254
255 //
256 // Visit the children, in the right order.
257 //
258 if (visit)
259 {
260 incrementDepth(node);
261
Olli Etuaho8afe1e12015-08-05 18:00:01 +0300262 // Some binary operations like indexing can be inside an expression which must be an
263 // l-value.
Olli Etuaho27446bd2015-08-10 14:59:53 +0300264 bool parentOperatorRequiresLValue = operatorRequiresLValue();
265 bool parentInFunctionCallOutParameter = isInFunctionCallOutParameter();
266 if (node->isAssignment())
Olli Etuahoa26ad582015-08-04 13:51:47 +0300267 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300268 ASSERT(!isLValueRequiredHere());
269 setOperatorRequiresLValue(true);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300270 }
271
Olli Etuaho27446bd2015-08-10 14:59:53 +0300272 if (node->getLeft())
273 node->getLeft()->traverse(this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000274
Olli Etuaho27446bd2015-08-10 14:59:53 +0300275 if (inVisit)
276 visit = visitBinary(InVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000277
Olli Etuaho27446bd2015-08-10 14:59:53 +0300278 if (node->isAssignment())
279 setOperatorRequiresLValue(false);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300280
Olli Etuaho8afe1e12015-08-05 18:00:01 +0300281 // Index is not required to be an l-value even when the surrounding expression is required
282 // to be an l-value.
Olli Etuaho27446bd2015-08-10 14:59:53 +0300283 TOperator op = node->getOp();
284 if (op == EOpIndexDirect || op == EOpIndexDirectInterfaceBlock ||
285 op == EOpIndexDirectStruct || op == EOpIndexIndirect)
Olli Etuaho8afe1e12015-08-05 18:00:01 +0300286 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300287 setOperatorRequiresLValue(false);
288 setInFunctionCallOutParameter(false);
Olli Etuaho8afe1e12015-08-05 18:00:01 +0300289 }
290
Olli Etuaho27446bd2015-08-10 14:59:53 +0300291 if (visit && node->getRight())
292 node->getRight()->traverse(this);
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700293
Olli Etuaho27446bd2015-08-10 14:59:53 +0300294 setOperatorRequiresLValue(parentOperatorRequiresLValue);
295 setInFunctionCallOutParameter(parentInFunctionCallOutParameter);
Olli Etuaho8afe1e12015-08-05 18:00:01 +0300296
Olli Etuaho27446bd2015-08-10 14:59:53 +0300297 decrementDepth();
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700298 }
299
300 //
301 // Visit the node after the children, if requested and the traversal
302 // hasn't been cancelled yet.
303 //
Olli Etuaho27446bd2015-08-10 14:59:53 +0300304 if (visit && postVisit)
305 visitBinary(PostVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000306}
307
308//
309// Traverse a unary node. Same comments in binary node apply here.
310//
Olli Etuaho27446bd2015-08-10 14:59:53 +0300311void TIntermTraverser::traverseUnary(TIntermUnary *node)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000312{
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700313 bool visit = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000314
Olli Etuaho27446bd2015-08-10 14:59:53 +0300315 if (preVisit)
316 visit = visitUnary(PreVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000317
Olli Etuahoa26ad582015-08-04 13:51:47 +0300318 if (visit)
319 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300320 incrementDepth(node);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300321
Olli Etuaho3fc93372015-08-11 14:50:59 +0300322 node->getOperand()->traverse(this);
323
324 decrementDepth();
325 }
326
327 if (visit && postVisit)
328 visitUnary(PostVisit, node);
329}
330
331void TLValueTrackingTraverser::traverseUnary(TIntermUnary *node)
332{
333 bool visit = true;
334
335 if (preVisit)
336 visit = visitUnary(PreVisit, node);
337
338 if (visit)
339 {
340 incrementDepth(node);
341
Olli Etuaho27446bd2015-08-10 14:59:53 +0300342 ASSERT(!operatorRequiresLValue());
343 switch (node->getOp())
Olli Etuahoa26ad582015-08-04 13:51:47 +0300344 {
345 case EOpPostIncrement:
346 case EOpPostDecrement:
347 case EOpPreIncrement:
348 case EOpPreDecrement:
Olli Etuaho27446bd2015-08-10 14:59:53 +0300349 setOperatorRequiresLValue(true);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300350 break;
351 default:
352 break;
353 }
354
Olli Etuaho27446bd2015-08-10 14:59:53 +0300355 node->getOperand()->traverse(this);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300356
Olli Etuaho27446bd2015-08-10 14:59:53 +0300357 setOperatorRequiresLValue(false);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300358
Olli Etuaho27446bd2015-08-10 14:59:53 +0300359 decrementDepth();
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700360 }
361
Olli Etuaho27446bd2015-08-10 14:59:53 +0300362 if (visit && postVisit)
363 visitUnary(PostVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000364}
365
366//
367// Traverse an aggregate node. Same comments in binary node apply here.
368//
Olli Etuaho27446bd2015-08-10 14:59:53 +0300369void TIntermTraverser::traverseAggregate(TIntermAggregate *node)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000370{
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700371 bool visit = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000372
Olli Etuaho27446bd2015-08-10 14:59:53 +0300373 TIntermSequence *sequence = node->getSequence();
Olli Etuaho3fc93372015-08-11 14:50:59 +0300374
375 if (preVisit)
376 visit = visitAggregate(PreVisit, node);
377
378 if (visit)
379 {
380 incrementDepth(node);
381
382 if (node->getOp() == EOpSequence)
383 pushParentBlock(node);
384
385 for (auto *child : *sequence)
386 {
387 child->traverse(this);
388 if (visit && inVisit)
389 {
390 if (child != sequence->back())
391 visit = visitAggregate(InVisit, node);
392 }
393
394 if (node->getOp() == EOpSequence)
395 incrementParentBlockPos();
396 }
397
398 if (node->getOp() == EOpSequence)
399 popParentBlock();
400
401 decrementDepth();
402 }
403
404 if (visit && postVisit)
405 visitAggregate(PostVisit, node);
406}
407
408void TLValueTrackingTraverser::traverseAggregate(TIntermAggregate *node)
409{
410 bool visit = true;
411
412 TIntermSequence *sequence = node->getSequence();
Olli Etuaho27446bd2015-08-10 14:59:53 +0300413 switch (node->getOp())
Olli Etuahoa26ad582015-08-04 13:51:47 +0300414 {
415 case EOpFunction:
416 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300417 TIntermAggregate *params = sequence->front()->getAsAggregate();
Olli Etuahoa26ad582015-08-04 13:51:47 +0300418 ASSERT(params != nullptr);
419 ASSERT(params->getOp() == EOpParameters);
Olli Etuaho27446bd2015-08-10 14:59:53 +0300420 addToFunctionMap(node->getName(), params->getSequence());
Olli Etuahoa26ad582015-08-04 13:51:47 +0300421 break;
422 }
423 case EOpPrototype:
Olli Etuaho27446bd2015-08-10 14:59:53 +0300424 addToFunctionMap(node->getName(), sequence);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300425 break;
426 default:
427 break;
428 }
429
Olli Etuaho27446bd2015-08-10 14:59:53 +0300430 if (preVisit)
431 visit = visitAggregate(PreVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000432
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700433 if (visit)
434 {
Olli Etuahoa26ad582015-08-04 13:51:47 +0300435 bool inFunctionMap = false;
Olli Etuaho27446bd2015-08-10 14:59:53 +0300436 if (node->getOp() == EOpFunctionCall)
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700437 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300438 inFunctionMap = isInFunctionMap(node);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300439 if (!inFunctionMap)
Olli Etuaho64f0be92015-06-03 17:38:34 +0300440 {
Olli Etuahoa26ad582015-08-04 13:51:47 +0300441 // The function is not user-defined - it is likely built-in texture function.
442 // Assume that those do not have out parameters.
Olli Etuaho27446bd2015-08-10 14:59:53 +0300443 setInFunctionCallOutParameter(false);
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700444 }
445 }
446
Olli Etuaho27446bd2015-08-10 14:59:53 +0300447 incrementDepth(node);
Olli Etuaho56eea882015-05-18 12:41:03 +0300448
Olli Etuahoa26ad582015-08-04 13:51:47 +0300449 if (inFunctionMap)
450 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300451 TIntermSequence *params = getFunctionParameters(node);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300452 TIntermSequence::iterator paramIter = params->begin();
Olli Etuaho27446bd2015-08-10 14:59:53 +0300453 for (auto *child : *sequence)
Olli Etuahoa26ad582015-08-04 13:51:47 +0300454 {
455 ASSERT(paramIter != params->end());
456 TQualifier qualifier = (*paramIter)->getAsTyped()->getQualifier();
Olli Etuaho27446bd2015-08-10 14:59:53 +0300457 setInFunctionCallOutParameter(qualifier == EvqOut || qualifier == EvqInOut);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300458
Olli Etuaho27446bd2015-08-10 14:59:53 +0300459 child->traverse(this);
460 if (visit && inVisit)
Olli Etuahoa26ad582015-08-04 13:51:47 +0300461 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300462 if (child != sequence->back())
463 visit = visitAggregate(InVisit, node);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300464 }
465
466 ++paramIter;
467 }
468
Olli Etuaho27446bd2015-08-10 14:59:53 +0300469 setInFunctionCallOutParameter(false);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300470 }
471 else
472 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300473 if (node->getOp() == EOpSequence)
474 pushParentBlock(node);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300475
Olli Etuaho27446bd2015-08-10 14:59:53 +0300476 for (auto *child : *sequence)
Olli Etuahoa26ad582015-08-04 13:51:47 +0300477 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300478 child->traverse(this);
479 if (visit && inVisit)
Olli Etuahoa26ad582015-08-04 13:51:47 +0300480 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300481 if (child != sequence->back())
482 visit = visitAggregate(InVisit, node);
Olli Etuahoa26ad582015-08-04 13:51:47 +0300483 }
484
Olli Etuaho27446bd2015-08-10 14:59:53 +0300485 if (node->getOp() == EOpSequence)
486 incrementParentBlockPos();
Olli Etuahoa26ad582015-08-04 13:51:47 +0300487 }
488
Olli Etuaho27446bd2015-08-10 14:59:53 +0300489 if (node->getOp() == EOpSequence)
490 popParentBlock();
Olli Etuahoa26ad582015-08-04 13:51:47 +0300491 }
492
Olli Etuaho27446bd2015-08-10 14:59:53 +0300493 decrementDepth();
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700494 }
495
Olli Etuaho27446bd2015-08-10 14:59:53 +0300496 if (visit && postVisit)
497 visitAggregate(PostVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000498}
499
500//
501// Traverse a selection node. Same comments in binary node apply here.
502//
Olli Etuaho27446bd2015-08-10 14:59:53 +0300503void TIntermTraverser::traverseSelection(TIntermSelection *node)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000504{
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700505 bool visit = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000506
Olli Etuaho27446bd2015-08-10 14:59:53 +0300507 if (preVisit)
508 visit = visitSelection(PreVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000509
Zhenyao Moe40d1e92014-07-16 17:40:36 -0700510 if (visit)
511 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300512 incrementDepth(node);
513 node->getCondition()->traverse(this);
514 if (node->getTrueBlock())
515 node->getTrueBlock()->traverse(this);
516 if (node->getFalseBlock())
517 node->getFalseBlock()->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 visitSelection(PostVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000523}
524
525//
Olli Etuahoa3a36662015-02-17 13:46:51 +0200526// Traverse a switch node. Same comments in binary node apply here.
527//
Olli Etuaho27446bd2015-08-10 14:59:53 +0300528void TIntermTraverser::traverseSwitch(TIntermSwitch *node)
Olli Etuahoa3a36662015-02-17 13:46:51 +0200529{
530 bool visit = true;
531
Olli Etuaho27446bd2015-08-10 14:59:53 +0300532 if (preVisit)
533 visit = visitSwitch(PreVisit, node);
Olli Etuahoa3a36662015-02-17 13:46:51 +0200534
535 if (visit)
536 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300537 incrementDepth(node);
538 node->getInit()->traverse(this);
539 if (inVisit)
540 visit = visitSwitch(InVisit, node);
541 if (visit && node->getStatementList())
542 node->getStatementList()->traverse(this);
543 decrementDepth();
Olli Etuahoa3a36662015-02-17 13:46:51 +0200544 }
545
Olli Etuaho27446bd2015-08-10 14:59:53 +0300546 if (visit && postVisit)
547 visitSwitch(PostVisit, node);
Olli Etuahoa3a36662015-02-17 13:46:51 +0200548}
549
550//
Olli Etuaho27446bd2015-08-10 14:59:53 +0300551// Traverse a case node. Same comments in binary node apply here.
Olli Etuahoa3a36662015-02-17 13:46:51 +0200552//
Olli Etuaho27446bd2015-08-10 14:59:53 +0300553void TIntermTraverser::traverseCase(TIntermCase *node)
Olli Etuahoa3a36662015-02-17 13:46:51 +0200554{
555 bool visit = true;
556
Olli Etuaho27446bd2015-08-10 14:59:53 +0300557 if (preVisit)
558 visit = visitCase(PreVisit, node);
Olli Etuahoa3a36662015-02-17 13:46:51 +0200559
Olli Etuaho27446bd2015-08-10 14:59:53 +0300560 if (visit && node->getCondition())
561 node->getCondition()->traverse(this);
Olli Etuahoa3a36662015-02-17 13:46:51 +0200562
Olli Etuaho27446bd2015-08-10 14:59:53 +0300563 if (visit && postVisit)
564 visitCase(PostVisit, node);
Olli Etuahoa3a36662015-02-17 13:46:51 +0200565}
566
567//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000568// Traverse a loop node. Same comments in binary node apply here.
569//
Olli Etuaho27446bd2015-08-10 14:59:53 +0300570void TIntermTraverser::traverseLoop(TIntermLoop *node)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000571{
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700572 bool visit = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000573
Olli Etuaho27446bd2015-08-10 14:59:53 +0300574 if (preVisit)
575 visit = visitLoop(PreVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000576
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700577 if (visit)
578 {
Olli Etuaho27446bd2015-08-10 14:59:53 +0300579 incrementDepth(node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000580
Olli Etuaho27446bd2015-08-10 14:59:53 +0300581 if (node->getInit())
582 node->getInit()->traverse(this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000583
Olli Etuaho27446bd2015-08-10 14:59:53 +0300584 if (node->getCondition())
585 node->getCondition()->traverse(this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000586
Olli Etuaho27446bd2015-08-10 14:59:53 +0300587 if (node->getBody())
588 node->getBody()->traverse(this);
Zhenyao Mo6cb95f32013-10-03 17:01:52 -0700589
Olli Etuaho27446bd2015-08-10 14:59:53 +0300590 if (node->getExpression())
591 node->getExpression()->traverse(this);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000592
Olli Etuaho27446bd2015-08-10 14:59:53 +0300593 decrementDepth();
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700594 }
595
Olli Etuaho27446bd2015-08-10 14:59:53 +0300596 if (visit && postVisit)
597 visitLoop(PostVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000598}
599
600//
601// Traverse a branch node. Same comments in binary node apply here.
602//
Olli Etuaho27446bd2015-08-10 14:59:53 +0300603void TIntermTraverser::traverseBranch(TIntermBranch *node)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000604{
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700605 bool visit = true;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000606
Olli Etuaho27446bd2015-08-10 14:59:53 +0300607 if (preVisit)
608 visit = visitBranch(PreVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000609
Olli Etuaho27446bd2015-08-10 14:59:53 +0300610 if (visit && node->getExpression())
611 {
612 incrementDepth(node);
613 node->getExpression()->traverse(this);
614 decrementDepth();
Zhenyao Moe88dcaf2013-10-03 16:55:19 -0700615 }
616
Olli Etuaho27446bd2015-08-10 14:59:53 +0300617 if (visit && postVisit)
618 visitBranch(PostVisit, node);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000619}
620
Olli Etuaho27446bd2015-08-10 14:59:53 +0300621void TIntermTraverser::traverseRaw(TIntermRaw *node)
Jamie Madill4cfb1e82014-07-07 12:49:23 -0400622{
Olli Etuaho27446bd2015-08-10 14:59:53 +0300623 visitRaw(node);
Jamie Madill4cfb1e82014-07-07 12:49:23 -0400624}