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 // 26 void TIntermSymbol::traverse(TIntermTraverser* it) 27 { 28 it->visitSymbol(this); 29 } 30 31 void TIntermConstantUnion::traverse(TIntermTraverser* it) 32 { 33 it->visitConstantUnion(this); 34 } 35 36 // 37 // Traverse a binary node. 38 // 39 void 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 // 109 void 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 // 129 void 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 // 185 void 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 // 217 void 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 // 277 void 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