blob: 6834c8452bd8278a30def8a3df545f6b0fdbe6bf [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,
shannonwoods@chromium.org5668c5d2013-05-30 00:11:48 +000088 EOpIndexDirectInterfaceBlock,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000089
alokp@chromium.org2cf17712010-03-30 20:33:18 +000090 EOpVectorSwizzle,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000091
alokp@chromium.org2cf17712010-03-30 20:33:18 +000092 //
93 // Built-in functions potentially mapped to operators
94 //
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000095
alokp@chromium.org2cf17712010-03-30 20:33:18 +000096 EOpRadians,
97 EOpDegrees,
98 EOpSin,
99 EOpCos,
100 EOpTan,
101 EOpAsin,
102 EOpAcos,
103 EOpAtan,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000104
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000105 EOpPow,
106 EOpExp,
107 EOpLog,
108 EOpExp2,
109 EOpLog2,
110 EOpSqrt,
111 EOpInverseSqrt,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000112
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000113 EOpAbs,
114 EOpSign,
115 EOpFloor,
116 EOpCeil,
117 EOpFract,
118 EOpMod,
119 EOpMin,
120 EOpMax,
121 EOpClamp,
122 EOpMix,
123 EOpStep,
124 EOpSmoothStep,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000125
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000126 EOpLength,
127 EOpDistance,
128 EOpDot,
129 EOpCross,
130 EOpNormalize,
131 EOpFaceForward,
132 EOpReflect,
133 EOpRefract,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000134
alokp@chromium.org06098892010-08-26 19:36:42 +0000135 EOpDFdx, // Fragment only, OES_standard_derivatives extension
136 EOpDFdy, // Fragment only, OES_standard_derivatives extension
137 EOpFwidth, // Fragment only, OES_standard_derivatives extension
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000138
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000139 EOpMatrixTimesMatrix,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000140
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000141 EOpAny,
142 EOpAll,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000143
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000144 //
145 // Branch
146 //
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000147
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000148 EOpKill, // Fragment only
149 EOpReturn,
150 EOpBreak,
151 EOpContinue,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000152
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000153 //
154 // Constructors
155 //
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000156
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000157 EOpConstructInt,
158 EOpConstructBool,
159 EOpConstructFloat,
160 EOpConstructVec2,
161 EOpConstructVec3,
162 EOpConstructVec4,
163 EOpConstructBVec2,
164 EOpConstructBVec3,
165 EOpConstructBVec4,
166 EOpConstructIVec2,
167 EOpConstructIVec3,
168 EOpConstructIVec4,
169 EOpConstructMat2,
170 EOpConstructMat3,
171 EOpConstructMat4,
172 EOpConstructStruct,
173
174 //
175 // moves
176 //
177
178 EOpAssign,
179 EOpInitialize,
180 EOpAddAssign,
181 EOpSubAssign,
182 EOpMulAssign,
183 EOpVectorTimesMatrixAssign,
184 EOpVectorTimesScalarAssign,
185 EOpMatrixTimesScalarAssign,
186 EOpMatrixTimesMatrixAssign,
daniel@transgaming.comb3077d02013-01-11 04:12:09 +0000187 EOpDivAssign
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000188};
189
alokp@chromium.orgb59a7782010-11-24 18:38:33 +0000190extern const char* getOperatorString(TOperator op);
191
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000192class TIntermTraverser;
193class TIntermAggregate;
194class TIntermBinary;
daniel@transgaming.com4a35ef22010-04-08 03:51:06 +0000195class TIntermUnary;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000196class TIntermConstantUnion;
197class TIntermSelection;
198class TIntermTyped;
199class TIntermSymbol;
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000200class TIntermLoop;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000201class TInfoSink;
202
203//
204// Base class for the tree nodes
205//
206class TIntermNode {
207public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000208 POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000209
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000210 TIntermNode() : line(0) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000211
212 TSourceLoc getLine() const { return line; }
213 void setLine(TSourceLoc l) { line = l; }
214
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000215 virtual void traverse(TIntermTraverser*) = 0;
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000216 virtual TIntermTyped* getAsTyped() { return 0; }
217 virtual TIntermConstantUnion* getAsConstantUnion() { return 0; }
218 virtual TIntermAggregate* getAsAggregate() { return 0; }
219 virtual TIntermBinary* getAsBinaryNode() { return 0; }
220 virtual TIntermUnary* getAsUnaryNode() { return 0; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000221 virtual TIntermSelection* getAsSelectionNode() { return 0; }
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000222 virtual TIntermSymbol* getAsSymbolNode() { return 0; }
223 virtual TIntermLoop* getAsLoopNode() { return 0; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000224 virtual ~TIntermNode() { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000225
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000226protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000227 TSourceLoc line;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000228};
229
230//
231// This is just to help yacc.
232//
233struct TIntermNodePair {
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000234 TIntermNode* node1;
235 TIntermNode* node2;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000236};
237
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000238//
239// Intermediate class for nodes that have a type.
240//
241class TIntermTyped : public TIntermNode {
242public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000243 TIntermTyped(const TType& t) : type(t) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000244 virtual TIntermTyped* getAsTyped() { return this; }
alokp@chromium.orgdd037b22010-03-30 18:47:20 +0000245
alokp@chromium.org58e54292010-08-24 21:40:03 +0000246 void setType(const TType& t) { type = t; }
247 const TType& getType() const { return type; }
248 TType* getTypePointer() { return &type; }
249
250 TBasicType getBasicType() const { return type.getBasicType(); }
251 TQualifier getQualifier() const { return type.getQualifier(); }
252 TPrecision getPrecision() const { return type.getPrecision(); }
253 int getNominalSize() const { return type.getNominalSize(); }
254
255 bool isMatrix() const { return type.isMatrix(); }
256 bool isArray() const { return type.isArray(); }
257 bool isVector() const { return type.isVector(); }
258 bool isScalar() const { return type.isScalar(); }
259 const char* getBasicString() const { return type.getBasicString(); }
260 const char* getQualifierString() const { return type.getQualifierString(); }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000261 TString getCompleteString() const { return type.getCompleteString(); }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000262
daniel@transgaming.com3ca980a2012-12-20 21:11:52 +0000263 int totalRegisterCount() const { return type.totalRegisterCount(); }
264 int elementRegisterCount() const { return type.elementRegisterCount(); }
265 int getArraySize() const { return type.getArraySize(); }
266
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000267protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000268 TType type;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000269};
270
271//
272// Handle for, do-while, and while loops.
273//
alokp@chromium.org52813552010-11-16 18:36:09 +0000274enum TLoopType {
275 ELoopFor,
276 ELoopWhile,
daniel@transgaming.comb3077d02013-01-11 04:12:09 +0000277 ELoopDoWhile
alokp@chromium.org52813552010-11-16 18:36:09 +0000278};
279
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000280class TIntermLoop : public TIntermNode {
281public:
alokp@chromium.org52813552010-11-16 18:36:09 +0000282 TIntermLoop(TLoopType aType,
283 TIntermNode *aInit, TIntermTyped* aCond, TIntermTyped* aExpr,
284 TIntermNode* aBody) :
285 type(aType),
286 init(aInit),
287 cond(aCond),
288 expr(aExpr),
zmo@google.com0b8d4eb2011-04-04 19:17:11 +0000289 body(aBody),
290 unrollFlag(false) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000291
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000292 virtual TIntermLoop* getAsLoopNode() { return this; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000293 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000294
alokp@chromium.org52813552010-11-16 18:36:09 +0000295 TLoopType getType() const { return type; }
296 TIntermNode* getInit() { return init; }
297 TIntermTyped* getCondition() { return cond; }
298 TIntermTyped* getExpression() { return expr; }
299 TIntermNode* getBody() { return body; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000300
zmo@google.com0b8d4eb2011-04-04 19:17:11 +0000301 void setUnrollFlag(bool flag) { unrollFlag = flag; }
302 bool getUnrollFlag() { return unrollFlag; }
303
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000304protected:
alokp@chromium.org52813552010-11-16 18:36:09 +0000305 TLoopType type;
306 TIntermNode* init; // for-loop initialization
307 TIntermTyped* cond; // loop exit condition
308 TIntermTyped* expr; // for-loop expression
309 TIntermNode* body; // loop body
zmo@google.com0b8d4eb2011-04-04 19:17:11 +0000310
311 bool unrollFlag; // Whether the loop should be unrolled or not.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000312};
313
314//
315// Handle break, continue, return, and kill.
316//
317class TIntermBranch : public TIntermNode {
318public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000319 TIntermBranch(TOperator op, TIntermTyped* e) :
320 flowOp(op),
321 expression(e) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000322
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000323 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000324
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000325 TOperator getFlowOp() { return flowOp; }
326 TIntermTyped* getExpression() { return expression; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000327
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000328protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000329 TOperator flowOp;
330 TIntermTyped* expression; // non-zero except for "return exp;" statements
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000331};
332
333//
334// Nodes that correspond to symbols or constants in the source code.
335//
336class TIntermSymbol : public TIntermTyped {
337public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000338 // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. If sym comes from
339 // per process globalpoolallocator, then it causes increased memory usage per compile
340 // it is essential to use "symbol = sym" to assign to symbol
341 TIntermSymbol(int i, const TString& sym, const TType& t) :
zmo@google.comfd747b82011-04-23 01:30:07 +0000342 TIntermTyped(t), id(i) { symbol = sym; originalSymbol = sym; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000343
344 int getId() const { return id; }
345 const TString& getSymbol() const { return symbol; }
346
zmo@google.comfd747b82011-04-23 01:30:07 +0000347 void setId(int newId) { id = newId; }
348 void setSymbol(const TString& sym) { symbol = sym; }
349
350 const TString& getOriginalSymbol() const { return originalSymbol; }
351
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000352 virtual void traverse(TIntermTraverser*);
353 virtual TIntermSymbol* getAsSymbolNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000354
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000355protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000356 int id;
357 TString symbol;
zmo@google.comfd747b82011-04-23 01:30:07 +0000358 TString originalSymbol;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000359};
360
361class TIntermConstantUnion : public TIntermTyped {
362public:
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000363 TIntermConstantUnion(ConstantUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000364
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000365 ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; }
shannon.woods%transgaming.com@gtempaccount.comc0d0c222013-04-13 03:29:36 +0000366
367 int getIConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getIConst() : 0; }
368 float getFConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getFConst() : 0.0f; }
369 bool getBConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getBConst() : false; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000370
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000371 virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000372 virtual void traverse(TIntermTraverser*);
373
374 TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
375
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000376protected:
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000377 ConstantUnion *unionArrayPointer;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000378};
379
380//
381// Intermediate class for node types that hold operators.
382//
383class TIntermOperator : public TIntermTyped {
384public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000385 TOperator getOp() const { return op; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000386 void setOp(TOperator o) { op = o; }
387
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000388 bool modifiesState() const;
389 bool isConstructor() const;
alokp@chromium.org58e54292010-08-24 21:40:03 +0000390
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000391protected:
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000392 TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat, EbpUndefined)), op(o) {}
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000393 TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
394 TOperator op;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000395};
396
397//
398// Nodes for all the basic binary math operators.
399//
400class TIntermBinary : public TIntermOperator {
401public:
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000402 TIntermBinary(TOperator o) : TIntermOperator(o), addIndexClamp(false) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000403
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000404 virtual TIntermBinary* getAsBinaryNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000405 virtual void traverse(TIntermTraverser*);
406
407 void setLeft(TIntermTyped* n) { left = n; }
408 void setRight(TIntermTyped* n) { right = n; }
409 TIntermTyped* getLeft() const { return left; }
410 TIntermTyped* getRight() const { return right; }
411 bool promote(TInfoSink&);
412
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000413 void setAddIndexClamp() { addIndexClamp = true; }
414 bool getAddIndexClamp() { return addIndexClamp; }
415
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000416protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000417 TIntermTyped* left;
418 TIntermTyped* right;
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000419
420 // If set to true, wrap any EOpIndexIndirect with a clamp to bounds.
421 bool addIndexClamp;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000422};
423
424//
425// Nodes for unary math operators.
426//
427class TIntermUnary : public TIntermOperator {
428public:
zmo@google.com32e97312011-08-24 01:03:11 +0000429 TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0), useEmulatedFunction(false) {}
zmo@google.come4eb9912011-08-29 21:13:12 +0000430 TIntermUnary(TOperator o) : TIntermOperator(o), operand(0), useEmulatedFunction(false) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000431
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000432 virtual void traverse(TIntermTraverser*);
daniel@transgaming.com4a35ef22010-04-08 03:51:06 +0000433 virtual TIntermUnary* getAsUnaryNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000434
435 void setOperand(TIntermTyped* o) { operand = o; }
436 TIntermTyped* getOperand() { return operand; }
437 bool promote(TInfoSink&);
438
zmo@google.com32e97312011-08-24 01:03:11 +0000439 void setUseEmulatedFunction() { useEmulatedFunction = true; }
440 bool getUseEmulatedFunction() { return useEmulatedFunction; }
441
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000442protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000443 TIntermTyped* operand;
zmo@google.comf420c422011-09-12 18:27:59 +0000444
445 // If set to true, replace the built-in function call with an emulated one
446 // to work around driver bugs.
447 bool useEmulatedFunction;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000448};
449
450typedef TVector<TIntermNode*> TIntermSequence;
451typedef TVector<int> TQualifierList;
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000452
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000453//
454// Nodes that operate on an arbitrary sized set of children.
455//
456class TIntermAggregate : public TIntermOperator {
457public:
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000458 TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), endLine(0), useEmulatedFunction(false) { }
459 TIntermAggregate(TOperator o) : TIntermOperator(o), useEmulatedFunction(false) { }
460 ~TIntermAggregate() { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000461
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000462 virtual TIntermAggregate* getAsAggregate() { return this; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000463 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000464
465 TIntermSequence& getSequence() { return sequence; }
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000466
alokp@chromium.org58e54292010-08-24 21:40:03 +0000467 void setName(const TString& n) { name = n; }
468 const TString& getName() const { return name; }
469
470 void setUserDefined() { userDefined = true; }
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000471 bool isUserDefined() const { return userDefined; }
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000472
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000473 void setOptimize(bool o) { optimize = o; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000474 bool getOptimize() { return optimize; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000475 void setDebug(bool d) { debug = d; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000476 bool getDebug() { return debug; }
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000477
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000478 void setEndLine(TSourceLoc line) { endLine = line; }
479 TSourceLoc getEndLine() const { return endLine; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000480
zmo@google.comf420c422011-09-12 18:27:59 +0000481 void setUseEmulatedFunction() { useEmulatedFunction = true; }
482 bool getUseEmulatedFunction() { return useEmulatedFunction; }
483
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000484protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000485 TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
486 TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
487 TIntermSequence sequence;
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000488 TString name;
489 bool userDefined; // used for user defined function names
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000490
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000491 bool optimize;
492 bool debug;
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000493 TSourceLoc endLine;
zmo@google.comf420c422011-09-12 18:27:59 +0000494
495 // If set to true, replace the built-in function call with an emulated one
496 // to work around driver bugs.
497 bool useEmulatedFunction;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000498};
499
500//
501// For if tests. Simplified since there is no switch statement.
502//
503class TIntermSelection : public TIntermTyped {
504public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000505 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000506 TIntermTyped(TType(EbtVoid, EbpUndefined)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000507 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
508 TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000509
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000510 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000511
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000512 bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000513 TIntermNode* getCondition() const { return condition; }
514 TIntermNode* getTrueBlock() const { return trueBlock; }
515 TIntermNode* getFalseBlock() const { return falseBlock; }
516 TIntermSelection* getAsSelectionNode() { return this; }
517
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000518protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000519 TIntermTyped* condition;
520 TIntermNode* trueBlock;
521 TIntermNode* falseBlock;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000522};
523
524enum Visit
525{
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000526 PreVisit,
527 InVisit,
528 PostVisit
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000529};
530
531//
532// For traversing the tree. User should derive from this,
533// put their traversal specific data in it, and then pass
534// it to a Traverse method.
535//
536// When using this, just fill in the methods for nodes you want visited.
537// Return false from a pre-visit to skip visiting that node's subtree.
538//
539class TIntermTraverser
540{
541public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000542 POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000543
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000544 TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
545 preVisit(preVisit),
546 inVisit(inVisit),
547 postVisit(postVisit),
548 rightToLeft(rightToLeft),
549 depth(0) {}
maxvujovic@gmail.comc6b3b3c2012-06-27 22:49:39 +0000550 virtual ~TIntermTraverser() {};
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000551
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000552 virtual void visitSymbol(TIntermSymbol*) {}
553 virtual void visitConstantUnion(TIntermConstantUnion*) {}
554 virtual bool visitBinary(Visit visit, TIntermBinary*) {return true;}
555 virtual bool visitUnary(Visit visit, TIntermUnary*) {return true;}
556 virtual bool visitSelection(Visit visit, TIntermSelection*) {return true;}
557 virtual bool visitAggregate(Visit visit, TIntermAggregate*) {return true;}
558 virtual bool visitLoop(Visit visit, TIntermLoop*) {return true;}
559 virtual bool visitBranch(Visit visit, TIntermBranch*) {return true;}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000560
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000561 void incrementDepth() {depth++;}
562 void decrementDepth() {depth--;}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000563
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000564 // Return the original name if hash function pointer is NULL;
565 // otherwise return the hashed name.
566 static TString hash(const TString& name, ShHashFunction64 hashFunction);
567
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000568 const bool preVisit;
569 const bool inVisit;
570 const bool postVisit;
571 const bool rightToLeft;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000572
573protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000574 int depth;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000575};
576
577#endif // __INTERMEDIATE_H