blob: 1dbeef01cc5c3d4677cf9ebedd234336b747fda5 [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.com0aa3b5a2012-11-28 19:43:24 +000019#include "GLSLANG/ShaderLang.h"
20
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000021#include "compiler/Common.h"
22#include "compiler/Types.h"
23#include "compiler/ConstantUnion.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000024
25//
26// Operators used by the high-level (parse tree) representation.
27//
28enum TOperator {
alokp@chromium.org2cf17712010-03-30 20:33:18 +000029 EOpNull, // if in a node, should only mean a node is still being built
30 EOpSequence, // denotes a list of statements, or parameters, etc.
31 EOpFunctionCall,
32 EOpFunction, // For function definition
33 EOpParameters, // an aggregate listing the parameters to a function
daniel@transgaming.comd1acd1e2010-04-13 03:25:57 +000034
alokp@chromium.org2cf17712010-03-30 20:33:18 +000035 EOpDeclaration,
daniel@transgaming.comd1acd1e2010-04-13 03:25:57 +000036 EOpPrototype,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000037
alokp@chromium.org2cf17712010-03-30 20:33:18 +000038 //
39 // Unary operators
40 //
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000041
alokp@chromium.org2cf17712010-03-30 20:33:18 +000042 EOpNegative,
43 EOpLogicalNot,
44 EOpVectorLogicalNot,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000045
alokp@chromium.org2cf17712010-03-30 20:33:18 +000046 EOpPostIncrement,
47 EOpPostDecrement,
48 EOpPreIncrement,
49 EOpPreDecrement,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000050
alokp@chromium.org2cf17712010-03-30 20:33:18 +000051 EOpConvIntToBool,
52 EOpConvFloatToBool,
53 EOpConvBoolToFloat,
54 EOpConvIntToFloat,
55 EOpConvFloatToInt,
56 EOpConvBoolToInt,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000057
alokp@chromium.org2cf17712010-03-30 20:33:18 +000058 //
59 // binary operations
60 //
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000061
alokp@chromium.org2cf17712010-03-30 20:33:18 +000062 EOpAdd,
63 EOpSub,
64 EOpMul,
65 EOpDiv,
66 EOpEqual,
67 EOpNotEqual,
68 EOpVectorEqual,
69 EOpVectorNotEqual,
70 EOpLessThan,
71 EOpGreaterThan,
72 EOpLessThanEqual,
73 EOpGreaterThanEqual,
74 EOpComma,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000075
alokp@chromium.org2cf17712010-03-30 20:33:18 +000076 EOpVectorTimesScalar,
77 EOpVectorTimesMatrix,
78 EOpMatrixTimesVector,
79 EOpMatrixTimesScalar,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000080
alokp@chromium.org2cf17712010-03-30 20:33:18 +000081 EOpLogicalOr,
82 EOpLogicalXor,
83 EOpLogicalAnd,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000084
alokp@chromium.org2cf17712010-03-30 20:33:18 +000085 EOpIndexDirect,
86 EOpIndexIndirect,
87 EOpIndexDirectStruct,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000088
alokp@chromium.org2cf17712010-03-30 20:33:18 +000089 EOpVectorSwizzle,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000090
alokp@chromium.org2cf17712010-03-30 20:33:18 +000091 //
92 // Built-in functions potentially mapped to operators
93 //
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000094
alokp@chromium.org2cf17712010-03-30 20:33:18 +000095 EOpRadians,
96 EOpDegrees,
97 EOpSin,
98 EOpCos,
99 EOpTan,
100 EOpAsin,
101 EOpAcos,
102 EOpAtan,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000103
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000104 EOpPow,
105 EOpExp,
106 EOpLog,
107 EOpExp2,
108 EOpLog2,
109 EOpSqrt,
110 EOpInverseSqrt,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000111
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000112 EOpAbs,
113 EOpSign,
114 EOpFloor,
115 EOpCeil,
116 EOpFract,
117 EOpMod,
118 EOpMin,
119 EOpMax,
120 EOpClamp,
121 EOpMix,
122 EOpStep,
123 EOpSmoothStep,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000124
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000125 EOpLength,
126 EOpDistance,
127 EOpDot,
128 EOpCross,
129 EOpNormalize,
130 EOpFaceForward,
131 EOpReflect,
132 EOpRefract,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000133
alokp@chromium.org06098892010-08-26 19:36:42 +0000134 EOpDFdx, // Fragment only, OES_standard_derivatives extension
135 EOpDFdy, // Fragment only, OES_standard_derivatives extension
136 EOpFwidth, // Fragment only, OES_standard_derivatives extension
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000137
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000138 EOpMatrixTimesMatrix,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000139
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000140 EOpAny,
141 EOpAll,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000142
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000143 //
144 // Branch
145 //
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000146
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000147 EOpKill, // Fragment only
148 EOpReturn,
149 EOpBreak,
150 EOpContinue,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000151
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000152 //
153 // Constructors
154 //
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000155
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000156 EOpConstructInt,
157 EOpConstructBool,
158 EOpConstructFloat,
159 EOpConstructVec2,
160 EOpConstructVec3,
161 EOpConstructVec4,
162 EOpConstructBVec2,
163 EOpConstructBVec3,
164 EOpConstructBVec4,
165 EOpConstructIVec2,
166 EOpConstructIVec3,
167 EOpConstructIVec4,
168 EOpConstructMat2,
169 EOpConstructMat3,
170 EOpConstructMat4,
171 EOpConstructStruct,
172
173 //
174 // moves
175 //
176
177 EOpAssign,
178 EOpInitialize,
179 EOpAddAssign,
180 EOpSubAssign,
181 EOpMulAssign,
182 EOpVectorTimesMatrixAssign,
183 EOpVectorTimesScalarAssign,
184 EOpMatrixTimesScalarAssign,
185 EOpMatrixTimesMatrixAssign,
186 EOpDivAssign,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000187};
188
alokp@chromium.orgb59a7782010-11-24 18:38:33 +0000189extern const char* getOperatorString(TOperator op);
190
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000191class TIntermTraverser;
192class TIntermAggregate;
193class TIntermBinary;
daniel@transgaming.com4a35ef22010-04-08 03:51:06 +0000194class TIntermUnary;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000195class TIntermConstantUnion;
196class TIntermSelection;
197class TIntermTyped;
198class TIntermSymbol;
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000199class TIntermLoop;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000200class TInfoSink;
201
202//
203// Base class for the tree nodes
204//
205class TIntermNode {
206public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000207 POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000208
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000209 TIntermNode() : line(0) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000210
211 TSourceLoc getLine() const { return line; }
212 void setLine(TSourceLoc l) { line = l; }
213
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000214 virtual void traverse(TIntermTraverser*) = 0;
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000215 virtual TIntermTyped* getAsTyped() { return 0; }
216 virtual TIntermConstantUnion* getAsConstantUnion() { return 0; }
217 virtual TIntermAggregate* getAsAggregate() { return 0; }
218 virtual TIntermBinary* getAsBinaryNode() { return 0; }
219 virtual TIntermUnary* getAsUnaryNode() { return 0; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000220 virtual TIntermSelection* getAsSelectionNode() { return 0; }
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000221 virtual TIntermSymbol* getAsSymbolNode() { return 0; }
222 virtual TIntermLoop* getAsLoopNode() { return 0; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000223 virtual ~TIntermNode() { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000224
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000225protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000226 TSourceLoc line;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000227};
228
229//
230// This is just to help yacc.
231//
232struct TIntermNodePair {
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000233 TIntermNode* node1;
234 TIntermNode* node2;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000235};
236
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000237//
238// Intermediate class for nodes that have a type.
239//
240class TIntermTyped : public TIntermNode {
241public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000242 TIntermTyped(const TType& t) : type(t) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000243 virtual TIntermTyped* getAsTyped() { return this; }
alokp@chromium.orgdd037b22010-03-30 18:47:20 +0000244
alokp@chromium.org58e54292010-08-24 21:40:03 +0000245 void setType(const TType& t) { type = t; }
246 const TType& getType() const { return type; }
247 TType* getTypePointer() { return &type; }
248
249 TBasicType getBasicType() const { return type.getBasicType(); }
250 TQualifier getQualifier() const { return type.getQualifier(); }
251 TPrecision getPrecision() const { return type.getPrecision(); }
252 int getNominalSize() const { return type.getNominalSize(); }
253
254 bool isMatrix() const { return type.isMatrix(); }
255 bool isArray() const { return type.isArray(); }
256 bool isVector() const { return type.isVector(); }
257 bool isScalar() const { return type.isScalar(); }
258 const char* getBasicString() const { return type.getBasicString(); }
259 const char* getQualifierString() const { return type.getQualifierString(); }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000260 TString getCompleteString() const { return type.getCompleteString(); }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000261
daniel@transgaming.com3ca980a2012-12-20 21:11:52 +0000262 int totalRegisterCount() const { return type.totalRegisterCount(); }
263 int elementRegisterCount() const { return type.elementRegisterCount(); }
264 int getArraySize() const { return type.getArraySize(); }
265
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000266protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000267 TType type;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000268};
269
270//
271// Handle for, do-while, and while loops.
272//
alokp@chromium.org52813552010-11-16 18:36:09 +0000273enum TLoopType {
274 ELoopFor,
275 ELoopWhile,
276 ELoopDoWhile,
277};
278
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000279class TIntermLoop : public TIntermNode {
280public:
alokp@chromium.org52813552010-11-16 18:36:09 +0000281 TIntermLoop(TLoopType aType,
282 TIntermNode *aInit, TIntermTyped* aCond, TIntermTyped* aExpr,
283 TIntermNode* aBody) :
284 type(aType),
285 init(aInit),
286 cond(aCond),
287 expr(aExpr),
zmo@google.com0b8d4eb2011-04-04 19:17:11 +0000288 body(aBody),
289 unrollFlag(false) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000290
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000291 virtual TIntermLoop* getAsLoopNode() { return this; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000292 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000293
alokp@chromium.org52813552010-11-16 18:36:09 +0000294 TLoopType getType() const { return type; }
295 TIntermNode* getInit() { return init; }
296 TIntermTyped* getCondition() { return cond; }
297 TIntermTyped* getExpression() { return expr; }
298 TIntermNode* getBody() { return body; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000299
zmo@google.com0b8d4eb2011-04-04 19:17:11 +0000300 void setUnrollFlag(bool flag) { unrollFlag = flag; }
301 bool getUnrollFlag() { return unrollFlag; }
302
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000303protected:
alokp@chromium.org52813552010-11-16 18:36:09 +0000304 TLoopType type;
305 TIntermNode* init; // for-loop initialization
306 TIntermTyped* cond; // loop exit condition
307 TIntermTyped* expr; // for-loop expression
308 TIntermNode* body; // loop body
zmo@google.com0b8d4eb2011-04-04 19:17:11 +0000309
310 bool unrollFlag; // Whether the loop should be unrolled or not.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000311};
312
313//
314// Handle break, continue, return, and kill.
315//
316class TIntermBranch : public TIntermNode {
317public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000318 TIntermBranch(TOperator op, TIntermTyped* e) :
319 flowOp(op),
320 expression(e) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000321
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000322 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000323
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000324 TOperator getFlowOp() { return flowOp; }
325 TIntermTyped* getExpression() { return expression; }
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 TOperator flowOp;
329 TIntermTyped* expression; // non-zero except for "return exp;" statements
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000330};
331
332//
333// Nodes that correspond to symbols or constants in the source code.
334//
335class TIntermSymbol : public TIntermTyped {
336public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000337 // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. If sym comes from
338 // per process globalpoolallocator, then it causes increased memory usage per compile
339 // it is essential to use "symbol = sym" to assign to symbol
340 TIntermSymbol(int i, const TString& sym, const TType& t) :
zmo@google.comfd747b82011-04-23 01:30:07 +0000341 TIntermTyped(t), id(i) { symbol = sym; originalSymbol = sym; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000342
343 int getId() const { return id; }
344 const TString& getSymbol() const { return symbol; }
345
zmo@google.comfd747b82011-04-23 01:30:07 +0000346 void setId(int newId) { id = newId; }
347 void setSymbol(const TString& sym) { symbol = sym; }
348
349 const TString& getOriginalSymbol() const { return originalSymbol; }
350
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000351 virtual void traverse(TIntermTraverser*);
352 virtual TIntermSymbol* getAsSymbolNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000353
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000354protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000355 int id;
356 TString symbol;
zmo@google.comfd747b82011-04-23 01:30:07 +0000357 TString originalSymbol;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000358};
359
360class TIntermConstantUnion : public TIntermTyped {
361public:
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000362 TIntermConstantUnion(ConstantUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000363
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000364 ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; }
365 void setUnionArrayPointer(ConstantUnion *c) { unionArrayPointer = c; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000366
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000367 virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000368 virtual void traverse(TIntermTraverser*);
369
370 TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
371
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000372protected:
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000373 ConstantUnion *unionArrayPointer;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000374};
375
376//
377// Intermediate class for node types that hold operators.
378//
379class TIntermOperator : public TIntermTyped {
380public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000381 TOperator getOp() const { return op; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000382 void setOp(TOperator o) { op = o; }
383
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000384 bool modifiesState() const;
385 bool isConstructor() const;
alokp@chromium.org58e54292010-08-24 21:40:03 +0000386
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000387protected:
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000388 TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat, EbpUndefined)), op(o) {}
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000389 TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
390 TOperator op;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000391};
392
393//
394// Nodes for all the basic binary math operators.
395//
396class TIntermBinary : public TIntermOperator {
397public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000398 TIntermBinary(TOperator o) : TIntermOperator(o) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000399
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000400 virtual TIntermBinary* getAsBinaryNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000401 virtual void traverse(TIntermTraverser*);
402
403 void setLeft(TIntermTyped* n) { left = n; }
404 void setRight(TIntermTyped* n) { right = n; }
405 TIntermTyped* getLeft() const { return left; }
406 TIntermTyped* getRight() const { return right; }
407 bool promote(TInfoSink&);
408
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000409protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000410 TIntermTyped* left;
411 TIntermTyped* right;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000412};
413
414//
415// Nodes for unary math operators.
416//
417class TIntermUnary : public TIntermOperator {
418public:
zmo@google.com32e97312011-08-24 01:03:11 +0000419 TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0), useEmulatedFunction(false) {}
zmo@google.come4eb9912011-08-29 21:13:12 +0000420 TIntermUnary(TOperator o) : TIntermOperator(o), operand(0), useEmulatedFunction(false) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000421
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000422 virtual void traverse(TIntermTraverser*);
daniel@transgaming.com4a35ef22010-04-08 03:51:06 +0000423 virtual TIntermUnary* getAsUnaryNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000424
425 void setOperand(TIntermTyped* o) { operand = o; }
426 TIntermTyped* getOperand() { return operand; }
427 bool promote(TInfoSink&);
428
zmo@google.com32e97312011-08-24 01:03:11 +0000429 void setUseEmulatedFunction() { useEmulatedFunction = true; }
430 bool getUseEmulatedFunction() { return useEmulatedFunction; }
431
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000432protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000433 TIntermTyped* operand;
zmo@google.comf420c422011-09-12 18:27:59 +0000434
435 // If set to true, replace the built-in function call with an emulated one
436 // to work around driver bugs.
437 bool useEmulatedFunction;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000438};
439
440typedef TVector<TIntermNode*> TIntermSequence;
441typedef TVector<int> TQualifierList;
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000442
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000443//
444// Nodes that operate on an arbitrary sized set of children.
445//
446class TIntermAggregate : public TIntermOperator {
447public:
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000448 TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), endLine(0), useEmulatedFunction(false) { }
449 TIntermAggregate(TOperator o) : TIntermOperator(o), useEmulatedFunction(false) { }
450 ~TIntermAggregate() { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000451
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000452 virtual TIntermAggregate* getAsAggregate() { return this; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000453 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000454
455 TIntermSequence& getSequence() { return sequence; }
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000456
alokp@chromium.org58e54292010-08-24 21:40:03 +0000457 void setName(const TString& n) { name = n; }
458 const TString& getName() const { return name; }
459
460 void setUserDefined() { userDefined = true; }
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000461 bool isUserDefined() const { return userDefined; }
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000462
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000463 void setOptimize(bool o) { optimize = o; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000464 bool getOptimize() { return optimize; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000465 void setDebug(bool d) { debug = d; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000466 bool getDebug() { return debug; }
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000467
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000468 void setEndLine(TSourceLoc line) { endLine = line; }
469 TSourceLoc getEndLine() const { return endLine; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000470
zmo@google.comf420c422011-09-12 18:27:59 +0000471 void setUseEmulatedFunction() { useEmulatedFunction = true; }
472 bool getUseEmulatedFunction() { return useEmulatedFunction; }
473
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000474protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000475 TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
476 TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
477 TIntermSequence sequence;
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000478 TString name;
479 bool userDefined; // used for user defined function names
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000480
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000481 bool optimize;
482 bool debug;
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000483 TSourceLoc endLine;
zmo@google.comf420c422011-09-12 18:27:59 +0000484
485 // If set to true, replace the built-in function call with an emulated one
486 // to work around driver bugs.
487 bool useEmulatedFunction;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000488};
489
490//
491// For if tests. Simplified since there is no switch statement.
492//
493class TIntermSelection : public TIntermTyped {
494public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000495 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000496 TIntermTyped(TType(EbtVoid, EbpUndefined)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000497 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
498 TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000499
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000500 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000501
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000502 bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000503 TIntermNode* getCondition() const { return condition; }
504 TIntermNode* getTrueBlock() const { return trueBlock; }
505 TIntermNode* getFalseBlock() const { return falseBlock; }
506 TIntermSelection* getAsSelectionNode() { return this; }
507
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000508protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000509 TIntermTyped* condition;
510 TIntermNode* trueBlock;
511 TIntermNode* falseBlock;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000512};
513
514enum Visit
515{
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000516 PreVisit,
517 InVisit,
518 PostVisit
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000519};
520
521//
522// For traversing the tree. User should derive from this,
523// put their traversal specific data in it, and then pass
524// it to a Traverse method.
525//
526// When using this, just fill in the methods for nodes you want visited.
527// Return false from a pre-visit to skip visiting that node's subtree.
528//
529class TIntermTraverser
530{
531public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000532 POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000533
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000534 TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
535 preVisit(preVisit),
536 inVisit(inVisit),
537 postVisit(postVisit),
538 rightToLeft(rightToLeft),
539 depth(0) {}
maxvujovic@gmail.comc6b3b3c2012-06-27 22:49:39 +0000540 virtual ~TIntermTraverser() {};
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000541
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000542 virtual void visitSymbol(TIntermSymbol*) {}
543 virtual void visitConstantUnion(TIntermConstantUnion*) {}
544 virtual bool visitBinary(Visit visit, TIntermBinary*) {return true;}
545 virtual bool visitUnary(Visit visit, TIntermUnary*) {return true;}
546 virtual bool visitSelection(Visit visit, TIntermSelection*) {return true;}
547 virtual bool visitAggregate(Visit visit, TIntermAggregate*) {return true;}
548 virtual bool visitLoop(Visit visit, TIntermLoop*) {return true;}
549 virtual bool visitBranch(Visit visit, TIntermBranch*) {return true;}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000550
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000551 void incrementDepth() {depth++;}
552 void decrementDepth() {depth--;}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000553
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000554 // Return the original name if hash function pointer is NULL;
555 // otherwise return the hashed name.
556 static TString hash(const TString& name, ShHashFunction64 hashFunction);
557
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000558 const bool preVisit;
559 const bool inVisit;
560 const bool postVisit;
561 const bool rightToLeft;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000562
563protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000564 int depth;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000565};
566
567#endif // __INTERMEDIATE_H