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
501 EOpClip, // discard if input value < 0
503 EOpLog10, // base 10 log
505 EOpSaturate, // clamp from 0 to 1
506 EOpSinCos, // sin and cos in out parameters
507 EOpGenMul, // mul(x,y) on any of mat/vec/scalars
508 EOpDst, // x = 1, y=src0.y * src1.y, z=src0.z, w=src1.w
509 EOpInterlockedAdd, // atomic ops, but uses [optional] out arg instead of return
510 EOpInterlockedAnd, // ...
511 EOpInterlockedCompareExchange, // ...
512 EOpInterlockedCompareStore, // ...
513 EOpInterlockedExchange, // ...
514 EOpInterlockedMax, // ...
515 EOpInterlockedMin, // ...
516 EOpInterlockedOr, // ...
517 EOpInterlockedXor, // ...
521 class TIntermTraverser;
522 class TIntermOperator;
523 class TIntermAggregate;
526 class TIntermConstantUnion;
527 class TIntermSelection;
534 } // end namespace glslang
537 // Base class for the tree nodes
539 // (Put outside the glslang namespace, as it's used as part of the external interface.)
543 POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator())
545 TIntermNode() { loc.init(); }
546 virtual const glslang::TSourceLoc& getLoc() const { return loc; }
547 virtual void setLoc(const glslang::TSourceLoc& l) { loc = l; }
548 virtual void traverse(glslang::TIntermTraverser*) = 0;
549 virtual glslang::TIntermTyped* getAsTyped() { return 0; }
550 virtual glslang::TIntermOperator* getAsOperator() { return 0; }
551 virtual glslang::TIntermConstantUnion* getAsConstantUnion() { return 0; }
552 virtual glslang::TIntermAggregate* getAsAggregate() { return 0; }
553 virtual glslang::TIntermUnary* getAsUnaryNode() { return 0; }
554 virtual glslang::TIntermBinary* getAsBinaryNode() { return 0; }
555 virtual glslang::TIntermSelection* getAsSelectionNode() { return 0; }
556 virtual glslang::TIntermSwitch* getAsSwitchNode() { return 0; }
557 virtual glslang::TIntermMethod* getAsMethodNode() { return 0; }
558 virtual glslang::TIntermSymbol* getAsSymbolNode() { return 0; }
559 virtual glslang::TIntermBranch* getAsBranchNode() { return 0; }
561 virtual const glslang::TIntermTyped* getAsTyped() const { return 0; }
562 virtual const glslang::TIntermOperator* getAsOperator() const { return 0; }
563 virtual const glslang::TIntermConstantUnion* getAsConstantUnion() const { return 0; }
564 virtual const glslang::TIntermAggregate* getAsAggregate() const { return 0; }
565 virtual const glslang::TIntermUnary* getAsUnaryNode() const { return 0; }
566 virtual const glslang::TIntermBinary* getAsBinaryNode() const { return 0; }
567 virtual const glslang::TIntermSelection* getAsSelectionNode() const { return 0; }
568 virtual const glslang::TIntermSwitch* getAsSwitchNode() const { return 0; }
569 virtual const glslang::TIntermMethod* getAsMethodNode() const { return 0; }
570 virtual const glslang::TIntermSymbol* getAsSymbolNode() const { return 0; }
571 virtual const glslang::TIntermBranch* getAsBranchNode() const { return 0; }
572 virtual ~TIntermNode() { }
574 glslang::TSourceLoc loc;
580 // This is just to help yacc.
582 struct TIntermNodePair {
588 // Intermediate class for nodes that have a type.
590 class TIntermTyped : public TIntermNode {
592 TIntermTyped(const TType& t) { type.shallowCopy(t); }
593 TIntermTyped(TBasicType basicType) { TType bt(basicType); type.shallowCopy(bt); }
594 virtual TIntermTyped* getAsTyped() { return this; }
595 virtual const TIntermTyped* getAsTyped() const { return this; }
596 virtual void setType(const TType& t) { type.shallowCopy(t); }
597 virtual const TType& getType() const { return type; }
598 virtual TType& getWritableType() { return type; }
600 virtual TBasicType getBasicType() const { return type.getBasicType(); }
601 virtual TQualifier& getQualifier() { return type.getQualifier(); }
602 virtual const TQualifier& getQualifier() const { return type.getQualifier(); }
603 virtual void propagatePrecision(TPrecisionQualifier);
604 virtual int getVectorSize() const { return type.getVectorSize(); }
605 virtual int getMatrixCols() const { return type.getMatrixCols(); }
606 virtual int getMatrixRows() const { return type.getMatrixRows(); }
607 virtual bool isMatrix() const { return type.isMatrix(); }
608 virtual bool isArray() const { return type.isArray(); }
609 virtual bool isVector() const { return type.isVector(); }
610 virtual bool isScalar() const { return type.isScalar(); }
611 virtual bool isStruct() const { return type.isStruct(); }
612 TString getCompleteString() const { return type.getCompleteString(); }
619 // Handle for, do-while, and while loops.
621 class TIntermLoop : public TIntermNode {
623 TIntermLoop(TIntermNode* aBody, TIntermTyped* aTest, TIntermTyped* aTerminal, bool testFirst) :
628 virtual void traverse(TIntermTraverser*);
629 TIntermNode* getBody() const { return body; }
630 TIntermTyped* getTest() const { return test; }
631 TIntermTyped* getTerminal() const { return terminal; }
632 bool testFirst() const { return first; }
634 TIntermNode* body; // code to loop over
635 TIntermTyped* test; // exit condition associated with loop, could be 0 for 'for' loops
636 TIntermTyped* terminal; // exists for for-loops
637 bool first; // true for while and for, not for do-while
641 // Handle case, break, continue, return, and kill.
643 class TIntermBranch : public TIntermNode {
645 TIntermBranch(TOperator op, TIntermTyped* e) :
648 virtual TIntermBranch* getAsBranchNode() { return this; }
649 virtual const TIntermBranch* getAsBranchNode() const { return this; }
650 virtual void traverse(TIntermTraverser*);
651 TOperator getFlowOp() const { return flowOp; }
652 TIntermTyped* getExpression() const { return expression; }
655 TIntermTyped* expression;
659 // Represent method names before seeing their calling signature
660 // or resolving them to operations. Just an expression as the base object
661 // and a textural name.
663 class TIntermMethod : public TIntermTyped {
665 TIntermMethod(TIntermTyped* o, const TType& t, const TString& m) : TIntermTyped(t), object(o), method(m) { }
666 virtual TIntermMethod* getAsMethodNode() { return this; }
667 virtual const TIntermMethod* getAsMethodNode() const { return this; }
668 virtual const TString& getMethodName() const { return method; }
669 virtual TIntermTyped* getObject() const { return object; }
670 virtual void traverse(TIntermTraverser*);
672 TIntermTyped* object;
677 // Nodes that correspond to symbols or constants in the source code.
679 class TIntermSymbol : public TIntermTyped {
681 // if symbol is initialized as symbol(sym), the memory comes from the pool allocator of sym. If sym comes from
682 // per process threadPoolAllocator, then it causes increased memory usage per compile
683 // it is essential to use "symbol = sym" to assign to symbol
684 TIntermSymbol(int i, const TString& n, const TType& t)
685 : TIntermTyped(t), id(i), constSubtree(nullptr)
687 virtual int getId() const { return id; }
688 virtual const TString& getName() const { return name; }
689 virtual void traverse(TIntermTraverser*);
690 virtual TIntermSymbol* getAsSymbolNode() { return this; }
691 virtual const TIntermSymbol* getAsSymbolNode() const { return this; }
692 void setConstArray(const TConstUnionArray& c) { constArray = c; }
693 const TConstUnionArray& getConstArray() const { return constArray; }
694 void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; }
695 TIntermTyped* getConstSubtree() const { return constSubtree; }
697 int id; // the unique id of the symbol this node represents
698 TString name; // the name of the symbol this node represents
699 TConstUnionArray constArray; // if the symbol is a front-end compile-time constant, this is its value
700 TIntermTyped* constSubtree;
703 class TIntermConstantUnion : public TIntermTyped {
705 TIntermConstantUnion(const TConstUnionArray& ua, const TType& t) : TIntermTyped(t), constArray(ua), literal(false) { }
706 const TConstUnionArray& getConstArray() const { return constArray; }
707 virtual TIntermConstantUnion* getAsConstantUnion() { return this; }
708 virtual const TIntermConstantUnion* getAsConstantUnion() const { return this; }
709 virtual void traverse(TIntermTraverser*);
710 virtual TIntermTyped* fold(TOperator, const TIntermTyped*) const;
711 virtual TIntermTyped* fold(TOperator, const TType&) const;
712 void setLiteral() { literal = true; }
713 void setExpression() { literal = false; }
714 bool isLiteral() const { return literal; }
716 const TConstUnionArray constArray;
717 bool literal; // true if node represents a literal in the source code
720 // Represent the independent aspects of a texturing TOperator
721 struct TCrackedTextureOp {
735 // Intermediate class for node types that hold operators.
737 class TIntermOperator : public TIntermTyped {
739 virtual TIntermOperator* getAsOperator() { return this; }
740 virtual const TIntermOperator* getAsOperator() const { return this; }
741 TOperator getOp() const { return op; }
742 virtual bool promote() { return true; }
743 bool modifiesState() const;
744 bool isConstructor() const;
745 bool isTexture() const { return op > EOpTextureGuardBegin && op < EOpTextureGuardEnd; }
746 bool isImage() const { return op > EOpImageGuardBegin && op < EOpImageGuardEnd; }
747 bool isSparseTexture() const { return op > EOpSparseTextureGuardBegin && op < EOpSparseTextureGuardEnd; }
748 bool isSparseImage() const { return op == EOpSparseImageLoad; }
750 // Crack the op into the individual dimensions of texturing operation.
751 void crackTexture(TSampler sampler, TCrackedTextureOp& cracked) const
753 cracked.query = false;
754 cracked.proj = false;
756 cracked.fetch = false;
757 cracked.offset = false;
758 cracked.offsets = false;
759 cracked.gather = false;
760 cracked.grad = false;
761 cracked.subpass = false;
762 cracked.lodClamp = false;
765 case EOpImageQuerySize:
766 case EOpImageQuerySamples:
767 case EOpTextureQuerySize:
768 case EOpTextureQueryLod:
769 case EOpTextureQueryLevels:
770 case EOpTextureQuerySamples:
771 case EOpSparseTexelsResident:
772 cracked.query = true;
775 case EOpSparseTexture:
777 case EOpTextureClamp:
778 case EOpSparseTextureClamp:
779 cracked.lodClamp = true;
785 case EOpSparseTextureLod:
788 case EOpTextureOffset:
789 case EOpSparseTextureOffset:
790 cracked.offset = true;
792 case EOpTextureOffsetClamp:
793 case EOpSparseTextureOffsetClamp:
794 cracked.offset = true;
795 cracked.lodClamp = true;
797 case EOpTextureFetch:
798 case EOpSparseTextureFetch:
799 cracked.fetch = true;
800 if (sampler.dim == Esd1D || (sampler.dim == Esd2D && ! sampler.ms) || sampler.dim == Esd3D)
803 case EOpTextureFetchOffset:
804 case EOpSparseTextureFetchOffset:
805 cracked.fetch = true;
806 cracked.offset = true;
807 if (sampler.dim == Esd1D || (sampler.dim == Esd2D && ! sampler.ms) || sampler.dim == Esd3D)
810 case EOpTextureProjOffset:
811 cracked.offset = true;
814 case EOpTextureLodOffset:
815 case EOpSparseTextureLodOffset:
816 cracked.offset = true;
819 case EOpTextureProjLod:
823 case EOpTextureProjLodOffset:
824 cracked.offset = true;
829 case EOpSparseTextureGrad:
832 case EOpTextureGradClamp:
833 case EOpSparseTextureGradClamp:
835 cracked.lodClamp = true;
837 case EOpTextureGradOffset:
838 case EOpSparseTextureGradOffset:
840 cracked.offset = true;
842 case EOpTextureProjGrad:
846 case EOpTextureProjGradOffset:
848 cracked.offset = true;
851 case EOpTextureGradOffsetClamp:
852 case EOpSparseTextureGradOffsetClamp:
854 cracked.offset = true;
855 cracked.lodClamp = true;
857 case EOpTextureGather:
858 case EOpSparseTextureGather:
859 cracked.gather = true;
861 case EOpTextureGatherOffset:
862 case EOpSparseTextureGatherOffset:
863 cracked.gather = true;
864 cracked.offset = true;
866 case EOpTextureGatherOffsets:
867 case EOpSparseTextureGatherOffsets:
868 cracked.gather = true;
869 cracked.offsets = true;
872 case EOpSubpassLoadMS:
873 cracked.subpass = true;
881 TIntermOperator(TOperator o) : TIntermTyped(EbtFloat), op(o) {}
882 TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
887 // Nodes for all the basic binary math operators.
889 class TIntermBinary : public TIntermOperator {
891 TIntermBinary(TOperator o) : TIntermOperator(o) {}
892 virtual void traverse(TIntermTraverser*);
893 virtual void setLeft(TIntermTyped* n) { left = n; }
894 virtual void setRight(TIntermTyped* n) { right = n; }
895 virtual TIntermTyped* getLeft() const { return left; }
896 virtual TIntermTyped* getRight() const { return right; }
897 virtual TIntermBinary* getAsBinaryNode() { return this; }
898 virtual const TIntermBinary* getAsBinaryNode() const { return this; }
899 virtual bool promote();
900 virtual void updatePrecision();
907 // Nodes for unary math operators.
909 class TIntermUnary : public TIntermOperator {
911 TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0) {}
912 TIntermUnary(TOperator o) : TIntermOperator(o), operand(0) {}
913 virtual void traverse(TIntermTraverser*);
914 virtual void setOperand(TIntermTyped* o) { operand = o; }
915 virtual TIntermTyped* getOperand() { return operand; }
916 virtual const TIntermTyped* getOperand() const { return operand; }
917 virtual TIntermUnary* getAsUnaryNode() { return this; }
918 virtual const TIntermUnary* getAsUnaryNode() const { return this; }
919 virtual bool promote();
920 virtual void updatePrecision();
922 TIntermTyped* operand;
925 typedef TVector<TIntermNode*> TIntermSequence;
926 typedef TVector<int> TQualifierList;
928 // Nodes that operate on an arbitrary sized set of children.
930 class TIntermAggregate : public TIntermOperator {
932 TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(0) { }
933 TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(0) { }
934 ~TIntermAggregate() { delete pragmaTable; }
935 virtual TIntermAggregate* getAsAggregate() { return this; }
936 virtual const TIntermAggregate* getAsAggregate() const { return this; }
937 virtual void setOperator(TOperator o) { op = o; }
938 virtual TIntermSequence& getSequence() { return sequence; }
939 virtual const TIntermSequence& getSequence() const { return sequence; }
940 virtual void setName(const TString& n) { name = n; }
941 virtual const TString& getName() const { return name; }
942 virtual void traverse(TIntermTraverser*);
943 virtual void setUserDefined() { userDefined = true; }
944 virtual bool isUserDefined() { return userDefined; }
945 virtual TQualifierList& getQualifierList() { return qualifier; }
946 virtual const TQualifierList& getQualifierList() const { return qualifier; }
947 void setOptimize(bool o) { optimize = o; }
948 void setDebug(bool d) { debug = d; }
949 bool getOptimize() const { return optimize; }
950 bool getDebug() const { return debug; }
951 void addToPragmaTable(const TPragmaTable& pTable);
952 const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
954 TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
955 TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
956 TIntermSequence sequence;
957 TQualifierList qualifier;
959 bool userDefined; // used for user defined function names
962 TPragmaTable* pragmaTable;
968 class TIntermSelection : public TIntermTyped {
970 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
971 TIntermTyped(EbtVoid), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
972 TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
973 TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
974 virtual void traverse(TIntermTraverser*);
975 virtual TIntermTyped* getCondition() const { return condition; }
976 virtual TIntermNode* getTrueBlock() const { return trueBlock; }
977 virtual TIntermNode* getFalseBlock() const { return falseBlock; }
978 virtual TIntermSelection* getAsSelectionNode() { return this; }
979 virtual const TIntermSelection* getAsSelectionNode() const { return this; }
981 TIntermTyped* condition;
982 TIntermNode* trueBlock;
983 TIntermNode* falseBlock;
987 // For switch statements. Designed use is that a switch will have sequence of nodes
988 // that are either case/default nodes or a *single* node that represents all the code
989 // in between (if any) consecutive case/defaults. So, a traversal need only deal with
990 // 0 or 1 nodes per case/default statement.
992 class TIntermSwitch : public TIntermNode {
994 TIntermSwitch(TIntermTyped* cond, TIntermAggregate* b) : condition(cond), body(b) { }
995 virtual void traverse(TIntermTraverser*);
996 virtual TIntermNode* getCondition() const { return condition; }
997 virtual TIntermAggregate* getBody() const { return body; }
998 virtual TIntermSwitch* getAsSwitchNode() { return this; }
999 virtual const TIntermSwitch* getAsSwitchNode() const { return this; }
1001 TIntermTyped* condition;
1002 TIntermAggregate* body;
1013 // For traversing the tree. User should derive from this,
1014 // put their traversal specific data in it, and then pass
1015 // it to a Traverse method.
1017 // When using this, just fill in the methods for nodes you want visited.
1018 // Return false from a pre-visit to skip visiting that node's subtree.
1020 // Explicitly set postVisit to true if you want post visiting, otherwise,
1021 // filled in methods will only be called at pre-visit time (before processing
1022 // the subtree). Similarly for inVisit for in-order visiting of nodes with
1023 // multiple children.
1025 // If you only want post-visits, explicitly turn off preVisit (and inVisit)
1026 // and turn on postVisit.
1028 // In general, for the visit*() methods, return true from interior nodes
1029 // to have the traversal continue on to children.
1031 // If you process children yourself, or don't want them processed, return false.
1033 class TIntermTraverser {
1035 POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator())
1036 TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
1039 postVisit(postVisit),
1040 rightToLeft(rightToLeft),
1043 virtual ~TIntermTraverser() { }
1045 virtual void visitSymbol(TIntermSymbol*) { }
1046 virtual void visitConstantUnion(TIntermConstantUnion*) { }
1047 virtual bool visitBinary(TVisit, TIntermBinary*) { return true; }
1048 virtual bool visitUnary(TVisit, TIntermUnary*) { return true; }
1049 virtual bool visitSelection(TVisit, TIntermSelection*) { return true; }
1050 virtual bool visitAggregate(TVisit, TIntermAggregate*) { return true; }
1051 virtual bool visitLoop(TVisit, TIntermLoop*) { return true; }
1052 virtual bool visitBranch(TVisit, TIntermBranch*) { return true; }
1053 virtual bool visitSwitch(TVisit, TIntermSwitch*) { return true; }
1055 int getMaxDepth() const { return maxDepth; }
1057 void incrementDepth(TIntermNode *current)
1060 maxDepth = (std::max)(maxDepth, depth);
1061 path.push_back(current);
1064 void decrementDepth()
1070 TIntermNode *getParentNode()
1072 return path.size() == 0 ? NULL : path.back();
1075 const bool preVisit;
1077 const bool postVisit;
1078 const bool rightToLeft;
1081 TIntermTraverser& operator=(TIntermTraverser&);
1086 // All the nodes from root to the current node's parent during traversing.
1087 TVector<TIntermNode *> path;
1090 // KHR_vulkan_glsl says "Two arrays sized with specialization constants are the same type only if
1091 // sized with the same symbol, involving no operations"
1092 inline bool SameSpecializationConstants(TIntermTyped* node1, TIntermTyped* node2)
1094 return node1->getAsSymbolNode() && node2->getAsSymbolNode() &&
1095 node1->getAsSymbolNode()->getId() == node2->getAsSymbolNode()->getId();
1098 } // end namespace glslang
1100 #endif // __INTERMEDIATE_H