1// 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 7#include "compiler/intermediate.h" 8 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// 26void TIntermSymbol::traverse(TIntermTraverser* it) 27{ 28 it->visitSymbol(this); 29} 30 31void TIntermConstantUnion::traverse(TIntermTraverser* it) 32{ 33 it->visitConstantUnion(this); 34} 35 36// 37// Traverse a binary node. 38// 39void TIntermBinary::traverse(TIntermTraverser* it) 40{ 41 bool visit = true; 42 43 // 44 // visit the node before children if pre-visiting. 45 // 46 if(it->preVisit) 47 { 48 visit = it->visitBinary(PreVisit, this); 49 } 50 51 // 52 // Visit the children, in the right order. 53 // 54 if(visit) 55 { 56 it->incrementDepth(); 57 58 if(it->rightToLeft) 59 { 60 if(right) 61 { 62 right->traverse(it); 63 } 64 65 if(it->inVisit) 66 { 67 visit = it->visitBinary(InVisit, this); 68 } 69 70 if(visit && left) 71 { 72 left->traverse(it); 73 } 74 } 75 else 76 { 77 if(left) 78 { 79 left->traverse(it); 80 } 81 82 if(it->inVisit) 83 { 84 visit = it->visitBinary(InVisit, this); 85 } 86 87 if(visit && right) 88 { 89 right->traverse(it); 90 } 91 } 92 93 it->decrementDepth(); 94 } 95 96 // 97 // Visit the node after the children, if requested and the traversal 98 // hasn't been cancelled yet. 99 // 100 if(visit && it->postVisit) 101 { 102 it->visitBinary(PostVisit, this); 103 } 104} 105 106// 107// Traverse a unary node. Same comments in binary node apply here. 108// 109void TIntermUnary::traverse(TIntermTraverser* it) 110{ 111 bool visit = true; 112 113 if (it->preVisit) 114 visit = it->visitUnary(PreVisit, this); 115 116 if (visit) { 117 it->incrementDepth(); 118 operand->traverse(it); 119 it->decrementDepth(); 120 } 121 122 if (visit && it->postVisit) 123 it->visitUnary(PostVisit, this); 124} 125 126// 127// Traverse an aggregate node. Same comments in binary node apply here. 128// 129void TIntermAggregate::traverse(TIntermTraverser* it) 130{ 131 bool visit = true; 132 133 if(it->preVisit) 134 { 135 visit = it->visitAggregate(PreVisit, this); 136 } 137 138 if(visit) 139 { 140 it->incrementDepth(); 141 142 if(it->rightToLeft) 143 { 144 for(TIntermSequence::reverse_iterator sit = sequence.rbegin(); sit != sequence.rend(); sit++) 145 { 146 (*sit)->traverse(it); 147 148 if(visit && it->inVisit) 149 { 150 if(*sit != sequence.front()) 151 { 152 visit = it->visitAggregate(InVisit, this); 153 } 154 } 155 } 156 } 157 else 158 { 159 for(TIntermSequence::iterator sit = sequence.begin(); sit != sequence.end(); sit++) 160 { 161 (*sit)->traverse(it); 162 163 if(visit && it->inVisit) 164 { 165 if(*sit != sequence.back()) 166 { 167 visit = it->visitAggregate(InVisit, this); 168 } 169 } 170 } 171 } 172 173 it->decrementDepth(); 174 } 175 176 if(visit && it->postVisit) 177 { 178 it->visitAggregate(PostVisit, this); 179 } 180} 181 182// 183// Traverse a selection node. Same comments in binary node apply here. 184// 185void TIntermSelection::traverse(TIntermTraverser* it) 186{ 187 bool visit = true; 188 189 if (it->preVisit) 190 visit = it->visitSelection(PreVisit, this); 191 192 if (visit) { 193 it->incrementDepth(); 194 if (it->rightToLeft) { 195 if (falseBlock) 196 falseBlock->traverse(it); 197 if (trueBlock) 198 trueBlock->traverse(it); 199 condition->traverse(it); 200 } else { 201 condition->traverse(it); 202 if (trueBlock) 203 trueBlock->traverse(it); 204 if (falseBlock) 205 falseBlock->traverse(it); 206 } 207 it->decrementDepth(); 208 } 209 210 if (visit && it->postVisit) 211 it->visitSelection(PostVisit, this); 212} 213 214// 215// Traverse a loop node. Same comments in binary node apply here. 216// 217void TIntermLoop::traverse(TIntermTraverser* it) 218{ 219 bool visit = true; 220 221 if(it->preVisit) 222 { 223 visit = it->visitLoop(PreVisit, this); 224 } 225 226 if(visit) 227 { 228 it->incrementDepth(); 229 230 if(it->rightToLeft) 231 { 232 if(expr) 233 { 234 expr->traverse(it); 235 } 236 237 if(body) 238 { 239 body->traverse(it); 240 } 241 242 if(cond) 243 { 244 cond->traverse(it); 245 } 246 } 247 else 248 { 249 if(cond) 250 { 251 cond->traverse(it); 252 } 253 254 if(body) 255 { 256 body->traverse(it); 257 } 258 259 if(expr) 260 { 261 expr->traverse(it); 262 } 263 } 264 265 it->decrementDepth(); 266 } 267 268 if(visit && it->postVisit) 269 { 270 it->visitLoop(PostVisit, this); 271 } 272} 273 274// 275// Traverse a branch node. Same comments in binary node apply here. 276// 277void TIntermBranch::traverse(TIntermTraverser* it) 278{ 279 bool visit = true; 280 281 if (it->preVisit) 282 visit = it->visitBranch(PreVisit, this); 283 284 if (visit && expression) { 285 it->incrementDepth(); 286 expression->traverse(it); 287 it->decrementDepth(); 288 } 289 290 if (visit && it->postVisit) 291 it->visitBranch(PostVisit, this); 292} 293 294