2 //Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
3 //Copyright (C) 2012-2013 LunarG, Inc.
7 //Redistribution and use in source and binary forms, with or without
8 //modification, are permitted provided that the following conditions
11 // Redistributions of source code must retain the above copyright
12 // notice, this list of conditions and the following disclaimer.
14 // Redistributions in binary form must reproduce the above
15 // copyright notice, this list of conditions and the following
16 // disclaimer in the documentation and/or other materials provided
17 // with the distribution.
19 // Neither the name of 3Dlabs Inc. Ltd. nor the names of its
20 // contributors may be used to endorse or promote products derived
21 // from this software without specific prior written permission.
23 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 //"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 //LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 //FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27 //COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 //INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29 //BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30 //LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
31 //CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 //LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
33 //ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34 //POSSIBILITY OF SUCH DAMAGE.
38 // Definition of the in-memory high-level intermediate representation
39 // of shaders. This is a tree that parser creates.
41 // Nodes in the tree are defined as a hierarchy of classes derived from
42 // TIntermNode. Each is a node in a tree. There is no preset branching factor;
43 // each node can have it's own type of list of children.
46 #ifndef __INTERMEDIATE_H
47 #define __INTERMEDIATE_H
49 #include "../Include/Common.h"
50 #include "../Include/Types.h"
51 #include "../Include/ConstantUnion.h"
56 // Operators used by the high-level (parse tree) representation.
59 EOpNull, // if in a node, should only mean a node is still being built
60 EOpSequence, // denotes a list of statements, or parameters, etc.
61 EOpLinkerObjects, // for aggregate node of objects the linker may need, if not reference by the rest of the AST
63 EOpFunction, // For function definition
64 EOpParameters, // an aggregate listing the parameters to a function
125 EOpVectorTimesScalar,
126 EOpVectorTimesMatrix,
127 EOpMatrixTimesVector,
128 EOpMatrixTimesScalar,
136 EOpIndexDirectStruct,
143 // Built-in functions mapped to operators
219 EOpDPdx, // Fragment only
220 EOpDPdy, // Fragment only
221 EOpFwidth, // Fragment only
222 EOpDPdxFine, // Fragment only
223 EOpDPdyFine, // Fragment only
224 EOpFwidthFine, // Fragment only
225 EOpDPdxCoarse, // Fragment only
226 EOpDPdyCoarse, // Fragment only
227 EOpFwidthCoarse, // Fragment only
229 EOpInterpolateAtCentroid, // Fragment only
230 EOpInterpolateAtSample, // Fragment only
231 EOpInterpolateAtOffset, // Fragment only
233 EOpMatrixTimesMatrix,
241 EOpEmitVertex, // geometry only
242 EOpEndPrimitive, // geometry only
243 EOpEmitStreamVertex, // geometry only
244 EOpEndStreamPrimitive, // geometry only
248 EOpMemoryBarrierAtomicCounter,
249 EOpMemoryBarrierBuffer,
250 EOpMemoryBarrierImage,
251 EOpMemoryBarrierShared, // compute only
252 EOpGroupMemoryBarrier, // compute only
263 EOpAtomicCounterIncrement,
264 EOpAtomicCounterDecrement,
274 EOpKill, // Fragment only
285 EOpConstructGuardStart,
286 EOpConstructInt, // these first scalar forms also identify what implicit conversion is needed
325 EOpConstructGuardEnd,
335 EOpVectorTimesMatrixAssign,
336 EOpVectorTimesScalarAssign,
337 EOpMatrixTimesScalarAssign,
338 EOpMatrixTimesMatrixAssign,
342 EOpInclusiveOrAssign,
343 EOpExclusiveOrAssign,
351 EOpArrayLength, // "Array" distinguishes from length(v) built-in function, but it applies to vectors and matrices as well.
360 EOpImageQuerySamples,
369 EOpImageAtomicExchange,
370 EOpImageAtomicCompSwap,
377 // Texture operations
380 EOpTextureGuardBegin,
384 EOpTextureQueryLevels,
385 EOpTextureQuerySamples,
391 EOpTextureFetchOffset,
392 EOpTextureProjOffset,
395 EOpTextureProjLodOffset,
397 EOpTextureGradOffset,
399 EOpTextureProjGradOffset,
401 EOpTextureGatherOffset,
402 EOpTextureGatherOffsets,
404 EOpTextureOffsetClamp,
406 EOpTextureGradOffsetClamp,
408 EOpSparseTextureGuardBegin,
412 EOpSparseTextureOffset,
413 EOpSparseTextureFetch,
414 EOpSparseTextureFetchOffset,
415 EOpSparseTextureLodOffset,
416 EOpSparseTextureGrad,
417 EOpSparseTextureGradOffset,
418 EOpSparseTextureGather,
419 EOpSparseTextureGatherOffset,
420 EOpSparseTextureGatherOffsets,
421 EOpSparseTexelsResident,
422 EOpSparseTextureClamp,
423 EOpSparseTextureOffsetClamp,
424 EOpSparseTextureGradClamp,
425 EOpSparseTextureGradOffsetClamp,
427 EOpSparseTextureGuardEnd,
432 // Integer operations
447 class TIntermTraverser;
448 class TIntermOperator;
449 class TIntermAggregate;
452 class TIntermConstantUnion;
453 class TIntermSelection;
460 } // end namespace glslang
463 // Base class for the tree nodes
465 // (Put outside the glslang namespace, as it's used as part of the external interface.)
469 POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator())
471 TIntermNode() { loc.init(); }
472 virtual const glslang::TSourceLoc& getLoc() const { return loc; }
473 virtual void setLoc(const glslang::TSourceLoc& l) { loc = l; }
474 virtual void traverse(glslang::TIntermTraverser*) = 0;
475 virtual glslang::TIntermTyped* getAsTyped() { return 0; }
476 virtual glslang::TIntermOperator* getAsOperator() { return 0; }
477 virtual glslang::TIntermConstantUnion* getAsConstantUnion() { return 0; }
478 virtual glslang::TIntermAggregate* getAsAggregate() { return 0; }
479 virtual glslang::TIntermUnary* getAsUnaryNode() { return 0; }
480 virtual glslang::TIntermBinary* getAsBinaryNode() { return 0; }
481 virtual glslang::TIntermSelection* getAsSelectionNode() { return 0; }
482 virtual glslang::TIntermSwitch* getAsSwitchNode() { return 0; }
483 virtual glslang::TIntermMethod* getAsMethodNode() { return 0; }
484 virtual glslang::TIntermSymbol* getAsSymbolNode() { return 0; }
485 virtual glslang::TIntermBranch* getAsBranchNode() { return 0; }
487 virtual const glslang::TIntermTyped* getAsTyped() const { return 0; }
488 virtual const glslang::TIntermOperator* getAsOperator() const { return 0; }
489 virtual const glslang::TIntermConstantUnion* getAsConstantUnion() const { return 0; }
490 virtual const glslang::TIntermAggregate* getAsAggregate() const { return 0; }
491 virtual const glslang::TIntermUnary* getAsUnaryNode() const { return 0; }
492 virtual const glslang::TIntermBinary* getAsBinaryNode() const { return 0; }
493 virtual const glslang::TIntermSelection* getAsSelectionNode() const { return 0; }
494 virtual const glslang::TIntermSwitch* getAsSwitchNode() const { return 0; }
495 virtual const glslang::TIntermMethod* getAsMethodNode() const { return 0; }
496 virtual const glslang::TIntermSymbol* getAsSymbolNode() const { return 0; }
497 virtual const glslang::TIntermBranch* getAsBranchNode() const { return 0; }
498 virtual ~TIntermNode() { }
500 glslang::TSourceLoc loc;
506 // This is just to help yacc.
508 struct TIntermNodePair {
514 // Intermediate class for nodes that have a type.
516 class TIntermTyped : public TIntermNode {
518 TIntermTyped(const TType& t) { type.shallowCopy(t); }
519 TIntermTyped(TBasicType basicType) { TType bt(basicType); type.shallowCopy(bt); }
520 virtual TIntermTyped* getAsTyped() { return this; }
521 virtual const TIntermTyped* getAsTyped() const { return this; }
522 virtual void setType(const TType& t) { type.shallowCopy(t); }
523 virtual const TType& getType() const { return type; }
524 virtual TType& getWritableType() { return type; }
526 virtual TBasicType getBasicType() const { return type.getBasicType(); }
527 virtual TQualifier& getQualifier() { return type.getQualifier(); }
528 virtual const TQualifier& getQualifier() const { return type.getQualifier(); }
529 virtual void propagatePrecision(TPrecisionQualifier);
530 virtual int getVectorSize() const { return type.getVectorSize(); }
531 virtual int getMatrixCols() const { return type.getMatrixCols(); }
532 virtual int getMatrixRows() const { return type.getMatrixRows(); }
533 virtual bool isMatrix() const { return type.isMatrix(); }
534 virtual bool isArray() const { return type.isArray(); }
535 virtual bool isVector() const { return type.isVector(); }
536 virtual bool isScalar() const { return type.isScalar(); }
537 virtual bool isStruct() const { return type.isStruct(); }
538 TString getCompleteString() const { return type.getCompleteString(); }
545 // Handle for, do-while, and while loops.
547 class TIntermLoop : public TIntermNode {
549 TIntermLoop(TIntermNode* aBody, TIntermTyped* aTest, TIntermTyped* aTerminal, bool testFirst) :
554 virtual void traverse(TIntermTraverser*);
555 TIntermNode* getBody() const { return body; }
556 TIntermTyped* getTest() const { return test; }
557 TIntermTyped* getTerminal() const { return terminal; }
558 bool testFirst() const { return first; }
560 TIntermNode* body; // code to loop over
561 TIntermTyped* test; // exit condition associated with loop, could be 0 for 'for' loops
562 TIntermTyped* terminal; // exists for for-loops
563 bool first; // true for while and for, not for do-while
567 // Handle case, break, continue, return, and kill.
569 class TIntermBranch : public TIntermNode {
571 TIntermBranch(TOperator op, TIntermTyped* e) :
574 virtual TIntermBranch* getAsBranchNode() { return this; }
575 virtual const TIntermBranch* getAsBranchNode() const { return this; }
576 virtual void traverse(TIntermTraverser*);
577 TOperator getFlowOp() const { return flowOp; }
578 TIntermTyped* getExpression() const { return expression; }
581 TIntermTyped* expression;
585 // Represent method names before seeing their calling signature
586 // or resolving them to operations. Just an expression as the base object
587 // and a textural name.
589 class TIntermMethod : public TIntermTyped {
591 TIntermMethod(TIntermTyped* o, const TType& t, const TString& m) : TIntermTyped(t), object(o), method(m) { }
592 virtual TIntermMethod* getAsMethodNode() { return this; }
593 virtual const TIntermMethod* getAsMethodNode() const { return this; }
594 virtual const TString& getMethodName() const { return method; }
595 virtual TIntermTyped* getObject() const { return object; }
596 virtual void traverse(TIntermTraverser*);
598 TIntermTyped* object;
603 // Nodes that correspond to symbols or constants in the source code.
605 class TIntermSymbol : public TIntermTyped {
607 // if symbol is initialized as symbol(sym), the memory comes from the poolallocator of sym. If sym comes from
608 // per process threadPoolAllocator, then it causes increased memory usage per compile
609 // it is essential to use "symbol = sym" to assign to symbol
610 TIntermSymbol(int i, const TString& n, const TType& t) :
611 TIntermTyped(t), id(i) { name = n;}
612 virtual int getId() const { return id; }
613 virtual const TString& getName() const { return name; }
614 virtual void traverse(TIntermTraverser*);
615 virtual TIntermSymbol* getAsSymbolNode() { return this; }
616 virtual const TIntermSymbol* getAsSymbolNode() const { return this; }
617 void setConstArray(const TConstUnionArray& c) { unionArray = c; }
618 const TConstUnionArray& getConstArray() const { return unionArray; }
622 TConstUnionArray unionArray;
625 class TIntermConstantUnion : public TIntermTyped {
627 TIntermConstantUnion(const TConstUnionArray& ua, const TType& t) : TIntermTyped(t), unionArray(ua), literal(false) { }
628 const TConstUnionArray& getConstArray() const { return unionArray; }
629 virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
630 virtual const TIntermConstantUnion* getAsConstantUnion() const { return this; }
631 virtual void traverse(TIntermTraverser*);
632 virtual TIntermTyped* fold(TOperator, const TIntermTyped*) const;
633 virtual TIntermTyped* fold(TOperator, const TType&) const;
634 void setLiteral() { literal = true; }
635 void setExpression() { literal = false; }
636 bool isLiteral() const { return literal; }
638 const TConstUnionArray unionArray;
639 bool literal; // true if node represents a literal in the source code
642 // Represent the independent aspects of a texturing TOperator
643 struct TCrackedTextureOp {
656 // Intermediate class for node types that hold operators.
658 class TIntermOperator : public TIntermTyped {
660 virtual TIntermOperator* getAsOperator() { return this; }
661 virtual const TIntermOperator* getAsOperator() const { return this; }
662 TOperator getOp() const { return op; }
663 virtual bool promote() { return true; }
664 bool modifiesState() const;
665 bool isConstructor() const;
666 bool isTexture() const { return op > EOpTextureGuardBegin && op < EOpTextureGuardEnd; }
667 bool isImage() const { return op > EOpImageGuardBegin && op < EOpImageGuardEnd; }
668 bool isSparseTexture() const { return op > EOpSparseTextureGuardBegin && op < EOpSparseTextureGuardEnd; }
669 bool isSparseImage() const { return op == EOpSparseImageLoad; }
671 // Crack the op into the individual dimensions of texturing operation.
672 void crackTexture(TSampler sampler, TCrackedTextureOp& cracked) const
674 cracked.query = false;
675 cracked.proj = false;
677 cracked.fetch = false;
678 cracked.offset = false;
679 cracked.offsets = false;
680 cracked.gather = false;
681 cracked.grad = false;
682 cracked.lodClamp = false;
685 case EOpImageQuerySize:
686 case EOpImageQuerySamples:
687 case EOpTextureQuerySize:
688 case EOpTextureQueryLod:
689 case EOpTextureQueryLevels:
690 case EOpTextureQuerySamples:
691 case EOpSparseTexelsResident:
692 cracked.query = true;
695 case EOpSparseTexture:
697 case EOpTextureClamp:
698 case EOpSparseTextureClamp:
699 cracked.lodClamp = true;
705 case EOpSparseTextureLod:
708 case EOpTextureOffset:
709 case EOpSparseTextureOffset:
710 cracked.offset = true;
712 case EOpTextureOffsetClamp:
713 case EOpSparseTextureOffsetClamp:
714 cracked.offset = true;
715 cracked.lodClamp = true;
717 case EOpTextureFetch:
718 case EOpSparseTextureFetch:
719 cracked.fetch = true;
720 if (sampler.dim == Esd1D || (sampler.dim == Esd2D && ! sampler.ms) || sampler.dim == Esd3D)
723 case EOpTextureFetchOffset:
724 case EOpSparseTextureFetchOffset:
725 cracked.fetch = true;
726 cracked.offset = true;
727 if (sampler.dim == Esd1D || (sampler.dim == Esd2D && ! sampler.ms) || sampler.dim == Esd3D)
730 case EOpTextureProjOffset:
731 cracked.offset = true;
734 case EOpTextureLodOffset:
735 case EOpSparseTextureLodOffset:
736 cracked.offset = true;
739 case EOpTextureProjLod:
743 case EOpTextureProjLodOffset:
744 cracked.offset = true;
749 case EOpSparseTextureGrad:
752 case EOpTextureGradClamp:
753 case EOpSparseTextureGradClamp:
755 cracked.lodClamp = true;
757 case EOpTextureGradOffset:
758 case EOpSparseTextureGradOffset:
760 cracked.offset = true;
762 case EOpTextureProjGrad:
766 case EOpTextureProjGradOffset:
768 cracked.offset = true;
771 case EOpTextureGradOffsetClamp:
772 case EOpSparseTextureGradOffsetClamp:
774 cracked.offset = true;
775 cracked.lodClamp = true;
777 case EOpTextureGather:
778 case EOpSparseTextureGather:
779 cracked.gather = true;
781 case EOpTextureGatherOffset:
782 case EOpSparseTextureGatherOffset:
783 cracked.gather = true;
784 cracked.offset = true;
786 case EOpTextureGatherOffsets:
787 case EOpSparseTextureGatherOffsets:
788 cracked.gather = true;
789 cracked.offsets = true;
797 TIntermOperator(TOperator o) : TIntermTyped(EbtFloat), op(o) {}
798 TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
803 // Nodes for all the basic binary math operators.
805 class TIntermBinary : public TIntermOperator {
807 TIntermBinary(TOperator o) : TIntermOperator(o) {}
808 virtual void traverse(TIntermTraverser*);
809 virtual void setLeft(TIntermTyped* n) { left = n; }
810 virtual void setRight(TIntermTyped* n) { right = n; }
811 virtual TIntermTyped* getLeft() const { return left; }
812 virtual TIntermTyped* getRight() const { return right; }
813 virtual TIntermBinary* getAsBinaryNode() { return this; }
814 virtual const TIntermBinary* getAsBinaryNode() const { return this; }
815 virtual bool promote();
816 virtual void updatePrecision();
823 // Nodes for unary math operators.
825 class TIntermUnary : public TIntermOperator {
827 TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0) {}
828 TIntermUnary(TOperator o) : TIntermOperator(o), operand(0) {}
829 virtual void traverse(TIntermTraverser*);
830 virtual void setOperand(TIntermTyped* o) { operand = o; }
831 virtual TIntermTyped* getOperand() { return operand; }
832 virtual const TIntermTyped* getOperand() const { return operand; }
833 virtual TIntermUnary* getAsUnaryNode() { return this; }
834 virtual const TIntermUnary* getAsUnaryNode() const { return this; }
835 virtual bool promote();
836 virtual void updatePrecision();
838 TIntermTyped* operand;
841 typedef TVector<TIntermNode*> TIntermSequence;
842 typedef TVector<int> TQualifierList;
844 // Nodes that operate on an arbitrary sized set of children.
846 class TIntermAggregate : public TIntermOperator {
848 TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(0) { }
849 TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(0) { }
850 // Since pragmaTable is allocated with the PoolAllocator, we
851 // only want to destroy it, not free the associated memory.
852 ~TIntermAggregate() { pragmaTable->~TPragmaTable(); }
853 virtual TIntermAggregate* getAsAggregate() { return this; }
854 virtual const TIntermAggregate* getAsAggregate() const { return this; }
855 virtual void setOperator(TOperator o) { op = o; }
856 virtual TIntermSequence& getSequence() { return sequence; }
857 virtual const TIntermSequence& getSequence() const { return sequence; }
858 virtual void setName(const TString& n) { name = n; }
859 virtual const TString& getName() const { return name; }
860 virtual void traverse(TIntermTraverser*);
861 virtual void setUserDefined() { userDefined = true; }
862 virtual bool isUserDefined() { return userDefined; }
863 virtual TQualifierList& getQualifierList() { return qualifier; }
864 virtual const TQualifierList& getQualifierList() const { return qualifier; }
865 void setOptimize(bool o) { optimize = o; }
866 void setDebug(bool d) { debug = d; }
867 bool getOptimize() const { return optimize; }
868 bool getDebug() const { return debug; }
869 void addToPragmaTable(const TPragmaTable& pTable);
870 const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
872 TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
873 TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
874 TIntermSequence sequence;
875 TQualifierList qualifier;
877 bool userDefined; // used for user defined function names
880 TPragmaTable* pragmaTable;
886 class TIntermSelection : public TIntermTyped {
888 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
889 TIntermTyped(EbtVoid), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
890 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
891 TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
892 virtual void traverse(TIntermTraverser*);
893 virtual TIntermTyped* getCondition() const { return condition; }
894 virtual TIntermNode* getTrueBlock() const { return trueBlock; }
895 virtual TIntermNode* getFalseBlock() const { return falseBlock; }
896 virtual TIntermSelection* getAsSelectionNode() { return this; }
897 virtual const TIntermSelection* getAsSelectionNode() const { return this; }
899 TIntermTyped* condition;
900 TIntermNode* trueBlock;
901 TIntermNode* falseBlock;
905 // For switch statements. Designed use is that a switch will have sequence of nodes
906 // that are either case/default nodes or a *single* node that represents all the code
907 // in between (if any) consecutive case/defaults. So, a traversal need only deal with
908 // 0 or 1 nodes per case/default statement.
910 class TIntermSwitch : public TIntermNode {
912 TIntermSwitch(TIntermTyped* cond, TIntermAggregate* b) : condition(cond), body(b) { }
913 virtual void traverse(TIntermTraverser*);
914 virtual TIntermNode* getCondition() const { return condition; }
915 virtual TIntermAggregate* getBody() const { return body; }
916 virtual TIntermSwitch* getAsSwitchNode() { return this; }
917 virtual const TIntermSwitch* getAsSwitchNode() const { return this; }
919 TIntermTyped* condition;
920 TIntermAggregate* body;
931 // For traversing the tree. User should derive from this,
932 // put their traversal specific data in it, and then pass
933 // it to a Traverse method.
935 // When using this, just fill in the methods for nodes you want visited.
936 // Return false from a pre-visit to skip visiting that node's subtree.
938 // Explicitly set postVisit to true if you want post visiting, otherwise,
939 // filled in methods will only be called at pre-visit time (before processing
940 // the subtree). Similary for inVisit for in-order visiting of nodes with
941 // multiple children.
943 // If you only want post-visits, explicitly turn off preVisit (and inVisit)
944 // and turn on postVisit.
946 class TIntermTraverser {
948 POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator())
949 TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
952 postVisit(postVisit),
953 rightToLeft(rightToLeft),
956 virtual ~TIntermTraverser() { }
958 virtual void visitSymbol(TIntermSymbol*) { }
959 virtual void visitConstantUnion(TIntermConstantUnion*) { }
960 virtual bool visitBinary(TVisit, TIntermBinary*) { return true; }
961 virtual bool visitUnary(TVisit, TIntermUnary*) { return true; }
962 virtual bool visitSelection(TVisit, TIntermSelection*) { return true; }
963 virtual bool visitAggregate(TVisit, TIntermAggregate*) { return true; }
964 virtual bool visitLoop(TVisit, TIntermLoop*) { return true; }
965 virtual bool visitBranch(TVisit, TIntermBranch*) { return true; }
966 virtual bool visitSwitch(TVisit, TIntermSwitch*) { return true; }
968 int getMaxDepth() const { return maxDepth; }
970 void incrementDepth(TIntermNode *current)
973 maxDepth = std::max(maxDepth, depth);
974 path.push_back(current);
977 void decrementDepth()
983 TIntermNode *getParentNode()
985 return path.size() == 0 ? NULL : path.back();
990 const bool postVisit;
991 const bool rightToLeft;
994 TIntermTraverser& operator=(TIntermTraverser&);
999 // All the nodes from root to the current node's parent during traversing.
1000 TVector<TIntermNode *> path;
1003 } // end namespace glslang
1005 #endif // __INTERMEDIATE_H