blob: d2629056e069d940e7383598d3d8adb3c0e70f44 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
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//
8// Definition of the in-memory high-level intermediate representation
9// of shaders. This is a tree that parser creates.
10//
11// Nodes in the tree are defined as a hierarchy of classes derived from
12// TIntermNode. Each is a node in a tree. There is no preset branching factor;
13// each node can have it's own type of list of children.
14//
15
16#ifndef __INTERMEDIATE_H
17#define __INTERMEDIATE_H
18
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000019#include "compiler/Common.h"
20#include "compiler/Types.h"
21#include "compiler/ConstantUnion.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000022
23//
24// Operators used by the high-level (parse tree) representation.
25//
26enum TOperator {
alokp@chromium.org2cf17712010-03-30 20:33:18 +000027 EOpNull, // if in a node, should only mean a node is still being built
28 EOpSequence, // denotes a list of statements, or parameters, etc.
29 EOpFunctionCall,
30 EOpFunction, // For function definition
31 EOpParameters, // an aggregate listing the parameters to a function
daniel@transgaming.comd1acd1e2010-04-13 03:25:57 +000032
alokp@chromium.org2cf17712010-03-30 20:33:18 +000033 EOpDeclaration,
daniel@transgaming.comd1acd1e2010-04-13 03:25:57 +000034 EOpPrototype,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000035
alokp@chromium.org2cf17712010-03-30 20:33:18 +000036 //
37 // Unary operators
38 //
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000039
alokp@chromium.org2cf17712010-03-30 20:33:18 +000040 EOpNegative,
41 EOpLogicalNot,
42 EOpVectorLogicalNot,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000043
alokp@chromium.org2cf17712010-03-30 20:33:18 +000044 EOpPostIncrement,
45 EOpPostDecrement,
46 EOpPreIncrement,
47 EOpPreDecrement,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000048
alokp@chromium.org2cf17712010-03-30 20:33:18 +000049 EOpConvIntToBool,
50 EOpConvFloatToBool,
51 EOpConvBoolToFloat,
52 EOpConvIntToFloat,
53 EOpConvFloatToInt,
54 EOpConvBoolToInt,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000055
alokp@chromium.org2cf17712010-03-30 20:33:18 +000056 //
57 // binary operations
58 //
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000059
alokp@chromium.org2cf17712010-03-30 20:33:18 +000060 EOpAdd,
61 EOpSub,
62 EOpMul,
63 EOpDiv,
64 EOpEqual,
65 EOpNotEqual,
66 EOpVectorEqual,
67 EOpVectorNotEqual,
68 EOpLessThan,
69 EOpGreaterThan,
70 EOpLessThanEqual,
71 EOpGreaterThanEqual,
72 EOpComma,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000073
alokp@chromium.org2cf17712010-03-30 20:33:18 +000074 EOpVectorTimesScalar,
75 EOpVectorTimesMatrix,
76 EOpMatrixTimesVector,
77 EOpMatrixTimesScalar,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000078
alokp@chromium.org2cf17712010-03-30 20:33:18 +000079 EOpLogicalOr,
80 EOpLogicalXor,
81 EOpLogicalAnd,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000082
alokp@chromium.org2cf17712010-03-30 20:33:18 +000083 EOpIndexDirect,
84 EOpIndexIndirect,
85 EOpIndexDirectStruct,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000086
alokp@chromium.org2cf17712010-03-30 20:33:18 +000087 EOpVectorSwizzle,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000088
alokp@chromium.org2cf17712010-03-30 20:33:18 +000089 //
90 // Built-in functions potentially mapped to operators
91 //
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000092
alokp@chromium.org2cf17712010-03-30 20:33:18 +000093 EOpRadians,
94 EOpDegrees,
95 EOpSin,
96 EOpCos,
97 EOpTan,
98 EOpAsin,
99 EOpAcos,
100 EOpAtan,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000101
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000102 EOpPow,
103 EOpExp,
104 EOpLog,
105 EOpExp2,
106 EOpLog2,
107 EOpSqrt,
108 EOpInverseSqrt,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000109
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000110 EOpAbs,
111 EOpSign,
112 EOpFloor,
113 EOpCeil,
114 EOpFract,
115 EOpMod,
116 EOpMin,
117 EOpMax,
118 EOpClamp,
119 EOpMix,
120 EOpStep,
121 EOpSmoothStep,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000122
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000123 EOpLength,
124 EOpDistance,
125 EOpDot,
126 EOpCross,
127 EOpNormalize,
128 EOpFaceForward,
129 EOpReflect,
130 EOpRefract,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000131
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000132 //EOpDPdx, // Fragment only, OES_standard_derivatives extension
133 //EOpDPdy, // Fragment only, OES_standard_derivatives extension
134 //EOpFwidth, // Fragment only, OES_standard_derivatives extension
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000135
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000136 EOpMatrixTimesMatrix,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000137
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000138 EOpAny,
139 EOpAll,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000140
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000141 //
142 // Branch
143 //
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000144
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000145 EOpKill, // Fragment only
146 EOpReturn,
147 EOpBreak,
148 EOpContinue,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000149
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000150 //
151 // Constructors
152 //
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000153
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000154 EOpConstructInt,
155 EOpConstructBool,
156 EOpConstructFloat,
157 EOpConstructVec2,
158 EOpConstructVec3,
159 EOpConstructVec4,
160 EOpConstructBVec2,
161 EOpConstructBVec3,
162 EOpConstructBVec4,
163 EOpConstructIVec2,
164 EOpConstructIVec3,
165 EOpConstructIVec4,
166 EOpConstructMat2,
167 EOpConstructMat3,
168 EOpConstructMat4,
169 EOpConstructStruct,
170
171 //
172 // moves
173 //
174
175 EOpAssign,
176 EOpInitialize,
177 EOpAddAssign,
178 EOpSubAssign,
179 EOpMulAssign,
180 EOpVectorTimesMatrixAssign,
181 EOpVectorTimesScalarAssign,
182 EOpMatrixTimesScalarAssign,
183 EOpMatrixTimesMatrixAssign,
184 EOpDivAssign,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000185};
186
187class TIntermTraverser;
188class TIntermAggregate;
189class TIntermBinary;
daniel@transgaming.com4a35ef22010-04-08 03:51:06 +0000190class TIntermUnary;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000191class TIntermConstantUnion;
192class TIntermSelection;
193class TIntermTyped;
194class TIntermSymbol;
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000195class TIntermLoop;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000196class TInfoSink;
197
198//
199// Base class for the tree nodes
200//
201class TIntermNode {
202public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000203 POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000204
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000205 TIntermNode() : line(0) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000206
207 TSourceLoc getLine() const { return line; }
208 void setLine(TSourceLoc l) { line = l; }
209
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000210 virtual void traverse(TIntermTraverser*) = 0;
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000211 virtual TIntermTyped* getAsTyped() { return 0; }
212 virtual TIntermConstantUnion* getAsConstantUnion() { return 0; }
213 virtual TIntermAggregate* getAsAggregate() { return 0; }
214 virtual TIntermBinary* getAsBinaryNode() { return 0; }
215 virtual TIntermUnary* getAsUnaryNode() { return 0; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000216 virtual TIntermSelection* getAsSelectionNode() { return 0; }
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000217 virtual TIntermSymbol* getAsSymbolNode() { return 0; }
218 virtual TIntermLoop* getAsLoopNode() { return 0; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000219 virtual ~TIntermNode() { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000220
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000221protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000222 TSourceLoc line;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000223};
224
225//
226// This is just to help yacc.
227//
228struct TIntermNodePair {
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000229 TIntermNode* node1;
230 TIntermNode* node2;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000231};
232
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000233//
234// Intermediate class for nodes that have a type.
235//
236class TIntermTyped : public TIntermNode {
237public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000238 TIntermTyped(const TType& t) : type(t) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000239 virtual TIntermTyped* getAsTyped() { return this; }
alokp@chromium.orgdd037b22010-03-30 18:47:20 +0000240
alokp@chromium.org58e54292010-08-24 21:40:03 +0000241 void setType(const TType& t) { type = t; }
242 const TType& getType() const { return type; }
243 TType* getTypePointer() { return &type; }
244
245 TBasicType getBasicType() const { return type.getBasicType(); }
246 TQualifier getQualifier() const { return type.getQualifier(); }
247 TPrecision getPrecision() const { return type.getPrecision(); }
248 int getNominalSize() const { return type.getNominalSize(); }
249
250 bool isMatrix() const { return type.isMatrix(); }
251 bool isArray() const { return type.isArray(); }
252 bool isVector() const { return type.isVector(); }
253 bool isScalar() const { return type.isScalar(); }
254 const char* getBasicString() const { return type.getBasicString(); }
255 const char* getQualifierString() const { return type.getQualifierString(); }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000256 TString getCompleteString() const { return type.getCompleteString(); }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000257
258protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000259 TType type;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000260};
261
262//
263// Handle for, do-while, and while loops.
264//
265class TIntermLoop : public TIntermNode {
266public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000267 TIntermLoop(TIntermNode *init, TIntermNode* aBody, TIntermTyped* aTest, TIntermTyped* aTerminal, bool testFirst) :
268 init(init),
269 body(aBody),
270 test(aTest),
271 terminal(aTerminal),
272 first(testFirst) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000273
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000274 virtual TIntermLoop* getAsLoopNode() { return this; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000275 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000276
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000277 TIntermNode *getInit() { return init; }
278 TIntermNode *getBody() { return body; }
279 TIntermTyped *getTest() { return test; }
280 TIntermTyped *getTerminal() { return terminal; }
281 bool testFirst() { return first; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000282
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000283protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000284 TIntermNode *init;
285 TIntermNode *body; // code to loop over
286 TIntermTyped *test; // exit condition associated with loop, could be 0 for 'for' loops
287 TIntermTyped *terminal; // exists for for-loops
288 bool first; // true for while and for, not for do-while
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000289};
290
291//
292// Handle break, continue, return, and kill.
293//
294class TIntermBranch : public TIntermNode {
295public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000296 TIntermBranch(TOperator op, TIntermTyped* e) :
297 flowOp(op),
298 expression(e) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000299
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000300 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000301
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000302 TOperator getFlowOp() { return flowOp; }
303 TIntermTyped* getExpression() { return expression; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000304
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000305protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000306 TOperator flowOp;
307 TIntermTyped* expression; // non-zero except for "return exp;" statements
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000308};
309
310//
311// Nodes that correspond to symbols or constants in the source code.
312//
313class TIntermSymbol : public TIntermTyped {
314public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000315 // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. If sym comes from
316 // per process globalpoolallocator, then it causes increased memory usage per compile
317 // it is essential to use "symbol = sym" to assign to symbol
318 TIntermSymbol(int i, const TString& sym, const TType& t) :
319 TIntermTyped(t), id(i) { symbol = sym;}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000320
321 int getId() const { return id; }
322 const TString& getSymbol() const { return symbol; }
323
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000324 virtual void traverse(TIntermTraverser*);
325 virtual TIntermSymbol* getAsSymbolNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000326
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000327protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000328 int id;
329 TString symbol;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000330};
331
332class TIntermConstantUnion : public TIntermTyped {
333public:
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000334 TIntermConstantUnion(ConstantUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000335
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000336 ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; }
337 void setUnionArrayPointer(ConstantUnion *c) { unionArrayPointer = c; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000338
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000339 virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000340 virtual void traverse(TIntermTraverser*);
341
342 TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
343
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000344protected:
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000345 ConstantUnion *unionArrayPointer;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000346};
347
348//
349// Intermediate class for node types that hold operators.
350//
351class TIntermOperator : public TIntermTyped {
352public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000353 TOperator getOp() const { return op; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000354 void setOp(TOperator o) { op = o; }
355
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000356 bool modifiesState() const;
357 bool isConstructor() const;
alokp@chromium.org58e54292010-08-24 21:40:03 +0000358
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000359protected:
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000360 TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat, EbpUndefined)), op(o) {}
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000361 TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
362 TOperator op;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000363};
364
365//
366// Nodes for all the basic binary math operators.
367//
368class TIntermBinary : public TIntermOperator {
369public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000370 TIntermBinary(TOperator o) : TIntermOperator(o) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000371
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000372 virtual TIntermBinary* getAsBinaryNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000373 virtual void traverse(TIntermTraverser*);
374
375 void setLeft(TIntermTyped* n) { left = n; }
376 void setRight(TIntermTyped* n) { right = n; }
377 TIntermTyped* getLeft() const { return left; }
378 TIntermTyped* getRight() const { return right; }
379 bool promote(TInfoSink&);
380
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000381protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000382 TIntermTyped* left;
383 TIntermTyped* right;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000384};
385
386//
387// Nodes for unary math operators.
388//
389class TIntermUnary : public TIntermOperator {
390public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000391 TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0) {}
392 TIntermUnary(TOperator o) : TIntermOperator(o), operand(0) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000393
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000394 virtual void traverse(TIntermTraverser*);
daniel@transgaming.com4a35ef22010-04-08 03:51:06 +0000395 virtual TIntermUnary* getAsUnaryNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000396
397 void setOperand(TIntermTyped* o) { operand = o; }
398 TIntermTyped* getOperand() { return operand; }
399 bool promote(TInfoSink&);
400
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000401protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000402 TIntermTyped* operand;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000403};
404
405typedef TVector<TIntermNode*> TIntermSequence;
406typedef TVector<int> TQualifierList;
407//
408// Nodes that operate on an arbitrary sized set of children.
409//
410class TIntermAggregate : public TIntermOperator {
411public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000412 TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(0) { }
413 TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(0) { }
414 ~TIntermAggregate() { delete pragmaTable; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000415
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000416 virtual TIntermAggregate* getAsAggregate() { return this; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000417 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000418
419 TIntermSequence& getSequence() { return sequence; }
420 void setName(const TString& n) { name = n; }
421 const TString& getName() const { return name; }
422
423 void setUserDefined() { userDefined = true; }
424 bool isUserDefined() { return userDefined; }
425 TQualifierList& getQualifier() { return qualifier; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000426 void setOptimize(bool o) { optimize = o; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000427 bool getOptimize() { return optimize; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000428 void setDebug(bool d) { debug = d; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000429 bool getDebug() { return debug; }
430 void addToPragmaTable(const TPragmaTable& pTable);
431 const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000432
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000433protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000434 TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
435 TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
436 TIntermSequence sequence;
437 TQualifierList qualifier;
438 TString name;
439 bool userDefined; // used for user defined function names
440 bool optimize;
441 bool debug;
442 TPragmaTable *pragmaTable;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000443};
444
445//
446// For if tests. Simplified since there is no switch statement.
447//
448class TIntermSelection : public TIntermTyped {
449public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000450 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000451 TIntermTyped(TType(EbtVoid, EbpUndefined)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000452 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
453 TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000454
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000455 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000456
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000457 bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000458 TIntermNode* getCondition() const { return condition; }
459 TIntermNode* getTrueBlock() const { return trueBlock; }
460 TIntermNode* getFalseBlock() const { return falseBlock; }
461 TIntermSelection* getAsSelectionNode() { return this; }
462
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000463protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000464 TIntermTyped* condition;
465 TIntermNode* trueBlock;
466 TIntermNode* falseBlock;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000467};
468
469enum Visit
470{
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000471 PreVisit,
472 InVisit,
473 PostVisit
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000474};
475
476//
477// For traversing the tree. User should derive from this,
478// put their traversal specific data in it, and then pass
479// it to a Traverse method.
480//
481// When using this, just fill in the methods for nodes you want visited.
482// Return false from a pre-visit to skip visiting that node's subtree.
483//
484class TIntermTraverser
485{
486public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000487 POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000488
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000489 TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
490 preVisit(preVisit),
491 inVisit(inVisit),
492 postVisit(postVisit),
493 rightToLeft(rightToLeft),
494 depth(0) {}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000495
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000496 virtual void visitSymbol(TIntermSymbol*) {}
497 virtual void visitConstantUnion(TIntermConstantUnion*) {}
498 virtual bool visitBinary(Visit visit, TIntermBinary*) {return true;}
499 virtual bool visitUnary(Visit visit, TIntermUnary*) {return true;}
500 virtual bool visitSelection(Visit visit, TIntermSelection*) {return true;}
501 virtual bool visitAggregate(Visit visit, TIntermAggregate*) {return true;}
502 virtual bool visitLoop(Visit visit, TIntermLoop*) {return true;}
503 virtual bool visitBranch(Visit visit, TIntermBranch*) {return true;}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000504
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000505 void incrementDepth() {depth++;}
506 void decrementDepth() {depth--;}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000507
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000508 const bool preVisit;
509 const bool inVisit;
510 const bool postVisit;
511 const bool rightToLeft;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000512
513protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000514 int depth;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000515};
516
517#endif // __INTERMEDIATE_H