blob: 00c0faff86e39d41310c7558a6049c609a2ec023 [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,
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +000052 EOpConvUnsignedIntToBool,
alokp@chromium.org2cf17712010-03-30 20:33:18 +000053 EOpConvFloatToBool,
54 EOpConvBoolToFloat,
55 EOpConvIntToFloat,
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +000056 EOpConvUnsignedIntToFloat,
alokp@chromium.org2cf17712010-03-30 20:33:18 +000057 EOpConvFloatToInt,
58 EOpConvBoolToInt,
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +000059 EOpConvUnsignedIntToInt,
60 EOpConvIntToUnsignedInt,
61 EOpConvFloatToUnsignedInt,
62 EOpConvBoolToUnsignedInt,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000063
alokp@chromium.org2cf17712010-03-30 20:33:18 +000064 //
65 // binary operations
66 //
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000067
alokp@chromium.org2cf17712010-03-30 20:33:18 +000068 EOpAdd,
69 EOpSub,
70 EOpMul,
71 EOpDiv,
72 EOpEqual,
73 EOpNotEqual,
74 EOpVectorEqual,
75 EOpVectorNotEqual,
76 EOpLessThan,
77 EOpGreaterThan,
78 EOpLessThanEqual,
79 EOpGreaterThanEqual,
80 EOpComma,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000081
alokp@chromium.org2cf17712010-03-30 20:33:18 +000082 EOpVectorTimesScalar,
83 EOpVectorTimesMatrix,
84 EOpMatrixTimesVector,
85 EOpMatrixTimesScalar,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000086
alokp@chromium.org2cf17712010-03-30 20:33:18 +000087 EOpLogicalOr,
88 EOpLogicalXor,
89 EOpLogicalAnd,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000090
alokp@chromium.org2cf17712010-03-30 20:33:18 +000091 EOpIndexDirect,
92 EOpIndexIndirect,
93 EOpIndexDirectStruct,
shannonwoods@chromium.org5668c5d2013-05-30 00:11:48 +000094 EOpIndexDirectInterfaceBlock,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000095
alokp@chromium.org2cf17712010-03-30 20:33:18 +000096 EOpVectorSwizzle,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000097
alokp@chromium.org2cf17712010-03-30 20:33:18 +000098 //
99 // Built-in functions potentially mapped to operators
100 //
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000101
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000102 EOpRadians,
103 EOpDegrees,
104 EOpSin,
105 EOpCos,
106 EOpTan,
107 EOpAsin,
108 EOpAcos,
109 EOpAtan,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000110
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000111 EOpPow,
112 EOpExp,
113 EOpLog,
114 EOpExp2,
115 EOpLog2,
116 EOpSqrt,
117 EOpInverseSqrt,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000118
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000119 EOpAbs,
120 EOpSign,
121 EOpFloor,
122 EOpCeil,
123 EOpFract,
124 EOpMod,
125 EOpMin,
126 EOpMax,
127 EOpClamp,
128 EOpMix,
129 EOpStep,
130 EOpSmoothStep,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000131
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000132 EOpLength,
133 EOpDistance,
134 EOpDot,
135 EOpCross,
136 EOpNormalize,
137 EOpFaceForward,
138 EOpReflect,
139 EOpRefract,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000140
alokp@chromium.org06098892010-08-26 19:36:42 +0000141 EOpDFdx, // Fragment only, OES_standard_derivatives extension
142 EOpDFdy, // Fragment only, OES_standard_derivatives extension
143 EOpFwidth, // Fragment only, OES_standard_derivatives extension
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000144
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000145 EOpMatrixTimesMatrix,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000146
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000147 EOpAny,
148 EOpAll,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000149
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000150 //
151 // Branch
152 //
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000153
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000154 EOpKill, // Fragment only
155 EOpReturn,
156 EOpBreak,
157 EOpContinue,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000158
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000159 //
160 // Constructors
161 //
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000162
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000163 EOpConstructInt,
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +0000164 EOpConstructUnsignedInt,
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000165 EOpConstructBool,
166 EOpConstructFloat,
167 EOpConstructVec2,
168 EOpConstructVec3,
169 EOpConstructVec4,
170 EOpConstructBVec2,
171 EOpConstructBVec3,
172 EOpConstructBVec4,
173 EOpConstructIVec2,
174 EOpConstructIVec3,
175 EOpConstructIVec4,
176 EOpConstructMat2,
177 EOpConstructMat3,
178 EOpConstructMat4,
179 EOpConstructStruct,
180
181 //
182 // moves
183 //
184
185 EOpAssign,
186 EOpInitialize,
187 EOpAddAssign,
188 EOpSubAssign,
189 EOpMulAssign,
190 EOpVectorTimesMatrixAssign,
191 EOpVectorTimesScalarAssign,
192 EOpMatrixTimesScalarAssign,
193 EOpMatrixTimesMatrixAssign,
daniel@transgaming.comb3077d02013-01-11 04:12:09 +0000194 EOpDivAssign
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000195};
196
alokp@chromium.orgb59a7782010-11-24 18:38:33 +0000197extern const char* getOperatorString(TOperator op);
198
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000199class TIntermTraverser;
200class TIntermAggregate;
201class TIntermBinary;
daniel@transgaming.com4a35ef22010-04-08 03:51:06 +0000202class TIntermUnary;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000203class TIntermConstantUnion;
204class TIntermSelection;
205class TIntermTyped;
206class TIntermSymbol;
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000207class TIntermLoop;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000208class TInfoSink;
209
210//
211// Base class for the tree nodes
212//
213class TIntermNode {
214public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000215 POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000216
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000217 TIntermNode() : line(0) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000218
219 TSourceLoc getLine() const { return line; }
220 void setLine(TSourceLoc l) { line = l; }
221
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000222 virtual void traverse(TIntermTraverser*) = 0;
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000223 virtual TIntermTyped* getAsTyped() { return 0; }
224 virtual TIntermConstantUnion* getAsConstantUnion() { return 0; }
225 virtual TIntermAggregate* getAsAggregate() { return 0; }
226 virtual TIntermBinary* getAsBinaryNode() { return 0; }
227 virtual TIntermUnary* getAsUnaryNode() { return 0; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000228 virtual TIntermSelection* getAsSelectionNode() { return 0; }
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000229 virtual TIntermSymbol* getAsSymbolNode() { return 0; }
230 virtual TIntermLoop* getAsLoopNode() { return 0; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000231 virtual ~TIntermNode() { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000232
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000233protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000234 TSourceLoc line;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000235};
236
237//
238// This is just to help yacc.
239//
240struct TIntermNodePair {
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000241 TIntermNode* node1;
242 TIntermNode* node2;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000243};
244
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000245//
246// Intermediate class for nodes that have a type.
247//
248class TIntermTyped : public TIntermNode {
249public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000250 TIntermTyped(const TType& t) : type(t) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000251 virtual TIntermTyped* getAsTyped() { return this; }
alokp@chromium.orgdd037b22010-03-30 18:47:20 +0000252
alokp@chromium.org58e54292010-08-24 21:40:03 +0000253 void setType(const TType& t) { type = t; }
254 const TType& getType() const { return type; }
255 TType* getTypePointer() { return &type; }
256
257 TBasicType getBasicType() const { return type.getBasicType(); }
258 TQualifier getQualifier() const { return type.getQualifier(); }
259 TPrecision getPrecision() const { return type.getPrecision(); }
shannonwoods@chromium.org09e09882013-05-30 00:18:25 +0000260 int getCols() const { return type.getCols(); }
261 int getRows() const { return type.getRows(); }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000262 int getNominalSize() const { return type.getNominalSize(); }
shannonwoods@chromium.org09e09882013-05-30 00:18:25 +0000263 int getSecondarySize() const { return type.getSecondarySize(); }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000264
265 bool isMatrix() const { return type.isMatrix(); }
266 bool isArray() const { return type.isArray(); }
267 bool isVector() const { return type.isVector(); }
268 bool isScalar() const { return type.isScalar(); }
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +0000269 bool isScalarInt() const { return type.isScalarInt(); }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000270 const char* getBasicString() const { return type.getBasicString(); }
271 const char* getQualifierString() const { return type.getQualifierString(); }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000272 TString getCompleteString() const { return type.getCompleteString(); }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000273
daniel@transgaming.com3ca980a2012-12-20 21:11:52 +0000274 int totalRegisterCount() const { return type.totalRegisterCount(); }
275 int elementRegisterCount() const { return type.elementRegisterCount(); }
276 int getArraySize() const { return type.getArraySize(); }
277
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000278protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000279 TType type;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000280};
281
282//
283// Handle for, do-while, and while loops.
284//
alokp@chromium.org52813552010-11-16 18:36:09 +0000285enum TLoopType {
286 ELoopFor,
287 ELoopWhile,
daniel@transgaming.comb3077d02013-01-11 04:12:09 +0000288 ELoopDoWhile
alokp@chromium.org52813552010-11-16 18:36:09 +0000289};
290
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000291class TIntermLoop : public TIntermNode {
292public:
alokp@chromium.org52813552010-11-16 18:36:09 +0000293 TIntermLoop(TLoopType aType,
294 TIntermNode *aInit, TIntermTyped* aCond, TIntermTyped* aExpr,
295 TIntermNode* aBody) :
296 type(aType),
297 init(aInit),
298 cond(aCond),
299 expr(aExpr),
zmo@google.com0b8d4eb2011-04-04 19:17:11 +0000300 body(aBody),
301 unrollFlag(false) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000302
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000303 virtual TIntermLoop* getAsLoopNode() { return this; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000304 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000305
alokp@chromium.org52813552010-11-16 18:36:09 +0000306 TLoopType getType() const { return type; }
307 TIntermNode* getInit() { return init; }
308 TIntermTyped* getCondition() { return cond; }
309 TIntermTyped* getExpression() { return expr; }
310 TIntermNode* getBody() { return body; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000311
zmo@google.com0b8d4eb2011-04-04 19:17:11 +0000312 void setUnrollFlag(bool flag) { unrollFlag = flag; }
313 bool getUnrollFlag() { return unrollFlag; }
314
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000315protected:
alokp@chromium.org52813552010-11-16 18:36:09 +0000316 TLoopType type;
317 TIntermNode* init; // for-loop initialization
318 TIntermTyped* cond; // loop exit condition
319 TIntermTyped* expr; // for-loop expression
320 TIntermNode* body; // loop body
zmo@google.com0b8d4eb2011-04-04 19:17:11 +0000321
322 bool unrollFlag; // Whether the loop should be unrolled or not.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000323};
324
325//
326// Handle break, continue, return, and kill.
327//
328class TIntermBranch : public TIntermNode {
329public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000330 TIntermBranch(TOperator op, TIntermTyped* e) :
331 flowOp(op),
332 expression(e) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000333
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000334 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000335
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000336 TOperator getFlowOp() { return flowOp; }
337 TIntermTyped* getExpression() { return expression; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000338
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000339protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000340 TOperator flowOp;
341 TIntermTyped* expression; // non-zero except for "return exp;" statements
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000342};
343
344//
345// Nodes that correspond to symbols or constants in the source code.
346//
347class TIntermSymbol : public TIntermTyped {
348public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000349 // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. If sym comes from
350 // per process globalpoolallocator, then it causes increased memory usage per compile
351 // it is essential to use "symbol = sym" to assign to symbol
352 TIntermSymbol(int i, const TString& sym, const TType& t) :
zmo@google.comfd747b82011-04-23 01:30:07 +0000353 TIntermTyped(t), id(i) { symbol = sym; originalSymbol = sym; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000354
355 int getId() const { return id; }
356 const TString& getSymbol() const { return symbol; }
357
zmo@google.comfd747b82011-04-23 01:30:07 +0000358 void setId(int newId) { id = newId; }
359 void setSymbol(const TString& sym) { symbol = sym; }
360
361 const TString& getOriginalSymbol() const { return originalSymbol; }
362
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000363 virtual void traverse(TIntermTraverser*);
364 virtual TIntermSymbol* getAsSymbolNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000365
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000366protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000367 int id;
368 TString symbol;
zmo@google.comfd747b82011-04-23 01:30:07 +0000369 TString originalSymbol;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000370};
371
372class TIntermConstantUnion : public TIntermTyped {
373public:
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000374 TIntermConstantUnion(ConstantUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000375
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000376 ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; }
shannon.woods%transgaming.com@gtempaccount.comc0d0c222013-04-13 03:29:36 +0000377
378 int getIConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getIConst() : 0; }
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +0000379 int getUConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getUConst() : 0; }
shannon.woods%transgaming.com@gtempaccount.comc0d0c222013-04-13 03:29:36 +0000380 float getFConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getFConst() : 0.0f; }
381 bool getBConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getBConst() : false; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000382
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000383 virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000384 virtual void traverse(TIntermTraverser*);
385
386 TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
387
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000388protected:
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000389 ConstantUnion *unionArrayPointer;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000390};
391
392//
393// Intermediate class for node types that hold operators.
394//
395class TIntermOperator : public TIntermTyped {
396public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000397 TOperator getOp() const { return op; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000398 void setOp(TOperator o) { op = o; }
399
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000400 bool modifiesState() const;
401 bool isConstructor() const;
alokp@chromium.org58e54292010-08-24 21:40:03 +0000402
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000403protected:
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000404 TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat, EbpUndefined)), op(o) {}
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000405 TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
406 TOperator op;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000407};
408
409//
410// Nodes for all the basic binary math operators.
411//
412class TIntermBinary : public TIntermOperator {
413public:
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000414 TIntermBinary(TOperator o) : TIntermOperator(o), addIndexClamp(false) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000415
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000416 virtual TIntermBinary* getAsBinaryNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000417 virtual void traverse(TIntermTraverser*);
418
419 void setLeft(TIntermTyped* n) { left = n; }
420 void setRight(TIntermTyped* n) { right = n; }
421 TIntermTyped* getLeft() const { return left; }
422 TIntermTyped* getRight() const { return right; }
423 bool promote(TInfoSink&);
424
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000425 void setAddIndexClamp() { addIndexClamp = true; }
426 bool getAddIndexClamp() { return addIndexClamp; }
427
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000428protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000429 TIntermTyped* left;
430 TIntermTyped* right;
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000431
432 // If set to true, wrap any EOpIndexIndirect with a clamp to bounds.
433 bool addIndexClamp;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000434};
435
436//
437// Nodes for unary math operators.
438//
439class TIntermUnary : public TIntermOperator {
440public:
zmo@google.com32e97312011-08-24 01:03:11 +0000441 TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0), useEmulatedFunction(false) {}
zmo@google.come4eb9912011-08-29 21:13:12 +0000442 TIntermUnary(TOperator o) : TIntermOperator(o), operand(0), useEmulatedFunction(false) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000443
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000444 virtual void traverse(TIntermTraverser*);
daniel@transgaming.com4a35ef22010-04-08 03:51:06 +0000445 virtual TIntermUnary* getAsUnaryNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000446
447 void setOperand(TIntermTyped* o) { operand = o; }
448 TIntermTyped* getOperand() { return operand; }
449 bool promote(TInfoSink&);
450
zmo@google.com32e97312011-08-24 01:03:11 +0000451 void setUseEmulatedFunction() { useEmulatedFunction = true; }
452 bool getUseEmulatedFunction() { return useEmulatedFunction; }
453
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000454protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000455 TIntermTyped* operand;
zmo@google.comf420c422011-09-12 18:27:59 +0000456
457 // If set to true, replace the built-in function call with an emulated one
458 // to work around driver bugs.
459 bool useEmulatedFunction;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000460};
461
462typedef TVector<TIntermNode*> TIntermSequence;
463typedef TVector<int> TQualifierList;
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000464
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000465//
466// Nodes that operate on an arbitrary sized set of children.
467//
468class TIntermAggregate : public TIntermOperator {
469public:
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000470 TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), endLine(0), useEmulatedFunction(false) { }
471 TIntermAggregate(TOperator o) : TIntermOperator(o), useEmulatedFunction(false) { }
472 ~TIntermAggregate() { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000473
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000474 virtual TIntermAggregate* getAsAggregate() { return this; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000475 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000476
477 TIntermSequence& getSequence() { return sequence; }
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000478
alokp@chromium.org58e54292010-08-24 21:40:03 +0000479 void setName(const TString& n) { name = n; }
480 const TString& getName() const { return name; }
481
482 void setUserDefined() { userDefined = true; }
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000483 bool isUserDefined() const { return userDefined; }
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000484
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000485 void setOptimize(bool o) { optimize = o; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000486 bool getOptimize() { return optimize; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000487 void setDebug(bool d) { debug = d; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000488 bool getDebug() { return debug; }
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000489
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000490 void setEndLine(TSourceLoc line) { endLine = line; }
491 TSourceLoc getEndLine() const { return endLine; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000492
zmo@google.comf420c422011-09-12 18:27:59 +0000493 void setUseEmulatedFunction() { useEmulatedFunction = true; }
494 bool getUseEmulatedFunction() { return useEmulatedFunction; }
495
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000496protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000497 TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
498 TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
499 TIntermSequence sequence;
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000500 TString name;
501 bool userDefined; // used for user defined function names
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000502
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000503 bool optimize;
504 bool debug;
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000505 TSourceLoc endLine;
zmo@google.comf420c422011-09-12 18:27:59 +0000506
507 // If set to true, replace the built-in function call with an emulated one
508 // to work around driver bugs.
509 bool useEmulatedFunction;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000510};
511
512//
513// For if tests. Simplified since there is no switch statement.
514//
515class TIntermSelection : public TIntermTyped {
516public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000517 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000518 TIntermTyped(TType(EbtVoid, EbpUndefined)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000519 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
520 TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000521
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000522 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000523
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000524 bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000525 TIntermNode* getCondition() const { return condition; }
526 TIntermNode* getTrueBlock() const { return trueBlock; }
527 TIntermNode* getFalseBlock() const { return falseBlock; }
528 TIntermSelection* getAsSelectionNode() { return this; }
529
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000530protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000531 TIntermTyped* condition;
532 TIntermNode* trueBlock;
533 TIntermNode* falseBlock;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000534};
535
536enum Visit
537{
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000538 PreVisit,
539 InVisit,
540 PostVisit
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000541};
542
543//
544// For traversing the tree. User should derive from this,
545// put their traversal specific data in it, and then pass
546// it to a Traverse method.
547//
548// When using this, just fill in the methods for nodes you want visited.
549// Return false from a pre-visit to skip visiting that node's subtree.
550//
551class TIntermTraverser
552{
553public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000554 POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000555
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000556 TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
557 preVisit(preVisit),
558 inVisit(inVisit),
559 postVisit(postVisit),
560 rightToLeft(rightToLeft),
561 depth(0) {}
maxvujovic@gmail.comc6b3b3c2012-06-27 22:49:39 +0000562 virtual ~TIntermTraverser() {};
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000563
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000564 virtual void visitSymbol(TIntermSymbol*) {}
565 virtual void visitConstantUnion(TIntermConstantUnion*) {}
566 virtual bool visitBinary(Visit visit, TIntermBinary*) {return true;}
567 virtual bool visitUnary(Visit visit, TIntermUnary*) {return true;}
568 virtual bool visitSelection(Visit visit, TIntermSelection*) {return true;}
569 virtual bool visitAggregate(Visit visit, TIntermAggregate*) {return true;}
570 virtual bool visitLoop(Visit visit, TIntermLoop*) {return true;}
571 virtual bool visitBranch(Visit visit, TIntermBranch*) {return true;}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000572
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000573 void incrementDepth() {depth++;}
574 void decrementDepth() {depth--;}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000575
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000576 // Return the original name if hash function pointer is NULL;
577 // otherwise return the hashed name.
578 static TString hash(const TString& name, ShHashFunction64 hashFunction);
579
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000580 const bool preVisit;
581 const bool inVisit;
582 const bool postVisit;
583 const bool rightToLeft;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000584
585protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000586 int depth;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000587};
588
589#endif // __INTERMEDIATE_H