blob: e980ac46cd81e41c0276347f48b860113df9aeff [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(); }
shannonwoods@chromium.org09e09882013-05-30 00:18:25 +0000253 int getCols() const { return type.getCols(); }
254 int getRows() const { return type.getRows(); }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000255 int getNominalSize() const { return type.getNominalSize(); }
shannonwoods@chromium.org09e09882013-05-30 00:18:25 +0000256 int getSecondarySize() const { return type.getSecondarySize(); }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000257
258 bool isMatrix() const { return type.isMatrix(); }
259 bool isArray() const { return type.isArray(); }
260 bool isVector() const { return type.isVector(); }
261 bool isScalar() const { return type.isScalar(); }
262 const char* getBasicString() const { return type.getBasicString(); }
263 const char* getQualifierString() const { return type.getQualifierString(); }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000264 TString getCompleteString() const { return type.getCompleteString(); }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000265
daniel@transgaming.com3ca980a2012-12-20 21:11:52 +0000266 int totalRegisterCount() const { return type.totalRegisterCount(); }
267 int elementRegisterCount() const { return type.elementRegisterCount(); }
268 int getArraySize() const { return type.getArraySize(); }
269
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000270protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000271 TType type;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000272};
273
274//
275// Handle for, do-while, and while loops.
276//
alokp@chromium.org52813552010-11-16 18:36:09 +0000277enum TLoopType {
278 ELoopFor,
279 ELoopWhile,
daniel@transgaming.comb3077d02013-01-11 04:12:09 +0000280 ELoopDoWhile
alokp@chromium.org52813552010-11-16 18:36:09 +0000281};
282
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000283class TIntermLoop : public TIntermNode {
284public:
alokp@chromium.org52813552010-11-16 18:36:09 +0000285 TIntermLoop(TLoopType aType,
286 TIntermNode *aInit, TIntermTyped* aCond, TIntermTyped* aExpr,
287 TIntermNode* aBody) :
288 type(aType),
289 init(aInit),
290 cond(aCond),
291 expr(aExpr),
zmo@google.com0b8d4eb2011-04-04 19:17:11 +0000292 body(aBody),
293 unrollFlag(false) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000294
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000295 virtual TIntermLoop* getAsLoopNode() { return this; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000296 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000297
alokp@chromium.org52813552010-11-16 18:36:09 +0000298 TLoopType getType() const { return type; }
299 TIntermNode* getInit() { return init; }
300 TIntermTyped* getCondition() { return cond; }
301 TIntermTyped* getExpression() { return expr; }
302 TIntermNode* getBody() { return body; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000303
zmo@google.com0b8d4eb2011-04-04 19:17:11 +0000304 void setUnrollFlag(bool flag) { unrollFlag = flag; }
305 bool getUnrollFlag() { return unrollFlag; }
306
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000307protected:
alokp@chromium.org52813552010-11-16 18:36:09 +0000308 TLoopType type;
309 TIntermNode* init; // for-loop initialization
310 TIntermTyped* cond; // loop exit condition
311 TIntermTyped* expr; // for-loop expression
312 TIntermNode* body; // loop body
zmo@google.com0b8d4eb2011-04-04 19:17:11 +0000313
314 bool unrollFlag; // Whether the loop should be unrolled or not.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000315};
316
317//
318// Handle break, continue, return, and kill.
319//
320class TIntermBranch : public TIntermNode {
321public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000322 TIntermBranch(TOperator op, TIntermTyped* e) :
323 flowOp(op),
324 expression(e) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000325
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000326 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000327
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000328 TOperator getFlowOp() { return flowOp; }
329 TIntermTyped* getExpression() { return expression; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000330
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000331protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000332 TOperator flowOp;
333 TIntermTyped* expression; // non-zero except for "return exp;" statements
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000334};
335
336//
337// Nodes that correspond to symbols or constants in the source code.
338//
339class TIntermSymbol : public TIntermTyped {
340public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000341 // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. If sym comes from
342 // per process globalpoolallocator, then it causes increased memory usage per compile
343 // it is essential to use "symbol = sym" to assign to symbol
344 TIntermSymbol(int i, const TString& sym, const TType& t) :
zmo@google.comfd747b82011-04-23 01:30:07 +0000345 TIntermTyped(t), id(i) { symbol = sym; originalSymbol = sym; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000346
347 int getId() const { return id; }
348 const TString& getSymbol() const { return symbol; }
349
zmo@google.comfd747b82011-04-23 01:30:07 +0000350 void setId(int newId) { id = newId; }
351 void setSymbol(const TString& sym) { symbol = sym; }
352
353 const TString& getOriginalSymbol() const { return originalSymbol; }
354
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000355 virtual void traverse(TIntermTraverser*);
356 virtual TIntermSymbol* getAsSymbolNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000357
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000358protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000359 int id;
360 TString symbol;
zmo@google.comfd747b82011-04-23 01:30:07 +0000361 TString originalSymbol;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000362};
363
364class TIntermConstantUnion : public TIntermTyped {
365public:
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000366 TIntermConstantUnion(ConstantUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000367
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000368 ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; }
shannon.woods%transgaming.com@gtempaccount.comc0d0c222013-04-13 03:29:36 +0000369
370 int getIConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getIConst() : 0; }
371 float getFConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getFConst() : 0.0f; }
372 bool getBConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getBConst() : false; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000373
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000374 virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000375 virtual void traverse(TIntermTraverser*);
376
377 TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
378
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000379protected:
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000380 ConstantUnion *unionArrayPointer;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000381};
382
383//
384// Intermediate class for node types that hold operators.
385//
386class TIntermOperator : public TIntermTyped {
387public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000388 TOperator getOp() const { return op; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000389 void setOp(TOperator o) { op = o; }
390
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000391 bool modifiesState() const;
392 bool isConstructor() const;
alokp@chromium.org58e54292010-08-24 21:40:03 +0000393
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000394protected:
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000395 TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat, EbpUndefined)), op(o) {}
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000396 TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
397 TOperator op;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000398};
399
400//
401// Nodes for all the basic binary math operators.
402//
403class TIntermBinary : public TIntermOperator {
404public:
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000405 TIntermBinary(TOperator o) : TIntermOperator(o), addIndexClamp(false) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000406
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000407 virtual TIntermBinary* getAsBinaryNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000408 virtual void traverse(TIntermTraverser*);
409
410 void setLeft(TIntermTyped* n) { left = n; }
411 void setRight(TIntermTyped* n) { right = n; }
412 TIntermTyped* getLeft() const { return left; }
413 TIntermTyped* getRight() const { return right; }
414 bool promote(TInfoSink&);
415
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000416 void setAddIndexClamp() { addIndexClamp = true; }
417 bool getAddIndexClamp() { return addIndexClamp; }
418
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000419protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000420 TIntermTyped* left;
421 TIntermTyped* right;
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000422
423 // If set to true, wrap any EOpIndexIndirect with a clamp to bounds.
424 bool addIndexClamp;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000425};
426
427//
428// Nodes for unary math operators.
429//
430class TIntermUnary : public TIntermOperator {
431public:
zmo@google.com32e97312011-08-24 01:03:11 +0000432 TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0), useEmulatedFunction(false) {}
zmo@google.come4eb9912011-08-29 21:13:12 +0000433 TIntermUnary(TOperator o) : TIntermOperator(o), operand(0), useEmulatedFunction(false) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000434
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000435 virtual void traverse(TIntermTraverser*);
daniel@transgaming.com4a35ef22010-04-08 03:51:06 +0000436 virtual TIntermUnary* getAsUnaryNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000437
438 void setOperand(TIntermTyped* o) { operand = o; }
439 TIntermTyped* getOperand() { return operand; }
440 bool promote(TInfoSink&);
441
zmo@google.com32e97312011-08-24 01:03:11 +0000442 void setUseEmulatedFunction() { useEmulatedFunction = true; }
443 bool getUseEmulatedFunction() { return useEmulatedFunction; }
444
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000445protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000446 TIntermTyped* operand;
zmo@google.comf420c422011-09-12 18:27:59 +0000447
448 // If set to true, replace the built-in function call with an emulated one
449 // to work around driver bugs.
450 bool useEmulatedFunction;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000451};
452
453typedef TVector<TIntermNode*> TIntermSequence;
454typedef TVector<int> TQualifierList;
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000455
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000456//
457// Nodes that operate on an arbitrary sized set of children.
458//
459class TIntermAggregate : public TIntermOperator {
460public:
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000461 TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), endLine(0), useEmulatedFunction(false) { }
462 TIntermAggregate(TOperator o) : TIntermOperator(o), useEmulatedFunction(false) { }
463 ~TIntermAggregate() { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000464
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000465 virtual TIntermAggregate* getAsAggregate() { return this; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000466 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000467
468 TIntermSequence& getSequence() { return sequence; }
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000469
alokp@chromium.org58e54292010-08-24 21:40:03 +0000470 void setName(const TString& n) { name = n; }
471 const TString& getName() const { return name; }
472
473 void setUserDefined() { userDefined = true; }
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000474 bool isUserDefined() const { return userDefined; }
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000475
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000476 void setOptimize(bool o) { optimize = o; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000477 bool getOptimize() { return optimize; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000478 void setDebug(bool d) { debug = d; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000479 bool getDebug() { return debug; }
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000480
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000481 void setEndLine(TSourceLoc line) { endLine = line; }
482 TSourceLoc getEndLine() const { return endLine; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000483
zmo@google.comf420c422011-09-12 18:27:59 +0000484 void setUseEmulatedFunction() { useEmulatedFunction = true; }
485 bool getUseEmulatedFunction() { return useEmulatedFunction; }
486
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000487protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000488 TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
489 TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
490 TIntermSequence sequence;
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000491 TString name;
492 bool userDefined; // used for user defined function names
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000493
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000494 bool optimize;
495 bool debug;
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000496 TSourceLoc endLine;
zmo@google.comf420c422011-09-12 18:27:59 +0000497
498 // If set to true, replace the built-in function call with an emulated one
499 // to work around driver bugs.
500 bool useEmulatedFunction;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000501};
502
503//
504// For if tests. Simplified since there is no switch statement.
505//
506class TIntermSelection : public TIntermTyped {
507public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000508 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000509 TIntermTyped(TType(EbtVoid, EbpUndefined)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000510 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
511 TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000512
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000513 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000514
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000515 bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000516 TIntermNode* getCondition() const { return condition; }
517 TIntermNode* getTrueBlock() const { return trueBlock; }
518 TIntermNode* getFalseBlock() const { return falseBlock; }
519 TIntermSelection* getAsSelectionNode() { return this; }
520
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000521protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000522 TIntermTyped* condition;
523 TIntermNode* trueBlock;
524 TIntermNode* falseBlock;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000525};
526
527enum Visit
528{
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000529 PreVisit,
530 InVisit,
531 PostVisit
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000532};
533
534//
535// For traversing the tree. User should derive from this,
536// put their traversal specific data in it, and then pass
537// it to a Traverse method.
538//
539// When using this, just fill in the methods for nodes you want visited.
540// Return false from a pre-visit to skip visiting that node's subtree.
541//
542class TIntermTraverser
543{
544public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000545 POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000546
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000547 TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
548 preVisit(preVisit),
549 inVisit(inVisit),
550 postVisit(postVisit),
551 rightToLeft(rightToLeft),
552 depth(0) {}
maxvujovic@gmail.comc6b3b3c2012-06-27 22:49:39 +0000553 virtual ~TIntermTraverser() {};
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000554
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000555 virtual void visitSymbol(TIntermSymbol*) {}
556 virtual void visitConstantUnion(TIntermConstantUnion*) {}
557 virtual bool visitBinary(Visit visit, TIntermBinary*) {return true;}
558 virtual bool visitUnary(Visit visit, TIntermUnary*) {return true;}
559 virtual bool visitSelection(Visit visit, TIntermSelection*) {return true;}
560 virtual bool visitAggregate(Visit visit, TIntermAggregate*) {return true;}
561 virtual bool visitLoop(Visit visit, TIntermLoop*) {return true;}
562 virtual bool visitBranch(Visit visit, TIntermBranch*) {return true;}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000563
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000564 void incrementDepth() {depth++;}
565 void decrementDepth() {depth--;}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000566
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000567 // Return the original name if hash function pointer is NULL;
568 // otherwise return the hashed name.
569 static TString hash(const TString& name, ShHashFunction64 hashFunction);
570
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000571 const bool preVisit;
572 const bool inVisit;
573 const bool postVisit;
574 const bool rightToLeft;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000575
576protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000577 int depth;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000578};
579
580#endif // __INTERMEDIATE_H