1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/angle/src/compiler/IntermTraverse.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,293 @@ 1.4 +// 1.5 +// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved. 1.6 +// Use of this source code is governed by a BSD-style license that can be 1.7 +// found in the LICENSE file. 1.8 +// 1.9 + 1.10 +#include "compiler/intermediate.h" 1.11 + 1.12 +// 1.13 +// Traverse the intermediate representation tree, and 1.14 +// call a node type specific function for each node. 1.15 +// Done recursively through the member function Traverse(). 1.16 +// Node types can be skipped if their function to call is 0, 1.17 +// but their subtree will still be traversed. 1.18 +// Nodes with children can have their whole subtree skipped 1.19 +// if preVisit is turned on and the type specific function 1.20 +// returns false. 1.21 +// 1.22 +// preVisit, postVisit, and rightToLeft control what order 1.23 +// nodes are visited in. 1.24 +// 1.25 + 1.26 +// 1.27 +// Traversal functions for terminals are straighforward.... 1.28 +// 1.29 +void TIntermSymbol::traverse(TIntermTraverser* it) 1.30 +{ 1.31 + it->visitSymbol(this); 1.32 +} 1.33 + 1.34 +void TIntermConstantUnion::traverse(TIntermTraverser* it) 1.35 +{ 1.36 + it->visitConstantUnion(this); 1.37 +} 1.38 + 1.39 +// 1.40 +// Traverse a binary node. 1.41 +// 1.42 +void TIntermBinary::traverse(TIntermTraverser* it) 1.43 +{ 1.44 + bool visit = true; 1.45 + 1.46 + // 1.47 + // visit the node before children if pre-visiting. 1.48 + // 1.49 + if(it->preVisit) 1.50 + { 1.51 + visit = it->visitBinary(PreVisit, this); 1.52 + } 1.53 + 1.54 + // 1.55 + // Visit the children, in the right order. 1.56 + // 1.57 + if(visit) 1.58 + { 1.59 + it->incrementDepth(); 1.60 + 1.61 + if(it->rightToLeft) 1.62 + { 1.63 + if(right) 1.64 + { 1.65 + right->traverse(it); 1.66 + } 1.67 + 1.68 + if(it->inVisit) 1.69 + { 1.70 + visit = it->visitBinary(InVisit, this); 1.71 + } 1.72 + 1.73 + if(visit && left) 1.74 + { 1.75 + left->traverse(it); 1.76 + } 1.77 + } 1.78 + else 1.79 + { 1.80 + if(left) 1.81 + { 1.82 + left->traverse(it); 1.83 + } 1.84 + 1.85 + if(it->inVisit) 1.86 + { 1.87 + visit = it->visitBinary(InVisit, this); 1.88 + } 1.89 + 1.90 + if(visit && right) 1.91 + { 1.92 + right->traverse(it); 1.93 + } 1.94 + } 1.95 + 1.96 + it->decrementDepth(); 1.97 + } 1.98 + 1.99 + // 1.100 + // Visit the node after the children, if requested and the traversal 1.101 + // hasn't been cancelled yet. 1.102 + // 1.103 + if(visit && it->postVisit) 1.104 + { 1.105 + it->visitBinary(PostVisit, this); 1.106 + } 1.107 +} 1.108 + 1.109 +// 1.110 +// Traverse a unary node. Same comments in binary node apply here. 1.111 +// 1.112 +void TIntermUnary::traverse(TIntermTraverser* it) 1.113 +{ 1.114 + bool visit = true; 1.115 + 1.116 + if (it->preVisit) 1.117 + visit = it->visitUnary(PreVisit, this); 1.118 + 1.119 + if (visit) { 1.120 + it->incrementDepth(); 1.121 + operand->traverse(it); 1.122 + it->decrementDepth(); 1.123 + } 1.124 + 1.125 + if (visit && it->postVisit) 1.126 + it->visitUnary(PostVisit, this); 1.127 +} 1.128 + 1.129 +// 1.130 +// Traverse an aggregate node. Same comments in binary node apply here. 1.131 +// 1.132 +void TIntermAggregate::traverse(TIntermTraverser* it) 1.133 +{ 1.134 + bool visit = true; 1.135 + 1.136 + if(it->preVisit) 1.137 + { 1.138 + visit = it->visitAggregate(PreVisit, this); 1.139 + } 1.140 + 1.141 + if(visit) 1.142 + { 1.143 + it->incrementDepth(); 1.144 + 1.145 + if(it->rightToLeft) 1.146 + { 1.147 + for(TIntermSequence::reverse_iterator sit = sequence.rbegin(); sit != sequence.rend(); sit++) 1.148 + { 1.149 + (*sit)->traverse(it); 1.150 + 1.151 + if(visit && it->inVisit) 1.152 + { 1.153 + if(*sit != sequence.front()) 1.154 + { 1.155 + visit = it->visitAggregate(InVisit, this); 1.156 + } 1.157 + } 1.158 + } 1.159 + } 1.160 + else 1.161 + { 1.162 + for(TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++) 1.163 + { 1.164 + (*sit)->traverse(it); 1.165 + 1.166 + if(visit && it->inVisit) 1.167 + { 1.168 + if(*sit != sequence.back()) 1.169 + { 1.170 + visit = it->visitAggregate(InVisit, this); 1.171 + } 1.172 + } 1.173 + } 1.174 + } 1.175 + 1.176 + it->decrementDepth(); 1.177 + } 1.178 + 1.179 + if(visit && it->postVisit) 1.180 + { 1.181 + it->visitAggregate(PostVisit, this); 1.182 + } 1.183 +} 1.184 + 1.185 +// 1.186 +// Traverse a selection node. Same comments in binary node apply here. 1.187 +// 1.188 +void TIntermSelection::traverse(TIntermTraverser* it) 1.189 +{ 1.190 + bool visit = true; 1.191 + 1.192 + if (it->preVisit) 1.193 + visit = it->visitSelection(PreVisit, this); 1.194 + 1.195 + if (visit) { 1.196 + it->incrementDepth(); 1.197 + if (it->rightToLeft) { 1.198 + if (falseBlock) 1.199 + falseBlock->traverse(it); 1.200 + if (trueBlock) 1.201 + trueBlock->traverse(it); 1.202 + condition->traverse(it); 1.203 + } else { 1.204 + condition->traverse(it); 1.205 + if (trueBlock) 1.206 + trueBlock->traverse(it); 1.207 + if (falseBlock) 1.208 + falseBlock->traverse(it); 1.209 + } 1.210 + it->decrementDepth(); 1.211 + } 1.212 + 1.213 + if (visit && it->postVisit) 1.214 + it->visitSelection(PostVisit, this); 1.215 +} 1.216 + 1.217 +// 1.218 +// Traverse a loop node. Same comments in binary node apply here. 1.219 +// 1.220 +void TIntermLoop::traverse(TIntermTraverser* it) 1.221 +{ 1.222 + bool visit = true; 1.223 + 1.224 + if(it->preVisit) 1.225 + { 1.226 + visit = it->visitLoop(PreVisit, this); 1.227 + } 1.228 + 1.229 + if(visit) 1.230 + { 1.231 + it->incrementDepth(); 1.232 + 1.233 + if(it->rightToLeft) 1.234 + { 1.235 + if(expr) 1.236 + { 1.237 + expr->traverse(it); 1.238 + } 1.239 + 1.240 + if(body) 1.241 + { 1.242 + body->traverse(it); 1.243 + } 1.244 + 1.245 + if(cond) 1.246 + { 1.247 + cond->traverse(it); 1.248 + } 1.249 + } 1.250 + else 1.251 + { 1.252 + if(cond) 1.253 + { 1.254 + cond->traverse(it); 1.255 + } 1.256 + 1.257 + if(body) 1.258 + { 1.259 + body->traverse(it); 1.260 + } 1.261 + 1.262 + if(expr) 1.263 + { 1.264 + expr->traverse(it); 1.265 + } 1.266 + } 1.267 + 1.268 + it->decrementDepth(); 1.269 + } 1.270 + 1.271 + if(visit && it->postVisit) 1.272 + { 1.273 + it->visitLoop(PostVisit, this); 1.274 + } 1.275 +} 1.276 + 1.277 +// 1.278 +// Traverse a branch node. Same comments in binary node apply here. 1.279 +// 1.280 +void TIntermBranch::traverse(TIntermTraverser* it) 1.281 +{ 1.282 + bool visit = true; 1.283 + 1.284 + if (it->preVisit) 1.285 + visit = it->visitBranch(PreVisit, this); 1.286 + 1.287 + if (visit && expression) { 1.288 + it->incrementDepth(); 1.289 + expression->traverse(it); 1.290 + it->decrementDepth(); 1.291 + } 1.292 + 1.293 + if (visit && it->postVisit) 1.294 + it->visitBranch(PostVisit, this); 1.295 +} 1.296 +