zenilib  0.5.3.0
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
intermOut.cpp
Go to the documentation of this file.
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 
8 
9 //
10 // Two purposes:
11 // 1. Show an example of how to iterate tree. Functions can
12 // also directly call Traverse() on children themselves to
13 // have finer grained control over the process than shown here.
14 // See the last function for how to get started.
15 // 2. Print out a text based description of the tree.
16 //
17 
18 //
19 // Use this class to carry along data from node to node in
20 // the traversal
21 //
22 class TOutputTraverser : public TIntermTraverser {
23 public:
24  TOutputTraverser(TInfoSinkBase& i) : sink(i) { }
26 
27 protected:
30  bool visitBinary(Visit visit, TIntermBinary*);
31  bool visitUnary(Visit visit, TIntermUnary*);
34  bool visitLoop(Visit visit, TIntermLoop*);
35  bool visitBranch(Visit visit, TIntermBranch*);
36 };
37 
39 {
41 
42  if (qualifier != EvqTemporary && qualifier != EvqGlobal)
43  stream << getQualifierString() << " " << getPrecisionString() << " ";
44  if (array)
45  stream << "array[" << getArraySize() << "] of ";
46  if (matrix)
47  stream << size << "X" << size << " matrix of ";
48  else if (size > 1)
49  stream << size << "-component vector of ";
50 
51  stream << getBasicString();
52  return stream.str();
53 }
54 
55 //
56 // Helper functions for printing, not part of traversing.
57 //
58 
60 {
61  int i;
62 
63  sink.location(node->getLine());
64 
65  for (i = 0; i < depth; ++i)
66  sink << " ";
67 }
68 
69 //
70 // The rest of the file are the traversal functions. The last one
71 // is the one that starts the traversal.
72 //
73 // Return true from interior nodes to have the external traversal
74 // continue on to children. If you process children yourself,
75 // return false.
76 //
77 
78 void TOutputTraverser::visitSymbol(TIntermSymbol* node)
79 {
80  OutputTreeText(sink, node, depth);
81 
82  sink << "'" << node->getSymbol() << "' ";
83  sink << "(" << node->getCompleteString() << ")\n";
84 }
85 
86 bool TOutputTraverser::visitBinary(Visit visit, TIntermBinary* node)
87 {
88  TInfoSinkBase& out = sink;
89 
90  OutputTreeText(out, node, depth);
91 
92  switch (node->getOp()) {
93  case EOpAssign: out << "move second child to first child"; break;
94  case EOpInitialize: out << "initialize first child with second child"; break;
95  case EOpAddAssign: out << "add second child into first child"; break;
96  case EOpSubAssign: out << "subtract second child into first child"; break;
97  case EOpMulAssign: out << "multiply second child into first child"; break;
98  case EOpVectorTimesMatrixAssign: out << "matrix mult second child into first child"; break;
99  case EOpVectorTimesScalarAssign: out << "vector scale second child into first child"; break;
100  case EOpMatrixTimesScalarAssign: out << "matrix scale second child into first child"; break;
101  case EOpMatrixTimesMatrixAssign: out << "matrix mult second child into first child"; break;
102  case EOpDivAssign: out << "divide second child into first child"; break;
103  case EOpIndexDirect: out << "direct index"; break;
104  case EOpIndexIndirect: out << "indirect index"; break;
105  case EOpIndexDirectStruct: out << "direct index for structure"; break;
106  case EOpVectorSwizzle: out << "vector swizzle"; break;
107 
108  case EOpAdd: out << "add"; break;
109  case EOpSub: out << "subtract"; break;
110  case EOpMul: out << "component-wise multiply"; break;
111  case EOpDiv: out << "divide"; break;
112  case EOpEqual: out << "Compare Equal"; break;
113  case EOpNotEqual: out << "Compare Not Equal"; break;
114  case EOpLessThan: out << "Compare Less Than"; break;
115  case EOpGreaterThan: out << "Compare Greater Than"; break;
116  case EOpLessThanEqual: out << "Compare Less Than or Equal"; break;
117  case EOpGreaterThanEqual: out << "Compare Greater Than or Equal"; break;
118 
119  case EOpVectorTimesScalar: out << "vector-scale"; break;
120  case EOpVectorTimesMatrix: out << "vector-times-matrix"; break;
121  case EOpMatrixTimesVector: out << "matrix-times-vector"; break;
122  case EOpMatrixTimesScalar: out << "matrix-scale"; break;
123  case EOpMatrixTimesMatrix: out << "matrix-multiply"; break;
124 
125  case EOpLogicalOr: out << "logical-or"; break;
126  case EOpLogicalXor: out << "logical-xor"; break;
127  case EOpLogicalAnd: out << "logical-and"; break;
128  default: out << "<unknown op>";
129  }
130 
131  out << " (" << node->getCompleteString() << ")";
132 
133  out << "\n";
134 
135  return true;
136 }
137 
138 bool TOutputTraverser::visitUnary(Visit visit, TIntermUnary* node)
139 {
140  TInfoSinkBase& out = sink;
141 
142  OutputTreeText(out, node, depth);
143 
144  switch (node->getOp()) {
145  case EOpNegative: out << "Negate value"; break;
146  case EOpVectorLogicalNot:
147  case EOpLogicalNot: out << "Negate conditional"; break;
148 
149  case EOpPostIncrement: out << "Post-Increment"; break;
150  case EOpPostDecrement: out << "Post-Decrement"; break;
151  case EOpPreIncrement: out << "Pre-Increment"; break;
152  case EOpPreDecrement: out << "Pre-Decrement"; break;
153 
154  case EOpConvIntToBool: out << "Convert int to bool"; break;
155  case EOpConvFloatToBool:out << "Convert float to bool";break;
156  case EOpConvBoolToFloat:out << "Convert bool to float";break;
157  case EOpConvIntToFloat: out << "Convert int to float"; break;
158  case EOpConvFloatToInt: out << "Convert float to int"; break;
159  case EOpConvBoolToInt: out << "Convert bool to int"; break;
160 
161  case EOpRadians: out << "radians"; break;
162  case EOpDegrees: out << "degrees"; break;
163  case EOpSin: out << "sine"; break;
164  case EOpCos: out << "cosine"; break;
165  case EOpTan: out << "tangent"; break;
166  case EOpAsin: out << "arc sine"; break;
167  case EOpAcos: out << "arc cosine"; break;
168  case EOpAtan: out << "arc tangent"; break;
169 
170  case EOpExp: out << "exp"; break;
171  case EOpLog: out << "log"; break;
172  case EOpExp2: out << "exp2"; break;
173  case EOpLog2: out << "log2"; break;
174  case EOpSqrt: out << "sqrt"; break;
175  case EOpInverseSqrt: out << "inverse sqrt"; break;
176 
177  case EOpAbs: out << "Absolute value"; break;
178  case EOpSign: out << "Sign"; break;
179  case EOpFloor: out << "Floor"; break;
180  case EOpCeil: out << "Ceiling"; break;
181  case EOpFract: out << "Fraction"; break;
182 
183  case EOpLength: out << "length"; break;
184  case EOpNormalize: out << "normalize"; break;
185  // case EOpDPdx: out << "dPdx"; break;
186  // case EOpDPdy: out << "dPdy"; break;
187  // case EOpFwidth: out << "fwidth"; break;
188 
189  case EOpAny: out << "any"; break;
190  case EOpAll: out << "all"; break;
191 
192  default:
193  out.prefix(EPrefixError);
194  out << "Bad unary op";
195  }
196 
197  out << " (" << node->getCompleteString() << ")";
198 
199  out << "\n";
200 
201  return true;
202 }
203 
204 bool TOutputTraverser::visitAggregate(Visit visit, TIntermAggregate* node)
205 {
206  TInfoSinkBase& out = sink;
207 
208  if (node->getOp() == EOpNull) {
209  out.prefix(EPrefixError);
210  out << "node is still EOpNull!";
211  return true;
212  }
213 
214  OutputTreeText(out, node, depth);
215 
216  switch (node->getOp()) {
217  case EOpSequence: out << "Sequence\n"; return true;
218  case EOpComma: out << "Comma\n"; return true;
219  case EOpFunction: out << "Function Definition: " << node->getName(); break;
220  case EOpFunctionCall: out << "Function Call: " << node->getName(); break;
221  case EOpParameters: out << "Function Parameters: "; break;
222 
223  case EOpConstructFloat: out << "Construct float"; break;
224  case EOpConstructVec2: out << "Construct vec2"; break;
225  case EOpConstructVec3: out << "Construct vec3"; break;
226  case EOpConstructVec4: out << "Construct vec4"; break;
227  case EOpConstructBool: out << "Construct bool"; break;
228  case EOpConstructBVec2: out << "Construct bvec2"; break;
229  case EOpConstructBVec3: out << "Construct bvec3"; break;
230  case EOpConstructBVec4: out << "Construct bvec4"; break;
231  case EOpConstructInt: out << "Construct int"; break;
232  case EOpConstructIVec2: out << "Construct ivec2"; break;
233  case EOpConstructIVec3: out << "Construct ivec3"; break;
234  case EOpConstructIVec4: out << "Construct ivec4"; break;
235  case EOpConstructMat2: out << "Construct mat2"; break;
236  case EOpConstructMat3: out << "Construct mat3"; break;
237  case EOpConstructMat4: out << "Construct mat4"; break;
238  case EOpConstructStruct: out << "Construct structure"; break;
239 
240  case EOpLessThan: out << "Compare Less Than"; break;
241  case EOpGreaterThan: out << "Compare Greater Than"; break;
242  case EOpLessThanEqual: out << "Compare Less Than or Equal"; break;
243  case EOpGreaterThanEqual: out << "Compare Greater Than or Equal"; break;
244  case EOpVectorEqual: out << "Equal"; break;
245  case EOpVectorNotEqual: out << "NotEqual"; break;
246 
247  case EOpMod: out << "mod"; break;
248  case EOpPow: out << "pow"; break;
249 
250  case EOpAtan: out << "arc tangent"; break;
251 
252  case EOpMin: out << "min"; break;
253  case EOpMax: out << "max"; break;
254  case EOpClamp: out << "clamp"; break;
255  case EOpMix: out << "mix"; break;
256  case EOpStep: out << "step"; break;
257  case EOpSmoothStep: out << "smoothstep"; break;
258 
259  case EOpDistance: out << "distance"; break;
260  case EOpDot: out << "dot-product"; break;
261  case EOpCross: out << "cross-product"; break;
262  case EOpFaceForward: out << "face-forward"; break;
263  case EOpReflect: out << "reflect"; break;
264  case EOpRefract: out << "refract"; break;
265  case EOpMul: out << "component-wise multiply"; break;
266 
267  case EOpDeclaration: out << "Declaration: "; break;
268 
269  default:
270  out.prefix(EPrefixError);
271  out << "Bad aggregation op";
272  }
273 
274  if (node->getOp() != EOpSequence && node->getOp() != EOpParameters)
275  out << " (" << node->getCompleteString() << ")";
276 
277  out << "\n";
278 
279  return true;
280 }
281 
282 bool TOutputTraverser::visitSelection(Visit visit, TIntermSelection* node)
283 {
284  TInfoSinkBase& out = sink;
285 
286  OutputTreeText(out, node, depth);
287 
288  out << "Test condition and select";
289  out << " (" << node->getCompleteString() << ")\n";
290 
291  ++depth;
292 
293  OutputTreeText(sink, node, depth);
294  out << "Condition\n";
295  node->getCondition()->traverse(this);
296 
297  OutputTreeText(sink, node, depth);
298  if (node->getTrueBlock()) {
299  out << "true case\n";
300  node->getTrueBlock()->traverse(this);
301  } else
302  out << "true case is null\n";
303 
304  if (node->getFalseBlock()) {
305  OutputTreeText(sink, node, depth);
306  out << "false case\n";
307  node->getFalseBlock()->traverse(this);
308  }
309 
310  --depth;
311 
312  return false;
313 }
314 
315 void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node)
316 {
317  TInfoSinkBase& out = sink;
318 
319  size_t size = node->getType().getObjectSize();
320 
321  for (size_t i = 0; i < size; i++) {
322  OutputTreeText(out, node, depth);
323  switch (node->getUnionArrayPointer()[i].getType()) {
324  case EbtBool:
325  if (node->getUnionArrayPointer()[i].getBConst())
326  out << "true";
327  else
328  out << "false";
329 
330  out << " (" << "const bool" << ")";
331  out << "\n";
332  break;
333  case EbtFloat:
334  out << node->getUnionArrayPointer()[i].getFConst();
335  out << " (const float)\n";
336  break;
337  case EbtInt:
338  out << node->getUnionArrayPointer()[i].getIConst();
339  out << " (const int)\n";
340  break;
341  default:
342  out.message(EPrefixInternalError, node->getLine(), "Unknown constant");
343  break;
344  }
345  }
346 }
347 
348 bool TOutputTraverser::visitLoop(Visit visit, TIntermLoop* node)
349 {
350  TInfoSinkBase& out = sink;
351 
352  OutputTreeText(out, node, depth);
353 
354  out << "Loop with condition ";
355  if (node->getType() == ELoopDoWhile)
356  out << "not ";
357  out << "tested first\n";
358 
359  ++depth;
360 
361  OutputTreeText(sink, node, depth);
362  if (node->getCondition()) {
363  out << "Loop Condition\n";
364  node->getCondition()->traverse(this);
365  } else
366  out << "No loop condition\n";
367 
368  OutputTreeText(sink, node, depth);
369  if (node->getBody()) {
370  out << "Loop Body\n";
371  node->getBody()->traverse(this);
372  } else
373  out << "No loop body\n";
374 
375  if (node->getExpression()) {
376  OutputTreeText(sink, node, depth);
377  out << "Loop Terminal Expression\n";
378  node->getExpression()->traverse(this);
379  }
380 
381  --depth;
382 
383  return false;
384 }
385 
386 bool TOutputTraverser::visitBranch(Visit visit, TIntermBranch* node)
387 {
388  TInfoSinkBase& out = sink;
389 
390  OutputTreeText(out, node, depth);
391 
392  switch (node->getFlowOp()) {
393  case EOpKill: out << "Branch: Kill"; break;
394  case EOpBreak: out << "Branch: Break"; break;
395  case EOpContinue: out << "Branch: Continue"; break;
396  case EOpReturn: out << "Branch: Return"; break;
397  default: out << "Branch: Unknown Branch"; break;
398  }
399 
400  if (node->getExpression()) {
401  out << " with expression\n";
402  ++depth;
403  node->getExpression()->traverse(this);
404  --depth;
405  } else
406  out << "\n";
407 
408  return false;
409 }
410 
411 //
412 // This function is the one to call externally to start the traversal.
413 // Individual functions can be initialized to 0 to skip processing of that
414 // type of node. It's children will still be processed.
415 //
417 {
418  if (root == 0)
419  return;
420 
421  TOutputTraverser it(infoSink.info);
422 
423  root->traverse(&it);
424 }
GLsizei GLenum GLboolean sink
Definition: glew.h:4448
void message(TPrefixType p, const TSourceLoc &loc, const char *m)
Definition: InfoSink.cpp:49
Visit
Definition: intermediate.h:524
TOperator getOp() const
Definition: intermediate.h:389
bool getBConst()
Definition: ConstantUnion.h:27
virtual bool visitAggregate(Visit visit, TIntermAggregate *)
Definition: intermediate.h:557
TIntermNode * getTrueBlock() const
Definition: intermediate.h:514
TIntermTyped * getCondition()
Definition: intermediate.h:301
GLuint GLuint stream
Definition: glew.h:6573
TString getCompleteString() const
Definition: intermediate.h:265
TOperator getFlowOp()
Definition: intermediate.h:329
TIntermNode * getFalseBlock() const
Definition: intermediate.h:515
const char * getQualifierString() const
Definition: Types.h:211
virtual bool visitBranch(Visit visit, TIntermBranch *)
Definition: intermediate.h:559
GLenum array
Definition: glew.h:8327
const char * getPrecisionString() const
Definition: Types.h:210
virtual bool visitUnary(Visit visit, TIntermUnary *)
Definition: intermediate.h:555
void OutputTreeText(TInfoSinkBase &sink, TIntermNode *node, const int depth)
Definition: intermOut.cpp:59
float getFConst()
Definition: ConstantUnion.h:26
virtual void visitSymbol(TIntermSymbol *)
Definition: intermediate.h:552
virtual bool visitBinary(Visit visit, TIntermBinary *)
Definition: intermediate.h:554
std::basic_ostringstream< char, std::char_traits< char >, TStringAllocator > TStringStream
Definition: Common.h:42
virtual void traverse(TIntermTraverser *)=0
TIntermNode * getCondition() const
Definition: intermediate.h:513
const TSourceLoc & getLine() const
Definition: intermediate.h:217
const TType & getType() const
Definition: intermediate.h:251
TIntermNode * getBody()
Definition: intermediate.h:303
ConstantUnion * getUnionArrayPointer() const
Definition: intermediate.h:369
TBasicType getType() const
TIntermTyped * getExpression()
Definition: intermediate.h:330
const TString & getName() const
Definition: intermediate.h:472
GLint GLenum GLsizei GLsizei GLsizei depth
Definition: gl2ext.h:845
GLuint GLenum matrix
Definition: glew.h:13408
std::basic_string< char, std::char_traits< char >, TStringAllocator > TString
Definition: Common.h:41
virtual bool visitLoop(Visit visit, TIntermLoop *)
Definition: intermediate.h:558
virtual bool visitSelection(Visit visit, TIntermSelection *)
Definition: intermediate.h:556
void outputTree(TIntermNode *)
Definition: intermOut.cpp:416
virtual void visitConstantUnion(TIntermConstantUnion *)
Definition: intermediate.h:553
int getArraySize() const
Definition: Types.h:163
TIntermTyped * getExpression()
Definition: intermediate.h:302
TString getCompleteString() const
Definition: intermOut.cpp:38
size_t getObjectSize() const
Definition: SymbolTable.cpp:61
const char * getBasicString() const
Definition: Types.h:209
const TString & getSymbol() const
Definition: intermediate.h:349
TInfoSinkBase info
Definition: InfoSink.h:110
int i
Definition: pngrutil.c:1377
void location(int file, int line)
Definition: InfoSink.cpp:34
void prefix(TPrefixType p)
Definition: InfoSink.cpp:9
GLsizei size
Definition: gl2ext.h:1467
TLoopType getType() const
Definition: intermediate.h:299