Home | History | Annotate | Download | only in Include
      1 //
      2 //Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
      3 //Copyright (C) 2012-2016 LunarG, Inc.
      4 //
      5 //All rights reserved.
      6 //
      7 //Redistribution and use in source and binary forms, with or without
      8 //modification, are permitted provided that the following conditions
      9 //are met:
     10 //
     11 //    Redistributions of source code must retain the above copyright
     12 //    notice, this list of conditions and the following disclaimer.
     13 //
     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.
     18 //
     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.
     22 //
     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.
     35 //
     36 
     37 //
     38 // Definition of the in-memory high-level intermediate representation
     39 // of shaders.  This is a tree that parser creates.
     40 //
     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.
     44 //
     45 
     46 #ifndef __INTERMEDIATE_H
     47 #define __INTERMEDIATE_H
     48 
     49 #include "../Include/Common.h"
     50 #include "../Include/Types.h"
     51 #include "../Include/ConstantUnion.h"
     52 
     53 namespace glslang {
     54 
     55 //
     56 // Operators used by the high-level (parse tree) representation.
     57 //
     58 enum TOperator {
     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
     62     EOpFunctionCall,
     63     EOpFunction,        // For function definition
     64     EOpParameters,      // an aggregate listing the parameters to a function
     65 
     66     //
     67     // Unary operators
     68     //
     69 
     70     EOpNegative,
     71     EOpLogicalNot,
     72     EOpVectorLogicalNot,
     73     EOpBitwiseNot,
     74 
     75     EOpPostIncrement,
     76     EOpPostDecrement,
     77     EOpPreIncrement,
     78     EOpPreDecrement,
     79 
     80     EOpConvIntToBool,
     81     EOpConvUintToBool,
     82     EOpConvFloatToBool,
     83     EOpConvDoubleToBool,
     84     EOpConvInt64ToBool,
     85     EOpConvUint64ToBool,
     86     EOpConvBoolToFloat,
     87     EOpConvIntToFloat,
     88     EOpConvUintToFloat,
     89     EOpConvDoubleToFloat,
     90     EOpConvInt64ToFloat,
     91     EOpConvUint64ToFloat,
     92     EOpConvUintToInt,
     93     EOpConvFloatToInt,
     94     EOpConvBoolToInt,
     95     EOpConvDoubleToInt,
     96     EOpConvInt64ToInt,
     97     EOpConvUint64ToInt,
     98     EOpConvIntToUint,
     99     EOpConvFloatToUint,
    100     EOpConvBoolToUint,
    101     EOpConvDoubleToUint,
    102     EOpConvInt64ToUint,
    103     EOpConvUint64ToUint,
    104     EOpConvIntToDouble,
    105     EOpConvUintToDouble,
    106     EOpConvFloatToDouble,
    107     EOpConvBoolToDouble,
    108     EOpConvInt64ToDouble,
    109     EOpConvUint64ToDouble,
    110     EOpConvBoolToInt64,
    111     EOpConvIntToInt64,
    112     EOpConvUintToInt64,
    113     EOpConvFloatToInt64,
    114     EOpConvDoubleToInt64,
    115     EOpConvUint64ToInt64,
    116     EOpConvBoolToUint64,
    117     EOpConvIntToUint64,
    118     EOpConvUintToUint64,
    119     EOpConvFloatToUint64,
    120     EOpConvDoubleToUint64,
    121     EOpConvInt64ToUint64,
    122 
    123     //
    124     // binary operations
    125     //
    126 
    127     EOpAdd,
    128     EOpSub,
    129     EOpMul,
    130     EOpDiv,
    131     EOpMod,
    132     EOpRightShift,
    133     EOpLeftShift,
    134     EOpAnd,
    135     EOpInclusiveOr,
    136     EOpExclusiveOr,
    137     EOpEqual,
    138     EOpNotEqual,
    139     EOpVectorEqual,
    140     EOpVectorNotEqual,
    141     EOpLessThan,
    142     EOpGreaterThan,
    143     EOpLessThanEqual,
    144     EOpGreaterThanEqual,
    145     EOpComma,
    146 
    147     EOpVectorTimesScalar,
    148     EOpVectorTimesMatrix,
    149     EOpMatrixTimesVector,
    150     EOpMatrixTimesScalar,
    151 
    152     EOpLogicalOr,
    153     EOpLogicalXor,
    154     EOpLogicalAnd,
    155 
    156     EOpIndexDirect,
    157     EOpIndexIndirect,
    158     EOpIndexDirectStruct,
    159 
    160     EOpVectorSwizzle,
    161 
    162     EOpMethod,
    163 
    164     //
    165     // Built-in functions mapped to operators
    166     //
    167 
    168     EOpRadians,
    169     EOpDegrees,
    170     EOpSin,
    171     EOpCos,
    172     EOpTan,
    173     EOpAsin,
    174     EOpAcos,
    175     EOpAtan,
    176     EOpSinh,
    177     EOpCosh,
    178     EOpTanh,
    179     EOpAsinh,
    180     EOpAcosh,
    181     EOpAtanh,
    182 
    183     EOpPow,
    184     EOpExp,
    185     EOpLog,
    186     EOpExp2,
    187     EOpLog2,
    188     EOpSqrt,
    189     EOpInverseSqrt,
    190 
    191     EOpAbs,
    192     EOpSign,
    193     EOpFloor,
    194     EOpTrunc,
    195     EOpRound,
    196     EOpRoundEven,
    197     EOpCeil,
    198     EOpFract,
    199     EOpModf,
    200     EOpMin,
    201     EOpMax,
    202     EOpClamp,
    203     EOpMix,
    204     EOpStep,
    205     EOpSmoothStep,
    206 
    207     EOpIsNan,
    208     EOpIsInf,
    209 
    210     EOpFma,
    211 
    212     EOpFrexp,
    213     EOpLdexp,
    214 
    215     EOpFloatBitsToInt,
    216     EOpFloatBitsToUint,
    217     EOpIntBitsToFloat,
    218     EOpUintBitsToFloat,
    219     EOpDoubleBitsToInt64,
    220     EOpDoubleBitsToUint64,
    221     EOpInt64BitsToDouble,
    222     EOpUint64BitsToDouble,
    223     EOpPackSnorm2x16,
    224     EOpUnpackSnorm2x16,
    225     EOpPackUnorm2x16,
    226     EOpUnpackUnorm2x16,
    227     EOpPackSnorm4x8,
    228     EOpUnpackSnorm4x8,
    229     EOpPackUnorm4x8,
    230     EOpUnpackUnorm4x8,
    231     EOpPackHalf2x16,
    232     EOpUnpackHalf2x16,
    233     EOpPackDouble2x32,
    234     EOpUnpackDouble2x32,
    235     EOpPackInt2x32,
    236     EOpUnpackInt2x32,
    237     EOpPackUint2x32,
    238     EOpUnpackUint2x32,
    239 
    240     EOpLength,
    241     EOpDistance,
    242     EOpDot,
    243     EOpCross,
    244     EOpNormalize,
    245     EOpFaceForward,
    246     EOpReflect,
    247     EOpRefract,
    248 
    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
    258 
    259     EOpInterpolateAtCentroid, // Fragment only
    260     EOpInterpolateAtSample,   // Fragment only
    261     EOpInterpolateAtOffset,   // Fragment only
    262 
    263     EOpMatrixTimesMatrix,
    264     EOpOuterProduct,
    265     EOpDeterminant,
    266     EOpMatrixInverse,
    267     EOpTranspose,
    268 
    269     EOpFtransform,
    270 
    271     EOpNoise,
    272 
    273     EOpEmitVertex,           // geometry only
    274     EOpEndPrimitive,         // geometry only
    275     EOpEmitStreamVertex,     // geometry only
    276     EOpEndStreamPrimitive,   // geometry only
    277 
    278     EOpBarrier,
    279     EOpMemoryBarrier,
    280     EOpMemoryBarrierAtomicCounter,
    281     EOpMemoryBarrierBuffer,
    282     EOpMemoryBarrierImage,
    283     EOpMemoryBarrierShared,  // compute only
    284     EOpGroupMemoryBarrier,   // compute only
    285 
    286     EOpBallot,
    287     EOpReadInvocation,
    288     EOpReadFirstInvocation,
    289 
    290     EOpAnyInvocation,
    291     EOpAllInvocations,
    292     EOpAllInvocationsEqual,
    293 
    294     EOpAtomicAdd,
    295     EOpAtomicMin,
    296     EOpAtomicMax,
    297     EOpAtomicAnd,
    298     EOpAtomicOr,
    299     EOpAtomicXor,
    300     EOpAtomicExchange,
    301     EOpAtomicCompSwap,
    302 
    303     EOpAtomicCounterIncrement,
    304     EOpAtomicCounterDecrement,
    305     EOpAtomicCounter,
    306 
    307     EOpAny,
    308     EOpAll,
    309 
    310     //
    311     // Branch
    312     //
    313 
    314     EOpKill,            // Fragment only
    315     EOpReturn,
    316     EOpBreak,
    317     EOpContinue,
    318     EOpCase,
    319     EOpDefault,
    320 
    321     //
    322     // Constructors
    323     //
    324 
    325     EOpConstructGuardStart,
    326     EOpConstructInt,          // these first scalar forms also identify what implicit conversion is needed
    327     EOpConstructUint,
    328     EOpConstructInt64,
    329     EOpConstructUint64,
    330     EOpConstructBool,
    331     EOpConstructFloat,
    332     EOpConstructDouble,
    333     EOpConstructVec2,
    334     EOpConstructVec3,
    335     EOpConstructVec4,
    336     EOpConstructDVec2,
    337     EOpConstructDVec3,
    338     EOpConstructDVec4,
    339     EOpConstructBVec2,
    340     EOpConstructBVec3,
    341     EOpConstructBVec4,
    342     EOpConstructIVec2,
    343     EOpConstructIVec3,
    344     EOpConstructIVec4,
    345     EOpConstructUVec2,
    346     EOpConstructUVec3,
    347     EOpConstructUVec4,
    348     EOpConstructI64Vec2,
    349     EOpConstructI64Vec3,
    350     EOpConstructI64Vec4,
    351     EOpConstructU64Vec2,
    352     EOpConstructU64Vec3,
    353     EOpConstructU64Vec4,
    354     EOpConstructMat2x2,
    355     EOpConstructMat2x3,
    356     EOpConstructMat2x4,
    357     EOpConstructMat3x2,
    358     EOpConstructMat3x3,
    359     EOpConstructMat3x4,
    360     EOpConstructMat4x2,
    361     EOpConstructMat4x3,
    362     EOpConstructMat4x4,
    363     EOpConstructDMat2x2,
    364     EOpConstructDMat2x3,
    365     EOpConstructDMat2x4,
    366     EOpConstructDMat3x2,
    367     EOpConstructDMat3x3,
    368     EOpConstructDMat3x4,
    369     EOpConstructDMat4x2,
    370     EOpConstructDMat4x3,
    371     EOpConstructDMat4x4,
    372     EOpConstructStruct,
    373     EOpConstructTextureSampler,
    374     EOpConstructGuardEnd,
    375 
    376     //
    377     // moves
    378     //
    379 
    380     EOpAssign,
    381     EOpAddAssign,
    382     EOpSubAssign,
    383     EOpMulAssign,
    384     EOpVectorTimesMatrixAssign,
    385     EOpVectorTimesScalarAssign,
    386     EOpMatrixTimesScalarAssign,
    387     EOpMatrixTimesMatrixAssign,
    388     EOpDivAssign,
    389     EOpModAssign,
    390     EOpAndAssign,
    391     EOpInclusiveOrAssign,
    392     EOpExclusiveOrAssign,
    393     EOpLeftShiftAssign,
    394     EOpRightShiftAssign,
    395 
    396     //
    397     // Array operators
    398     //
    399 
    400     EOpArrayLength,      // "Array" distinguishes from length(v) built-in function, but it applies to vectors and matrices as well.
    401 
    402     //
    403     // Image operations
    404     //
    405 
    406     EOpImageGuardBegin,
    407 
    408     EOpImageQuerySize,
    409     EOpImageQuerySamples,
    410     EOpImageLoad,
    411     EOpImageStore,
    412     EOpImageAtomicAdd,
    413     EOpImageAtomicMin,
    414     EOpImageAtomicMax,
    415     EOpImageAtomicAnd,
    416     EOpImageAtomicOr,
    417     EOpImageAtomicXor,
    418     EOpImageAtomicExchange,
    419     EOpImageAtomicCompSwap,
    420 
    421     EOpSubpassLoad,
    422     EOpSubpassLoadMS,
    423     EOpSparseImageLoad,
    424 
    425     EOpImageGuardEnd,
    426 
    427     //
    428     // Texture operations
    429     //
    430 
    431     EOpTextureGuardBegin,
    432 
    433     EOpTextureQuerySize,
    434     EOpTextureQueryLod,
    435     EOpTextureQueryLevels,
    436     EOpTextureQuerySamples,
    437     EOpTexture,
    438     EOpTextureProj,
    439     EOpTextureLod,
    440     EOpTextureOffset,
    441     EOpTextureFetch,
    442     EOpTextureFetchOffset,
    443     EOpTextureProjOffset,
    444     EOpTextureLodOffset,
    445     EOpTextureProjLod,
    446     EOpTextureProjLodOffset,
    447     EOpTextureGrad,
    448     EOpTextureGradOffset,
    449     EOpTextureProjGrad,
    450     EOpTextureProjGradOffset,
    451     EOpTextureGather,
    452     EOpTextureGatherOffset,
    453     EOpTextureGatherOffsets,
    454     EOpTextureClamp,
    455     EOpTextureOffsetClamp,
    456     EOpTextureGradClamp,
    457     EOpTextureGradOffsetClamp,
    458 
    459     EOpSparseTextureGuardBegin,
    460 
    461     EOpSparseTexture,
    462     EOpSparseTextureLod,
    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,
    477 
    478     EOpSparseTextureGuardEnd,
    479 
    480     EOpTextureGuardEnd,
    481 
    482     //
    483     // Integer operations
    484     //
    485 
    486     EOpAddCarry,
    487     EOpSubBorrow,
    488     EOpUMulExtended,
    489     EOpIMulExtended,
    490     EOpBitfieldExtract,
    491     EOpBitfieldInsert,
    492     EOpBitFieldReverse,
    493     EOpBitCount,
    494     EOpFindLSB,
    495     EOpFindMSB,
    496 
    497     //
    498     // HLSL operations
    499     //
    500 
    501     EOpClip,                // discard if input value < 0
    502     EOpIsFinite,
    503     EOpLog10,               // base 10 log
    504     EOpRcp,                 // 1/x
    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,      // ...
    518     EOpAllMemoryBarrierWithGroupSync,    // memory barriers without non-hlsl AST equivalents
    519     EOpGroupMemoryBarrierWithGroupSync,  // ...
    520     EOpWorkgroupMemoryBarrier,           // ...
    521     EOpWorkgroupMemoryBarrierWithGroupSync, // ...
    522     EOpEvaluateAttributeSnapped,         // InterpolateAtOffset with int position on 16x16 grid
    523     EOpF32tof16,                         // HLSL conversion: half of a PackHalf2x16
    524     EOpF16tof32,                         // HLSL conversion: half of an UnpackHalf2x16
    525     EOpLit,                              // HLSL lighting coefficient vector
    526     EOpTextureBias,                      // HLSL texture bias: will be lowered to EOpTexture
    527     EOpAsDouble,                         // slightly different from EOpUint64BitsToDouble
    528 
    529     EOpMethodSample,                     // Texture object methods.  These are translated to existing
    530     EOpMethodSampleBias,                 // AST methods, and exist to represent HLSL semantics until that
    531     EOpMethodSampleCmp,                  // translation is performed.  See HlslParseContext::decomposeSampleMethods().
    532     EOpMethodSampleCmpLevelZero,         // ...
    533     EOpMethodSampleGrad,                 // ...
    534     EOpMethodSampleLevel,                // ...
    535     EOpMethodLoad,                       // ...
    536     EOpMethodGetDimensions,              // ...
    537     EOpMethodGetSamplePosition,          // ...
    538     EOpMethodGather,                     // ...
    539     EOpMethodCalculateLevelOfDetail,     // ...
    540     EOpMethodCalculateLevelOfDetailUnclamped,     // ...
    541 };
    542 
    543 class TIntermTraverser;
    544 class TIntermOperator;
    545 class TIntermAggregate;
    546 class TIntermUnary;
    547 class TIntermBinary;
    548 class TIntermConstantUnion;
    549 class TIntermSelection;
    550 class TIntermSwitch;
    551 class TIntermBranch;
    552 class TIntermTyped;
    553 class TIntermMethod;
    554 class TIntermSymbol;
    555 
    556 } // end namespace glslang
    557 
    558 //
    559 // Base class for the tree nodes
    560 //
    561 // (Put outside the glslang namespace, as it's used as part of the external interface.)
    562 //
    563 class TIntermNode {
    564 public:
    565     POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator())
    566 
    567     TIntermNode() { loc.init(); }
    568     virtual const glslang::TSourceLoc& getLoc() const { return loc; }
    569     virtual void setLoc(const glslang::TSourceLoc& l) { loc = l; }
    570     virtual void traverse(glslang::TIntermTraverser*) = 0;
    571     virtual       glslang::TIntermTyped*         getAsTyped()               { return 0; }
    572     virtual       glslang::TIntermOperator*      getAsOperator()            { return 0; }
    573     virtual       glslang::TIntermConstantUnion* getAsConstantUnion()       { return 0; }
    574     virtual       glslang::TIntermAggregate*     getAsAggregate()           { return 0; }
    575     virtual       glslang::TIntermUnary*         getAsUnaryNode()           { return 0; }
    576     virtual       glslang::TIntermBinary*        getAsBinaryNode()          { return 0; }
    577     virtual       glslang::TIntermSelection*     getAsSelectionNode()       { return 0; }
    578     virtual       glslang::TIntermSwitch*        getAsSwitchNode()          { return 0; }
    579     virtual       glslang::TIntermMethod*        getAsMethodNode()          { return 0; }
    580     virtual       glslang::TIntermSymbol*        getAsSymbolNode()          { return 0; }
    581     virtual       glslang::TIntermBranch*        getAsBranchNode()          { return 0; }
    582 
    583     virtual const glslang::TIntermTyped*         getAsTyped()         const { return 0; }
    584     virtual const glslang::TIntermOperator*      getAsOperator()      const { return 0; }
    585     virtual const glslang::TIntermConstantUnion* getAsConstantUnion() const { return 0; }
    586     virtual const glslang::TIntermAggregate*     getAsAggregate()     const { return 0; }
    587     virtual const glslang::TIntermUnary*         getAsUnaryNode()     const { return 0; }
    588     virtual const glslang::TIntermBinary*        getAsBinaryNode()    const { return 0; }
    589     virtual const glslang::TIntermSelection*     getAsSelectionNode() const { return 0; }
    590     virtual const glslang::TIntermSwitch*        getAsSwitchNode()    const { return 0; }
    591     virtual const glslang::TIntermMethod*        getAsMethodNode()    const { return 0; }
    592     virtual const glslang::TIntermSymbol*        getAsSymbolNode()    const { return 0; }
    593     virtual const glslang::TIntermBranch*        getAsBranchNode()    const { return 0; }
    594     virtual ~TIntermNode() { }
    595 
    596 protected:
    597     TIntermNode(const TIntermNode&);
    598     TIntermNode& operator=(const TIntermNode&);
    599     glslang::TSourceLoc loc;
    600 };
    601 
    602 namespace glslang {
    603 
    604 //
    605 // This is just to help yacc.
    606 //
    607 struct TIntermNodePair {
    608     TIntermNode* node1;
    609     TIntermNode* node2;
    610 };
    611 
    612 //
    613 // Intermediate class for nodes that have a type.
    614 //
    615 class TIntermTyped : public TIntermNode {
    616 public:
    617     TIntermTyped(const TType& t) { type.shallowCopy(t); }
    618     TIntermTyped(TBasicType basicType) { TType bt(basicType); type.shallowCopy(bt); }
    619     virtual       TIntermTyped* getAsTyped()       { return this; }
    620     virtual const TIntermTyped* getAsTyped() const { return this; }
    621     virtual void setType(const TType& t) { type.shallowCopy(t); }
    622     virtual const TType& getType() const { return type; }
    623     virtual TType& getWritableType() { return type; }
    624 
    625     virtual TBasicType getBasicType() const { return type.getBasicType(); }
    626     virtual TQualifier& getQualifier() { return type.getQualifier(); }
    627     virtual const TQualifier& getQualifier() const { return type.getQualifier(); }
    628     virtual void propagatePrecision(TPrecisionQualifier);
    629     virtual int getVectorSize() const { return type.getVectorSize(); }
    630     virtual int getMatrixCols() const { return type.getMatrixCols(); }
    631     virtual int getMatrixRows() const { return type.getMatrixRows(); }
    632     virtual bool isMatrix() const { return type.isMatrix(); }
    633     virtual bool isArray()  const { return type.isArray(); }
    634     virtual bool isVector() const { return type.isVector(); }
    635     virtual bool isScalar() const { return type.isScalar(); }
    636     virtual bool isStruct() const { return type.isStruct(); }
    637     TString getCompleteString() const { return type.getCompleteString(); }
    638 
    639 protected:
    640     TIntermTyped& operator=(const TIntermTyped&);
    641     TType type;
    642 };
    643 
    644 //
    645 // Handle for, do-while, and while loops.
    646 //
    647 class TIntermLoop : public TIntermNode {
    648 public:
    649     TIntermLoop(TIntermNode* aBody, TIntermTyped* aTest, TIntermTyped* aTerminal, bool testFirst) :
    650         body(aBody),
    651         test(aTest),
    652         terminal(aTerminal),
    653         first(testFirst) { }
    654     virtual void traverse(TIntermTraverser*);
    655     TIntermNode*  getBody() const { return body; }
    656     TIntermTyped* getTest() const { return test; }
    657     TIntermTyped* getTerminal() const { return terminal; }
    658     bool testFirst() const { return first; }
    659 protected:
    660     TIntermNode* body;       // code to loop over
    661     TIntermTyped* test;      // exit condition associated with loop, could be 0 for 'for' loops
    662     TIntermTyped* terminal;  // exists for for-loops
    663     bool first;              // true for while and for, not for do-while
    664 };
    665 
    666 //
    667 // Handle case, break, continue, return, and kill.
    668 //
    669 class TIntermBranch : public TIntermNode {
    670 public:
    671     TIntermBranch(TOperator op, TIntermTyped* e) :
    672         flowOp(op),
    673         expression(e) { }
    674     virtual       TIntermBranch* getAsBranchNode()       { return this; }
    675     virtual const TIntermBranch* getAsBranchNode() const { return this; }
    676     virtual void traverse(TIntermTraverser*);
    677     TOperator getFlowOp() const { return flowOp; }
    678     TIntermTyped* getExpression() const { return expression; }
    679 protected:
    680     TOperator flowOp;
    681     TIntermTyped* expression;
    682 };
    683 
    684 //
    685 // Represent method names before seeing their calling signature
    686 // or resolving them to operations.  Just an expression as the base object
    687 // and a textural name.
    688 //
    689 class TIntermMethod : public TIntermTyped {
    690 public:
    691     TIntermMethod(TIntermTyped* o, const TType& t, const TString& m) : TIntermTyped(t), object(o), method(m) { }
    692     virtual       TIntermMethod* getAsMethodNode()       { return this; }
    693     virtual const TIntermMethod* getAsMethodNode() const { return this; }
    694     virtual const TString& getMethodName() const { return method; }
    695     virtual TIntermTyped* getObject() const { return object; }
    696     virtual void traverse(TIntermTraverser*);
    697 protected:
    698     TIntermTyped* object;
    699     TString method;
    700 };
    701 
    702 //
    703 // Nodes that correspond to symbols or constants in the source code.
    704 //
    705 class TIntermSymbol : public TIntermTyped {
    706 public:
    707     // if symbol is initialized as symbol(sym), the memory comes from the pool allocator of sym. If sym comes from
    708     // per process threadPoolAllocator, then it causes increased memory usage per compile
    709     // it is essential to use "symbol = sym" to assign to symbol
    710     TIntermSymbol(int i, const TString& n, const TType& t)
    711         : TIntermTyped(t), id(i), constSubtree(nullptr)
    712           { name = n; }
    713     virtual int getId() const { return id; }
    714     virtual const TString& getName() const { return name; }
    715     virtual void traverse(TIntermTraverser*);
    716     virtual       TIntermSymbol* getAsSymbolNode()       { return this; }
    717     virtual const TIntermSymbol* getAsSymbolNode() const { return this; }
    718     void setConstArray(const TConstUnionArray& c) { constArray = c; }
    719     const TConstUnionArray& getConstArray() const { return constArray; }
    720     void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; }
    721     TIntermTyped* getConstSubtree() const { return constSubtree; }
    722 
    723 protected:
    724     int id;                      // the unique id of the symbol this node represents
    725     TString name;                // the name of the symbol this node represents
    726     TConstUnionArray constArray; // if the symbol is a front-end compile-time constant, this is its value
    727     TIntermTyped* constSubtree;
    728 };
    729 
    730 class TIntermConstantUnion : public TIntermTyped {
    731 public:
    732     TIntermConstantUnion(const TConstUnionArray& ua, const TType& t) : TIntermTyped(t), constArray(ua), literal(false) { }
    733     const TConstUnionArray& getConstArray() const { return constArray; }
    734     virtual       TIntermConstantUnion* getAsConstantUnion()       { return this; }
    735     virtual const TIntermConstantUnion* getAsConstantUnion() const { return this; }
    736     virtual void traverse(TIntermTraverser*);
    737     virtual TIntermTyped* fold(TOperator, const TIntermTyped*) const;
    738     virtual TIntermTyped* fold(TOperator, const TType&) const;
    739     void setLiteral() { literal = true; }
    740     void setExpression() { literal = false; }
    741     bool isLiteral() const { return literal; }
    742 
    743 protected:
    744     TIntermConstantUnion& operator=(const TIntermConstantUnion&);
    745 
    746     const TConstUnionArray constArray;
    747     bool literal;  // true if node represents a literal in the source code
    748 };
    749 
    750 // Represent the independent aspects of a texturing TOperator
    751 struct TCrackedTextureOp {
    752     bool query;
    753     bool proj;
    754     bool lod;
    755     bool fetch;
    756     bool offset;
    757     bool offsets;
    758     bool gather;
    759     bool grad;
    760     bool subpass;
    761     bool lodClamp;
    762 };
    763 
    764 //
    765 // Intermediate class for node types that hold operators.
    766 //
    767 class TIntermOperator : public TIntermTyped {
    768 public:
    769     virtual       TIntermOperator* getAsOperator()       { return this; }
    770     virtual const TIntermOperator* getAsOperator() const { return this; }
    771     TOperator getOp() const { return op; }
    772     virtual bool promote() { return true; }
    773     bool modifiesState() const;
    774     bool isConstructor() const;
    775     bool isTexture() const { return op > EOpTextureGuardBegin && op < EOpTextureGuardEnd; }
    776     bool isImage()   const { return op > EOpImageGuardBegin   && op < EOpImageGuardEnd; }
    777     bool isSparseTexture() const { return op > EOpSparseTextureGuardBegin && op < EOpSparseTextureGuardEnd; }
    778     bool isSparseImage()   const { return op == EOpSparseImageLoad; }
    779 
    780     // Crack the op into the individual dimensions of texturing operation.
    781     void crackTexture(TSampler sampler, TCrackedTextureOp& cracked) const
    782     {
    783         cracked.query = false;
    784         cracked.proj = false;
    785         cracked.lod = false;
    786         cracked.fetch = false;
    787         cracked.offset = false;
    788         cracked.offsets = false;
    789         cracked.gather = false;
    790         cracked.grad = false;
    791         cracked.subpass = false;
    792         cracked.lodClamp = false;
    793 
    794         switch (op) {
    795         case EOpImageQuerySize:
    796         case EOpImageQuerySamples:
    797         case EOpTextureQuerySize:
    798         case EOpTextureQueryLod:
    799         case EOpTextureQueryLevels:
    800         case EOpTextureQuerySamples:
    801         case EOpSparseTexelsResident:
    802             cracked.query = true;
    803             break;
    804         case EOpTexture:
    805         case EOpSparseTexture:
    806             break;
    807         case EOpTextureClamp:
    808         case EOpSparseTextureClamp:
    809             cracked.lodClamp = true;
    810             break;
    811         case EOpTextureProj:
    812             cracked.proj = true;
    813             break;
    814         case EOpTextureLod:
    815         case EOpSparseTextureLod:
    816             cracked.lod = true;
    817             break;
    818         case EOpTextureOffset:
    819         case EOpSparseTextureOffset:
    820             cracked.offset = true;
    821             break;
    822         case EOpTextureOffsetClamp:
    823         case EOpSparseTextureOffsetClamp:
    824             cracked.offset = true;
    825             cracked.lodClamp = true;
    826             break;
    827         case EOpTextureFetch:
    828         case EOpSparseTextureFetch:
    829             cracked.fetch = true;
    830             if (sampler.dim == Esd1D || (sampler.dim == Esd2D && ! sampler.ms) || sampler.dim == Esd3D)
    831                 cracked.lod = true;
    832             break;
    833         case EOpTextureFetchOffset:
    834         case EOpSparseTextureFetchOffset:
    835             cracked.fetch = true;
    836             cracked.offset = true;
    837             if (sampler.dim == Esd1D || (sampler.dim == Esd2D && ! sampler.ms) || sampler.dim == Esd3D)
    838                 cracked.lod = true;
    839             break;
    840         case EOpTextureProjOffset:
    841             cracked.offset = true;
    842             cracked.proj = true;
    843             break;
    844         case EOpTextureLodOffset:
    845         case EOpSparseTextureLodOffset:
    846             cracked.offset = true;
    847             cracked.lod = true;
    848             break;
    849         case EOpTextureProjLod:
    850             cracked.lod = true;
    851             cracked.proj = true;
    852             break;
    853         case EOpTextureProjLodOffset:
    854             cracked.offset = true;
    855             cracked.lod = true;
    856             cracked.proj = true;
    857             break;
    858         case EOpTextureGrad:
    859         case EOpSparseTextureGrad:
    860             cracked.grad = true;
    861             break;
    862         case EOpTextureGradClamp:
    863         case EOpSparseTextureGradClamp:
    864             cracked.grad = true;
    865             cracked.lodClamp = true;
    866             break;
    867         case EOpTextureGradOffset:
    868         case EOpSparseTextureGradOffset:
    869             cracked.grad = true;
    870             cracked.offset = true;
    871             break;
    872         case EOpTextureProjGrad:
    873             cracked.grad = true;
    874             cracked.proj = true;
    875             break;
    876         case EOpTextureProjGradOffset:
    877             cracked.grad = true;
    878             cracked.offset = true;
    879             cracked.proj = true;
    880             break;
    881         case EOpTextureGradOffsetClamp:
    882         case EOpSparseTextureGradOffsetClamp:
    883             cracked.grad = true;
    884             cracked.offset = true;
    885             cracked.lodClamp = true;
    886             break;
    887         case EOpTextureGather:
    888         case EOpSparseTextureGather:
    889             cracked.gather = true;
    890             break;
    891         case EOpTextureGatherOffset:
    892         case EOpSparseTextureGatherOffset:
    893             cracked.gather = true;
    894             cracked.offset = true;
    895             break;
    896         case EOpTextureGatherOffsets:
    897         case EOpSparseTextureGatherOffsets:
    898             cracked.gather = true;
    899             cracked.offsets = true;
    900             break;
    901         case EOpSubpassLoad:
    902         case EOpSubpassLoadMS:
    903             cracked.subpass = true;
    904             break;
    905         default:
    906             break;
    907         }
    908     }
    909 
    910 protected:
    911     TIntermOperator(TOperator o) : TIntermTyped(EbtFloat), op(o) {}
    912     TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o) {}
    913     TOperator op;
    914 };
    915 
    916 //
    917 // Nodes for all the basic binary math operators.
    918 //
    919 class TIntermBinary : public TIntermOperator {
    920 public:
    921     TIntermBinary(TOperator o) : TIntermOperator(o) {}
    922     virtual void traverse(TIntermTraverser*);
    923     virtual void setLeft(TIntermTyped* n) { left = n; }
    924     virtual void setRight(TIntermTyped* n) { right = n; }
    925     virtual TIntermTyped* getLeft() const { return left; }
    926     virtual TIntermTyped* getRight() const { return right; }
    927     virtual       TIntermBinary* getAsBinaryNode()       { return this; }
    928     virtual const TIntermBinary* getAsBinaryNode() const { return this; }
    929     virtual bool promote();
    930     virtual void updatePrecision();
    931 protected:
    932     TIntermTyped* left;
    933     TIntermTyped* right;
    934 };
    935 
    936 //
    937 // Nodes for unary math operators.
    938 //
    939 class TIntermUnary : public TIntermOperator {
    940 public:
    941     TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(0) {}
    942     TIntermUnary(TOperator o) : TIntermOperator(o), operand(0) {}
    943     virtual void traverse(TIntermTraverser*);
    944     virtual void setOperand(TIntermTyped* o) { operand = o; }
    945     virtual       TIntermTyped* getOperand() { return operand; }
    946     virtual const TIntermTyped* getOperand() const { return operand; }
    947     virtual       TIntermUnary* getAsUnaryNode()       { return this; }
    948     virtual const TIntermUnary* getAsUnaryNode() const { return this; }
    949     virtual bool promote();
    950     virtual void updatePrecision();
    951 protected:
    952     TIntermTyped* operand;
    953 };
    954 
    955 typedef TVector<TIntermNode*> TIntermSequence;
    956 typedef TVector<int> TQualifierList;
    957 //
    958 // Nodes that operate on an arbitrary sized set of children.
    959 //
    960 class TIntermAggregate : public TIntermOperator {
    961 public:
    962     TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(0) { }
    963     TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(0) { }
    964     ~TIntermAggregate() { delete pragmaTable; }
    965     virtual       TIntermAggregate* getAsAggregate()       { return this; }
    966     virtual const TIntermAggregate* getAsAggregate() const { return this; }
    967     virtual void setOperator(TOperator o) { op = o; }
    968     virtual       TIntermSequence& getSequence()       { return sequence; }
    969     virtual const TIntermSequence& getSequence() const { return sequence; }
    970     virtual void setName(const TString& n) { name = n; }
    971     virtual const TString& getName() const { return name; }
    972     virtual void traverse(TIntermTraverser*);
    973     virtual void setUserDefined() { userDefined = true; }
    974     virtual bool isUserDefined() { return userDefined; }
    975     virtual TQualifierList& getQualifierList() { return qualifier; }
    976     virtual const TQualifierList& getQualifierList() const { return qualifier; }
    977     void setOptimize(bool o) { optimize = o; }
    978     void setDebug(bool d) { debug = d; }
    979     bool getOptimize() const { return optimize; }
    980     bool getDebug() const { return debug; }
    981     void addToPragmaTable(const TPragmaTable& pTable);
    982     const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
    983 protected:
    984     TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
    985     TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
    986     TIntermSequence sequence;
    987     TQualifierList qualifier;
    988     TString name;
    989     bool userDefined; // used for user defined function names
    990     bool optimize;
    991     bool debug;
    992     TPragmaTable* pragmaTable;
    993 };
    994 
    995 //
    996 // For if tests.
    997 //
    998 class TIntermSelection : public TIntermTyped {
    999 public:
   1000     TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
   1001         TIntermTyped(EbtVoid), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
   1002     TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
   1003         TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB) {}
   1004     virtual void traverse(TIntermTraverser*);
   1005     virtual TIntermTyped* getCondition() const { return condition; }
   1006     virtual TIntermNode* getTrueBlock() const { return trueBlock; }
   1007     virtual TIntermNode* getFalseBlock() const { return falseBlock; }
   1008     virtual       TIntermSelection* getAsSelectionNode()       { return this; }
   1009     virtual const TIntermSelection* getAsSelectionNode() const { return this; }
   1010 protected:
   1011     TIntermTyped* condition;
   1012     TIntermNode* trueBlock;
   1013     TIntermNode* falseBlock;
   1014 };
   1015 
   1016 //
   1017 // For switch statements.  Designed use is that a switch will have sequence of nodes
   1018 // that are either case/default nodes or a *single* node that represents all the code
   1019 // in between (if any) consecutive case/defaults.  So, a traversal need only deal with
   1020 // 0 or 1 nodes per case/default statement.
   1021 //
   1022 class TIntermSwitch : public TIntermNode {
   1023 public:
   1024     TIntermSwitch(TIntermTyped* cond, TIntermAggregate* b) : condition(cond), body(b) { }
   1025     virtual void traverse(TIntermTraverser*);
   1026     virtual TIntermNode* getCondition() const { return condition; }
   1027     virtual TIntermAggregate* getBody() const { return body; }
   1028     virtual       TIntermSwitch* getAsSwitchNode()       { return this; }
   1029     virtual const TIntermSwitch* getAsSwitchNode() const { return this; }
   1030 protected:
   1031     TIntermTyped* condition;
   1032     TIntermAggregate* body;
   1033 };
   1034 
   1035 enum TVisit
   1036 {
   1037     EvPreVisit,
   1038     EvInVisit,
   1039     EvPostVisit
   1040 };
   1041 
   1042 //
   1043 // For traversing the tree.  User should derive from this,
   1044 // put their traversal specific data in it, and then pass
   1045 // it to a Traverse method.
   1046 //
   1047 // When using this, just fill in the methods for nodes you want visited.
   1048 // Return false from a pre-visit to skip visiting that node's subtree.
   1049 //
   1050 // Explicitly set postVisit to true if you want post visiting, otherwise,
   1051 // filled in methods will only be called at pre-visit time (before processing
   1052 // the subtree).  Similarly for inVisit for in-order visiting of nodes with
   1053 // multiple children.
   1054 //
   1055 // If you only want post-visits, explicitly turn off preVisit (and inVisit)
   1056 // and turn on postVisit.
   1057 //
   1058 // In general, for the visit*() methods, return true from interior nodes
   1059 // to have the traversal continue on to children.
   1060 //
   1061 // If you process children yourself, or don't want them processed, return false.
   1062 //
   1063 class TIntermTraverser {
   1064 public:
   1065     POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator())
   1066     TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
   1067             preVisit(preVisit),
   1068             inVisit(inVisit),
   1069             postVisit(postVisit),
   1070             rightToLeft(rightToLeft),
   1071             depth(0),
   1072             maxDepth(0) { }
   1073     virtual ~TIntermTraverser() { }
   1074 
   1075     virtual void visitSymbol(TIntermSymbol*)               { }
   1076     virtual void visitConstantUnion(TIntermConstantUnion*) { }
   1077     virtual bool visitBinary(TVisit, TIntermBinary*)       { return true; }
   1078     virtual bool visitUnary(TVisit, TIntermUnary*)         { return true; }
   1079     virtual bool visitSelection(TVisit, TIntermSelection*) { return true; }
   1080     virtual bool visitAggregate(TVisit, TIntermAggregate*) { return true; }
   1081     virtual bool visitLoop(TVisit, TIntermLoop*)           { return true; }
   1082     virtual bool visitBranch(TVisit, TIntermBranch*)       { return true; }
   1083     virtual bool visitSwitch(TVisit, TIntermSwitch*)       { return true; }
   1084 
   1085     int getMaxDepth() const { return maxDepth; }
   1086 
   1087     void incrementDepth(TIntermNode *current)
   1088     {
   1089         depth++;
   1090         maxDepth = (std::max)(maxDepth, depth);
   1091         path.push_back(current);
   1092     }
   1093 
   1094     void decrementDepth()
   1095     {
   1096         depth--;
   1097         path.pop_back();
   1098     }
   1099 
   1100     TIntermNode *getParentNode()
   1101     {
   1102         return path.size() == 0 ? NULL : path.back();
   1103     }
   1104 
   1105     const bool preVisit;
   1106     const bool inVisit;
   1107     const bool postVisit;
   1108     const bool rightToLeft;
   1109 
   1110 protected:
   1111     TIntermTraverser& operator=(TIntermTraverser&);
   1112 
   1113     int depth;
   1114     int maxDepth;
   1115 
   1116     // All the nodes from root to the current node's parent during traversing.
   1117     TVector<TIntermNode *> path;
   1118 };
   1119 
   1120 // KHR_vulkan_glsl says "Two arrays sized with specialization constants are the same type only if
   1121 // sized with the same symbol, involving no operations"
   1122 inline bool SameSpecializationConstants(TIntermTyped* node1, TIntermTyped* node2)
   1123 {
   1124     return node1->getAsSymbolNode() && node2->getAsSymbolNode() &&
   1125            node1->getAsSymbolNode()->getId() == node2->getAsSymbolNode()->getId();
   1126 }
   1127 
   1128 } // end namespace glslang
   1129 
   1130 #endif // __INTERMEDIATE_H
   1131