blob: 8e76ef921f1f3b323bc30f9eec6b59d9d1a4f2e8 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
shannon.woods%transgaming.com@gtempaccount.comc0d0c222013-04-13 03:29:36 +00002// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003// 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,
daniel@transgaming.comb3077d02013-01-11 04:12:09 +0000186 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,
daniel@transgaming.comb3077d02013-01-11 04:12:09 +0000276 ELoopDoWhile
alokp@chromium.org52813552010-11-16 18:36:09 +0000277};
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; }
shannon.woods%transgaming.com@gtempaccount.comc0d0c222013-04-13 03:29:36 +0000365
366 int getIConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getIConst() : 0; }
367 float getFConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getFConst() : 0.0f; }
368 bool getBConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getBConst() : false; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000369
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000370 virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000371 virtual void traverse(TIntermTraverser*);
372
373 TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
374
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000375protected:
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000376 ConstantUnion *unionArrayPointer;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000377};
378
379//
380// Intermediate class for node types that hold operators.
381//
382class TIntermOperator : public TIntermTyped {
383public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000384 TOperator getOp() const { return op; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000385 void setOp(TOperator o) { op = o; }
386
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000387 bool modifiesState() const;
388 bool isConstructor() const;
alokp@chromium.org58e54292010-08-24 21:40:03 +0000389
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000390protected:
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000391 TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat, EbpUndefined)), op(o) {}
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000392 TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
393 TOperator op;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000394};
395
396//
397// Nodes for all the basic binary math operators.
398//
399class TIntermBinary : public TIntermOperator {
400public:
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000401 TIntermBinary(TOperator o) : TIntermOperator(o), addIndexClamp(false) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000402
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000403 virtual TIntermBinary* getAsBinaryNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000404 virtual void traverse(TIntermTraverser*);
405
406 void setLeft(TIntermTyped* n) { left = n; }
407 void setRight(TIntermTyped* n) { right = n; }
408 TIntermTyped* getLeft() const { return left; }
409 TIntermTyped* getRight() const { return right; }
410 bool promote(TInfoSink&);
411
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000412 void setAddIndexClamp() { addIndexClamp = true; }
413 bool getAddIndexClamp() { return addIndexClamp; }
414
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000415protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000416 TIntermTyped* left;
417 TIntermTyped* right;
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000418
419 // If set to true, wrap any EOpIndexIndirect with a clamp to bounds.
420 bool addIndexClamp;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000421};
422
423//
424// Nodes for unary math operators.
425//
426class TIntermUnary : public TIntermOperator {
427public:
zmo@google.com32e97312011-08-24 01:03:11 +0000428 TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0), useEmulatedFunction(false) {}
zmo@google.come4eb9912011-08-29 21:13:12 +0000429 TIntermUnary(TOperator o) : TIntermOperator(o), operand(0), useEmulatedFunction(false) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000430
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000431 virtual void traverse(TIntermTraverser*);
daniel@transgaming.com4a35ef22010-04-08 03:51:06 +0000432 virtual TIntermUnary* getAsUnaryNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000433
434 void setOperand(TIntermTyped* o) { operand = o; }
435 TIntermTyped* getOperand() { return operand; }
436 bool promote(TInfoSink&);
437
zmo@google.com32e97312011-08-24 01:03:11 +0000438 void setUseEmulatedFunction() { useEmulatedFunction = true; }
439 bool getUseEmulatedFunction() { return useEmulatedFunction; }
440
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000441protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000442 TIntermTyped* operand;
zmo@google.comf420c422011-09-12 18:27:59 +0000443
444 // If set to true, replace the built-in function call with an emulated one
445 // to work around driver bugs.
446 bool useEmulatedFunction;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000447};
448
449typedef TVector<TIntermNode*> TIntermSequence;
450typedef TVector<int> TQualifierList;
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000451
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000452//
453// Nodes that operate on an arbitrary sized set of children.
454//
455class TIntermAggregate : public TIntermOperator {
456public:
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000457 TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), endLine(0), useEmulatedFunction(false) { }
458 TIntermAggregate(TOperator o) : TIntermOperator(o), useEmulatedFunction(false) { }
459 ~TIntermAggregate() { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000460
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000461 virtual TIntermAggregate* getAsAggregate() { return this; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000462 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000463
464 TIntermSequence& getSequence() { return sequence; }
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000465
alokp@chromium.org58e54292010-08-24 21:40:03 +0000466 void setName(const TString& n) { name = n; }
467 const TString& getName() const { return name; }
468
469 void setUserDefined() { userDefined = true; }
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000470 bool isUserDefined() const { return userDefined; }
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000471
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000472 void setOptimize(bool o) { optimize = o; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000473 bool getOptimize() { return optimize; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000474 void setDebug(bool d) { debug = d; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000475 bool getDebug() { return debug; }
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000476
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000477 void setEndLine(TSourceLoc line) { endLine = line; }
478 TSourceLoc getEndLine() const { return endLine; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000479
zmo@google.comf420c422011-09-12 18:27:59 +0000480 void setUseEmulatedFunction() { useEmulatedFunction = true; }
481 bool getUseEmulatedFunction() { return useEmulatedFunction; }
482
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000483protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000484 TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
485 TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
486 TIntermSequence sequence;
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000487 TString name;
488 bool userDefined; // used for user defined function names
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000489
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000490 bool optimize;
491 bool debug;
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000492 TSourceLoc endLine;
zmo@google.comf420c422011-09-12 18:27:59 +0000493
494 // If set to true, replace the built-in function call with an emulated one
495 // to work around driver bugs.
496 bool useEmulatedFunction;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000497};
498
499//
500// For if tests. Simplified since there is no switch statement.
501//
502class TIntermSelection : public TIntermTyped {
503public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000504 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000505 TIntermTyped(TType(EbtVoid, EbpUndefined)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000506 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
507 TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000508
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000509 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000510
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000511 bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000512 TIntermNode* getCondition() const { return condition; }
513 TIntermNode* getTrueBlock() const { return trueBlock; }
514 TIntermNode* getFalseBlock() const { return falseBlock; }
515 TIntermSelection* getAsSelectionNode() { return this; }
516
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000517protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000518 TIntermTyped* condition;
519 TIntermNode* trueBlock;
520 TIntermNode* falseBlock;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000521};
522
523enum Visit
524{
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000525 PreVisit,
526 InVisit,
527 PostVisit
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000528};
529
530//
531// For traversing the tree. User should derive from this,
532// put their traversal specific data in it, and then pass
533// it to a Traverse method.
534//
535// When using this, just fill in the methods for nodes you want visited.
536// Return false from a pre-visit to skip visiting that node's subtree.
537//
538class TIntermTraverser
539{
540public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000541 POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000542
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000543 TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
544 preVisit(preVisit),
545 inVisit(inVisit),
546 postVisit(postVisit),
547 rightToLeft(rightToLeft),
548 depth(0) {}
maxvujovic@gmail.comc6b3b3c2012-06-27 22:49:39 +0000549 virtual ~TIntermTraverser() {};
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000550
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000551 virtual void visitSymbol(TIntermSymbol*) {}
552 virtual void visitConstantUnion(TIntermConstantUnion*) {}
553 virtual bool visitBinary(Visit visit, TIntermBinary*) {return true;}
554 virtual bool visitUnary(Visit visit, TIntermUnary*) {return true;}
555 virtual bool visitSelection(Visit visit, TIntermSelection*) {return true;}
556 virtual bool visitAggregate(Visit visit, TIntermAggregate*) {return true;}
557 virtual bool visitLoop(Visit visit, TIntermLoop*) {return true;}
558 virtual bool visitBranch(Visit visit, TIntermBranch*) {return true;}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000559
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000560 void incrementDepth() {depth++;}
561 void decrementDepth() {depth--;}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000562
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000563 // Return the original name if hash function pointer is NULL;
564 // otherwise return the hashed name.
565 static TString hash(const TString& name, ShHashFunction64 hashFunction);
566
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000567 const bool preVisit;
568 const bool inVisit;
569 const bool postVisit;
570 const bool rightToLeft;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000571
572protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000573 int depth;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000574};
575
576#endif // __INTERMEDIATE_H