gfx/angle/src/compiler/intermediate.h

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

michael@0 1 //
michael@0 2 // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
michael@0 3 // Use of this source code is governed by a BSD-style license that can be
michael@0 4 // found in the LICENSE file.
michael@0 5 //
michael@0 6
michael@0 7 //
michael@0 8 // Definition of the in-memory high-level intermediate representation
michael@0 9 // of shaders. This is a tree that parser creates.
michael@0 10 //
michael@0 11 // Nodes in the tree are defined as a hierarchy of classes derived from
michael@0 12 // TIntermNode. Each is a node in a tree. There is no preset branching factor;
michael@0 13 // each node can have it's own type of list of children.
michael@0 14 //
michael@0 15
michael@0 16 #ifndef __INTERMEDIATE_H
michael@0 17 #define __INTERMEDIATE_H
michael@0 18
michael@0 19 #include "GLSLANG/ShaderLang.h"
michael@0 20
michael@0 21 #include <algorithm>
michael@0 22 #include "compiler/Common.h"
michael@0 23 #include "compiler/Types.h"
michael@0 24 #include "compiler/ConstantUnion.h"
michael@0 25
michael@0 26 //
michael@0 27 // Operators used by the high-level (parse tree) representation.
michael@0 28 //
michael@0 29 enum TOperator {
michael@0 30 EOpNull, // if in a node, should only mean a node is still being built
michael@0 31 EOpSequence, // denotes a list of statements, or parameters, etc.
michael@0 32 EOpFunctionCall,
michael@0 33 EOpFunction, // For function definition
michael@0 34 EOpParameters, // an aggregate listing the parameters to a function
michael@0 35
michael@0 36 EOpDeclaration,
michael@0 37 EOpPrototype,
michael@0 38
michael@0 39 //
michael@0 40 // Unary operators
michael@0 41 //
michael@0 42
michael@0 43 EOpNegative,
michael@0 44 EOpLogicalNot,
michael@0 45 EOpVectorLogicalNot,
michael@0 46
michael@0 47 EOpPostIncrement,
michael@0 48 EOpPostDecrement,
michael@0 49 EOpPreIncrement,
michael@0 50 EOpPreDecrement,
michael@0 51
michael@0 52 EOpConvIntToBool,
michael@0 53 EOpConvFloatToBool,
michael@0 54 EOpConvBoolToFloat,
michael@0 55 EOpConvIntToFloat,
michael@0 56 EOpConvFloatToInt,
michael@0 57 EOpConvBoolToInt,
michael@0 58
michael@0 59 //
michael@0 60 // binary operations
michael@0 61 //
michael@0 62
michael@0 63 EOpAdd,
michael@0 64 EOpSub,
michael@0 65 EOpMul,
michael@0 66 EOpDiv,
michael@0 67 EOpEqual,
michael@0 68 EOpNotEqual,
michael@0 69 EOpVectorEqual,
michael@0 70 EOpVectorNotEqual,
michael@0 71 EOpLessThan,
michael@0 72 EOpGreaterThan,
michael@0 73 EOpLessThanEqual,
michael@0 74 EOpGreaterThanEqual,
michael@0 75 EOpComma,
michael@0 76
michael@0 77 EOpVectorTimesScalar,
michael@0 78 EOpVectorTimesMatrix,
michael@0 79 EOpMatrixTimesVector,
michael@0 80 EOpMatrixTimesScalar,
michael@0 81
michael@0 82 EOpLogicalOr,
michael@0 83 EOpLogicalXor,
michael@0 84 EOpLogicalAnd,
michael@0 85
michael@0 86 EOpIndexDirect,
michael@0 87 EOpIndexIndirect,
michael@0 88 EOpIndexDirectStruct,
michael@0 89
michael@0 90 EOpVectorSwizzle,
michael@0 91
michael@0 92 //
michael@0 93 // Built-in functions potentially mapped to operators
michael@0 94 //
michael@0 95
michael@0 96 EOpRadians,
michael@0 97 EOpDegrees,
michael@0 98 EOpSin,
michael@0 99 EOpCos,
michael@0 100 EOpTan,
michael@0 101 EOpAsin,
michael@0 102 EOpAcos,
michael@0 103 EOpAtan,
michael@0 104
michael@0 105 EOpPow,
michael@0 106 EOpExp,
michael@0 107 EOpLog,
michael@0 108 EOpExp2,
michael@0 109 EOpLog2,
michael@0 110 EOpSqrt,
michael@0 111 EOpInverseSqrt,
michael@0 112
michael@0 113 EOpAbs,
michael@0 114 EOpSign,
michael@0 115 EOpFloor,
michael@0 116 EOpCeil,
michael@0 117 EOpFract,
michael@0 118 EOpMod,
michael@0 119 EOpMin,
michael@0 120 EOpMax,
michael@0 121 EOpClamp,
michael@0 122 EOpMix,
michael@0 123 EOpStep,
michael@0 124 EOpSmoothStep,
michael@0 125
michael@0 126 EOpLength,
michael@0 127 EOpDistance,
michael@0 128 EOpDot,
michael@0 129 EOpCross,
michael@0 130 EOpNormalize,
michael@0 131 EOpFaceForward,
michael@0 132 EOpReflect,
michael@0 133 EOpRefract,
michael@0 134
michael@0 135 EOpDFdx, // Fragment only, OES_standard_derivatives extension
michael@0 136 EOpDFdy, // Fragment only, OES_standard_derivatives extension
michael@0 137 EOpFwidth, // Fragment only, OES_standard_derivatives extension
michael@0 138
michael@0 139 EOpMatrixTimesMatrix,
michael@0 140
michael@0 141 EOpAny,
michael@0 142 EOpAll,
michael@0 143
michael@0 144 //
michael@0 145 // Branch
michael@0 146 //
michael@0 147
michael@0 148 EOpKill, // Fragment only
michael@0 149 EOpReturn,
michael@0 150 EOpBreak,
michael@0 151 EOpContinue,
michael@0 152
michael@0 153 //
michael@0 154 // Constructors
michael@0 155 //
michael@0 156
michael@0 157 EOpConstructInt,
michael@0 158 EOpConstructBool,
michael@0 159 EOpConstructFloat,
michael@0 160 EOpConstructVec2,
michael@0 161 EOpConstructVec3,
michael@0 162 EOpConstructVec4,
michael@0 163 EOpConstructBVec2,
michael@0 164 EOpConstructBVec3,
michael@0 165 EOpConstructBVec4,
michael@0 166 EOpConstructIVec2,
michael@0 167 EOpConstructIVec3,
michael@0 168 EOpConstructIVec4,
michael@0 169 EOpConstructMat2,
michael@0 170 EOpConstructMat3,
michael@0 171 EOpConstructMat4,
michael@0 172 EOpConstructStruct,
michael@0 173
michael@0 174 //
michael@0 175 // moves
michael@0 176 //
michael@0 177
michael@0 178 EOpAssign,
michael@0 179 EOpInitialize,
michael@0 180 EOpAddAssign,
michael@0 181 EOpSubAssign,
michael@0 182 EOpMulAssign,
michael@0 183 EOpVectorTimesMatrixAssign,
michael@0 184 EOpVectorTimesScalarAssign,
michael@0 185 EOpMatrixTimesScalarAssign,
michael@0 186 EOpMatrixTimesMatrixAssign,
michael@0 187 EOpDivAssign
michael@0 188 };
michael@0 189
michael@0 190 extern const char* getOperatorString(TOperator op);
michael@0 191
michael@0 192 class TIntermTraverser;
michael@0 193 class TIntermAggregate;
michael@0 194 class TIntermBinary;
michael@0 195 class TIntermUnary;
michael@0 196 class TIntermConstantUnion;
michael@0 197 class TIntermSelection;
michael@0 198 class TIntermTyped;
michael@0 199 class TIntermSymbol;
michael@0 200 class TIntermLoop;
michael@0 201 class TInfoSink;
michael@0 202
michael@0 203 //
michael@0 204 // Base class for the tree nodes
michael@0 205 //
michael@0 206 class TIntermNode {
michael@0 207 public:
michael@0 208 POOL_ALLOCATOR_NEW_DELETE();
michael@0 209 TIntermNode() {
michael@0 210 // TODO: Move this to TSourceLoc constructor
michael@0 211 // after getting rid of TPublicType.
michael@0 212 line.first_file = line.last_file = 0;
michael@0 213 line.first_line = line.last_line = 0;
michael@0 214 }
michael@0 215 virtual ~TIntermNode() { }
michael@0 216
michael@0 217 const TSourceLoc& getLine() const { return line; }
michael@0 218 void setLine(const TSourceLoc& l) { line = l; }
michael@0 219
michael@0 220 virtual void traverse(TIntermTraverser*) = 0;
michael@0 221 virtual TIntermTyped* getAsTyped() { return 0; }
michael@0 222 virtual TIntermConstantUnion* getAsConstantUnion() { return 0; }
michael@0 223 virtual TIntermAggregate* getAsAggregate() { return 0; }
michael@0 224 virtual TIntermBinary* getAsBinaryNode() { return 0; }
michael@0 225 virtual TIntermUnary* getAsUnaryNode() { return 0; }
michael@0 226 virtual TIntermSelection* getAsSelectionNode() { return 0; }
michael@0 227 virtual TIntermSymbol* getAsSymbolNode() { return 0; }
michael@0 228 virtual TIntermLoop* getAsLoopNode() { return 0; }
michael@0 229
michael@0 230 protected:
michael@0 231 TSourceLoc line;
michael@0 232 };
michael@0 233
michael@0 234 //
michael@0 235 // This is just to help yacc.
michael@0 236 //
michael@0 237 struct TIntermNodePair {
michael@0 238 TIntermNode* node1;
michael@0 239 TIntermNode* node2;
michael@0 240 };
michael@0 241
michael@0 242 //
michael@0 243 // Intermediate class for nodes that have a type.
michael@0 244 //
michael@0 245 class TIntermTyped : public TIntermNode {
michael@0 246 public:
michael@0 247 TIntermTyped(const TType& t) : type(t) { }
michael@0 248 virtual TIntermTyped* getAsTyped() { return this; }
michael@0 249
michael@0 250 void setType(const TType& t) { type = t; }
michael@0 251 const TType& getType() const { return type; }
michael@0 252 TType* getTypePointer() { return &type; }
michael@0 253
michael@0 254 TBasicType getBasicType() const { return type.getBasicType(); }
michael@0 255 TQualifier getQualifier() const { return type.getQualifier(); }
michael@0 256 TPrecision getPrecision() const { return type.getPrecision(); }
michael@0 257 int getNominalSize() const { return type.getNominalSize(); }
michael@0 258
michael@0 259 bool isMatrix() const { return type.isMatrix(); }
michael@0 260 bool isArray() const { return type.isArray(); }
michael@0 261 bool isVector() const { return type.isVector(); }
michael@0 262 bool isScalar() const { return type.isScalar(); }
michael@0 263 const char* getBasicString() const { return type.getBasicString(); }
michael@0 264 const char* getQualifierString() const { return type.getQualifierString(); }
michael@0 265 TString getCompleteString() const { return type.getCompleteString(); }
michael@0 266
michael@0 267 int totalRegisterCount() const { return type.totalRegisterCount(); }
michael@0 268 int elementRegisterCount() const { return type.elementRegisterCount(); }
michael@0 269 int getArraySize() const { return type.getArraySize(); }
michael@0 270
michael@0 271 protected:
michael@0 272 TType type;
michael@0 273 };
michael@0 274
michael@0 275 //
michael@0 276 // Handle for, do-while, and while loops.
michael@0 277 //
michael@0 278 enum TLoopType {
michael@0 279 ELoopFor,
michael@0 280 ELoopWhile,
michael@0 281 ELoopDoWhile
michael@0 282 };
michael@0 283
michael@0 284 class TIntermLoop : public TIntermNode {
michael@0 285 public:
michael@0 286 TIntermLoop(TLoopType aType,
michael@0 287 TIntermNode *aInit, TIntermTyped* aCond, TIntermTyped* aExpr,
michael@0 288 TIntermNode* aBody) :
michael@0 289 type(aType),
michael@0 290 init(aInit),
michael@0 291 cond(aCond),
michael@0 292 expr(aExpr),
michael@0 293 body(aBody),
michael@0 294 unrollFlag(false) { }
michael@0 295
michael@0 296 virtual TIntermLoop* getAsLoopNode() { return this; }
michael@0 297 virtual void traverse(TIntermTraverser*);
michael@0 298
michael@0 299 TLoopType getType() const { return type; }
michael@0 300 TIntermNode* getInit() { return init; }
michael@0 301 TIntermTyped* getCondition() { return cond; }
michael@0 302 TIntermTyped* getExpression() { return expr; }
michael@0 303 TIntermNode* getBody() { return body; }
michael@0 304
michael@0 305 void setUnrollFlag(bool flag) { unrollFlag = flag; }
michael@0 306 bool getUnrollFlag() { return unrollFlag; }
michael@0 307
michael@0 308 protected:
michael@0 309 TLoopType type;
michael@0 310 TIntermNode* init; // for-loop initialization
michael@0 311 TIntermTyped* cond; // loop exit condition
michael@0 312 TIntermTyped* expr; // for-loop expression
michael@0 313 TIntermNode* body; // loop body
michael@0 314
michael@0 315 bool unrollFlag; // Whether the loop should be unrolled or not.
michael@0 316 };
michael@0 317
michael@0 318 //
michael@0 319 // Handle break, continue, return, and kill.
michael@0 320 //
michael@0 321 class TIntermBranch : public TIntermNode {
michael@0 322 public:
michael@0 323 TIntermBranch(TOperator op, TIntermTyped* e) :
michael@0 324 flowOp(op),
michael@0 325 expression(e) { }
michael@0 326
michael@0 327 virtual void traverse(TIntermTraverser*);
michael@0 328
michael@0 329 TOperator getFlowOp() { return flowOp; }
michael@0 330 TIntermTyped* getExpression() { return expression; }
michael@0 331
michael@0 332 protected:
michael@0 333 TOperator flowOp;
michael@0 334 TIntermTyped* expression; // non-zero except for "return exp;" statements
michael@0 335 };
michael@0 336
michael@0 337 //
michael@0 338 // Nodes that correspond to symbols or constants in the source code.
michael@0 339 //
michael@0 340 class TIntermSymbol : public TIntermTyped {
michael@0 341 public:
michael@0 342 // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. If sym comes from
michael@0 343 // per process globalpoolallocator, then it causes increased memory usage per compile
michael@0 344 // it is essential to use "symbol = sym" to assign to symbol
michael@0 345 TIntermSymbol(int i, const TString& sym, const TType& t) :
michael@0 346 TIntermTyped(t), id(i) { symbol = sym; originalSymbol = sym; }
michael@0 347
michael@0 348 int getId() const { return id; }
michael@0 349 const TString& getSymbol() const { return symbol; }
michael@0 350
michael@0 351 void setId(int newId) { id = newId; }
michael@0 352 void setSymbol(const TString& sym) { symbol = sym; }
michael@0 353
michael@0 354 const TString& getOriginalSymbol() const { return originalSymbol; }
michael@0 355
michael@0 356 virtual void traverse(TIntermTraverser*);
michael@0 357 virtual TIntermSymbol* getAsSymbolNode() { return this; }
michael@0 358
michael@0 359 protected:
michael@0 360 int id;
michael@0 361 TString symbol;
michael@0 362 TString originalSymbol;
michael@0 363 };
michael@0 364
michael@0 365 class TIntermConstantUnion : public TIntermTyped {
michael@0 366 public:
michael@0 367 TIntermConstantUnion(ConstantUnion *unionPointer, const TType& t) : TIntermTyped(t), unionArrayPointer(unionPointer) { }
michael@0 368
michael@0 369 ConstantUnion* getUnionArrayPointer() const { return unionArrayPointer; }
michael@0 370
michael@0 371 int getIConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getIConst() : 0; }
michael@0 372 float getFConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getFConst() : 0.0f; }
michael@0 373 bool getBConst(int index) const { return unionArrayPointer ? unionArrayPointer[index].getBConst() : false; }
michael@0 374
michael@0 375 virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
michael@0 376 virtual void traverse(TIntermTraverser*);
michael@0 377
michael@0 378 TIntermTyped* fold(TOperator, TIntermTyped*, TInfoSink&);
michael@0 379
michael@0 380 protected:
michael@0 381 ConstantUnion *unionArrayPointer;
michael@0 382 };
michael@0 383
michael@0 384 //
michael@0 385 // Intermediate class for node types that hold operators.
michael@0 386 //
michael@0 387 class TIntermOperator : public TIntermTyped {
michael@0 388 public:
michael@0 389 TOperator getOp() const { return op; }
michael@0 390 void setOp(TOperator o) { op = o; }
michael@0 391
michael@0 392 bool modifiesState() const;
michael@0 393 bool isConstructor() const;
michael@0 394
michael@0 395 protected:
michael@0 396 TIntermOperator(TOperator o) : TIntermTyped(TType(EbtFloat, EbpUndefined)), op(o) {}
michael@0 397 TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
michael@0 398 TOperator op;
michael@0 399 };
michael@0 400
michael@0 401 //
michael@0 402 // Nodes for all the basic binary math operators.
michael@0 403 //
michael@0 404 class TIntermBinary : public TIntermOperator {
michael@0 405 public:
michael@0 406 TIntermBinary(TOperator o) : TIntermOperator(o), addIndexClamp(false) {}
michael@0 407
michael@0 408 virtual TIntermBinary* getAsBinaryNode() { return this; }
michael@0 409 virtual void traverse(TIntermTraverser*);
michael@0 410
michael@0 411 void setLeft(TIntermTyped* n) { left = n; }
michael@0 412 void setRight(TIntermTyped* n) { right = n; }
michael@0 413 TIntermTyped* getLeft() const { return left; }
michael@0 414 TIntermTyped* getRight() const { return right; }
michael@0 415 bool promote(TInfoSink&);
michael@0 416
michael@0 417 void setAddIndexClamp() { addIndexClamp = true; }
michael@0 418 bool getAddIndexClamp() { return addIndexClamp; }
michael@0 419
michael@0 420 protected:
michael@0 421 TIntermTyped* left;
michael@0 422 TIntermTyped* right;
michael@0 423
michael@0 424 // If set to true, wrap any EOpIndexIndirect with a clamp to bounds.
michael@0 425 bool addIndexClamp;
michael@0 426 };
michael@0 427
michael@0 428 //
michael@0 429 // Nodes for unary math operators.
michael@0 430 //
michael@0 431 class TIntermUnary : public TIntermOperator {
michael@0 432 public:
michael@0 433 TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0), useEmulatedFunction(false) {}
michael@0 434 TIntermUnary(TOperator o) : TIntermOperator(o), operand(0), useEmulatedFunction(false) {}
michael@0 435
michael@0 436 virtual void traverse(TIntermTraverser*);
michael@0 437 virtual TIntermUnary* getAsUnaryNode() { return this; }
michael@0 438
michael@0 439 void setOperand(TIntermTyped* o) { operand = o; }
michael@0 440 TIntermTyped* getOperand() { return operand; }
michael@0 441 bool promote(TInfoSink&);
michael@0 442
michael@0 443 void setUseEmulatedFunction() { useEmulatedFunction = true; }
michael@0 444 bool getUseEmulatedFunction() { return useEmulatedFunction; }
michael@0 445
michael@0 446 protected:
michael@0 447 TIntermTyped* operand;
michael@0 448
michael@0 449 // If set to true, replace the built-in function call with an emulated one
michael@0 450 // to work around driver bugs.
michael@0 451 bool useEmulatedFunction;
michael@0 452 };
michael@0 453
michael@0 454 typedef TVector<TIntermNode*> TIntermSequence;
michael@0 455 typedef TVector<int> TQualifierList;
michael@0 456
michael@0 457 //
michael@0 458 // Nodes that operate on an arbitrary sized set of children.
michael@0 459 //
michael@0 460 class TIntermAggregate : public TIntermOperator {
michael@0 461 public:
michael@0 462 TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), useEmulatedFunction(false) { }
michael@0 463 TIntermAggregate(TOperator o) : TIntermOperator(o), useEmulatedFunction(false) { }
michael@0 464 ~TIntermAggregate() { }
michael@0 465
michael@0 466 virtual TIntermAggregate* getAsAggregate() { return this; }
michael@0 467 virtual void traverse(TIntermTraverser*);
michael@0 468
michael@0 469 TIntermSequence& getSequence() { return sequence; }
michael@0 470
michael@0 471 void setName(const TString& n) { name = n; }
michael@0 472 const TString& getName() const { return name; }
michael@0 473
michael@0 474 void setUserDefined() { userDefined = true; }
michael@0 475 bool isUserDefined() const { return userDefined; }
michael@0 476
michael@0 477 void setOptimize(bool o) { optimize = o; }
michael@0 478 bool getOptimize() { return optimize; }
michael@0 479 void setDebug(bool d) { debug = d; }
michael@0 480 bool getDebug() { return debug; }
michael@0 481
michael@0 482 void setUseEmulatedFunction() { useEmulatedFunction = true; }
michael@0 483 bool getUseEmulatedFunction() { return useEmulatedFunction; }
michael@0 484
michael@0 485 protected:
michael@0 486 TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
michael@0 487 TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
michael@0 488 TIntermSequence sequence;
michael@0 489 TString name;
michael@0 490 bool userDefined; // used for user defined function names
michael@0 491
michael@0 492 bool optimize;
michael@0 493 bool debug;
michael@0 494
michael@0 495 // If set to true, replace the built-in function call with an emulated one
michael@0 496 // to work around driver bugs.
michael@0 497 bool useEmulatedFunction;
michael@0 498 };
michael@0 499
michael@0 500 //
michael@0 501 // For if tests. Simplified since there is no switch statement.
michael@0 502 //
michael@0 503 class TIntermSelection : public TIntermTyped {
michael@0 504 public:
michael@0 505 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
michael@0 506 TIntermTyped(TType(EbtVoid, EbpUndefined)), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
michael@0 507 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
michael@0 508 TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
michael@0 509
michael@0 510 virtual void traverse(TIntermTraverser*);
michael@0 511
michael@0 512 bool usesTernaryOperator() const { return getBasicType() != EbtVoid; }
michael@0 513 TIntermNode* getCondition() const { return condition; }
michael@0 514 TIntermNode* getTrueBlock() const { return trueBlock; }
michael@0 515 TIntermNode* getFalseBlock() const { return falseBlock; }
michael@0 516 TIntermSelection* getAsSelectionNode() { return this; }
michael@0 517
michael@0 518 protected:
michael@0 519 TIntermTyped* condition;
michael@0 520 TIntermNode* trueBlock;
michael@0 521 TIntermNode* falseBlock;
michael@0 522 };
michael@0 523
michael@0 524 enum Visit
michael@0 525 {
michael@0 526 PreVisit,
michael@0 527 InVisit,
michael@0 528 PostVisit
michael@0 529 };
michael@0 530
michael@0 531 //
michael@0 532 // For traversing the tree. User should derive from this,
michael@0 533 // put their traversal specific data in it, and then pass
michael@0 534 // it to a Traverse method.
michael@0 535 //
michael@0 536 // When using this, just fill in the methods for nodes you want visited.
michael@0 537 // Return false from a pre-visit to skip visiting that node's subtree.
michael@0 538 //
michael@0 539 class TIntermTraverser
michael@0 540 {
michael@0 541 public:
michael@0 542 POOL_ALLOCATOR_NEW_DELETE();
michael@0 543 TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
michael@0 544 preVisit(preVisit),
michael@0 545 inVisit(inVisit),
michael@0 546 postVisit(postVisit),
michael@0 547 rightToLeft(rightToLeft),
michael@0 548 depth(0),
michael@0 549 maxDepth(0) {}
michael@0 550 virtual ~TIntermTraverser() {};
michael@0 551
michael@0 552 virtual void visitSymbol(TIntermSymbol*) {}
michael@0 553 virtual void visitConstantUnion(TIntermConstantUnion*) {}
michael@0 554 virtual bool visitBinary(Visit visit, TIntermBinary*) {return true;}
michael@0 555 virtual bool visitUnary(Visit visit, TIntermUnary*) {return true;}
michael@0 556 virtual bool visitSelection(Visit visit, TIntermSelection*) {return true;}
michael@0 557 virtual bool visitAggregate(Visit visit, TIntermAggregate*) {return true;}
michael@0 558 virtual bool visitLoop(Visit visit, TIntermLoop*) {return true;}
michael@0 559 virtual bool visitBranch(Visit visit, TIntermBranch*) {return true;}
michael@0 560
michael@0 561 int getMaxDepth() const {return maxDepth;}
michael@0 562 void incrementDepth() {depth++; maxDepth = std::max(maxDepth, depth); }
michael@0 563 void decrementDepth() {depth--;}
michael@0 564
michael@0 565 // Return the original name if hash function pointer is NULL;
michael@0 566 // otherwise return the hashed name.
michael@0 567 static TString hash(const TString& name, ShHashFunction64 hashFunction);
michael@0 568
michael@0 569 const bool preVisit;
michael@0 570 const bool inVisit;
michael@0 571 const bool postVisit;
michael@0 572 const bool rightToLeft;
michael@0 573
michael@0 574 protected:
michael@0 575 int depth;
michael@0 576 int maxDepth;
michael@0 577 };
michael@0 578
michael@0 579 #endif // __INTERMEDIATE_H

mercurial