2 //Copyright (C) 2002-2005 3Dlabs Inc. Ltd.
3 //Copyright (C) 2012-2016 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
106 EOpConvFloatToDouble,
108 EOpConvInt64ToDouble,
109 EOpConvUint64ToDouble,
114 EOpConvDoubleToInt64,
115 EOpConvUint64ToInt64,
119 EOpConvFloatToUint64,
120 EOpConvDoubleToUint64,
121 EOpConvInt64ToUint64,
147 EOpVectorTimesScalar,
148 EOpVectorTimesMatrix,
149 EOpMatrixTimesVector,
150 EOpMatrixTimesScalar,
158 EOpIndexDirectStruct,
165 // Built-in functions mapped to operators
219 EOpDoubleBitsToInt64,
220 EOpDoubleBitsToUint64,
221 EOpInt64BitsToDouble,
222 EOpUint64BitsToDouble,
249 EOpDPdx, // Fragment only
250 EOpDPdy, // Fragment only
251 EOpFwidth, // Fragment only
252 EOpDPdxFine, // Fragment only
253 EOpDPdyFine, // Fragment only
254 EOpFwidthFine, // Fragment only
255 EOpDPdxCoarse, // Fragment only
256 EOpDPdyCoarse, // Fragment only
257 EOpFwidthCoarse, // Fragment only
259 EOpInterpolateAtCentroid, // Fragment only
260 EOpInterpolateAtSample, // Fragment only
261 EOpInterpolateAtOffset, // Fragment only
263 EOpMatrixTimesMatrix,
273 EOpEmitVertex, // geometry only
274 EOpEndPrimitive, // geometry only
275 EOpEmitStreamVertex, // geometry only
276 EOpEndStreamPrimitive, // geometry only
280 EOpMemoryBarrierAtomicCounter,
281 EOpMemoryBarrierBuffer,
282 EOpMemoryBarrierImage,
283 EOpMemoryBarrierShared, // compute only
284 EOpGroupMemoryBarrier, // compute only
288 EOpReadFirstInvocation,
292 EOpAllInvocationsEqual,
303 EOpAtomicCounterIncrement,
304 EOpAtomicCounterDecrement,
314 EOpKill, // Fragment only
325 EOpConstructGuardStart,
326 EOpConstructInt, // these first scalar forms also identify what implicit conversion is needed
373 EOpConstructTextureSampler,
374 EOpConstructGuardEnd,
384 EOpVectorTimesMatrixAssign,
385 EOpVectorTimesScalarAssign,
386 EOpMatrixTimesScalarAssign,
387 EOpMatrixTimesMatrixAssign,
391 EOpInclusiveOrAssign,
392 EOpExclusiveOrAssign,
400 EOpArrayLength, // "Array" distinguishes from length(v) built-in function, but it applies to vectors and matrices as well.
409 EOpImageQuerySamples,
418 EOpImageAtomicExchange,
419 EOpImageAtomicCompSwap,
428 // Texture operations
431 EOpTextureGuardBegin,
435 EOpTextureQueryLevels,
436 EOpTextureQuerySamples,
442 EOpTextureFetchOffset,
443 EOpTextureProjOffset,
446 EOpTextureProjLodOffset,
448 EOpTextureGradOffset,
450 EOpTextureProjGradOffset,
452 EOpTextureGatherOffset,
453 EOpTextureGatherOffsets,
455 EOpTextureOffsetClamp,
457 EOpTextureGradOffsetClamp,
459 EOpSparseTextureGuardBegin,
463 EOpSparseTextureOffset,
464 EOpSparseTextureFetch,
465 EOpSparseTextureFetchOffset,
466 EOpSparseTextureLodOffset,
467 EOpSparseTextureGrad,
468 EOpSparseTextureGradOffset,
469 EOpSparseTextureGather,
470 EOpSparseTextureGatherOffset,
471 EOpSparseTextureGatherOffsets,
472 EOpSparseTexelsResident,
473 EOpSparseTextureClamp,
474 EOpSparseTextureOffsetClamp,
475 EOpSparseTextureGradClamp,
476 EOpSparseTextureGradOffsetClamp,
478 EOpSparseTextureGuardEnd,
483 // Integer operations
507 EOpGenMul, // mul(x,y) on any of mat/vec/scalars
511 class TIntermTraverser;
512 class TIntermOperator;
513 class TIntermAggregate;
516 class TIntermConstantUnion;
517 class TIntermSelection;
524 } // end namespace glslang
527 // Base class for the tree nodes
529 // (Put outside the glslang namespace, as it's used as part of the external interface.)
533 POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator())
535 TIntermNode() { loc.init(); }
536 virtual const glslang::TSourceLoc& getLoc() const { return loc; }
537 virtual void setLoc(const glslang::TSourceLoc& l) { loc = l; }
538 virtual void traverse(glslang::TIntermTraverser*) = 0;
539 virtual glslang::TIntermTyped* getAsTyped() { return 0; }
540 virtual glslang::TIntermOperator* getAsOperator() { return 0; }
541 virtual glslang::TIntermConstantUnion* getAsConstantUnion() { return 0; }
542 virtual glslang::TIntermAggregate* getAsAggregate() { return 0; }
543 virtual glslang::TIntermUnary* getAsUnaryNode() { return 0; }
544 virtual glslang::TIntermBinary* getAsBinaryNode() { return 0; }
545 virtual glslang::TIntermSelection* getAsSelectionNode() { return 0; }
546 virtual glslang::TIntermSwitch* getAsSwitchNode() { return 0; }
547 virtual glslang::TIntermMethod* getAsMethodNode() { return 0; }
548 virtual glslang::TIntermSymbol* getAsSymbolNode() { return 0; }
549 virtual glslang::TIntermBranch* getAsBranchNode() { return 0; }
551 virtual const glslang::TIntermTyped* getAsTyped() const { return 0; }
552 virtual const glslang::TIntermOperator* getAsOperator() const { return 0; }
553 virtual const glslang::TIntermConstantUnion* getAsConstantUnion() const { return 0; }
554 virtual const glslang::TIntermAggregate* getAsAggregate() const { return 0; }
555 virtual const glslang::TIntermUnary* getAsUnaryNode() const { return 0; }
556 virtual const glslang::TIntermBinary* getAsBinaryNode() const { return 0; }
557 virtual const glslang::TIntermSelection* getAsSelectionNode() const { return 0; }
558 virtual const glslang::TIntermSwitch* getAsSwitchNode() const { return 0; }
559 virtual const glslang::TIntermMethod* getAsMethodNode() const { return 0; }
560 virtual const glslang::TIntermSymbol* getAsSymbolNode() const { return 0; }
561 virtual const glslang::TIntermBranch* getAsBranchNode() const { return 0; }
562 virtual ~TIntermNode() { }
564 glslang::TSourceLoc loc;
570 // This is just to help yacc.
572 struct TIntermNodePair {
578 // Intermediate class for nodes that have a type.
580 class TIntermTyped : public TIntermNode {
582 TIntermTyped(const TType& t) { type.shallowCopy(t); }
583 TIntermTyped(TBasicType basicType) { TType bt(basicType); type.shallowCopy(bt); }
584 virtual TIntermTyped* getAsTyped() { return this; }
585 virtual const TIntermTyped* getAsTyped() const { return this; }
586 virtual void setType(const TType& t) { type.shallowCopy(t); }
587 virtual const TType& getType() const { return type; }
588 virtual TType& getWritableType() { return type; }
590 virtual TBasicType getBasicType() const { return type.getBasicType(); }
591 virtual TQualifier& getQualifier() { return type.getQualifier(); }
592 virtual const TQualifier& getQualifier() const { return type.getQualifier(); }
593 virtual void propagatePrecision(TPrecisionQualifier);
594 virtual int getVectorSize() const { return type.getVectorSize(); }
595 virtual int getMatrixCols() const { return type.getMatrixCols(); }
596 virtual int getMatrixRows() const { return type.getMatrixRows(); }
597 virtual bool isMatrix() const { return type.isMatrix(); }
598 virtual bool isArray() const { return type.isArray(); }
599 virtual bool isVector() const { return type.isVector(); }
600 virtual bool isScalar() const { return type.isScalar(); }
601 virtual bool isStruct() const { return type.isStruct(); }
602 TString getCompleteString() const { return type.getCompleteString(); }
609 // Handle for, do-while, and while loops.
611 class TIntermLoop : public TIntermNode {
613 TIntermLoop(TIntermNode* aBody, TIntermTyped* aTest, TIntermTyped* aTerminal, bool testFirst) :
618 virtual void traverse(TIntermTraverser*);
619 TIntermNode* getBody() const { return body; }
620 TIntermTyped* getTest() const { return test; }
621 TIntermTyped* getTerminal() const { return terminal; }
622 bool testFirst() const { return first; }
624 TIntermNode* body; // code to loop over
625 TIntermTyped* test; // exit condition associated with loop, could be 0 for 'for' loops
626 TIntermTyped* terminal; // exists for for-loops
627 bool first; // true for while and for, not for do-while
631 // Handle case, break, continue, return, and kill.
633 class TIntermBranch : public TIntermNode {
635 TIntermBranch(TOperator op, TIntermTyped* e) :
638 virtual TIntermBranch* getAsBranchNode() { return this; }
639 virtual const TIntermBranch* getAsBranchNode() const { return this; }
640 virtual void traverse(TIntermTraverser*);
641 TOperator getFlowOp() const { return flowOp; }
642 TIntermTyped* getExpression() const { return expression; }
645 TIntermTyped* expression;
649 // Represent method names before seeing their calling signature
650 // or resolving them to operations. Just an expression as the base object
651 // and a textural name.
653 class TIntermMethod : public TIntermTyped {
655 TIntermMethod(TIntermTyped* o, const TType& t, const TString& m) : TIntermTyped(t), object(o), method(m) { }
656 virtual TIntermMethod* getAsMethodNode() { return this; }
657 virtual const TIntermMethod* getAsMethodNode() const { return this; }
658 virtual const TString& getMethodName() const { return method; }
659 virtual TIntermTyped* getObject() const { return object; }
660 virtual void traverse(TIntermTraverser*);
662 TIntermTyped* object;
667 // Nodes that correspond to symbols or constants in the source code.
669 class TIntermSymbol : public TIntermTyped {
671 // if symbol is initialized as symbol(sym), the memory comes from the pool allocator of sym. If sym comes from
672 // per process threadPoolAllocator, then it causes increased memory usage per compile
673 // it is essential to use "symbol = sym" to assign to symbol
674 TIntermSymbol(int i, const TString& n, const TType& t)
675 : TIntermTyped(t), id(i), constSubtree(nullptr)
677 virtual int getId() const { return id; }
678 virtual const TString& getName() const { return name; }
679 virtual void traverse(TIntermTraverser*);
680 virtual TIntermSymbol* getAsSymbolNode() { return this; }
681 virtual const TIntermSymbol* getAsSymbolNode() const { return this; }
682 void setConstArray(const TConstUnionArray& c) { constArray = c; }
683 const TConstUnionArray& getConstArray() const { return constArray; }
684 void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; }
685 TIntermTyped* getConstSubtree() const { return constSubtree; }
687 int id; // the unique id of the symbol this node represents
688 TString name; // the name of the symbol this node represents
689 TConstUnionArray constArray; // if the symbol is a front-end compile-time constant, this is its value
690 TIntermTyped* constSubtree;
693 class TIntermConstantUnion : public TIntermTyped {
695 TIntermConstantUnion(const TConstUnionArray& ua, const TType& t) : TIntermTyped(t), constArray(ua), literal(false) { }
696 const TConstUnionArray& getConstArray() const { return constArray; }
697 virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
698 virtual const TIntermConstantUnion* getAsConstantUnion() const { return this; }
699 virtual void traverse(TIntermTraverser*);
700 virtual TIntermTyped* fold(TOperator, const TIntermTyped*) const;
701 virtual TIntermTyped* fold(TOperator, const TType&) const;
702 void setLiteral() { literal = true; }
703 void setExpression() { literal = false; }
704 bool isLiteral() const { return literal; }
706 const TConstUnionArray constArray;
707 bool literal; // true if node represents a literal in the source code
710 // Represent the independent aspects of a texturing TOperator
711 struct TCrackedTextureOp {
725 // Intermediate class for node types that hold operators.
727 class TIntermOperator : public TIntermTyped {
729 virtual TIntermOperator* getAsOperator() { return this; }
730 virtual const TIntermOperator* getAsOperator() const { return this; }
731 TOperator getOp() const { return op; }
732 virtual bool promote() { return true; }
733 bool modifiesState() const;
734 bool isConstructor() const;
735 bool isTexture() const { return op > EOpTextureGuardBegin && op < EOpTextureGuardEnd; }
736 bool isImage() const { return op > EOpImageGuardBegin && op < EOpImageGuardEnd; }
737 bool isSparseTexture() const { return op > EOpSparseTextureGuardBegin && op < EOpSparseTextureGuardEnd; }
738 bool isSparseImage() const { return op == EOpSparseImageLoad; }
740 // Crack the op into the individual dimensions of texturing operation.
741 void crackTexture(TSampler sampler, TCrackedTextureOp& cracked) const
743 cracked.query = false;
744 cracked.proj = false;
746 cracked.fetch = false;
747 cracked.offset = false;
748 cracked.offsets = false;
749 cracked.gather = false;
750 cracked.grad = false;
751 cracked.subpass = false;
752 cracked.lodClamp = false;
755 case EOpImageQuerySize:
756 case EOpImageQuerySamples:
757 case EOpTextureQuerySize:
758 case EOpTextureQueryLod:
759 case EOpTextureQueryLevels:
760 case EOpTextureQuerySamples:
761 case EOpSparseTexelsResident:
762 cracked.query = true;
765 case EOpSparseTexture:
767 case EOpTextureClamp:
768 case EOpSparseTextureClamp:
769 cracked.lodClamp = true;
775 case EOpSparseTextureLod:
778 case EOpTextureOffset:
779 case EOpSparseTextureOffset:
780 cracked.offset = true;
782 case EOpTextureOffsetClamp:
783 case EOpSparseTextureOffsetClamp:
784 cracked.offset = true;
785 cracked.lodClamp = true;
787 case EOpTextureFetch:
788 case EOpSparseTextureFetch:
789 cracked.fetch = true;
790 if (sampler.dim == Esd1D || (sampler.dim == Esd2D && ! sampler.ms) || sampler.dim == Esd3D)
793 case EOpTextureFetchOffset:
794 case EOpSparseTextureFetchOffset:
795 cracked.fetch = true;
796 cracked.offset = true;
797 if (sampler.dim == Esd1D || (sampler.dim == Esd2D && ! sampler.ms) || sampler.dim == Esd3D)
800 case EOpTextureProjOffset:
801 cracked.offset = true;
804 case EOpTextureLodOffset:
805 case EOpSparseTextureLodOffset:
806 cracked.offset = true;
809 case EOpTextureProjLod:
813 case EOpTextureProjLodOffset:
814 cracked.offset = true;
819 case EOpSparseTextureGrad:
822 case EOpTextureGradClamp:
823 case EOpSparseTextureGradClamp:
825 cracked.lodClamp = true;
827 case EOpTextureGradOffset:
828 case EOpSparseTextureGradOffset:
830 cracked.offset = true;
832 case EOpTextureProjGrad:
836 case EOpTextureProjGradOffset:
838 cracked.offset = true;
841 case EOpTextureGradOffsetClamp:
842 case EOpSparseTextureGradOffsetClamp:
844 cracked.offset = true;
845 cracked.lodClamp = true;
847 case EOpTextureGather:
848 case EOpSparseTextureGather:
849 cracked.gather = true;
851 case EOpTextureGatherOffset:
852 case EOpSparseTextureGatherOffset:
853 cracked.gather = true;
854 cracked.offset = true;
856 case EOpTextureGatherOffsets:
857 case EOpSparseTextureGatherOffsets:
858 cracked.gather = true;
859 cracked.offsets = true;
862 case EOpSubpassLoadMS:
863 cracked.subpass = true;
871 TIntermOperator(TOperator o) : TIntermTyped(EbtFloat), op(o) {}
872 TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
877 // Nodes for all the basic binary math operators.
879 class TIntermBinary : public TIntermOperator {
881 TIntermBinary(TOperator o) : TIntermOperator(o) {}
882 virtual void traverse(TIntermTraverser*);
883 virtual void setLeft(TIntermTyped* n) { left = n; }
884 virtual void setRight(TIntermTyped* n) { right = n; }
885 virtual TIntermTyped* getLeft() const { return left; }
886 virtual TIntermTyped* getRight() const { return right; }
887 virtual TIntermBinary* getAsBinaryNode() { return this; }
888 virtual const TIntermBinary* getAsBinaryNode() const { return this; }
889 virtual bool promote();
890 virtual void updatePrecision();
897 // Nodes for unary math operators.
899 class TIntermUnary : public TIntermOperator {
901 TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0) {}
902 TIntermUnary(TOperator o) : TIntermOperator(o), operand(0) {}
903 virtual void traverse(TIntermTraverser*);
904 virtual void setOperand(TIntermTyped* o) { operand = o; }
905 virtual TIntermTyped* getOperand() { return operand; }
906 virtual const TIntermTyped* getOperand() const { return operand; }
907 virtual TIntermUnary* getAsUnaryNode() { return this; }
908 virtual const TIntermUnary* getAsUnaryNode() const { return this; }
909 virtual bool promote();
910 virtual void updatePrecision();
912 TIntermTyped* operand;
915 typedef TVector<TIntermNode*> TIntermSequence;
916 typedef TVector<int> TQualifierList;
918 // Nodes that operate on an arbitrary sized set of children.
920 class TIntermAggregate : public TIntermOperator {
922 TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(0) { }
923 TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(0) { }
924 ~TIntermAggregate() { delete pragmaTable; }
925 virtual TIntermAggregate* getAsAggregate() { return this; }
926 virtual const TIntermAggregate* getAsAggregate() const { return this; }
927 virtual void setOperator(TOperator o) { op = o; }
928 virtual TIntermSequence& getSequence() { return sequence; }
929 virtual const TIntermSequence& getSequence() const { return sequence; }
930 virtual void setName(const TString& n) { name = n; }
931 virtual const TString& getName() const { return name; }
932 virtual void traverse(TIntermTraverser*);
933 virtual void setUserDefined() { userDefined = true; }
934 virtual bool isUserDefined() { return userDefined; }
935 virtual TQualifierList& getQualifierList() { return qualifier; }
936 virtual const TQualifierList& getQualifierList() const { return qualifier; }
937 void setOptimize(bool o) { optimize = o; }
938 void setDebug(bool d) { debug = d; }
939 bool getOptimize() const { return optimize; }
940 bool getDebug() const { return debug; }
941 void addToPragmaTable(const TPragmaTable& pTable);
942 const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
944 TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
945 TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
946 TIntermSequence sequence;
947 TQualifierList qualifier;
949 bool userDefined; // used for user defined function names
952 TPragmaTable* pragmaTable;
958 class TIntermSelection : public TIntermTyped {
960 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
961 TIntermTyped(EbtVoid), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
962 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
963 TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
964 virtual void traverse(TIntermTraverser*);
965 virtual TIntermTyped* getCondition() const { return condition; }
966 virtual TIntermNode* getTrueBlock() const { return trueBlock; }
967 virtual TIntermNode* getFalseBlock() const { return falseBlock; }
968 virtual TIntermSelection* getAsSelectionNode() { return this; }
969 virtual const TIntermSelection* getAsSelectionNode() const { return this; }
971 TIntermTyped* condition;
972 TIntermNode* trueBlock;
973 TIntermNode* falseBlock;
977 // For switch statements. Designed use is that a switch will have sequence of nodes
978 // that are either case/default nodes or a *single* node that represents all the code
979 // in between (if any) consecutive case/defaults. So, a traversal need only deal with
980 // 0 or 1 nodes per case/default statement.
982 class TIntermSwitch : public TIntermNode {
984 TIntermSwitch(TIntermTyped* cond, TIntermAggregate* b) : condition(cond), body(b) { }
985 virtual void traverse(TIntermTraverser*);
986 virtual TIntermNode* getCondition() const { return condition; }
987 virtual TIntermAggregate* getBody() const { return body; }
988 virtual TIntermSwitch* getAsSwitchNode() { return this; }
989 virtual const TIntermSwitch* getAsSwitchNode() const { return this; }
991 TIntermTyped* condition;
992 TIntermAggregate* body;
1003 // For traversing the tree. User should derive from this,
1004 // put their traversal specific data in it, and then pass
1005 // it to a Traverse method.
1007 // When using this, just fill in the methods for nodes you want visited.
1008 // Return false from a pre-visit to skip visiting that node's subtree.
1010 // Explicitly set postVisit to true if you want post visiting, otherwise,
1011 // filled in methods will only be called at pre-visit time (before processing
1012 // the subtree). Similarly for inVisit for in-order visiting of nodes with
1013 // multiple children.
1015 // If you only want post-visits, explicitly turn off preVisit (and inVisit)
1016 // and turn on postVisit.
1018 // In general, for the visit*() methods, return true from interior nodes
1019 // to have the traversal continue on to children.
1021 // If you process children yourself, or don't want them processed, return false.
1023 class TIntermTraverser {
1025 POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator())
1026 TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
1029 postVisit(postVisit),
1030 rightToLeft(rightToLeft),
1033 virtual ~TIntermTraverser() { }
1035 virtual void visitSymbol(TIntermSymbol*) { }
1036 virtual void visitConstantUnion(TIntermConstantUnion*) { }
1037 virtual bool visitBinary(TVisit, TIntermBinary*) { return true; }
1038 virtual bool visitUnary(TVisit, TIntermUnary*) { return true; }
1039 virtual bool visitSelection(TVisit, TIntermSelection*) { return true; }
1040 virtual bool visitAggregate(TVisit, TIntermAggregate*) { return true; }
1041 virtual bool visitLoop(TVisit, TIntermLoop*) { return true; }
1042 virtual bool visitBranch(TVisit, TIntermBranch*) { return true; }
1043 virtual bool visitSwitch(TVisit, TIntermSwitch*) { return true; }
1045 int getMaxDepth() const { return maxDepth; }
1047 void incrementDepth(TIntermNode *current)
1050 maxDepth = (std::max)(maxDepth, depth);
1051 path.push_back(current);
1054 void decrementDepth()
1060 TIntermNode *getParentNode()
1062 return path.size() == 0 ? NULL : path.back();
1065 const bool preVisit;
1067 const bool postVisit;
1068 const bool rightToLeft;
1071 TIntermTraverser& operator=(TIntermTraverser&);
1076 // All the nodes from root to the current node's parent during traversing.
1077 TVector<TIntermNode *> path;
1080 // KHR_vulkan_glsl says "Two arrays sized with specialization constants are the same type only if
1081 // sized with the same symbol, involving no operations"
1082 inline bool SameSpecializationConstants(TIntermTyped* node1, TIntermTyped* node2)
1084 return node1->getAsSymbolNode() && node2->getAsSymbolNode() &&
1085 node1->getAsSymbolNode()->getId() == node2->getAsSymbolNode()->getId();
1088 } // end namespace glslang
1090 #endif // __INTERMEDIATE_H