blob: 32f2dc10e91197d5e4f942f266bf41de67700dcb [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.org06098892010-08-26 19:36:42 +0000132 EOpDFdx, // Fragment only, OES_standard_derivatives extension
133 EOpDFdy, // 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
alokp@chromium.orgb59a7782010-11-24 18:38:33 +0000187extern const char* getOperatorString(TOperator op);
188
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000189class TIntermTraverser;
190class TIntermAggregate;
191class TIntermBinary;
daniel@transgaming.com4a35ef22010-04-08 03:51:06 +0000192class TIntermUnary;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000193class TIntermConstantUnion;
194class TIntermSelection;
195class TIntermTyped;
196class TIntermSymbol;
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000197class TIntermLoop;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000198class TInfoSink;
199
200//
201// Base class for the tree nodes
202//
203class TIntermNode {
204public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000205 POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000206
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000207 TIntermNode() : line(0) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000208
209 TSourceLoc getLine() const { return line; }
210 void setLine(TSourceLoc l) { line = l; }
211
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000212 virtual void traverse(TIntermTraverser*) = 0;
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000213 virtual TIntermTyped* getAsTyped() { return 0; }
214 virtual TIntermConstantUnion* getAsConstantUnion() { return 0; }
215 virtual TIntermAggregate* getAsAggregate() { return 0; }
216 virtual TIntermBinary* getAsBinaryNode() { return 0; }
217 virtual TIntermUnary* getAsUnaryNode() { return 0; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000218 virtual TIntermSelection* getAsSelectionNode() { return 0; }
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000219 virtual TIntermSymbol* getAsSymbolNode() { return 0; }
220 virtual TIntermLoop* getAsLoopNode() { return 0; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000221 virtual ~TIntermNode() { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000222
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000223protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000224 TSourceLoc line;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000225};
226
227//
228// This is just to help yacc.
229//
230struct TIntermNodePair {
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000231 TIntermNode* node1;
232 TIntermNode* node2;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000233};
234
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000235//
236// Intermediate class for nodes that have a type.
237//
238class TIntermTyped : public TIntermNode {
239public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000240 TIntermTyped(const TType& t) : type(t) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000241 virtual TIntermTyped* getAsTyped() { return this; }
alokp@chromium.orgdd037b22010-03-30 18:47:20 +0000242
alokp@chromium.org58e54292010-08-24 21:40:03 +0000243 void setType(const TType& t) { type = t; }
244 const TType& getType() const { return type; }
245 TType* getTypePointer() { return &type; }
246
247 TBasicType getBasicType() const { return type.getBasicType(); }
248 TQualifier getQualifier() const { return type.getQualifier(); }
249 TPrecision getPrecision() const { return type.getPrecision(); }
250 int getNominalSize() const { return type.getNominalSize(); }
251
252 bool isMatrix() const { return type.isMatrix(); }
253 bool isArray() const { return type.isArray(); }
254 bool isVector() const { return type.isVector(); }
255 bool isScalar() const { return type.isScalar(); }
256 const char* getBasicString() const { return type.getBasicString(); }
257 const char* getQualifierString() const { return type.getQualifierString(); }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000258 TString getCompleteString() const { return type.getCompleteString(); }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000259
260protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000261 TType type;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000262};
263
264//
265// Handle for, do-while, and while loops.
266//
alokp@chromium.org52813552010-11-16 18:36:09 +0000267enum TLoopType {
268 ELoopFor,
269 ELoopWhile,
270 ELoopDoWhile,
271};
272
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000273class TIntermLoop : public TIntermNode {
274public:
alokp@chromium.org52813552010-11-16 18:36:09 +0000275 TIntermLoop(TLoopType aType,
276 TIntermNode *aInit, TIntermTyped* aCond, TIntermTyped* aExpr,
277 TIntermNode* aBody) :
278 type(aType),
279 init(aInit),
280 cond(aCond),
281 expr(aExpr),
zmo@google.com0b8d4eb2011-04-04 19:17:11 +0000282 body(aBody),
283 unrollFlag(false) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000284
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000285 virtual TIntermLoop* getAsLoopNode() { return this; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000286 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000287
alokp@chromium.org52813552010-11-16 18:36:09 +0000288 TLoopType getType() const { return type; }
289 TIntermNode* getInit() { return init; }
290 TIntermTyped* getCondition() { return cond; }
291 TIntermTyped* getExpression() { return expr; }
292 TIntermNode* getBody() { return body; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000293
zmo@google.com0b8d4eb2011-04-04 19:17:11 +0000294 void setUnrollFlag(bool flag) { unrollFlag = flag; }
295 bool getUnrollFlag() { return unrollFlag; }
296
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000297protected:
alokp@chromium.org52813552010-11-16 18:36:09 +0000298 TLoopType type;
299 TIntermNode* init; // for-loop initialization
300 TIntermTyped* cond; // loop exit condition
301 TIntermTyped* expr; // for-loop expression
302 TIntermNode* body; // loop body
zmo@google.com0b8d4eb2011-04-04 19:17:11 +0000303
304 bool unrollFlag; // Whether the loop should be unrolled or not.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000305};
306
307//
308// Handle break, continue, return, and kill.
309//
310class TIntermBranch : public TIntermNode {
311public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000312 TIntermBranch(TOperator op, TIntermTyped* e) :
313 flowOp(op),
314 expression(e) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000315
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000316 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000317
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000318 TOperator getFlowOp() { return flowOp; }
319 TIntermTyped* getExpression() { return expression; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000320
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000321protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000322 TOperator flowOp;
323 TIntermTyped* expression; // non-zero except for "return exp;" statements
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000324};
325
326//
327// Nodes that correspond to symbols or constants in the source code.
328//
329class TIntermSymbol : public TIntermTyped {
330public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000331 // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. If sym comes from
332 // per process globalpoolallocator, then it causes increased memory usage per compile
333 // it is essential to use "symbol = sym" to assign to symbol
334 TIntermSymbol(int i, const TString& sym, const TType& t) :
zmo@google.comfd747b82011-04-23 01:30:07 +0000335 TIntermTyped(t), id(i) { symbol = sym; originalSymbol = sym; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000336
337 int getId() const { return id; }
338 const TString& getSymbol() const { return symbol; }
339
zmo@google.comfd747b82011-04-23 01:30:07 +0000340 void setId(int newId) { id = newId; }
341 void setSymbol(const TString& sym) { symbol = sym; }
342
343 const TString& getOriginalSymbol() const { return originalSymbol; }
344
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000345 virtual void traverse(TIntermTraverser*);
346 virtual TIntermSymbol* getAsSymbolNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000347
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000348protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000349 int id;
350 TString symbol;
zmo@google.comfd747b82011-04-23 01:30:07 +0000351 TString originalSymbol;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000352};
353
354class TIntermConstantUnion : public TIntermTyped {
355public:
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000356 TIntermConstantUnion(ConstantUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000357
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000358 ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; }
359 void setUnionArrayPointer(ConstantUnion *c) { unionArrayPointer = c; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000360
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000361 virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000362 virtual void traverse(TIntermTraverser*);
363
364 TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
365
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000366protected:
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000367 ConstantUnion *unionArrayPointer;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000368};
369
370//
371// Intermediate class for node types that hold operators.
372//
373class TIntermOperator : public TIntermTyped {
374public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000375 TOperator getOp() const { return op; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000376 void setOp(TOperator o) { op = o; }
377
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000378 bool modifiesState() const;
379 bool isConstructor() const;
alokp@chromium.org58e54292010-08-24 21:40:03 +0000380
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000381protected:
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000382 TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat, EbpUndefined)), op(o) {}
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000383 TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
384 TOperator op;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000385};
386
387//
388// Nodes for all the basic binary math operators.
389//
390class TIntermBinary : public TIntermOperator {
391public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000392 TIntermBinary(TOperator o) : TIntermOperator(o) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000393
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000394 virtual TIntermBinary* getAsBinaryNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000395 virtual void traverse(TIntermTraverser*);
396
397 void setLeft(TIntermTyped* n) { left = n; }
398 void setRight(TIntermTyped* n) { right = n; }
399 TIntermTyped* getLeft() const { return left; }
400 TIntermTyped* getRight() const { return right; }
401 bool promote(TInfoSink&);
402
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000403protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000404 TIntermTyped* left;
405 TIntermTyped* right;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000406};
407
408//
409// Nodes for unary math operators.
410//
411class TIntermUnary : public TIntermOperator {
412public:
zmo@google.com32e97312011-08-24 01:03:11 +0000413 TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0), useEmulatedFunction(false) {}
zmo@google.come4eb9912011-08-29 21:13:12 +0000414 TIntermUnary(TOperator o) : TIntermOperator(o), operand(0), useEmulatedFunction(false) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000415
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000416 virtual void traverse(TIntermTraverser*);
daniel@transgaming.com4a35ef22010-04-08 03:51:06 +0000417 virtual TIntermUnary* getAsUnaryNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000418
419 void setOperand(TIntermTyped* o) { operand = o; }
420 TIntermTyped* getOperand() { return operand; }
421 bool promote(TInfoSink&);
422
zmo@google.com32e97312011-08-24 01:03:11 +0000423 void setUseEmulatedFunction() { useEmulatedFunction = true; }
424 bool getUseEmulatedFunction() { return useEmulatedFunction; }
425
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000426protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000427 TIntermTyped* operand;
zmo@google.comf420c422011-09-12 18:27:59 +0000428
429 // If set to true, replace the built-in function call with an emulated one
430 // to work around driver bugs.
431 bool useEmulatedFunction;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000432};
433
434typedef TVector<TIntermNode*> TIntermSequence;
435typedef TVector<int> TQualifierList;
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000436
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000437//
438// Nodes that operate on an arbitrary sized set of children.
439//
440class TIntermAggregate : public TIntermOperator {
441public:
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000442 TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), endLine(0), useEmulatedFunction(false) { }
443 TIntermAggregate(TOperator o) : TIntermOperator(o), useEmulatedFunction(false) { }
444 ~TIntermAggregate() { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000445
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000446 virtual TIntermAggregate* getAsAggregate() { return this; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000447 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000448
449 TIntermSequence& getSequence() { return sequence; }
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000450
alokp@chromium.org58e54292010-08-24 21:40:03 +0000451 void setName(const TString& n) { name = n; }
452 const TString& getName() const { return name; }
453
454 void setUserDefined() { userDefined = true; }
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000455 bool isUserDefined() const { return userDefined; }
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000456
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000457 void setOptimize(bool o) { optimize = o; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000458 bool getOptimize() { return optimize; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000459 void setDebug(bool d) { debug = d; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000460 bool getDebug() { return debug; }
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000461
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000462 void setEndLine(TSourceLoc line) { endLine = line; }
463 TSourceLoc getEndLine() const { return endLine; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000464
zmo@google.comf420c422011-09-12 18:27:59 +0000465 void setUseEmulatedFunction() { useEmulatedFunction = true; }
466 bool getUseEmulatedFunction() { return useEmulatedFunction; }
467
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000468protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000469 TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
470 TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
471 TIntermSequence sequence;
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000472 TString name;
473 bool userDefined; // used for user defined function names
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000474
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000475 bool optimize;
476 bool debug;
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000477 TSourceLoc endLine;
zmo@google.comf420c422011-09-12 18:27:59 +0000478
479 // If set to true, replace the built-in function call with an emulated one
480 // to work around driver bugs.
481 bool useEmulatedFunction;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000482};
483
484//
485// For if tests. Simplified since there is no switch statement.
486//
487class TIntermSelection : public TIntermTyped {
488public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000489 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000490 TIntermTyped(TType(EbtVoid, EbpUndefined)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000491 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
492 TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000493
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000494 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000495
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000496 bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000497 TIntermNode* getCondition() const { return condition; }
498 TIntermNode* getTrueBlock() const { return trueBlock; }
499 TIntermNode* getFalseBlock() const { return falseBlock; }
500 TIntermSelection* getAsSelectionNode() { return this; }
501
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000502protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000503 TIntermTyped* condition;
504 TIntermNode* trueBlock;
505 TIntermNode* falseBlock;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000506};
507
508enum Visit
509{
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000510 PreVisit,
511 InVisit,
512 PostVisit
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000513};
514
515//
516// For traversing the tree. User should derive from this,
517// put their traversal specific data in it, and then pass
518// it to a Traverse method.
519//
520// When using this, just fill in the methods for nodes you want visited.
521// Return false from a pre-visit to skip visiting that node's subtree.
522//
523class TIntermTraverser
524{
525public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000526 POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000527
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000528 TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
529 preVisit(preVisit),
530 inVisit(inVisit),
531 postVisit(postVisit),
532 rightToLeft(rightToLeft),
533 depth(0) {}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000534
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000535 virtual void visitSymbol(TIntermSymbol*) {}
536 virtual void visitConstantUnion(TIntermConstantUnion*) {}
537 virtual bool visitBinary(Visit visit, TIntermBinary*) {return true;}
538 virtual bool visitUnary(Visit visit, TIntermUnary*) {return true;}
539 virtual bool visitSelection(Visit visit, TIntermSelection*) {return true;}
540 virtual bool visitAggregate(Visit visit, TIntermAggregate*) {return true;}
541 virtual bool visitLoop(Visit visit, TIntermLoop*) {return true;}
542 virtual bool visitBranch(Visit visit, TIntermBranch*) {return true;}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000543
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000544 void incrementDepth() {depth++;}
545 void decrementDepth() {depth--;}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000546
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000547 const bool preVisit;
548 const bool inVisit;
549 const bool postVisit;
550 const bool rightToLeft;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000551
552protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000553 int depth;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000554};
555
556#endif // __INTERMEDIATE_H