blob: 2a3ad9c2aead8c5487d4538f4f6392482dc506e1 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
2// Copyright (c) 2002-2010 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7//
8// Definition of the in-memory high-level intermediate representation
9// of shaders. This is a tree that parser creates.
10//
11// Nodes in the tree are defined as a hierarchy of classes derived from
12// TIntermNode. Each is a node in a tree. There is no preset branching factor;
13// each node can have it's own type of list of children.
14//
15
16#ifndef __INTERMEDIATE_H
17#define __INTERMEDIATE_H
18
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +000019#include "GLSLANG/ShaderLang.h"
20
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000021#include "compiler/Common.h"
22#include "compiler/Types.h"
23#include "compiler/ConstantUnion.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000024
25//
26// Operators used by the high-level (parse tree) representation.
27//
28enum TOperator {
alokp@chromium.org2cf17712010-03-30 20:33:18 +000029 EOpNull, // if in a node, should only mean a node is still being built
30 EOpSequence, // denotes a list of statements, or parameters, etc.
31 EOpFunctionCall,
32 EOpFunction, // For function definition
33 EOpParameters, // an aggregate listing the parameters to a function
daniel@transgaming.comd1acd1e2010-04-13 03:25:57 +000034
alokp@chromium.org2cf17712010-03-30 20:33:18 +000035 EOpDeclaration,
daniel@transgaming.comd1acd1e2010-04-13 03:25:57 +000036 EOpPrototype,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000037
alokp@chromium.org2cf17712010-03-30 20:33:18 +000038 //
39 // Unary operators
40 //
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000041
alokp@chromium.org2cf17712010-03-30 20:33:18 +000042 EOpNegative,
43 EOpLogicalNot,
44 EOpVectorLogicalNot,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000045
alokp@chromium.org2cf17712010-03-30 20:33:18 +000046 EOpPostIncrement,
47 EOpPostDecrement,
48 EOpPreIncrement,
49 EOpPreDecrement,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000050
alokp@chromium.org2cf17712010-03-30 20:33:18 +000051 EOpConvIntToBool,
52 EOpConvFloatToBool,
53 EOpConvBoolToFloat,
54 EOpConvIntToFloat,
55 EOpConvFloatToInt,
56 EOpConvBoolToInt,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000057
alokp@chromium.org2cf17712010-03-30 20:33:18 +000058 //
59 // binary operations
60 //
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000061
alokp@chromium.org2cf17712010-03-30 20:33:18 +000062 EOpAdd,
63 EOpSub,
64 EOpMul,
65 EOpDiv,
66 EOpEqual,
67 EOpNotEqual,
68 EOpVectorEqual,
69 EOpVectorNotEqual,
70 EOpLessThan,
71 EOpGreaterThan,
72 EOpLessThanEqual,
73 EOpGreaterThanEqual,
74 EOpComma,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000075
alokp@chromium.org2cf17712010-03-30 20:33:18 +000076 EOpVectorTimesScalar,
77 EOpVectorTimesMatrix,
78 EOpMatrixTimesVector,
79 EOpMatrixTimesScalar,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000080
alokp@chromium.org2cf17712010-03-30 20:33:18 +000081 EOpLogicalOr,
82 EOpLogicalXor,
83 EOpLogicalAnd,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000084
alokp@chromium.org2cf17712010-03-30 20:33:18 +000085 EOpIndexDirect,
86 EOpIndexIndirect,
87 EOpIndexDirectStruct,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000088
alokp@chromium.org2cf17712010-03-30 20:33:18 +000089 EOpVectorSwizzle,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000090
alokp@chromium.org2cf17712010-03-30 20:33:18 +000091 //
92 // Built-in functions potentially mapped to operators
93 //
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000094
alokp@chromium.org2cf17712010-03-30 20:33:18 +000095 EOpRadians,
96 EOpDegrees,
97 EOpSin,
98 EOpCos,
99 EOpTan,
100 EOpAsin,
101 EOpAcos,
102 EOpAtan,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000103
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000104 EOpPow,
105 EOpExp,
106 EOpLog,
107 EOpExp2,
108 EOpLog2,
109 EOpSqrt,
110 EOpInverseSqrt,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000111
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000112 EOpAbs,
113 EOpSign,
114 EOpFloor,
115 EOpCeil,
116 EOpFract,
117 EOpMod,
118 EOpMin,
119 EOpMax,
120 EOpClamp,
121 EOpMix,
122 EOpStep,
123 EOpSmoothStep,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000124
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000125 EOpLength,
126 EOpDistance,
127 EOpDot,
128 EOpCross,
129 EOpNormalize,
130 EOpFaceForward,
131 EOpReflect,
132 EOpRefract,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000133
alokp@chromium.org06098892010-08-26 19:36:42 +0000134 EOpDFdx, // Fragment only, OES_standard_derivatives extension
135 EOpDFdy, // Fragment only, OES_standard_derivatives extension
136 EOpFwidth, // Fragment only, OES_standard_derivatives extension
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000137
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000138 EOpMatrixTimesMatrix,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000139
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000140 EOpAny,
141 EOpAll,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000142
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000143 //
144 // Branch
145 //
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000146
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000147 EOpKill, // Fragment only
148 EOpReturn,
149 EOpBreak,
150 EOpContinue,
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000151
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000152 //
153 // Constructors
154 //
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000155
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000156 EOpConstructInt,
157 EOpConstructBool,
158 EOpConstructFloat,
159 EOpConstructVec2,
160 EOpConstructVec3,
161 EOpConstructVec4,
162 EOpConstructBVec2,
163 EOpConstructBVec3,
164 EOpConstructBVec4,
165 EOpConstructIVec2,
166 EOpConstructIVec3,
167 EOpConstructIVec4,
168 EOpConstructMat2,
169 EOpConstructMat3,
170 EOpConstructMat4,
171 EOpConstructStruct,
172
173 //
174 // moves
175 //
176
177 EOpAssign,
178 EOpInitialize,
179 EOpAddAssign,
180 EOpSubAssign,
181 EOpMulAssign,
182 EOpVectorTimesMatrixAssign,
183 EOpVectorTimesScalarAssign,
184 EOpMatrixTimesScalarAssign,
185 EOpMatrixTimesMatrixAssign,
daniel@transgaming.comb3077d02013-01-11 04:12:09 +0000186 EOpDivAssign
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000187};
188
alokp@chromium.orgb59a7782010-11-24 18:38:33 +0000189extern const char* getOperatorString(TOperator op);
190
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000191class TIntermTraverser;
192class TIntermAggregate;
193class TIntermBinary;
daniel@transgaming.com4a35ef22010-04-08 03:51:06 +0000194class TIntermUnary;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000195class TIntermConstantUnion;
196class TIntermSelection;
197class TIntermTyped;
198class TIntermSymbol;
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000199class TIntermLoop;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000200class TInfoSink;
201
202//
203// Base class for the tree nodes
204//
205class TIntermNode {
206public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000207 POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000208
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000209 TIntermNode() : line(0) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000210
211 TSourceLoc getLine() const { return line; }
212 void setLine(TSourceLoc l) { line = l; }
213
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000214 virtual void traverse(TIntermTraverser*) = 0;
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000215 virtual TIntermTyped* getAsTyped() { return 0; }
216 virtual TIntermConstantUnion* getAsConstantUnion() { return 0; }
217 virtual TIntermAggregate* getAsAggregate() { return 0; }
218 virtual TIntermBinary* getAsBinaryNode() { return 0; }
219 virtual TIntermUnary* getAsUnaryNode() { return 0; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000220 virtual TIntermSelection* getAsSelectionNode() { return 0; }
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000221 virtual TIntermSymbol* getAsSymbolNode() { return 0; }
222 virtual TIntermLoop* getAsLoopNode() { return 0; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000223 virtual ~TIntermNode() { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000224
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000225protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000226 TSourceLoc line;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000227};
228
229//
230// This is just to help yacc.
231//
232struct TIntermNodePair {
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000233 TIntermNode* node1;
234 TIntermNode* node2;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000235};
236
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000237//
238// Intermediate class for nodes that have a type.
239//
240class TIntermTyped : public TIntermNode {
241public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000242 TIntermTyped(const TType& t) : type(t) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000243 virtual TIntermTyped* getAsTyped() { return this; }
alokp@chromium.orgdd037b22010-03-30 18:47:20 +0000244
alokp@chromium.org58e54292010-08-24 21:40:03 +0000245 void setType(const TType& t) { type = t; }
246 const TType& getType() const { return type; }
247 TType* getTypePointer() { return &type; }
248
249 TBasicType getBasicType() const { return type.getBasicType(); }
250 TQualifier getQualifier() const { return type.getQualifier(); }
251 TPrecision getPrecision() const { return type.getPrecision(); }
252 int getNominalSize() const { return type.getNominalSize(); }
253
254 bool isMatrix() const { return type.isMatrix(); }
255 bool isArray() const { return type.isArray(); }
256 bool isVector() const { return type.isVector(); }
257 bool isScalar() const { return type.isScalar(); }
258 const char* getBasicString() const { return type.getBasicString(); }
259 const char* getQualifierString() const { return type.getQualifierString(); }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000260 TString getCompleteString() const { return type.getCompleteString(); }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000261
daniel@transgaming.com3ca980a2012-12-20 21:11:52 +0000262 int totalRegisterCount() const { return type.totalRegisterCount(); }
263 int elementRegisterCount() const { return type.elementRegisterCount(); }
264 int getArraySize() const { return type.getArraySize(); }
265
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000266protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000267 TType type;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000268};
269
270//
271// Handle for, do-while, and while loops.
272//
alokp@chromium.org52813552010-11-16 18:36:09 +0000273enum TLoopType {
274 ELoopFor,
275 ELoopWhile,
daniel@transgaming.comb3077d02013-01-11 04:12:09 +0000276 ELoopDoWhile
alokp@chromium.org52813552010-11-16 18:36:09 +0000277};
278
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000279class TIntermLoop : public TIntermNode {
280public:
alokp@chromium.org52813552010-11-16 18:36:09 +0000281 TIntermLoop(TLoopType aType,
282 TIntermNode *aInit, TIntermTyped* aCond, TIntermTyped* aExpr,
283 TIntermNode* aBody) :
284 type(aType),
285 init(aInit),
286 cond(aCond),
287 expr(aExpr),
zmo@google.com0b8d4eb2011-04-04 19:17:11 +0000288 body(aBody),
289 unrollFlag(false) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000290
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000291 virtual TIntermLoop* getAsLoopNode() { return this; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000292 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000293
alokp@chromium.org52813552010-11-16 18:36:09 +0000294 TLoopType getType() const { return type; }
295 TIntermNode* getInit() { return init; }
296 TIntermTyped* getCondition() { return cond; }
297 TIntermTyped* getExpression() { return expr; }
298 TIntermNode* getBody() { return body; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000299
zmo@google.com0b8d4eb2011-04-04 19:17:11 +0000300 void setUnrollFlag(bool flag) { unrollFlag = flag; }
301 bool getUnrollFlag() { return unrollFlag; }
302
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000303protected:
alokp@chromium.org52813552010-11-16 18:36:09 +0000304 TLoopType type;
305 TIntermNode* init; // for-loop initialization
306 TIntermTyped* cond; // loop exit condition
307 TIntermTyped* expr; // for-loop expression
308 TIntermNode* body; // loop body
zmo@google.com0b8d4eb2011-04-04 19:17:11 +0000309
310 bool unrollFlag; // Whether the loop should be unrolled or not.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000311};
312
313//
314// Handle break, continue, return, and kill.
315//
316class TIntermBranch : public TIntermNode {
317public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000318 TIntermBranch(TOperator op, TIntermTyped* e) :
319 flowOp(op),
320 expression(e) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000321
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000322 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000323
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000324 TOperator getFlowOp() { return flowOp; }
325 TIntermTyped* getExpression() { return expression; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000326
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000327protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000328 TOperator flowOp;
329 TIntermTyped* expression; // non-zero except for "return exp;" statements
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000330};
331
332//
333// Nodes that correspond to symbols or constants in the source code.
334//
335class TIntermSymbol : public TIntermTyped {
336public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000337 // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. If sym comes from
338 // per process globalpoolallocator, then it causes increased memory usage per compile
339 // it is essential to use "symbol = sym" to assign to symbol
340 TIntermSymbol(int i, const TString& sym, const TType& t) :
zmo@google.comfd747b82011-04-23 01:30:07 +0000341 TIntermTyped(t), id(i) { symbol = sym; originalSymbol = sym; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000342
343 int getId() const { return id; }
344 const TString& getSymbol() const { return symbol; }
345
zmo@google.comfd747b82011-04-23 01:30:07 +0000346 void setId(int newId) { id = newId; }
347 void setSymbol(const TString& sym) { symbol = sym; }
348
349 const TString& getOriginalSymbol() const { return originalSymbol; }
350
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000351 virtual void traverse(TIntermTraverser*);
352 virtual TIntermSymbol* getAsSymbolNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000353
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000354protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000355 int id;
356 TString symbol;
zmo@google.comfd747b82011-04-23 01:30:07 +0000357 TString originalSymbol;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000358};
359
360class TIntermConstantUnion : public TIntermTyped {
361public:
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000362 TIntermConstantUnion(ConstantUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000363
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000364 ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; }
365 void setUnionArrayPointer(ConstantUnion *c) { unionArrayPointer = c; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000366
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000367 virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000368 virtual void traverse(TIntermTraverser*);
369
370 TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
371
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000372protected:
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000373 ConstantUnion *unionArrayPointer;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000374};
375
376//
377// Intermediate class for node types that hold operators.
378//
379class TIntermOperator : public TIntermTyped {
380public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000381 TOperator getOp() const { return op; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000382 void setOp(TOperator o) { op = o; }
383
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000384 bool modifiesState() const;
385 bool isConstructor() const;
alokp@chromium.org58e54292010-08-24 21:40:03 +0000386
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000387protected:
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000388 TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat, EbpUndefined)), op(o) {}
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000389 TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
390 TOperator op;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000391};
392
393//
394// Nodes for all the basic binary math operators.
395//
396class TIntermBinary : public TIntermOperator {
397public:
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000398 TIntermBinary(TOperator o) : TIntermOperator(o), addIndexClamp(false) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000399
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000400 virtual TIntermBinary* getAsBinaryNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000401 virtual void traverse(TIntermTraverser*);
402
403 void setLeft(TIntermTyped* n) { left = n; }
404 void setRight(TIntermTyped* n) { right = n; }
405 TIntermTyped* getLeft() const { return left; }
406 TIntermTyped* getRight() const { return right; }
407 bool promote(TInfoSink&);
408
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000409 void setAddIndexClamp() { addIndexClamp = true; }
410 bool getAddIndexClamp() { return addIndexClamp; }
411
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000412protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000413 TIntermTyped* left;
414 TIntermTyped* right;
daniel@transgaming.com4167cc92013-01-11 04:11:53 +0000415
416 // If set to true, wrap any EOpIndexIndirect with a clamp to bounds.
417 bool addIndexClamp;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000418};
419
420//
421// Nodes for unary math operators.
422//
423class TIntermUnary : public TIntermOperator {
424public:
zmo@google.com32e97312011-08-24 01:03:11 +0000425 TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0), useEmulatedFunction(false) {}
zmo@google.come4eb9912011-08-29 21:13:12 +0000426 TIntermUnary(TOperator o) : TIntermOperator(o), operand(0), useEmulatedFunction(false) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000427
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000428 virtual void traverse(TIntermTraverser*);
daniel@transgaming.com4a35ef22010-04-08 03:51:06 +0000429 virtual TIntermUnary* getAsUnaryNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000430
431 void setOperand(TIntermTyped* o) { operand = o; }
432 TIntermTyped* getOperand() { return operand; }
433 bool promote(TInfoSink&);
434
zmo@google.com32e97312011-08-24 01:03:11 +0000435 void setUseEmulatedFunction() { useEmulatedFunction = true; }
436 bool getUseEmulatedFunction() { return useEmulatedFunction; }
437
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000438protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000439 TIntermTyped* operand;
zmo@google.comf420c422011-09-12 18:27:59 +0000440
441 // If set to true, replace the built-in function call with an emulated one
442 // to work around driver bugs.
443 bool useEmulatedFunction;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000444};
445
446typedef TVector<TIntermNode*> TIntermSequence;
447typedef TVector<int> TQualifierList;
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000448
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000449//
450// Nodes that operate on an arbitrary sized set of children.
451//
452class TIntermAggregate : public TIntermOperator {
453public:
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000454 TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), endLine(0), useEmulatedFunction(false) { }
455 TIntermAggregate(TOperator o) : TIntermOperator(o), useEmulatedFunction(false) { }
456 ~TIntermAggregate() { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000457
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000458 virtual TIntermAggregate* getAsAggregate() { return this; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000459 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000460
461 TIntermSequence& getSequence() { return sequence; }
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000462
alokp@chromium.org58e54292010-08-24 21:40:03 +0000463 void setName(const TString& n) { name = n; }
464 const TString& getName() const { return name; }
465
466 void setUserDefined() { userDefined = true; }
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000467 bool isUserDefined() const { return userDefined; }
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000468
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000469 void setOptimize(bool o) { optimize = o; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000470 bool getOptimize() { return optimize; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000471 void setDebug(bool d) { debug = d; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000472 bool getDebug() { return debug; }
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000473
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000474 void setEndLine(TSourceLoc line) { endLine = line; }
475 TSourceLoc getEndLine() const { return endLine; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000476
zmo@google.comf420c422011-09-12 18:27:59 +0000477 void setUseEmulatedFunction() { useEmulatedFunction = true; }
478 bool getUseEmulatedFunction() { return useEmulatedFunction; }
479
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000480protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000481 TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
482 TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
483 TIntermSequence sequence;
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000484 TString name;
485 bool userDefined; // used for user defined function names
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000486
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000487 bool optimize;
488 bool debug;
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000489 TSourceLoc endLine;
zmo@google.comf420c422011-09-12 18:27:59 +0000490
491 // If set to true, replace the built-in function call with an emulated one
492 // to work around driver bugs.
493 bool useEmulatedFunction;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000494};
495
496//
497// For if tests. Simplified since there is no switch statement.
498//
499class TIntermSelection : public TIntermTyped {
500public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000501 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000502 TIntermTyped(TType(EbtVoid, EbpUndefined)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000503 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
504 TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000505
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000506 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000507
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000508 bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000509 TIntermNode* getCondition() const { return condition; }
510 TIntermNode* getTrueBlock() const { return trueBlock; }
511 TIntermNode* getFalseBlock() const { return falseBlock; }
512 TIntermSelection* getAsSelectionNode() { return this; }
513
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000514protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000515 TIntermTyped* condition;
516 TIntermNode* trueBlock;
517 TIntermNode* falseBlock;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000518};
519
520enum Visit
521{
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000522 PreVisit,
523 InVisit,
524 PostVisit
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000525};
526
527//
528// For traversing the tree. User should derive from this,
529// put their traversal specific data in it, and then pass
530// it to a Traverse method.
531//
532// When using this, just fill in the methods for nodes you want visited.
533// Return false from a pre-visit to skip visiting that node's subtree.
534//
535class TIntermTraverser
536{
537public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000538 POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000539
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000540 TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
541 preVisit(preVisit),
542 inVisit(inVisit),
543 postVisit(postVisit),
544 rightToLeft(rightToLeft),
545 depth(0) {}
maxvujovic@gmail.comc6b3b3c2012-06-27 22:49:39 +0000546 virtual ~TIntermTraverser() {};
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000547
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000548 virtual void visitSymbol(TIntermSymbol*) {}
549 virtual void visitConstantUnion(TIntermConstantUnion*) {}
550 virtual bool visitBinary(Visit visit, TIntermBinary*) {return true;}
551 virtual bool visitUnary(Visit visit, TIntermUnary*) {return true;}
552 virtual bool visitSelection(Visit visit, TIntermSelection*) {return true;}
553 virtual bool visitAggregate(Visit visit, TIntermAggregate*) {return true;}
554 virtual bool visitLoop(Visit visit, TIntermLoop*) {return true;}
555 virtual bool visitBranch(Visit visit, TIntermBranch*) {return true;}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000556
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000557 void incrementDepth() {depth++;}
558 void decrementDepth() {depth--;}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000559
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000560 // Return the original name if hash function pointer is NULL;
561 // otherwise return the hashed name.
562 static TString hash(const TString& name, ShHashFunction64 hashFunction);
563
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000564 const bool preVisit;
565 const bool inVisit;
566 const bool postVisit;
567 const bool rightToLeft;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000568
569protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000570 int depth;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000571};
572
573#endif // __INTERMEDIATE_H