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