blob: d5d6a19cd008dc7d450ca99590b5f19cab06553a [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,
Nicolas Capensab60b932013-06-05 10:31:21 -040052 EOpConvUIntToBool,
alokp@chromium.org2cf17712010-03-30 20:33:18 +000053 EOpConvFloatToBool,
54 EOpConvBoolToFloat,
55 EOpConvIntToFloat,
Nicolas Capensab60b932013-06-05 10:31:21 -040056 EOpConvUIntToFloat,
alokp@chromium.org2cf17712010-03-30 20:33:18 +000057 EOpConvFloatToInt,
58 EOpConvBoolToInt,
Nicolas Capensab60b932013-06-05 10:31:21 -040059 EOpConvUIntToInt,
60 EOpConvIntToUInt,
61 EOpConvFloatToUInt,
62 EOpConvBoolToUInt,
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,
Nicolas Capensab60b932013-06-05 10:31:21 -0400164 EOpConstructUInt,
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,
shannonwoods@chromium.org8c788e82013-05-30 00:20:21 +0000176 EOpConstructUVec2,
177 EOpConstructUVec3,
178 EOpConstructUVec4,
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000179 EOpConstructMat2,
180 EOpConstructMat3,
181 EOpConstructMat4,
182 EOpConstructStruct,
183
184 //
185 // moves
186 //
187
188 EOpAssign,
189 EOpInitialize,
190 EOpAddAssign,
191 EOpSubAssign,
192 EOpMulAssign,
193 EOpVectorTimesMatrixAssign,
194 EOpVectorTimesScalarAssign,
195 EOpMatrixTimesScalarAssign,
196 EOpMatrixTimesMatrixAssign,
daniel@transgaming.comb3077d02013-01-11 04:12:09 +0000197 EOpDivAssign
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000198};
199
alokp@chromium.orgb59a7782010-11-24 18:38:33 +0000200extern const char* getOperatorString(TOperator op);
201
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000202class TIntermTraverser;
203class TIntermAggregate;
204class TIntermBinary;
daniel@transgaming.com4a35ef22010-04-08 03:51:06 +0000205class TIntermUnary;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000206class TIntermConstantUnion;
207class TIntermSelection;
208class TIntermTyped;
209class TIntermSymbol;
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000210class TIntermLoop;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000211class TInfoSink;
212
213//
214// Base class for the tree nodes
215//
216class TIntermNode {
217public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000218 POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000219
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000220 TIntermNode() : line(0) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000221
222 TSourceLoc getLine() const { return line; }
223 void setLine(TSourceLoc l) { line = l; }
224
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000225 virtual void traverse(TIntermTraverser*) = 0;
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000226 virtual TIntermTyped* getAsTyped() { return 0; }
227 virtual TIntermConstantUnion* getAsConstantUnion() { return 0; }
228 virtual TIntermAggregate* getAsAggregate() { return 0; }
229 virtual TIntermBinary* getAsBinaryNode() { return 0; }
230 virtual TIntermUnary* getAsUnaryNode() { return 0; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000231 virtual TIntermSelection* getAsSelectionNode() { return 0; }
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000232 virtual TIntermSymbol* getAsSymbolNode() { return 0; }
233 virtual TIntermLoop* getAsLoopNode() { return 0; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000234 virtual ~TIntermNode() { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000235
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000236protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000237 TSourceLoc line;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000238};
239
240//
241// This is just to help yacc.
242//
243struct TIntermNodePair {
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000244 TIntermNode* node1;
245 TIntermNode* node2;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000246};
247
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000248//
249// Intermediate class for nodes that have a type.
250//
251class TIntermTyped : public TIntermNode {
252public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000253 TIntermTyped(const TType& t) : type(t) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000254 virtual TIntermTyped* getAsTyped() { return this; }
alokp@chromium.orgdd037b22010-03-30 18:47:20 +0000255
alokp@chromium.org58e54292010-08-24 21:40:03 +0000256 void setType(const TType& t) { type = t; }
257 const TType& getType() const { return type; }
258 TType* getTypePointer() { return &type; }
259
260 TBasicType getBasicType() const { return type.getBasicType(); }
261 TQualifier getQualifier() const { return type.getQualifier(); }
262 TPrecision getPrecision() const { return type.getPrecision(); }
shannonwoods@chromium.org09e09882013-05-30 00:18:25 +0000263 int getCols() const { return type.getCols(); }
264 int getRows() const { return type.getRows(); }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000265 int getNominalSize() const { return type.getNominalSize(); }
shannonwoods@chromium.org09e09882013-05-30 00:18:25 +0000266 int getSecondarySize() const { return type.getSecondarySize(); }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000267
268 bool isMatrix() const { return type.isMatrix(); }
269 bool isArray() const { return type.isArray(); }
270 bool isVector() const { return type.isVector(); }
271 bool isScalar() const { return type.isScalar(); }
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +0000272 bool isScalarInt() const { return type.isScalarInt(); }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000273 const char* getBasicString() const { return type.getBasicString(); }
274 const char* getQualifierString() const { return type.getQualifierString(); }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000275 TString getCompleteString() const { return type.getCompleteString(); }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000276
daniel@transgaming.com3ca980a2012-12-20 21:11:52 +0000277 int totalRegisterCount() const { return type.totalRegisterCount(); }
278 int elementRegisterCount() const { return type.elementRegisterCount(); }
279 int getArraySize() const { return type.getArraySize(); }
280
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000281protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000282 TType type;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000283};
284
285//
286// Handle for, do-while, and while loops.
287//
alokp@chromium.org52813552010-11-16 18:36:09 +0000288enum TLoopType {
289 ELoopFor,
290 ELoopWhile,
daniel@transgaming.comb3077d02013-01-11 04:12:09 +0000291 ELoopDoWhile
alokp@chromium.org52813552010-11-16 18:36:09 +0000292};
293
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000294class TIntermLoop : public TIntermNode {
295public:
alokp@chromium.org52813552010-11-16 18:36:09 +0000296 TIntermLoop(TLoopType aType,
297 TIntermNode *aInit, TIntermTyped* aCond, TIntermTyped* aExpr,
298 TIntermNode* aBody) :
299 type(aType),
300 init(aInit),
301 cond(aCond),
302 expr(aExpr),
zmo@google.com0b8d4eb2011-04-04 19:17:11 +0000303 body(aBody),
304 unrollFlag(false) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000305
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000306 virtual TIntermLoop* getAsLoopNode() { return this; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000307 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000308
alokp@chromium.org52813552010-11-16 18:36:09 +0000309 TLoopType getType() const { return type; }
310 TIntermNode* getInit() { return init; }
311 TIntermTyped* getCondition() { return cond; }
312 TIntermTyped* getExpression() { return expr; }
313 TIntermNode* getBody() { return body; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000314
zmo@google.com0b8d4eb2011-04-04 19:17:11 +0000315 void setUnrollFlag(bool flag) { unrollFlag = flag; }
316 bool getUnrollFlag() { return unrollFlag; }
317
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000318protected:
alokp@chromium.org52813552010-11-16 18:36:09 +0000319 TLoopType type;
320 TIntermNode* init; // for-loop initialization
321 TIntermTyped* cond; // loop exit condition
322 TIntermTyped* expr; // for-loop expression
323 TIntermNode* body; // loop body
zmo@google.com0b8d4eb2011-04-04 19:17:11 +0000324
325 bool unrollFlag; // Whether the loop should be unrolled or not.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000326};
327
328//
329// Handle break, continue, return, and kill.
330//
331class TIntermBranch : public TIntermNode {
332public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000333 TIntermBranch(TOperator op, TIntermTyped* e) :
334 flowOp(op),
335 expression(e) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000336
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000337 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000338
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000339 TOperator getFlowOp() { return flowOp; }
340 TIntermTyped* getExpression() { return expression; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000341
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000342protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000343 TOperator flowOp;
344 TIntermTyped* expression; // non-zero except for "return exp;" statements
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000345};
346
347//
348// Nodes that correspond to symbols or constants in the source code.
349//
350class TIntermSymbol : public TIntermTyped {
351public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000352 // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. If sym comes from
353 // per process globalpoolallocator, then it causes increased memory usage per compile
354 // it is essential to use "symbol = sym" to assign to symbol
355 TIntermSymbol(int i, const TString& sym, const TType& t) :
zmo@google.comfd747b82011-04-23 01:30:07 +0000356 TIntermTyped(t), id(i) { symbol = sym; originalSymbol = sym; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000357
358 int getId() const { return id; }
359 const TString& getSymbol() const { return symbol; }
360
zmo@google.comfd747b82011-04-23 01:30:07 +0000361 void setId(int newId) { id = newId; }
362 void setSymbol(const TString& sym) { symbol = sym; }
363
364 const TString& getOriginalSymbol() const { return originalSymbol; }
365
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000366 virtual void traverse(TIntermTraverser*);
367 virtual TIntermSymbol* getAsSymbolNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000368
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000369protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000370 int id;
371 TString symbol;
zmo@google.comfd747b82011-04-23 01:30:07 +0000372 TString originalSymbol;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000373};
374
375class TIntermConstantUnion : public TIntermTyped {
376public:
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000377 TIntermConstantUnion(ConstantUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000378
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000379 ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; }
shannon.woods%transgaming.com@gtempaccount.comc0d0c222013-04-13 03:29:36 +0000380
381 int getIConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getIConst() : 0; }
Nicolas Capensc0f7c612013-06-05 11:46:09 -0400382 unsigned int getUConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getUConst() : 0; }
shannon.woods%transgaming.com@gtempaccount.comc0d0c222013-04-13 03:29:36 +0000383 float getFConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getFConst() : 0.0f; }
384 bool getBConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getBConst() : false; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000385
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000386 virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000387 virtual void traverse(TIntermTraverser*);
388
389 TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
390
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000391protected:
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000392 ConstantUnion *unionArrayPointer;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000393};
394
395//
396// Intermediate class for node types that hold operators.
397//
398class TIntermOperator : public TIntermTyped {
399public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000400 TOperator getOp() const { return op; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000401 void setOp(TOperator o) { op = o; }
402
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000403 bool modifiesState() const;
404 bool isConstructor() const;
alokp@chromium.org58e54292010-08-24 21:40:03 +0000405
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000406protected:
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000407 TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat, EbpUndefined)), op(o) {}
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000408 TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
409 TOperator op;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000410};
411
412//
413// Nodes for all the basic binary math operators.
414//
415class TIntermBinary : public TIntermOperator {
416public:
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000417 TIntermBinary(TOperator o) : TIntermOperator(o), addIndexClamp(false) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000418
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000419 virtual TIntermBinary* getAsBinaryNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000420 virtual void traverse(TIntermTraverser*);
421
422 void setLeft(TIntermTyped* n) { left = n; }
423 void setRight(TIntermTyped* n) { right = n; }
424 TIntermTyped* getLeft() const { return left; }
425 TIntermTyped* getRight() const { return right; }
426 bool promote(TInfoSink&);
427
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000428 void setAddIndexClamp() { addIndexClamp = true; }
429 bool getAddIndexClamp() { return addIndexClamp; }
430
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000431protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000432 TIntermTyped* left;
433 TIntermTyped* right;
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000434
435 // If set to true, wrap any EOpIndexIndirect with a clamp to bounds.
436 bool addIndexClamp;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000437};
438
439//
440// Nodes for unary math operators.
441//
442class TIntermUnary : public TIntermOperator {
443public:
zmo@google.com32e97312011-08-24 01:03:11 +0000444 TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0), useEmulatedFunction(false) {}
zmo@google.come4eb9912011-08-29 21:13:12 +0000445 TIntermUnary(TOperator o) : TIntermOperator(o), operand(0), useEmulatedFunction(false) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000446
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000447 virtual void traverse(TIntermTraverser*);
daniel@transgaming.com4a35ef22010-04-08 03:51:06 +0000448 virtual TIntermUnary* getAsUnaryNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000449
450 void setOperand(TIntermTyped* o) { operand = o; }
451 TIntermTyped* getOperand() { return operand; }
452 bool promote(TInfoSink&);
453
zmo@google.com32e97312011-08-24 01:03:11 +0000454 void setUseEmulatedFunction() { useEmulatedFunction = true; }
455 bool getUseEmulatedFunction() { return useEmulatedFunction; }
456
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000457protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000458 TIntermTyped* operand;
zmo@google.comf420c422011-09-12 18:27:59 +0000459
460 // If set to true, replace the built-in function call with an emulated one
461 // to work around driver bugs.
462 bool useEmulatedFunction;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000463};
464
465typedef TVector<TIntermNode*> TIntermSequence;
466typedef TVector<int> TQualifierList;
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000467
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000468//
469// Nodes that operate on an arbitrary sized set of children.
470//
471class TIntermAggregate : public TIntermOperator {
472public:
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000473 TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), endLine(0), useEmulatedFunction(false) { }
474 TIntermAggregate(TOperator o) : TIntermOperator(o), useEmulatedFunction(false) { }
475 ~TIntermAggregate() { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000476
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000477 virtual TIntermAggregate* getAsAggregate() { return this; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000478 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000479
480 TIntermSequence& getSequence() { return sequence; }
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000481
alokp@chromium.org58e54292010-08-24 21:40:03 +0000482 void setName(const TString& n) { name = n; }
483 const TString& getName() const { return name; }
484
485 void setUserDefined() { userDefined = true; }
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000486 bool isUserDefined() const { return userDefined; }
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000487
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000488 void setOptimize(bool o) { optimize = o; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000489 bool getOptimize() { return optimize; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000490 void setDebug(bool d) { debug = d; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000491 bool getDebug() { return debug; }
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000492
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000493 void setEndLine(TSourceLoc line) { endLine = line; }
494 TSourceLoc getEndLine() const { return endLine; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000495
zmo@google.comf420c422011-09-12 18:27:59 +0000496 void setUseEmulatedFunction() { useEmulatedFunction = true; }
497 bool getUseEmulatedFunction() { return useEmulatedFunction; }
498
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000499protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000500 TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
501 TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
502 TIntermSequence sequence;
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000503 TString name;
504 bool userDefined; // used for user defined function names
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000505
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000506 bool optimize;
507 bool debug;
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000508 TSourceLoc endLine;
zmo@google.comf420c422011-09-12 18:27:59 +0000509
510 // If set to true, replace the built-in function call with an emulated one
511 // to work around driver bugs.
512 bool useEmulatedFunction;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000513};
514
515//
516// For if tests. Simplified since there is no switch statement.
517//
518class TIntermSelection : public TIntermTyped {
519public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000520 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000521 TIntermTyped(TType(EbtVoid, EbpUndefined)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000522 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
523 TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000524
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000525 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000526
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000527 bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000528 TIntermNode* getCondition() const { return condition; }
529 TIntermNode* getTrueBlock() const { return trueBlock; }
530 TIntermNode* getFalseBlock() const { return falseBlock; }
531 TIntermSelection* getAsSelectionNode() { return this; }
532
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000533protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000534 TIntermTyped* condition;
535 TIntermNode* trueBlock;
536 TIntermNode* falseBlock;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000537};
538
539enum Visit
540{
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000541 PreVisit,
542 InVisit,
543 PostVisit
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000544};
545
546//
547// For traversing the tree. User should derive from this,
548// put their traversal specific data in it, and then pass
549// it to a Traverse method.
550//
551// When using this, just fill in the methods for nodes you want visited.
552// Return false from a pre-visit to skip visiting that node's subtree.
553//
554class TIntermTraverser
555{
556public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000557 POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000558
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000559 TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
560 preVisit(preVisit),
561 inVisit(inVisit),
562 postVisit(postVisit),
563 rightToLeft(rightToLeft),
564 depth(0) {}
maxvujovic@gmail.comc6b3b3c2012-06-27 22:49:39 +0000565 virtual ~TIntermTraverser() {};
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000566
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000567 virtual void visitSymbol(TIntermSymbol*) {}
568 virtual void visitConstantUnion(TIntermConstantUnion*) {}
569 virtual bool visitBinary(Visit visit, TIntermBinary*) {return true;}
570 virtual bool visitUnary(Visit visit, TIntermUnary*) {return true;}
571 virtual bool visitSelection(Visit visit, TIntermSelection*) {return true;}
572 virtual bool visitAggregate(Visit visit, TIntermAggregate*) {return true;}
573 virtual bool visitLoop(Visit visit, TIntermLoop*) {return true;}
574 virtual bool visitBranch(Visit visit, TIntermBranch*) {return true;}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000575
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000576 void incrementDepth() {depth++;}
577 void decrementDepth() {depth--;}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000578
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000579 // Return the original name if hash function pointer is NULL;
580 // otherwise return the hashed name.
581 static TString hash(const TString& name, ShHashFunction64 hashFunction);
582
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000583 const bool preVisit;
584 const bool inVisit;
585 const bool postVisit;
586 const bool rightToLeft;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000587
588protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000589 int depth;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000590};
591
592#endif // __INTERMEDIATE_H