Home | History | Annotate | Download | only in MachineIndependent
      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 #include "localintermediate.h"
     38 #include "../Include/InfoSink.h"
     39 
     40 #ifdef _MSC_VER
     41 #include <cfloat>
     42 #else
     43 #include <cmath>
     44 #endif
     45 
     46 namespace {
     47 
     48 bool IsInfinity(double x) {
     49 #ifdef _MSC_VER
     50     switch (_fpclass(x)) {
     51     case _FPCLASS_NINF:
     52     case _FPCLASS_PINF:
     53         return true;
     54     default:
     55         return false;
     56     }
     57 #else
     58     return std::isinf(x);
     59 #endif
     60 }
     61 
     62 bool IsNan(double x) {
     63 #ifdef _MSC_VER
     64     switch (_fpclass(x)) {
     65     case _FPCLASS_SNAN:
     66     case _FPCLASS_QNAN:
     67         return true;
     68     default:
     69         return false;
     70     }
     71 #else
     72   return std::isnan(x);
     73 #endif
     74 }
     75 
     76 }
     77 
     78 namespace glslang {
     79 
     80 //
     81 // Two purposes:
     82 // 1.  Show an example of how to iterate tree.  Functions can
     83 //     also directly call Traverse() on children themselves to
     84 //     have finer grained control over the process than shown here.
     85 //     See the last function for how to get started.
     86 // 2.  Print out a text based description of the tree.
     87 //
     88 
     89 //
     90 // Use this class to carry along data from node to node in
     91 // the traversal
     92 //
     93 class TOutputTraverser : public TIntermTraverser {
     94 public:
     95     TOutputTraverser(TInfoSink& i) : infoSink(i) { }
     96 
     97     virtual bool visitBinary(TVisit, TIntermBinary* node);
     98     virtual bool visitUnary(TVisit, TIntermUnary* node);
     99     virtual bool visitAggregate(TVisit, TIntermAggregate* node);
    100     virtual bool visitSelection(TVisit, TIntermSelection* node);
    101     virtual void visitConstantUnion(TIntermConstantUnion* node);
    102     virtual void visitSymbol(TIntermSymbol* node);
    103     virtual bool visitLoop(TVisit, TIntermLoop* node);
    104     virtual bool visitBranch(TVisit, TIntermBranch* node);
    105     virtual bool visitSwitch(TVisit, TIntermSwitch* node);
    106 
    107     TInfoSink& infoSink;
    108 protected:
    109     TOutputTraverser(TOutputTraverser&);
    110     TOutputTraverser& operator=(TOutputTraverser&);
    111 };
    112 
    113 //
    114 // Helper functions for printing, not part of traversing.
    115 //
    116 
    117 static void OutputTreeText(TInfoSink& infoSink, const TIntermNode* node, const int depth)
    118 {
    119     int i;
    120 
    121     infoSink.debug << node->getLoc().string << ":";
    122     if (node->getLoc().line)
    123         infoSink.debug << node->getLoc().line;
    124     else
    125         infoSink.debug << "? ";
    126 
    127     for (i = 0; i < depth; ++i)
    128         infoSink.debug << "  ";
    129 }
    130 
    131 //
    132 // The rest of the file are the traversal functions.  The last one
    133 // is the one that starts the traversal.
    134 //
    135 // Return true from interior nodes to have the external traversal
    136 // continue on to children.  If you process children yourself,
    137 // return false.
    138 //
    139 
    140 bool TOutputTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)
    141 {
    142     TInfoSink& out = infoSink;
    143 
    144     OutputTreeText(out, node, depth);
    145 
    146     switch (node->getOp()) {
    147     case EOpAssign:                   out.debug << "move second child to first child";           break;
    148     case EOpAddAssign:                out.debug << "add second child into first child";          break;
    149     case EOpSubAssign:                out.debug << "subtract second child into first child";     break;
    150     case EOpMulAssign:                out.debug << "multiply second child into first child";     break;
    151     case EOpVectorTimesMatrixAssign:  out.debug << "matrix mult second child into first child";  break;
    152     case EOpVectorTimesScalarAssign:  out.debug << "vector scale second child into first child"; break;
    153     case EOpMatrixTimesScalarAssign:  out.debug << "matrix scale second child into first child"; break;
    154     case EOpMatrixTimesMatrixAssign:  out.debug << "matrix mult second child into first child";  break;
    155     case EOpDivAssign:                out.debug << "divide second child into first child";       break;
    156     case EOpModAssign:                out.debug << "mod second child into first child";          break;
    157     case EOpAndAssign:                out.debug << "and second child into first child";          break;
    158     case EOpInclusiveOrAssign:        out.debug << "or second child into first child";           break;
    159     case EOpExclusiveOrAssign:        out.debug << "exclusive or second child into first child"; break;
    160     case EOpLeftShiftAssign:          out.debug << "left shift second child into first child";   break;
    161     case EOpRightShiftAssign:         out.debug << "right shift second child into first child";  break;
    162 
    163     case EOpIndexDirect:   out.debug << "direct index";   break;
    164     case EOpIndexIndirect: out.debug << "indirect index"; break;
    165     case EOpIndexDirectStruct:
    166         out.debug << (*node->getLeft()->getType().getStruct())[node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst()].type->getFieldName();
    167         out.debug << ": direct index for structure";      break;
    168     case EOpVectorSwizzle: out.debug << "vector swizzle"; break;
    169     case EOpMatrixSwizzle: out.debug << "matrix swizzle"; break;
    170 
    171     case EOpAdd:    out.debug << "add";                     break;
    172     case EOpSub:    out.debug << "subtract";                break;
    173     case EOpMul:    out.debug << "component-wise multiply"; break;
    174     case EOpDiv:    out.debug << "divide";                  break;
    175     case EOpMod:    out.debug << "mod";                     break;
    176     case EOpRightShift:  out.debug << "right-shift";  break;
    177     case EOpLeftShift:   out.debug << "left-shift";   break;
    178     case EOpAnd:         out.debug << "bitwise and";  break;
    179     case EOpInclusiveOr: out.debug << "inclusive-or"; break;
    180     case EOpExclusiveOr: out.debug << "exclusive-or"; break;
    181     case EOpEqual:            out.debug << "Compare Equal";                 break;
    182     case EOpNotEqual:         out.debug << "Compare Not Equal";             break;
    183     case EOpLessThan:         out.debug << "Compare Less Than";             break;
    184     case EOpGreaterThan:      out.debug << "Compare Greater Than";          break;
    185     case EOpLessThanEqual:    out.debug << "Compare Less Than or Equal";    break;
    186     case EOpGreaterThanEqual: out.debug << "Compare Greater Than or Equal"; break;
    187     case EOpVectorEqual:      out.debug << "Equal";                         break;
    188     case EOpVectorNotEqual:   out.debug << "NotEqual";                      break;
    189 
    190     case EOpVectorTimesScalar: out.debug << "vector-scale";          break;
    191     case EOpVectorTimesMatrix: out.debug << "vector-times-matrix";   break;
    192     case EOpMatrixTimesVector: out.debug << "matrix-times-vector";   break;
    193     case EOpMatrixTimesScalar: out.debug << "matrix-scale";          break;
    194     case EOpMatrixTimesMatrix: out.debug << "matrix-multiply";       break;
    195 
    196     case EOpLogicalOr:  out.debug << "logical-or";   break;
    197     case EOpLogicalXor: out.debug << "logical-xor"; break;
    198     case EOpLogicalAnd: out.debug << "logical-and"; break;
    199     default: out.debug << "<unknown op>";
    200     }
    201 
    202     out.debug << " (" << node->getCompleteString() << ")";
    203 
    204     out.debug << "\n";
    205 
    206     return true;
    207 }
    208 
    209 bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
    210 {
    211     TInfoSink& out = infoSink;
    212 
    213     OutputTreeText(out, node, depth);
    214 
    215     switch (node->getOp()) {
    216     case EOpNegative:       out.debug << "Negate value";         break;
    217     case EOpVectorLogicalNot:
    218     case EOpLogicalNot:     out.debug << "Negate conditional";   break;
    219     case EOpBitwiseNot:     out.debug << "Bitwise not";          break;
    220 
    221     case EOpPostIncrement:  out.debug << "Post-Increment";       break;
    222     case EOpPostDecrement:  out.debug << "Post-Decrement";       break;
    223     case EOpPreIncrement:   out.debug << "Pre-Increment";        break;
    224     case EOpPreDecrement:   out.debug << "Pre-Decrement";        break;
    225 
    226     case EOpConvIntToBool:     out.debug << "Convert int to bool";     break;
    227     case EOpConvUintToBool:    out.debug << "Convert uint to bool";    break;
    228     case EOpConvFloatToBool:   out.debug << "Convert float to bool";   break;
    229     case EOpConvDoubleToBool:  out.debug << "Convert double to bool";  break;
    230     case EOpConvInt64ToBool:   out.debug << "Convert int64 to bool";   break;
    231     case EOpConvUint64ToBool:  out.debug << "Convert uint64 to bool";  break;
    232     case EOpConvIntToFloat:    out.debug << "Convert int to float";    break;
    233     case EOpConvUintToFloat:   out.debug << "Convert uint to float";   break;
    234     case EOpConvDoubleToFloat: out.debug << "Convert double to float"; break;
    235     case EOpConvInt64ToFloat:  out.debug << "Convert int64 to float";  break;
    236     case EOpConvUint64ToFloat: out.debug << "Convert uint64 to float"; break;
    237     case EOpConvBoolToFloat:   out.debug << "Convert bool to float";   break;
    238     case EOpConvUintToInt:     out.debug << "Convert uint to int";     break;
    239     case EOpConvFloatToInt:    out.debug << "Convert float to int";    break;
    240     case EOpConvDoubleToInt:   out.debug << "Convert double to int";   break;
    241     case EOpConvBoolToInt:     out.debug << "Convert bool to int";     break;
    242     case EOpConvInt64ToInt:    out.debug << "Convert int64 to int";    break;
    243     case EOpConvUint64ToInt:   out.debug << "Convert uint64 to int";   break;
    244     case EOpConvIntToUint:     out.debug << "Convert int to uint";     break;
    245     case EOpConvFloatToUint:   out.debug << "Convert float to uint";   break;
    246     case EOpConvDoubleToUint:  out.debug << "Convert double to uint";  break;
    247     case EOpConvBoolToUint:    out.debug << "Convert bool to uint";    break;
    248     case EOpConvInt64ToUint:   out.debug << "Convert int64 to uint";   break;
    249     case EOpConvUint64ToUint:  out.debug << "Convert uint64 to uint";  break;
    250     case EOpConvIntToDouble:   out.debug << "Convert int to double";   break;
    251     case EOpConvUintToDouble:  out.debug << "Convert uint to double";  break;
    252     case EOpConvFloatToDouble: out.debug << "Convert float to double"; break;
    253     case EOpConvBoolToDouble:  out.debug << "Convert bool to double";  break;
    254     case EOpConvInt64ToDouble: out.debug << "Convert int64 to double"; break;
    255     case EOpConvUint64ToDouble: out.debug << "Convert uint64 to double";  break;
    256     case EOpConvBoolToInt64:   out.debug << "Convert bool to int64";   break;
    257     case EOpConvIntToInt64:    out.debug << "Convert int to int64";    break;
    258     case EOpConvUintToInt64:   out.debug << "Convert uint to int64";   break;
    259     case EOpConvFloatToInt64:  out.debug << "Convert float to int64";  break;
    260     case EOpConvDoubleToInt64: out.debug << "Convert double to int64"; break;
    261     case EOpConvUint64ToInt64: out.debug << "Convert uint64 to int64"; break;
    262     case EOpConvBoolToUint64:  out.debug << "Convert bool to uint64";  break;
    263     case EOpConvIntToUint64:   out.debug << "Convert int to uint64";   break;
    264     case EOpConvUintToUint64:  out.debug << "Convert uint to uint64";  break;
    265     case EOpConvFloatToUint64: out.debug << "Convert float to uint64"; break;
    266     case EOpConvDoubleToUint64: out.debug << "Convert double to uint64"; break;
    267     case EOpConvInt64ToUint64: out.debug << "Convert uint64 to uint64"; break;
    268 
    269     case EOpRadians:        out.debug << "radians";              break;
    270     case EOpDegrees:        out.debug << "degrees";              break;
    271     case EOpSin:            out.debug << "sine";                 break;
    272     case EOpCos:            out.debug << "cosine";               break;
    273     case EOpTan:            out.debug << "tangent";              break;
    274     case EOpAsin:           out.debug << "arc sine";             break;
    275     case EOpAcos:           out.debug << "arc cosine";           break;
    276     case EOpAtan:           out.debug << "arc tangent";          break;
    277     case EOpSinh:           out.debug << "hyp. sine";            break;
    278     case EOpCosh:           out.debug << "hyp. cosine";          break;
    279     case EOpTanh:           out.debug << "hyp. tangent";         break;
    280     case EOpAsinh:          out.debug << "arc hyp. sine";        break;
    281     case EOpAcosh:          out.debug << "arc hyp. cosine";      break;
    282     case EOpAtanh:          out.debug << "arc hyp. tangent";     break;
    283 
    284     case EOpExp:            out.debug << "exp";                  break;
    285     case EOpLog:            out.debug << "log";                  break;
    286     case EOpExp2:           out.debug << "exp2";                 break;
    287     case EOpLog2:           out.debug << "log2";                 break;
    288     case EOpSqrt:           out.debug << "sqrt";                 break;
    289     case EOpInverseSqrt:    out.debug << "inverse sqrt";         break;
    290 
    291     case EOpAbs:            out.debug << "Absolute value";       break;
    292     case EOpSign:           out.debug << "Sign";                 break;
    293     case EOpFloor:          out.debug << "Floor";                break;
    294     case EOpTrunc:          out.debug << "trunc";                break;
    295     case EOpRound:          out.debug << "round";                break;
    296     case EOpRoundEven:      out.debug << "roundEven";            break;
    297     case EOpCeil:           out.debug << "Ceiling";              break;
    298     case EOpFract:          out.debug << "Fraction";             break;
    299 
    300     case EOpIsNan:          out.debug << "isnan";                break;
    301     case EOpIsInf:          out.debug << "isinf";                break;
    302 
    303     case EOpFloatBitsToInt: out.debug << "floatBitsToInt";       break;
    304     case EOpFloatBitsToUint:out.debug << "floatBitsToUint";      break;
    305     case EOpIntBitsToFloat: out.debug << "intBitsToFloat";       break;
    306     case EOpUintBitsToFloat:out.debug << "uintBitsToFloat";      break;
    307     case EOpDoubleBitsToInt64:  out.debug << "doubleBitsToInt64";  break;
    308     case EOpDoubleBitsToUint64: out.debug << "doubleBitsToUint64"; break;
    309     case EOpInt64BitsToDouble:  out.debug << "int64BitsToDouble";  break;
    310     case EOpUint64BitsToDouble: out.debug << "uint64BitsToDouble"; break;
    311 #ifdef AMD_EXTENSIONS
    312     case EOpFloat16BitsToInt16:  out.debug << "float16BitsToInt16";  break;
    313     case EOpFloat16BitsToUint16: out.debug << "float16BitsToUint16"; break;
    314     case EOpInt16BitsToFloat16:  out.debug << "int16BitsToFloat16";  break;
    315     case EOpUint16BitsToFloat16: out.debug << "uint16BitsToFloat16"; break;
    316 #endif
    317 
    318     case EOpPackSnorm2x16:  out.debug << "packSnorm2x16";        break;
    319     case EOpUnpackSnorm2x16:out.debug << "unpackSnorm2x16";      break;
    320     case EOpPackUnorm2x16:  out.debug << "packUnorm2x16";        break;
    321     case EOpUnpackUnorm2x16:out.debug << "unpackUnorm2x16";      break;
    322     case EOpPackHalf2x16:   out.debug << "packHalf2x16";         break;
    323     case EOpUnpackHalf2x16: out.debug << "unpackHalf2x16";       break;
    324 
    325     case EOpPackSnorm4x8:     out.debug << "PackSnorm4x8";       break;
    326     case EOpUnpackSnorm4x8:   out.debug << "UnpackSnorm4x8";     break;
    327     case EOpPackUnorm4x8:     out.debug << "PackUnorm4x8";       break;
    328     case EOpUnpackUnorm4x8:   out.debug << "UnpackUnorm4x8";     break;
    329     case EOpPackDouble2x32:   out.debug << "PackDouble2x32";     break;
    330     case EOpUnpackDouble2x32: out.debug << "UnpackDouble2x32";   break;
    331 
    332     case EOpPackInt2x32:      out.debug << "packInt2x32";        break;
    333     case EOpUnpackInt2x32:    out.debug << "unpackInt2x32";      break;
    334     case EOpPackUint2x32:     out.debug << "packUint2x32";       break;
    335     case EOpUnpackUint2x32:   out.debug << "unpackUint2x32";     break;
    336 
    337 #ifdef AMD_EXTENSIONS
    338     case EOpPackInt2x16:      out.debug << "packInt2x16";        break;
    339     case EOpUnpackInt2x16:    out.debug << "unpackInt2x16";      break;
    340     case EOpPackUint2x16:     out.debug << "packUint2x16";       break;
    341     case EOpUnpackUint2x16:   out.debug << "unpackUint2x16";     break;
    342 
    343     case EOpPackInt4x16:      out.debug << "packInt4x16";        break;
    344     case EOpUnpackInt4x16:    out.debug << "unpackInt4x16";      break;
    345     case EOpPackUint4x16:     out.debug << "packUint4x16";       break;
    346     case EOpUnpackUint4x16:   out.debug << "unpackUint4x16";     break;
    347 
    348     case EOpPackFloat2x16:    out.debug << "packFloat2x16";      break;
    349     case EOpUnpackFloat2x16:  out.debug << "unpackFloat2x16";    break;
    350 #endif
    351 
    352     case EOpLength:         out.debug << "length";               break;
    353     case EOpNormalize:      out.debug << "normalize";            break;
    354     case EOpDPdx:           out.debug << "dPdx";                 break;
    355     case EOpDPdy:           out.debug << "dPdy";                 break;
    356     case EOpFwidth:         out.debug << "fwidth";               break;
    357     case EOpDPdxFine:       out.debug << "dPdxFine";             break;
    358     case EOpDPdyFine:       out.debug << "dPdyFine";             break;
    359     case EOpFwidthFine:     out.debug << "fwidthFine";           break;
    360     case EOpDPdxCoarse:     out.debug << "dPdxCoarse";           break;
    361     case EOpDPdyCoarse:     out.debug << "dPdyCoarse";           break;
    362     case EOpFwidthCoarse:   out.debug << "fwidthCoarse";         break;
    363 
    364     case EOpInterpolateAtCentroid: out.debug << "interpolateAtCentroid";  break;
    365 
    366     case EOpDeterminant:    out.debug << "determinant";          break;
    367     case EOpMatrixInverse:  out.debug << "inverse";              break;
    368     case EOpTranspose:      out.debug << "transpose";            break;
    369 
    370     case EOpAny:            out.debug << "any";                  break;
    371     case EOpAll:            out.debug << "all";                  break;
    372 
    373     case EOpArrayLength:    out.debug << "array length";         break;
    374 
    375     case EOpEmitStreamVertex:   out.debug << "EmitStreamVertex";   break;
    376     case EOpEndStreamPrimitive: out.debug << "EndStreamPrimitive"; break;
    377 
    378     case EOpAtomicCounterIncrement: out.debug << "AtomicCounterIncrement";break;
    379     case EOpAtomicCounterDecrement: out.debug << "AtomicCounterDecrement";break;
    380     case EOpAtomicCounter:          out.debug << "AtomicCounter";         break;
    381 
    382     case EOpTextureQuerySize:       out.debug << "textureSize";           break;
    383     case EOpTextureQueryLod:        out.debug << "textureQueryLod";       break;
    384     case EOpTextureQueryLevels:     out.debug << "textureQueryLevels";    break;
    385     case EOpTextureQuerySamples:    out.debug << "textureSamples";        break;
    386     case EOpImageQuerySize:         out.debug << "imageQuerySize";        break;
    387     case EOpImageQuerySamples:      out.debug << "imageQuerySamples";     break;
    388     case EOpImageLoad:              out.debug << "imageLoad";             break;
    389 
    390     case EOpBitFieldReverse:        out.debug << "bitFieldReverse";       break;
    391     case EOpBitCount:               out.debug << "bitCount";              break;
    392     case EOpFindLSB:                out.debug << "findLSB";               break;
    393     case EOpFindMSB:                out.debug << "findMSB";               break;
    394 
    395     case EOpNoise:                  out.debug << "noise";                 break;
    396 
    397     case EOpBallot:                 out.debug << "ballot";                break;
    398     case EOpReadFirstInvocation:    out.debug << "readFirstInvocation";   break;
    399 
    400     case EOpAnyInvocation:          out.debug << "anyInvocation";         break;
    401     case EOpAllInvocations:         out.debug << "allInvocations";        break;
    402     case EOpAllInvocationsEqual:    out.debug << "allInvocationsEqual";   break;
    403 
    404     case EOpClip:                   out.debug << "clip";                  break;
    405     case EOpIsFinite:               out.debug << "isfinite";              break;
    406     case EOpLog10:                  out.debug << "log10";                 break;
    407     case EOpRcp:                    out.debug << "rcp";                   break;
    408     case EOpSaturate:               out.debug << "saturate";              break;
    409 
    410     case EOpSparseTexelsResident:   out.debug << "sparseTexelsResident";  break;
    411 
    412 #ifdef AMD_EXTENSIONS
    413     case EOpMinInvocations:             out.debug << "minInvocations";              break;
    414     case EOpMaxInvocations:             out.debug << "maxInvocations";              break;
    415     case EOpAddInvocations:             out.debug << "addInvocations";              break;
    416     case EOpMinInvocationsNonUniform:   out.debug << "minInvocationsNonUniform";    break;
    417     case EOpMaxInvocationsNonUniform:   out.debug << "maxInvocationsNonUniform";    break;
    418     case EOpAddInvocationsNonUniform:   out.debug << "addInvocationsNonUniform";    break;
    419 
    420     case EOpMinInvocationsInclusiveScan:            out.debug << "minInvocationsInclusiveScan";             break;
    421     case EOpMaxInvocationsInclusiveScan:            out.debug << "maxInvocationsInclusiveScan";             break;
    422     case EOpAddInvocationsInclusiveScan:            out.debug << "addInvocationsInclusiveScan";             break;
    423     case EOpMinInvocationsInclusiveScanNonUniform:  out.debug << "minInvocationsInclusiveScanNonUniform";   break;
    424     case EOpMaxInvocationsInclusiveScanNonUniform:  out.debug << "maxInvocationsInclusiveScanNonUniform";   break;
    425     case EOpAddInvocationsInclusiveScanNonUniform:  out.debug << "addInvocationsInclusiveScanNonUniform";   break;
    426 
    427     case EOpMinInvocationsExclusiveScan:            out.debug << "minInvocationsExclusiveScan";             break;
    428     case EOpMaxInvocationsExclusiveScan:            out.debug << "maxInvocationsExclusiveScan";             break;
    429     case EOpAddInvocationsExclusiveScan:            out.debug << "addInvocationsExclusiveScan";             break;
    430     case EOpMinInvocationsExclusiveScanNonUniform:  out.debug << "minInvocationsExclusiveScanNonUniform";   break;
    431     case EOpMaxInvocationsExclusiveScanNonUniform:  out.debug << "maxInvocationsExclusiveScanNonUniform";   break;
    432     case EOpAddInvocationsExclusiveScanNonUniform:  out.debug << "addInvocationsExclusiveScanNonUniform";   break;
    433 
    434     case EOpMbcnt:                      out.debug << "mbcnt";                       break;
    435 
    436     case EOpCubeFaceIndex:          out.debug << "cubeFaceIndex";         break;
    437     case EOpCubeFaceCoord:          out.debug << "cubeFaceCoord";         break;
    438 
    439     case EOpConvBoolToFloat16:      out.debug << "Convert bool to float16";     break;
    440     case EOpConvIntToFloat16:       out.debug << "Convert int to float16";      break;
    441     case EOpConvUintToFloat16:      out.debug << "Convert uint to float16";     break;
    442     case EOpConvFloatToFloat16:     out.debug << "Convert float to float16";    break;
    443     case EOpConvDoubleToFloat16:    out.debug << "Convert double to float16";   break;
    444     case EOpConvInt64ToFloat16:     out.debug << "Convert int64 to float16";    break;
    445     case EOpConvUint64ToFloat16:    out.debug << "Convert uint64 to float16";   break;
    446     case EOpConvFloat16ToBool:      out.debug << "Convert float16 to bool";     break;
    447     case EOpConvFloat16ToInt:       out.debug << "Convert float16 to int";      break;
    448     case EOpConvFloat16ToUint:      out.debug << "Convert float16 to uint";     break;
    449     case EOpConvFloat16ToFloat:     out.debug << "Convert float16 to float";    break;
    450     case EOpConvFloat16ToDouble:    out.debug << "Convert float16 to double";   break;
    451     case EOpConvFloat16ToInt64:     out.debug << "Convert float16 to int64";    break;
    452     case EOpConvFloat16ToUint64:    out.debug << "Convert float16 to uint64";   break;
    453 
    454     case EOpConvBoolToInt16:        out.debug << "Convert bool to int16";       break;
    455     case EOpConvIntToInt16:         out.debug << "Convert int to int16";        break;
    456     case EOpConvUintToInt16:        out.debug << "Convert uint to int16";       break;
    457     case EOpConvFloatToInt16:       out.debug << "Convert float to int16";      break;
    458     case EOpConvDoubleToInt16:      out.debug << "Convert double to int16";     break;
    459     case EOpConvFloat16ToInt16:     out.debug << "Convert float16 to int16";    break;
    460     case EOpConvInt64ToInt16:       out.debug << "Convert int64 to int16";      break;
    461     case EOpConvUint64ToInt16:      out.debug << "Convert uint64 to int16";     break;
    462     case EOpConvUint16ToInt16:      out.debug << "Convert uint16 to int16";     break;
    463     case EOpConvInt16ToBool:        out.debug << "Convert int16 to bool";       break;
    464     case EOpConvInt16ToInt:         out.debug << "Convert int16 to int";        break;
    465     case EOpConvInt16ToUint:        out.debug << "Convert int16 to uint";       break;
    466     case EOpConvInt16ToFloat:       out.debug << "Convert int16 to float";      break;
    467     case EOpConvInt16ToDouble:      out.debug << "Convert int16 to double";     break;
    468     case EOpConvInt16ToFloat16:     out.debug << "Convert int16 to float16";    break;
    469     case EOpConvInt16ToInt64:       out.debug << "Convert int16 to int64";      break;
    470     case EOpConvInt16ToUint64:      out.debug << "Convert int16 to uint64";     break;
    471 
    472     case EOpConvBoolToUint16:       out.debug << "Convert bool to uint16";      break;
    473     case EOpConvIntToUint16:        out.debug << "Convert int to uint16";       break;
    474     case EOpConvUintToUint16:       out.debug << "Convert uint to uint16";      break;
    475     case EOpConvFloatToUint16:      out.debug << "Convert float to uint16";     break;
    476     case EOpConvDoubleToUint16:     out.debug << "Convert double to uint16";    break;
    477     case EOpConvFloat16ToUint16:    out.debug << "Convert float16 to uint16";   break;
    478     case EOpConvInt64ToUint16:      out.debug << "Convert int64 to uint16";     break;
    479     case EOpConvUint64ToUint16:     out.debug << "Convert uint64 to uint16";    break;
    480     case EOpConvInt16ToUint16:      out.debug << "Convert int16 to uint16";     break;
    481     case EOpConvUint16ToBool:       out.debug << "Convert uint16 to bool";      break;
    482     case EOpConvUint16ToInt:        out.debug << "Convert uint16 to int";       break;
    483     case EOpConvUint16ToUint:       out.debug << "Convert uint16 to uint";      break;
    484     case EOpConvUint16ToFloat:      out.debug << "Convert uint16 to float";     break;
    485     case EOpConvUint16ToDouble:     out.debug << "Convert uint16 to double";    break;
    486     case EOpConvUint16ToFloat16:    out.debug << "Convert uint16 to float16";   break;
    487     case EOpConvUint16ToInt64:      out.debug << "Convert uint16 to int64";     break;
    488     case EOpConvUint16ToUint64:     out.debug << "Convert uint16 to uint64";    break;
    489 #endif
    490 
    491     default: out.debug.message(EPrefixError, "Bad unary op");
    492     }
    493 
    494     out.debug << " (" << node->getCompleteString() << ")";
    495 
    496     out.debug << "\n";
    497 
    498     return true;
    499 }
    500 
    501 bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node)
    502 {
    503     TInfoSink& out = infoSink;
    504 
    505     if (node->getOp() == EOpNull) {
    506         out.debug.message(EPrefixError, "node is still EOpNull!");
    507         return true;
    508     }
    509 
    510     OutputTreeText(out, node, depth);
    511 
    512     switch (node->getOp()) {
    513     case EOpSequence:      out.debug << "Sequence\n";       return true;
    514     case EOpLinkerObjects: out.debug << "Linker Objects\n"; return true;
    515     case EOpComma:         out.debug << "Comma";            break;
    516     case EOpFunction:      out.debug << "Function Definition: " << node->getName(); break;
    517     case EOpFunctionCall:  out.debug << "Function Call: "       << node->getName(); break;
    518     case EOpParameters:    out.debug << "Function Parameters: ";                    break;
    519 
    520     case EOpConstructFloat: out.debug << "Construct float"; break;
    521     case EOpConstructDouble:out.debug << "Construct double"; break;
    522 
    523     case EOpConstructVec2:  out.debug << "Construct vec2";  break;
    524     case EOpConstructVec3:  out.debug << "Construct vec3";  break;
    525     case EOpConstructVec4:  out.debug << "Construct vec4";  break;
    526     case EOpConstructDVec2: out.debug << "Construct dvec2";  break;
    527     case EOpConstructDVec3: out.debug << "Construct dvec3";  break;
    528     case EOpConstructDVec4: out.debug << "Construct dvec4";  break;
    529     case EOpConstructBool:  out.debug << "Construct bool";  break;
    530     case EOpConstructBVec2: out.debug << "Construct bvec2"; break;
    531     case EOpConstructBVec3: out.debug << "Construct bvec3"; break;
    532     case EOpConstructBVec4: out.debug << "Construct bvec4"; break;
    533     case EOpConstructInt:   out.debug << "Construct int";   break;
    534     case EOpConstructIVec2: out.debug << "Construct ivec2"; break;
    535     case EOpConstructIVec3: out.debug << "Construct ivec3"; break;
    536     case EOpConstructIVec4: out.debug << "Construct ivec4"; break;
    537     case EOpConstructUint:    out.debug << "Construct uint";    break;
    538     case EOpConstructUVec2:   out.debug << "Construct uvec2";   break;
    539     case EOpConstructUVec3:   out.debug << "Construct uvec3";   break;
    540     case EOpConstructUVec4:   out.debug << "Construct uvec4";   break;
    541     case EOpConstructInt64:   out.debug << "Construct int64_t"; break;
    542     case EOpConstructI64Vec2: out.debug << "Construct i64vec2"; break;
    543     case EOpConstructI64Vec3: out.debug << "Construct i64vec3"; break;
    544     case EOpConstructI64Vec4: out.debug << "Construct i64vec4"; break;
    545     case EOpConstructUint64:  out.debug << "Construct uint64_t"; break;
    546     case EOpConstructU64Vec2: out.debug << "Construct u64vec2"; break;
    547     case EOpConstructU64Vec3: out.debug << "Construct u64vec3"; break;
    548     case EOpConstructU64Vec4: out.debug << "Construct u64vec4"; break;
    549 #ifdef AMD_EXTENSIONS
    550     case EOpConstructInt16:   out.debug << "Construct int16_t"; break;
    551     case EOpConstructI16Vec2: out.debug << "Construct i16vec2"; break;
    552     case EOpConstructI16Vec3: out.debug << "Construct i16vec3"; break;
    553     case EOpConstructI16Vec4: out.debug << "Construct i16vec4"; break;
    554     case EOpConstructUint16:  out.debug << "Construct uint16_t"; break;
    555     case EOpConstructU16Vec2: out.debug << "Construct u16vec2"; break;
    556     case EOpConstructU16Vec3: out.debug << "Construct u16vec3"; break;
    557     case EOpConstructU16Vec4: out.debug << "Construct u16vec4"; break;
    558 #endif
    559     case EOpConstructMat2x2:  out.debug << "Construct mat2";    break;
    560     case EOpConstructMat2x3:  out.debug << "Construct mat2x3";  break;
    561     case EOpConstructMat2x4:  out.debug << "Construct mat2x4";  break;
    562     case EOpConstructMat3x2:  out.debug << "Construct mat3x2";  break;
    563     case EOpConstructMat3x3:  out.debug << "Construct mat3";    break;
    564     case EOpConstructMat3x4:  out.debug << "Construct mat3x4";  break;
    565     case EOpConstructMat4x2:  out.debug << "Construct mat4x2";  break;
    566     case EOpConstructMat4x3:  out.debug << "Construct mat4x3";  break;
    567     case EOpConstructMat4x4:  out.debug << "Construct mat4";    break;
    568     case EOpConstructDMat2x2: out.debug << "Construct dmat2";   break;
    569     case EOpConstructDMat2x3: out.debug << "Construct dmat2x3"; break;
    570     case EOpConstructDMat2x4: out.debug << "Construct dmat2x4"; break;
    571     case EOpConstructDMat3x2: out.debug << "Construct dmat3x2"; break;
    572     case EOpConstructDMat3x3: out.debug << "Construct dmat3";   break;
    573     case EOpConstructDMat3x4: out.debug << "Construct dmat3x4"; break;
    574     case EOpConstructDMat4x2: out.debug << "Construct dmat4x2"; break;
    575     case EOpConstructDMat4x3: out.debug << "Construct dmat4x3"; break;
    576     case EOpConstructDMat4x4: out.debug << "Construct dmat4";   break;
    577     case EOpConstructIMat2x2: out.debug << "Construct imat2";   break;
    578     case EOpConstructIMat2x3: out.debug << "Construct imat2x3"; break;
    579     case EOpConstructIMat2x4: out.debug << "Construct imat2x4"; break;
    580     case EOpConstructIMat3x2: out.debug << "Construct imat3x2"; break;
    581     case EOpConstructIMat3x3: out.debug << "Construct imat3";   break;
    582     case EOpConstructIMat3x4: out.debug << "Construct imat3x4"; break;
    583     case EOpConstructIMat4x2: out.debug << "Construct imat4x2"; break;
    584     case EOpConstructIMat4x3: out.debug << "Construct imat4x3"; break;
    585     case EOpConstructIMat4x4: out.debug << "Construct imat4";   break;
    586     case EOpConstructUMat2x2: out.debug << "Construct umat2";   break;
    587     case EOpConstructUMat2x3: out.debug << "Construct umat2x3"; break;
    588     case EOpConstructUMat2x4: out.debug << "Construct umat2x4"; break;
    589     case EOpConstructUMat3x2: out.debug << "Construct umat3x2"; break;
    590     case EOpConstructUMat3x3: out.debug << "Construct umat3";   break;
    591     case EOpConstructUMat3x4: out.debug << "Construct umat3x4"; break;
    592     case EOpConstructUMat4x2: out.debug << "Construct umat4x2"; break;
    593     case EOpConstructUMat4x3: out.debug << "Construct umat4x3"; break;
    594     case EOpConstructUMat4x4: out.debug << "Construct umat4";   break;
    595     case EOpConstructBMat2x2: out.debug << "Construct bmat2";   break;
    596     case EOpConstructBMat2x3: out.debug << "Construct bmat2x3"; break;
    597     case EOpConstructBMat2x4: out.debug << "Construct bmat2x4"; break;
    598     case EOpConstructBMat3x2: out.debug << "Construct bmat3x2"; break;
    599     case EOpConstructBMat3x3: out.debug << "Construct bmat3";   break;
    600     case EOpConstructBMat3x4: out.debug << "Construct bmat3x4"; break;
    601     case EOpConstructBMat4x2: out.debug << "Construct bmat4x2"; break;
    602     case EOpConstructBMat4x3: out.debug << "Construct bmat4x3"; break;
    603     case EOpConstructBMat4x4: out.debug << "Construct bmat4";   break;
    604 #ifdef AMD_EXTENSIONS
    605     case EOpConstructFloat16:   out.debug << "Construct float16_t"; break;
    606     case EOpConstructF16Vec2:   out.debug << "Construct f16vec2";   break;
    607     case EOpConstructF16Vec3:   out.debug << "Construct f16vec3";   break;
    608     case EOpConstructF16Vec4:   out.debug << "Construct f16vec4";   break;
    609     case EOpConstructF16Mat2x2: out.debug << "Construct f16mat2";   break;
    610     case EOpConstructF16Mat2x3: out.debug << "Construct f16mat2x3"; break;
    611     case EOpConstructF16Mat2x4: out.debug << "Construct f16mat2x4"; break;
    612     case EOpConstructF16Mat3x2: out.debug << "Construct f16mat3x2"; break;
    613     case EOpConstructF16Mat3x3: out.debug << "Construct f16mat3";   break;
    614     case EOpConstructF16Mat3x4: out.debug << "Construct f16mat3x4"; break;
    615     case EOpConstructF16Mat4x2: out.debug << "Construct f16mat4x2"; break;
    616     case EOpConstructF16Mat4x3: out.debug << "Construct f16mat4x3"; break;
    617     case EOpConstructF16Mat4x4: out.debug << "Construct f16mat4";   break;
    618 #endif
    619     case EOpConstructStruct:  out.debug << "Construct structure";  break;
    620     case EOpConstructTextureSampler: out.debug << "Construct combined texture-sampler"; break;
    621 
    622     case EOpLessThan:         out.debug << "Compare Less Than";             break;
    623     case EOpGreaterThan:      out.debug << "Compare Greater Than";          break;
    624     case EOpLessThanEqual:    out.debug << "Compare Less Than or Equal";    break;
    625     case EOpGreaterThanEqual: out.debug << "Compare Greater Than or Equal"; break;
    626     case EOpVectorEqual:      out.debug << "Equal";                         break;
    627     case EOpVectorNotEqual:   out.debug << "NotEqual";                      break;
    628 
    629     case EOpMod:           out.debug << "mod";         break;
    630     case EOpModf:          out.debug << "modf";        break;
    631     case EOpPow:           out.debug << "pow";         break;
    632 
    633     case EOpAtan:          out.debug << "arc tangent"; break;
    634 
    635     case EOpMin:           out.debug << "min";         break;
    636     case EOpMax:           out.debug << "max";         break;
    637     case EOpClamp:         out.debug << "clamp";       break;
    638     case EOpMix:           out.debug << "mix";         break;
    639     case EOpStep:          out.debug << "step";        break;
    640     case EOpSmoothStep:    out.debug << "smoothstep";  break;
    641 
    642     case EOpDistance:      out.debug << "distance";                break;
    643     case EOpDot:           out.debug << "dot-product";             break;
    644     case EOpCross:         out.debug << "cross-product";           break;
    645     case EOpFaceForward:   out.debug << "face-forward";            break;
    646     case EOpReflect:       out.debug << "reflect";                 break;
    647     case EOpRefract:       out.debug << "refract";                 break;
    648     case EOpMul:           out.debug << "component-wise multiply"; break;
    649     case EOpOuterProduct:  out.debug << "outer product";           break;
    650 
    651     case EOpEmitVertex:    out.debug << "EmitVertex";              break;
    652     case EOpEndPrimitive:  out.debug << "EndPrimitive";            break;
    653 
    654     case EOpBarrier:                    out.debug << "Barrier";                    break;
    655     case EOpMemoryBarrier:              out.debug << "MemoryBarrier";              break;
    656     case EOpMemoryBarrierAtomicCounter: out.debug << "MemoryBarrierAtomicCounter"; break;
    657     case EOpMemoryBarrierBuffer:        out.debug << "MemoryBarrierBuffer";        break;
    658     case EOpMemoryBarrierImage:         out.debug << "MemoryBarrierImage";         break;
    659     case EOpMemoryBarrierShared:        out.debug << "MemoryBarrierShared";        break;
    660     case EOpGroupMemoryBarrier:         out.debug << "GroupMemoryBarrier";         break;
    661 
    662     case EOpReadInvocation:             out.debug << "readInvocation";        break;
    663 
    664 #ifdef AMD_EXTENSIONS
    665     case EOpSwizzleInvocations:         out.debug << "swizzleInvocations";       break;
    666     case EOpSwizzleInvocationsMasked:   out.debug << "swizzleInvocationsMasked"; break;
    667     case EOpWriteInvocation:            out.debug << "writeInvocation";          break;
    668 
    669     case EOpMin3:                       out.debug << "min3";                  break;
    670     case EOpMax3:                       out.debug << "max3";                  break;
    671     case EOpMid3:                       out.debug << "mid3";                  break;
    672 
    673     case EOpTime:                       out.debug << "time";                  break;
    674 #endif
    675 
    676     case EOpAtomicAdd:                  out.debug << "AtomicAdd";             break;
    677     case EOpAtomicMin:                  out.debug << "AtomicMin";             break;
    678     case EOpAtomicMax:                  out.debug << "AtomicMax";             break;
    679     case EOpAtomicAnd:                  out.debug << "AtomicAnd";             break;
    680     case EOpAtomicOr:                   out.debug << "AtomicOr";              break;
    681     case EOpAtomicXor:                  out.debug << "AtomicXor";             break;
    682     case EOpAtomicExchange:             out.debug << "AtomicExchange";        break;
    683     case EOpAtomicCompSwap:             out.debug << "AtomicCompSwap";        break;
    684 
    685     case EOpAtomicCounterAdd:           out.debug << "AtomicCounterAdd";      break;
    686     case EOpAtomicCounterSubtract:      out.debug << "AtomicCounterSubtract"; break;
    687     case EOpAtomicCounterMin:           out.debug << "AtomicCounterMin";      break;
    688     case EOpAtomicCounterMax:           out.debug << "AtomicCounterMax";      break;
    689     case EOpAtomicCounterAnd:           out.debug << "AtomicCounterAnd";      break;
    690     case EOpAtomicCounterOr:            out.debug << "AtomicCounterOr";       break;
    691     case EOpAtomicCounterXor:           out.debug << "AtomicCounterXor";      break;
    692     case EOpAtomicCounterExchange:      out.debug << "AtomicCounterExchange"; break;
    693     case EOpAtomicCounterCompSwap:      out.debug << "AtomicCounterCompSwap"; break;
    694 
    695     case EOpImageQuerySize:             out.debug << "imageQuerySize";        break;
    696     case EOpImageQuerySamples:          out.debug << "imageQuerySamples";     break;
    697     case EOpImageLoad:                  out.debug << "imageLoad";             break;
    698     case EOpImageStore:                 out.debug << "imageStore";            break;
    699     case EOpImageAtomicAdd:             out.debug << "imageAtomicAdd";        break;
    700     case EOpImageAtomicMin:             out.debug << "imageAtomicMin";        break;
    701     case EOpImageAtomicMax:             out.debug << "imageAtomicMax";        break;
    702     case EOpImageAtomicAnd:             out.debug << "imageAtomicAnd";        break;
    703     case EOpImageAtomicOr:              out.debug << "imageAtomicOr";         break;
    704     case EOpImageAtomicXor:             out.debug << "imageAtomicXor";        break;
    705     case EOpImageAtomicExchange:        out.debug << "imageAtomicExchange";   break;
    706     case EOpImageAtomicCompSwap:        out.debug << "imageAtomicCompSwap";   break;
    707 #ifdef AMD_EXTENSIONS
    708     case EOpImageLoadLod:               out.debug << "imageLoadLod";          break;
    709     case EOpImageStoreLod:              out.debug << "imageStoreLod";         break;
    710 #endif
    711 
    712     case EOpTextureQuerySize:           out.debug << "textureSize";           break;
    713     case EOpTextureQueryLod:            out.debug << "textureQueryLod";       break;
    714     case EOpTextureQueryLevels:         out.debug << "textureQueryLevels";    break;
    715     case EOpTextureQuerySamples:        out.debug << "textureSamples";        break;
    716     case EOpTexture:                    out.debug << "texture";               break;
    717     case EOpTextureProj:                out.debug << "textureProj";           break;
    718     case EOpTextureLod:                 out.debug << "textureLod";            break;
    719     case EOpTextureOffset:              out.debug << "textureOffset";         break;
    720     case EOpTextureFetch:               out.debug << "textureFetch";          break;
    721     case EOpTextureFetchOffset:         out.debug << "textureFetchOffset";    break;
    722     case EOpTextureProjOffset:          out.debug << "textureProjOffset";     break;
    723     case EOpTextureLodOffset:           out.debug << "textureLodOffset";      break;
    724     case EOpTextureProjLod:             out.debug << "textureProjLod";        break;
    725     case EOpTextureProjLodOffset:       out.debug << "textureProjLodOffset";  break;
    726     case EOpTextureGrad:                out.debug << "textureGrad";           break;
    727     case EOpTextureGradOffset:          out.debug << "textureGradOffset";     break;
    728     case EOpTextureProjGrad:            out.debug << "textureProjGrad";       break;
    729     case EOpTextureProjGradOffset:      out.debug << "textureProjGradOffset"; break;
    730     case EOpTextureGather:              out.debug << "textureGather";         break;
    731     case EOpTextureGatherOffset:        out.debug << "textureGatherOffset";   break;
    732     case EOpTextureGatherOffsets:       out.debug << "textureGatherOffsets";  break;
    733     case EOpTextureClamp:               out.debug << "textureClamp";          break;
    734     case EOpTextureOffsetClamp:         out.debug << "textureOffsetClamp";    break;
    735     case EOpTextureGradClamp:           out.debug << "textureGradClamp";      break;
    736     case EOpTextureGradOffsetClamp:     out.debug << "textureGradOffsetClamp";  break;
    737 #ifdef AMD_EXTENSIONS
    738     case EOpTextureGatherLod:           out.debug << "textureGatherLod";        break;
    739     case EOpTextureGatherLodOffset:     out.debug << "textureGatherLodOffset";  break;
    740     case EOpTextureGatherLodOffsets:    out.debug << "textureGatherLodOffsets"; break;
    741 #endif
    742 
    743     case EOpSparseTexture:                  out.debug << "sparseTexture";                   break;
    744     case EOpSparseTextureOffset:            out.debug << "sparseTextureOffset";             break;
    745     case EOpSparseTextureLod:               out.debug << "sparseTextureLod";                break;
    746     case EOpSparseTextureLodOffset:         out.debug << "sparseTextureLodOffset";          break;
    747     case EOpSparseTextureFetch:             out.debug << "sparseTexelFetch";                break;
    748     case EOpSparseTextureFetchOffset:       out.debug << "sparseTexelFetchOffset";          break;
    749     case EOpSparseTextureGrad:              out.debug << "sparseTextureGrad";               break;
    750     case EOpSparseTextureGradOffset:        out.debug << "sparseTextureGradOffset";         break;
    751     case EOpSparseTextureGather:            out.debug << "sparseTextureGather";             break;
    752     case EOpSparseTextureGatherOffset:      out.debug << "sparseTextureGatherOffset";       break;
    753     case EOpSparseTextureGatherOffsets:     out.debug << "sparseTextureGatherOffsets";      break;
    754     case EOpSparseImageLoad:                out.debug << "sparseImageLoad";                 break;
    755     case EOpSparseTextureClamp:             out.debug << "sparseTextureClamp";              break;
    756     case EOpSparseTextureOffsetClamp:       out.debug << "sparseTextureOffsetClamp";        break;
    757     case EOpSparseTextureGradClamp:         out.debug << "sparseTextureGradClamp";          break;
    758     case EOpSparseTextureGradOffsetClamp:   out.debug << "sparseTextureGradOffsetClam";     break;
    759 #ifdef AMD_EXTENSIONS
    760     case EOpSparseTextureGatherLod:         out.debug << "sparseTextureGatherLod";          break;
    761     case EOpSparseTextureGatherLodOffset:   out.debug << "sparseTextureGatherLodOffset";    break;
    762     case EOpSparseTextureGatherLodOffsets:  out.debug << "sparseTextureGatherLodOffsets";   break;
    763     case EOpSparseImageLoadLod:             out.debug << "sparseImageLoadLod";              break;
    764 #endif
    765 
    766     case EOpAddCarry:                   out.debug << "addCarry";              break;
    767     case EOpSubBorrow:                  out.debug << "subBorrow";             break;
    768     case EOpUMulExtended:               out.debug << "uMulExtended";          break;
    769     case EOpIMulExtended:               out.debug << "iMulExtended";          break;
    770     case EOpBitfieldExtract:            out.debug << "bitfieldExtract";       break;
    771     case EOpBitfieldInsert:             out.debug << "bitfieldInsert";        break;
    772 
    773     case EOpFma:                        out.debug << "fma";                   break;
    774     case EOpFrexp:                      out.debug << "frexp";                 break;
    775     case EOpLdexp:                      out.debug << "ldexp";                 break;
    776 
    777     case EOpInterpolateAtSample:   out.debug << "interpolateAtSample";    break;
    778     case EOpInterpolateAtOffset:   out.debug << "interpolateAtOffset";    break;
    779 #ifdef AMD_EXTENSIONS
    780     case EOpInterpolateAtVertex:   out.debug << "interpolateAtVertex";    break;
    781 #endif
    782 
    783     case EOpSinCos:                     out.debug << "sincos";                break;
    784     case EOpGenMul:                     out.debug << "mul";                   break;
    785 
    786     case EOpAllMemoryBarrierWithGroupSync:    out.debug << "AllMemoryBarrierWithGroupSync";    break;
    787     case EOpGroupMemoryBarrierWithGroupSync: out.debug << "GroupMemoryBarrierWithGroupSync"; break;
    788     case EOpWorkgroupMemoryBarrier:           out.debug << "WorkgroupMemoryBarrier";           break;
    789     case EOpWorkgroupMemoryBarrierWithGroupSync: out.debug << "WorkgroupMemoryBarrierWithGroupSync"; break;
    790 
    791     default: out.debug.message(EPrefixError, "Bad aggregation op");
    792     }
    793 
    794     if (node->getOp() != EOpSequence && node->getOp() != EOpParameters)
    795         out.debug << " (" << node->getCompleteString() << ")";
    796 
    797     out.debug << "\n";
    798 
    799     return true;
    800 }
    801 
    802 bool TOutputTraverser::visitSelection(TVisit /* visit */, TIntermSelection* node)
    803 {
    804     TInfoSink& out = infoSink;
    805 
    806     OutputTreeText(out, node, depth);
    807 
    808     out.debug << "Test condition and select";
    809     out.debug << " (" << node->getCompleteString() << ")\n";
    810 
    811     ++depth;
    812 
    813     OutputTreeText(out, node, depth);
    814     out.debug << "Condition\n";
    815     node->getCondition()->traverse(this);
    816 
    817     OutputTreeText(out, node, depth);
    818     if (node->getTrueBlock()) {
    819         out.debug << "true case\n";
    820         node->getTrueBlock()->traverse(this);
    821     } else
    822         out.debug << "true case is null\n";
    823 
    824     if (node->getFalseBlock()) {
    825         OutputTreeText(out, node, depth);
    826         out.debug << "false case\n";
    827         node->getFalseBlock()->traverse(this);
    828     }
    829 
    830     --depth;
    831 
    832     return false;
    833 }
    834 
    835 static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const TConstUnionArray& constUnion, int depth)
    836 {
    837     int size = node->getType().computeNumComponents();
    838 
    839     for (int i = 0; i < size; i++) {
    840         OutputTreeText(out, node, depth);
    841         switch (constUnion[i].getType()) {
    842         case EbtBool:
    843             if (constUnion[i].getBConst())
    844                 out.debug << "true";
    845             else
    846                 out.debug << "false";
    847 
    848             out.debug << " (" << "const bool" << ")";
    849 
    850             out.debug << "\n";
    851             break;
    852         case EbtFloat:
    853         case EbtDouble:
    854 #ifdef AMD_EXTENSIONS
    855         case EbtFloat16:
    856 #endif
    857             {
    858                 const double value = constUnion[i].getDConst();
    859                 // Print infinities and NaNs in a portable way.
    860                 if (IsInfinity(value)) {
    861                     if (value < 0)
    862                         out.debug << "-1.#INF\n";
    863                     else
    864                         out.debug << "+1.#INF\n";
    865                 } else if (IsNan(value))
    866                     out.debug << "1.#IND\n";
    867                 else {
    868                     const int maxSize = 300;
    869                     char buf[maxSize];
    870                     snprintf(buf, maxSize, "%f", value);
    871 
    872                     out.debug << buf << "\n";
    873                 }
    874             }
    875             break;
    876         case EbtInt:
    877             {
    878                 const int maxSize = 300;
    879                 char buf[maxSize];
    880                 snprintf(buf, maxSize, "%d (%s)", constUnion[i].getIConst(), "const int");
    881 
    882                 out.debug << buf << "\n";
    883             }
    884             break;
    885         case EbtUint:
    886             {
    887                 const int maxSize = 300;
    888                 char buf[maxSize];
    889                 snprintf(buf, maxSize, "%u (%s)", constUnion[i].getUConst(), "const uint");
    890 
    891                 out.debug << buf << "\n";
    892             }
    893             break;
    894         case EbtInt64:
    895             {
    896                 const int maxSize = 300;
    897                 char buf[maxSize];
    898                 snprintf(buf, maxSize, "%lld (%s)", constUnion[i].getI64Const(), "const int64_t");
    899 
    900                 out.debug << buf << "\n";
    901             }
    902             break;
    903         case EbtUint64:
    904             {
    905                 const int maxSize = 300;
    906                 char buf[maxSize];
    907                 snprintf(buf, maxSize, "%llu (%s)", constUnion[i].getU64Const(), "const uint64_t");
    908 
    909                 out.debug << buf << "\n";
    910             }
    911             break;
    912 #ifdef AMD_EXTENSIONS
    913         case EbtInt16:
    914             {
    915                 const int maxSize = 300;
    916                 char buf[maxSize];
    917                 snprintf(buf, maxSize, "%d (%s)", constUnion[i].getIConst(), "const int16_t");
    918 
    919                 out.debug << buf << "\n";
    920             }
    921             break;
    922         case EbtUint16:
    923             {
    924                 const int maxSize = 300;
    925                 char buf[maxSize];
    926                 snprintf(buf, maxSize, "%u (%s)", constUnion[i].getUConst(), "const uint16_t");
    927 
    928                 out.debug << buf << "\n";
    929             }
    930             break;
    931 #endif
    932         default:
    933             out.info.message(EPrefixInternalError, "Unknown constant", node->getLoc());
    934             break;
    935         }
    936     }
    937 }
    938 
    939 void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node)
    940 {
    941     OutputTreeText(infoSink, node, depth);
    942     infoSink.debug << "Constant:\n";
    943 
    944     OutputConstantUnion(infoSink, node, node->getConstArray(), depth + 1);
    945 }
    946 
    947 void TOutputTraverser::visitSymbol(TIntermSymbol* node)
    948 {
    949     OutputTreeText(infoSink, node, depth);
    950 
    951     infoSink.debug << "'" << node->getName() << "' (" << node->getCompleteString() << ")\n";
    952 
    953     if (! node->getConstArray().empty())
    954         OutputConstantUnion(infoSink, node, node->getConstArray(), depth + 1);
    955     else if (node->getConstSubtree()) {
    956         incrementDepth(node);
    957         node->getConstSubtree()->traverse(this);
    958         decrementDepth();
    959     }
    960 }
    961 
    962 bool TOutputTraverser::visitLoop(TVisit /* visit */, TIntermLoop* node)
    963 {
    964     TInfoSink& out = infoSink;
    965 
    966     OutputTreeText(out, node, depth);
    967 
    968     out.debug << "Loop with condition ";
    969     if (! node->testFirst())
    970         out.debug << "not ";
    971     out.debug << "tested first\n";
    972 
    973     ++depth;
    974 
    975     OutputTreeText(infoSink, node, depth);
    976     if (node->getTest()) {
    977         out.debug << "Loop Condition\n";
    978         node->getTest()->traverse(this);
    979     } else
    980         out.debug << "No loop condition\n";
    981 
    982     OutputTreeText(infoSink, node, depth);
    983     if (node->getBody()) {
    984         out.debug << "Loop Body\n";
    985         node->getBody()->traverse(this);
    986     } else
    987         out.debug << "No loop body\n";
    988 
    989     if (node->getTerminal()) {
    990         OutputTreeText(infoSink, node, depth);
    991         out.debug << "Loop Terminal Expression\n";
    992         node->getTerminal()->traverse(this);
    993     }
    994 
    995     --depth;
    996 
    997     return false;
    998 }
    999 
   1000 bool TOutputTraverser::visitBranch(TVisit /* visit*/, TIntermBranch* node)
   1001 {
   1002     TInfoSink& out = infoSink;
   1003 
   1004     OutputTreeText(out, node, depth);
   1005 
   1006     switch (node->getFlowOp()) {
   1007     case EOpKill:      out.debug << "Branch: Kill";           break;
   1008     case EOpBreak:     out.debug << "Branch: Break";          break;
   1009     case EOpContinue:  out.debug << "Branch: Continue";       break;
   1010     case EOpReturn:    out.debug << "Branch: Return";         break;
   1011     case EOpCase:      out.debug << "case: ";                 break;
   1012     case EOpDefault:   out.debug << "default: ";              break;
   1013     default:               out.debug << "Branch: Unknown Branch"; break;
   1014     }
   1015 
   1016     if (node->getExpression()) {
   1017         out.debug << " with expression\n";
   1018         ++depth;
   1019         node->getExpression()->traverse(this);
   1020         --depth;
   1021     } else
   1022         out.debug << "\n";
   1023 
   1024     return false;
   1025 }
   1026 
   1027 bool TOutputTraverser::visitSwitch(TVisit /* visit */, TIntermSwitch* node)
   1028 {
   1029     TInfoSink& out = infoSink;
   1030 
   1031     OutputTreeText(out, node, depth);
   1032     out.debug << "switch\n";
   1033 
   1034     OutputTreeText(out, node, depth);
   1035     out.debug << "condition\n";
   1036     ++depth;
   1037     node->getCondition()->traverse(this);
   1038 
   1039     --depth;
   1040     OutputTreeText(out, node, depth);
   1041     out.debug << "body\n";
   1042     ++depth;
   1043     node->getBody()->traverse(this);
   1044 
   1045     --depth;
   1046 
   1047     return false;
   1048 }
   1049 
   1050 //
   1051 // This function is the one to call externally to start the traversal.
   1052 // Individual functions can be initialized to 0 to skip processing of that
   1053 // type of node.  It's children will still be processed.
   1054 //
   1055 void TIntermediate::output(TInfoSink& infoSink, bool tree)
   1056 {
   1057     infoSink.debug << "Shader version: " << version << "\n";
   1058     if (requestedExtensions.size() > 0) {
   1059         for (auto extIt = requestedExtensions.begin(); extIt != requestedExtensions.end(); ++extIt)
   1060             infoSink.debug << "Requested " << *extIt << "\n";
   1061     }
   1062 
   1063     if (xfbMode)
   1064         infoSink.debug << "in xfb mode\n";
   1065 
   1066     switch (language) {
   1067     case EShLangVertex:
   1068         break;
   1069 
   1070     case EShLangTessControl:
   1071         infoSink.debug << "vertices = " << vertices << "\n";
   1072 
   1073         if (inputPrimitive != ElgNone)
   1074             infoSink.debug << "input primitive = " << TQualifier::getGeometryString(inputPrimitive) << "\n";
   1075         if (vertexSpacing != EvsNone)
   1076             infoSink.debug << "vertex spacing = " << TQualifier::getVertexSpacingString(vertexSpacing) << "\n";
   1077         if (vertexOrder != EvoNone)
   1078             infoSink.debug << "triangle order = " << TQualifier::getVertexOrderString(vertexOrder) << "\n";
   1079         break;
   1080 
   1081     case EShLangTessEvaluation:
   1082         infoSink.debug << "input primitive = " << TQualifier::getGeometryString(inputPrimitive) << "\n";
   1083         infoSink.debug << "vertex spacing = " << TQualifier::getVertexSpacingString(vertexSpacing) << "\n";
   1084         infoSink.debug << "triangle order = " << TQualifier::getVertexOrderString(vertexOrder) << "\n";
   1085         if (pointMode)
   1086             infoSink.debug << "using point mode\n";
   1087         break;
   1088 
   1089     case EShLangGeometry:
   1090         infoSink.debug << "invocations = " << invocations << "\n";
   1091         infoSink.debug << "max_vertices = " << vertices << "\n";
   1092         infoSink.debug << "input primitive = " << TQualifier::getGeometryString(inputPrimitive) << "\n";
   1093         infoSink.debug << "output primitive = " << TQualifier::getGeometryString(outputPrimitive) << "\n";
   1094         break;
   1095 
   1096     case EShLangFragment:
   1097         if (pixelCenterInteger)
   1098             infoSink.debug << "gl_FragCoord pixel center is integer\n";
   1099         if (originUpperLeft)
   1100             infoSink.debug << "gl_FragCoord origin is upper left\n";
   1101         if (earlyFragmentTests)
   1102             infoSink.debug << "using early_fragment_tests\n";
   1103         if (postDepthCoverage)
   1104             infoSink.debug << "using post_depth_coverage\n";
   1105         if (depthLayout != EldNone)
   1106             infoSink.debug << "using " << TQualifier::getLayoutDepthString(depthLayout) << "\n";
   1107         if (blendEquations != 0) {
   1108             infoSink.debug << "using";
   1109             // blendEquations is a mask, decode it
   1110             for (TBlendEquationShift be = (TBlendEquationShift)0; be < EBlendCount; be = (TBlendEquationShift)(be + 1)) {
   1111                 if (blendEquations & (1 << be))
   1112                     infoSink.debug << " " << TQualifier::getBlendEquationString(be);
   1113             }
   1114             infoSink.debug << "\n";
   1115         }
   1116         break;
   1117 
   1118     case EShLangCompute:
   1119         infoSink.debug << "local_size = (" << localSize[0] << ", " << localSize[1] << ", " << localSize[2] << ")\n";
   1120         {
   1121             if (localSizeSpecId[0] != TQualifier::layoutNotSet ||
   1122                 localSizeSpecId[1] != TQualifier::layoutNotSet ||
   1123                 localSizeSpecId[2] != TQualifier::layoutNotSet) {
   1124                 infoSink.debug << "local_size ids = (" <<
   1125                     localSizeSpecId[0] << ", " <<
   1126                     localSizeSpecId[1] << ", " <<
   1127                     localSizeSpecId[2] << ")\n";
   1128             }
   1129         }
   1130         break;
   1131 
   1132     default:
   1133         break;
   1134     }
   1135 
   1136     if (treeRoot == 0 || ! tree)
   1137         return;
   1138 
   1139     TOutputTraverser it(infoSink);
   1140 
   1141     treeRoot->traverse(&it);
   1142 }
   1143 
   1144 } // end namespace glslang
   1145