Home | History | Annotate | Download | only in compiler
      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