• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 //
traverse(TIntermTraverser * it)26 void TIntermSymbol::traverse(TIntermTraverser* it)
27 {
28 	it->visitSymbol(this);
29 }
30 
traverse(TIntermTraverser * it)31 void TIntermConstantUnion::traverse(TIntermTraverser* it)
32 {
33 	it->visitConstantUnion(this);
34 }
35 
36 //
37 // Traverse a binary node.
38 //
traverse(TIntermTraverser * it)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 //
traverse(TIntermTraverser * it)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 //
traverse(TIntermTraverser * it)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 //
traverse(TIntermTraverser * it)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 //
traverse(TIntermTraverser * it)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 //
traverse(TIntermTraverser * it)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