blob: 293db94b04635693a24586af3ea81ea1764ff6bc [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,
186 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
262protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000263 TType type;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000264};
265
266//
267// Handle for, do-while, and while loops.
268//
alokp@chromium.org52813552010-11-16 18:36:09 +0000269enum TLoopType {
270 ELoopFor,
271 ELoopWhile,
272 ELoopDoWhile,
273};
274
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000275class TIntermLoop : public TIntermNode {
276public:
alokp@chromium.org52813552010-11-16 18:36:09 +0000277 TIntermLoop(TLoopType aType,
278 TIntermNode *aInit, TIntermTyped* aCond, TIntermTyped* aExpr,
279 TIntermNode* aBody) :
280 type(aType),
281 init(aInit),
282 cond(aCond),
283 expr(aExpr),
zmo@google.com0b8d4eb2011-04-04 19:17:11 +0000284 body(aBody),
285 unrollFlag(false) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000286
alokp@chromium.orgd88b7732010-05-26 15:13:14 +0000287 virtual TIntermLoop* getAsLoopNode() { return this; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000288 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000289
alokp@chromium.org52813552010-11-16 18:36:09 +0000290 TLoopType getType() const { return type; }
291 TIntermNode* getInit() { return init; }
292 TIntermTyped* getCondition() { return cond; }
293 TIntermTyped* getExpression() { return expr; }
294 TIntermNode* getBody() { return body; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000295
zmo@google.com0b8d4eb2011-04-04 19:17:11 +0000296 void setUnrollFlag(bool flag) { unrollFlag = flag; }
297 bool getUnrollFlag() { return unrollFlag; }
298
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000299protected:
alokp@chromium.org52813552010-11-16 18:36:09 +0000300 TLoopType type;
301 TIntermNode* init; // for-loop initialization
302 TIntermTyped* cond; // loop exit condition
303 TIntermTyped* expr; // for-loop expression
304 TIntermNode* body; // loop body
zmo@google.com0b8d4eb2011-04-04 19:17:11 +0000305
306 bool unrollFlag; // Whether the loop should be unrolled or not.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000307};
308
309//
310// Handle break, continue, return, and kill.
311//
312class TIntermBranch : public TIntermNode {
313public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000314 TIntermBranch(TOperator op, TIntermTyped* e) :
315 flowOp(op),
316 expression(e) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000317
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000318 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000319
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000320 TOperator getFlowOp() { return flowOp; }
321 TIntermTyped* getExpression() { return expression; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000322
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000323protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000324 TOperator flowOp;
325 TIntermTyped* expression; // non-zero except for "return exp;" statements
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000326};
327
328//
329// Nodes that correspond to symbols or constants in the source code.
330//
331class TIntermSymbol : public TIntermTyped {
332public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000333 // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. If sym comes from
334 // per process globalpoolallocator, then it causes increased memory usage per compile
335 // it is essential to use "symbol = sym" to assign to symbol
336 TIntermSymbol(int i, const TString& sym, const TType& t) :
zmo@google.comfd747b82011-04-23 01:30:07 +0000337 TIntermTyped(t), id(i) { symbol = sym; originalSymbol = sym; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000338
339 int getId() const { return id; }
340 const TString& getSymbol() const { return symbol; }
341
zmo@google.comfd747b82011-04-23 01:30:07 +0000342 void setId(int newId) { id = newId; }
343 void setSymbol(const TString& sym) { symbol = sym; }
344
345 const TString& getOriginalSymbol() const { return originalSymbol; }
346
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000347 virtual void traverse(TIntermTraverser*);
348 virtual TIntermSymbol* getAsSymbolNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000349
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000350protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000351 int id;
352 TString symbol;
zmo@google.comfd747b82011-04-23 01:30:07 +0000353 TString originalSymbol;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000354};
355
356class TIntermConstantUnion : public TIntermTyped {
357public:
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000358 TIntermConstantUnion(ConstantUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000359
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000360 ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; }
361 void setUnionArrayPointer(ConstantUnion *c) { unionArrayPointer = c; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000362
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000363 virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000364 virtual void traverse(TIntermTraverser*);
365
366 TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
367
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000368protected:
alokp@chromium.org6ff56fd2010-05-05 16:37:50 +0000369 ConstantUnion *unionArrayPointer;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000370};
371
372//
373// Intermediate class for node types that hold operators.
374//
375class TIntermOperator : public TIntermTyped {
376public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000377 TOperator getOp() const { return op; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000378 void setOp(TOperator o) { op = o; }
379
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000380 bool modifiesState() const;
381 bool isConstructor() const;
alokp@chromium.org58e54292010-08-24 21:40:03 +0000382
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000383protected:
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000384 TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat, EbpUndefined)), op(o) {}
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000385 TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
386 TOperator op;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000387};
388
389//
390// Nodes for all the basic binary math operators.
391//
392class TIntermBinary : public TIntermOperator {
393public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000394 TIntermBinary(TOperator o) : TIntermOperator(o) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000395
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000396 virtual TIntermBinary* getAsBinaryNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000397 virtual void traverse(TIntermTraverser*);
398
399 void setLeft(TIntermTyped* n) { left = n; }
400 void setRight(TIntermTyped* n) { right = n; }
401 TIntermTyped* getLeft() const { return left; }
402 TIntermTyped* getRight() const { return right; }
403 bool promote(TInfoSink&);
404
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000405protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000406 TIntermTyped* left;
407 TIntermTyped* right;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000408};
409
410//
411// Nodes for unary math operators.
412//
413class TIntermUnary : public TIntermOperator {
414public:
zmo@google.com32e97312011-08-24 01:03:11 +0000415 TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0), useEmulatedFunction(false) {}
zmo@google.come4eb9912011-08-29 21:13:12 +0000416 TIntermUnary(TOperator o) : TIntermOperator(o), operand(0), useEmulatedFunction(false) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000417
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000418 virtual void traverse(TIntermTraverser*);
daniel@transgaming.com4a35ef22010-04-08 03:51:06 +0000419 virtual TIntermUnary* getAsUnaryNode() { return this; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000420
421 void setOperand(TIntermTyped* o) { operand = o; }
422 TIntermTyped* getOperand() { return operand; }
423 bool promote(TInfoSink&);
424
zmo@google.com32e97312011-08-24 01:03:11 +0000425 void setUseEmulatedFunction() { useEmulatedFunction = true; }
426 bool getUseEmulatedFunction() { return useEmulatedFunction; }
427
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000428protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000429 TIntermTyped* operand;
zmo@google.comf420c422011-09-12 18:27:59 +0000430
431 // If set to true, replace the built-in function call with an emulated one
432 // to work around driver bugs.
433 bool useEmulatedFunction;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000434};
435
436typedef TVector<TIntermNode*> TIntermSequence;
437typedef TVector<int> TQualifierList;
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000438
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000439//
440// Nodes that operate on an arbitrary sized set of children.
441//
442class TIntermAggregate : public TIntermOperator {
443public:
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000444 TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), endLine(0), useEmulatedFunction(false) { }
445 TIntermAggregate(TOperator o) : TIntermOperator(o), useEmulatedFunction(false) { }
446 ~TIntermAggregate() { }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000447
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000448 virtual TIntermAggregate* getAsAggregate() { return this; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000449 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000450
451 TIntermSequence& getSequence() { return sequence; }
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000452
alokp@chromium.org58e54292010-08-24 21:40:03 +0000453 void setName(const TString& n) { name = n; }
454 const TString& getName() const { return name; }
455
456 void setUserDefined() { userDefined = true; }
maxvujovic@gmail.com66ebd012012-05-30 22:18:11 +0000457 bool isUserDefined() const { return userDefined; }
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000458
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000459 void setOptimize(bool o) { optimize = o; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000460 bool getOptimize() { return optimize; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000461 void setDebug(bool d) { debug = d; }
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000462 bool getDebug() { return debug; }
alokp@chromium.org8b851c62012-06-15 16:25:11 +0000463
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000464 void setEndLine(TSourceLoc line) { endLine = line; }
465 TSourceLoc getEndLine() const { return endLine; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000466
zmo@google.comf420c422011-09-12 18:27:59 +0000467 void setUseEmulatedFunction() { useEmulatedFunction = true; }
468 bool getUseEmulatedFunction() { return useEmulatedFunction; }
469
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000470protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000471 TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
472 TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
473 TIntermSequence sequence;
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000474 TString name;
475 bool userDefined; // used for user defined function names
alokp@chromium.orgb19403a2010-09-08 17:56:26 +0000476
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000477 bool optimize;
478 bool debug;
apatrick@chromium.org0f4cefe2011-01-26 19:30:57 +0000479 TSourceLoc endLine;
zmo@google.comf420c422011-09-12 18:27:59 +0000480
481 // If set to true, replace the built-in function call with an emulated one
482 // to work around driver bugs.
483 bool useEmulatedFunction;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000484};
485
486//
487// For if tests. Simplified since there is no switch statement.
488//
489class TIntermSelection : public TIntermTyped {
490public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000491 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000492 TIntermTyped(TType(EbtVoid, EbpUndefined)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000493 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
494 TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
alokp@chromium.org58e54292010-08-24 21:40:03 +0000495
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000496 virtual void traverse(TIntermTraverser*);
alokp@chromium.org58e54292010-08-24 21:40:03 +0000497
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000498 bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
alokp@chromium.org58e54292010-08-24 21:40:03 +0000499 TIntermNode* getCondition() const { return condition; }
500 TIntermNode* getTrueBlock() const { return trueBlock; }
501 TIntermNode* getFalseBlock() const { return falseBlock; }
502 TIntermSelection* getAsSelectionNode() { return this; }
503
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000504protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000505 TIntermTyped* condition;
506 TIntermNode* trueBlock;
507 TIntermNode* falseBlock;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000508};
509
510enum Visit
511{
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000512 PreVisit,
513 InVisit,
514 PostVisit
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000515};
516
517//
518// For traversing the tree. User should derive from this,
519// put their traversal specific data in it, and then pass
520// it to a Traverse method.
521//
522// When using this, just fill in the methods for nodes you want visited.
523// Return false from a pre-visit to skip visiting that node's subtree.
524//
525class TIntermTraverser
526{
527public:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000528 POOL_ALLOCATOR_NEW_DELETE(GlobalPoolAllocator)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000529
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000530 TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
531 preVisit(preVisit),
532 inVisit(inVisit),
533 postVisit(postVisit),
534 rightToLeft(rightToLeft),
535 depth(0) {}
maxvujovic@gmail.comc6b3b3c2012-06-27 22:49:39 +0000536 virtual ~TIntermTraverser() {};
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000537
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000538 virtual void visitSymbol(TIntermSymbol*) {}
539 virtual void visitConstantUnion(TIntermConstantUnion*) {}
540 virtual bool visitBinary(Visit visit, TIntermBinary*) {return true;}
541 virtual bool visitUnary(Visit visit, TIntermUnary*) {return true;}
542 virtual bool visitSelection(Visit visit, TIntermSelection*) {return true;}
543 virtual bool visitAggregate(Visit visit, TIntermAggregate*) {return true;}
544 virtual bool visitLoop(Visit visit, TIntermLoop*) {return true;}
545 virtual bool visitBranch(Visit visit, TIntermBranch*) {return true;}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000546
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000547 void incrementDepth() {depth++;}
548 void decrementDepth() {depth--;}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000549
daniel@transgaming.com0aa3b5a2012-11-28 19:43:24 +0000550 // Return the original name if hash function pointer is NULL;
551 // otherwise return the hashed name.
552 static TString hash(const TString& name, ShHashFunction64 hashFunction);
553
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000554 const bool preVisit;
555 const bool inVisit;
556 const bool postVisit;
557 const bool rightToLeft;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000558
559protected:
alokp@chromium.org2cf17712010-03-30 20:33:18 +0000560 int depth;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000561};
562
563#endif // __INTERMEDIATE_H