Home | History | Annotate | Download | only in MachineIndependent
      1 //
      2 // Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
      3 // Copyright (C) 2012-2016 LunarG, Inc.
      4 // Copyright (C) 2017 ARM Limited.
      5 //
      6 // All rights reserved.
      7 //
      8 // Redistribution and use in source and binary forms, with or without
      9 // modification, are permitted provided that the following conditions
     10 // are met:
     11 //
     12 //    Redistributions of source code must retain the above copyright
     13 //    notice, this list of conditions and the following disclaimer.
     14 //
     15 //    Redistributions in binary form must reproduce the above
     16 //    copyright notice, this list of conditions and the following
     17 //    disclaimer in the documentation and/or other materials provided
     18 //    with the distribution.
     19 //
     20 //    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
     21 //    contributors may be used to endorse or promote products derived
     22 //    from this software without specific prior written permission.
     23 //
     24 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     25 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     26 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     27 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     28 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     29 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     30 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     31 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
     32 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     33 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
     34 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     35 // POSSIBILITY OF SUCH DAMAGE.
     36 //
     37 
     38 #include "localintermediate.h"
     39 #include "../Include/InfoSink.h"
     40 
     41 #ifdef _MSC_VER
     42 #include <cfloat>
     43 #else
     44 #include <cmath>
     45 #endif
     46 
     47 namespace {
     48 
     49 bool IsInfinity(double x) {
     50 #ifdef _MSC_VER
     51     switch (_fpclass(x)) {
     52     case _FPCLASS_NINF:
     53     case _FPCLASS_PINF:
     54         return true;
     55     default:
     56         return false;
     57     }
     58 #else
     59     return std::isinf(x);
     60 #endif
     61 }
     62 
     63 bool IsNan(double x) {
     64 #ifdef _MSC_VER
     65     switch (_fpclass(x)) {
     66     case _FPCLASS_SNAN:
     67     case _FPCLASS_QNAN:
     68         return true;
     69     default:
     70         return false;
     71     }
     72 #else
     73   return std::isnan(x);
     74 #endif
     75 }
     76 
     77 }
     78 
     79 namespace glslang {
     80 
     81 //
     82 // Two purposes:
     83 // 1.  Show an example of how to iterate tree.  Functions can
     84 //     also directly call Traverse() on children themselves to
     85 //     have finer grained control over the process than shown here.
     86 //     See the last function for how to get started.
     87 // 2.  Print out a text based description of the tree.
     88 //
     89 
     90 //
     91 // Use this class to carry along data from node to node in
     92 // the traversal
     93 //
     94 class TOutputTraverser : public TIntermTraverser {
     95 public:
     96     TOutputTraverser(TInfoSink& i) : infoSink(i), extraOutput(NoExtraOutput) { }
     97 
     98     enum EExtraOutput {
     99         NoExtraOutput,
    100         BinaryDoubleOutput
    101     };
    102     void setDoubleOutput(EExtraOutput extra) { extraOutput = extra; }
    103 
    104     virtual bool visitBinary(TVisit, TIntermBinary* node);
    105     virtual bool visitUnary(TVisit, TIntermUnary* node);
    106     virtual bool visitAggregate(TVisit, TIntermAggregate* node);
    107     virtual bool visitSelection(TVisit, TIntermSelection* node);
    108     virtual void visitConstantUnion(TIntermConstantUnion* node);
    109     virtual void visitSymbol(TIntermSymbol* node);
    110     virtual bool visitLoop(TVisit, TIntermLoop* node);
    111     virtual bool visitBranch(TVisit, TIntermBranch* node);
    112     virtual bool visitSwitch(TVisit, TIntermSwitch* node);
    113 
    114     TInfoSink& infoSink;
    115 protected:
    116     TOutputTraverser(TOutputTraverser&);
    117     TOutputTraverser& operator=(TOutputTraverser&);
    118 
    119     EExtraOutput extraOutput;
    120 };
    121 
    122 //
    123 // Helper functions for printing, not part of traversing.
    124 //
    125 
    126 static void OutputTreeText(TInfoSink& infoSink, const TIntermNode* node, const int depth)
    127 {
    128     int i;
    129 
    130     infoSink.debug << node->getLoc().string << ":";
    131     if (node->getLoc().line)
    132         infoSink.debug << node->getLoc().line;
    133     else
    134         infoSink.debug << "? ";
    135 
    136     for (i = 0; i < depth; ++i)
    137         infoSink.debug << "  ";
    138 }
    139 
    140 //
    141 // The rest of the file are the traversal functions.  The last one
    142 // is the one that starts the traversal.
    143 //
    144 // Return true from interior nodes to have the external traversal
    145 // continue on to children.  If you process children yourself,
    146 // return false.
    147 //
    148 
    149 bool TOutputTraverser::visitBinary(TVisit /* visit */, TIntermBinary* node)
    150 {
    151     TInfoSink& out = infoSink;
    152 
    153     OutputTreeText(out, node, depth);
    154 
    155     switch (node->getOp()) {
    156     case EOpAssign:                   out.debug << "move second child to first child";           break;
    157     case EOpAddAssign:                out.debug << "add second child into first child";          break;
    158     case EOpSubAssign:                out.debug << "subtract second child into first child";     break;
    159     case EOpMulAssign:                out.debug << "multiply second child into first child";     break;
    160     case EOpVectorTimesMatrixAssign:  out.debug << "matrix mult second child into first child";  break;
    161     case EOpVectorTimesScalarAssign:  out.debug << "vector scale second child into first child"; break;
    162     case EOpMatrixTimesScalarAssign:  out.debug << "matrix scale second child into first child"; break;
    163     case EOpMatrixTimesMatrixAssign:  out.debug << "matrix mult second child into first child";  break;
    164     case EOpDivAssign:                out.debug << "divide second child into first child";       break;
    165     case EOpModAssign:                out.debug << "mod second child into first child";          break;
    166     case EOpAndAssign:                out.debug << "and second child into first child";          break;
    167     case EOpInclusiveOrAssign:        out.debug << "or second child into first child";           break;
    168     case EOpExclusiveOrAssign:        out.debug << "exclusive or second child into first child"; break;
    169     case EOpLeftShiftAssign:          out.debug << "left shift second child into first child";   break;
    170     case EOpRightShiftAssign:         out.debug << "right shift second child into first child";  break;
    171 
    172     case EOpIndexDirect:   out.debug << "direct index";   break;
    173     case EOpIndexIndirect: out.debug << "indirect index"; break;
    174     case EOpIndexDirectStruct:
    175         {
    176             bool reference = node->getLeft()->getType().getBasicType() == EbtReference;
    177             const TTypeList *members = reference ? node->getLeft()->getType().getReferentType()->getStruct() : node->getLeft()->getType().getStruct();
    178             out.debug << (*members)[node->getRight()->getAsConstantUnion()->getConstArray()[0].getIConst()].type->getFieldName();
    179             out.debug << ": direct index for structure";      break;
    180         }
    181     case EOpVectorSwizzle: out.debug << "vector swizzle"; break;
    182     case EOpMatrixSwizzle: out.debug << "matrix swizzle"; break;
    183 
    184     case EOpAdd:    out.debug << "add";                     break;
    185     case EOpSub:    out.debug << "subtract";                break;
    186     case EOpMul:    out.debug << "component-wise multiply"; break;
    187     case EOpDiv:    out.debug << "divide";                  break;
    188     case EOpMod:    out.debug << "mod";                     break;
    189     case EOpRightShift:  out.debug << "right-shift";  break;
    190     case EOpLeftShift:   out.debug << "left-shift";   break;
    191     case EOpAnd:         out.debug << "bitwise and";  break;
    192     case EOpInclusiveOr: out.debug << "inclusive-or"; break;
    193     case EOpExclusiveOr: out.debug << "exclusive-or"; break;
    194     case EOpEqual:            out.debug << "Compare Equal";                 break;
    195     case EOpNotEqual:         out.debug << "Compare Not Equal";             break;
    196     case EOpLessThan:         out.debug << "Compare Less Than";             break;
    197     case EOpGreaterThan:      out.debug << "Compare Greater Than";          break;
    198     case EOpLessThanEqual:    out.debug << "Compare Less Than or Equal";    break;
    199     case EOpGreaterThanEqual: out.debug << "Compare Greater Than or Equal"; break;
    200     case EOpVectorEqual:      out.debug << "Equal";                         break;
    201     case EOpVectorNotEqual:   out.debug << "NotEqual";                      break;
    202 
    203     case EOpVectorTimesScalar: out.debug << "vector-scale";          break;
    204     case EOpVectorTimesMatrix: out.debug << "vector-times-matrix";   break;
    205     case EOpMatrixTimesVector: out.debug << "matrix-times-vector";   break;
    206     case EOpMatrixTimesScalar: out.debug << "matrix-scale";          break;
    207     case EOpMatrixTimesMatrix: out.debug << "matrix-multiply";       break;
    208 
    209     case EOpLogicalOr:  out.debug << "logical-or";   break;
    210     case EOpLogicalXor: out.debug << "logical-xor"; break;
    211     case EOpLogicalAnd: out.debug << "logical-and"; break;
    212 
    213     default: out.debug << "<unknown op>";
    214     }
    215 
    216     out.debug << " (" << node->getCompleteString() << ")";
    217 
    218     out.debug << "\n";
    219 
    220     return true;
    221 }
    222 
    223 bool TOutputTraverser::visitUnary(TVisit /* visit */, TIntermUnary* node)
    224 {
    225     TInfoSink& out = infoSink;
    226 
    227     OutputTreeText(out, node, depth);
    228 
    229     switch (node->getOp()) {
    230     case EOpNegative:       out.debug << "Negate value";         break;
    231     case EOpVectorLogicalNot:
    232     case EOpLogicalNot:     out.debug << "Negate conditional";   break;
    233     case EOpBitwiseNot:     out.debug << "Bitwise not";          break;
    234 
    235     case EOpPostIncrement:  out.debug << "Post-Increment";       break;
    236     case EOpPostDecrement:  out.debug << "Post-Decrement";       break;
    237     case EOpPreIncrement:   out.debug << "Pre-Increment";        break;
    238     case EOpPreDecrement:   out.debug << "Pre-Decrement";        break;
    239 
    240     // * -> bool
    241     case EOpConvInt8ToBool:    out.debug << "Convert int8_t to bool";  break;
    242     case EOpConvUint8ToBool:   out.debug << "Convert uint8_t to bool"; break;
    243     case EOpConvInt16ToBool:   out.debug << "Convert int16_t to bool"; break;
    244     case EOpConvUint16ToBool:  out.debug << "Convert uint16_t to bool";break;
    245     case EOpConvIntToBool:     out.debug << "Convert int to bool";     break;
    246     case EOpConvUintToBool:    out.debug << "Convert uint to bool";    break;
    247     case EOpConvInt64ToBool:   out.debug << "Convert int64 to bool";   break;
    248     case EOpConvUint64ToBool:  out.debug << "Convert uint64 to bool";  break;
    249     case EOpConvFloat16ToBool: out.debug << "Convert float16_t to bool";   break;
    250     case EOpConvFloatToBool:   out.debug << "Convert float to bool";   break;
    251     case EOpConvDoubleToBool:  out.debug << "Convert double to bool";  break;
    252 
    253     // bool -> *
    254     case EOpConvBoolToInt8:    out.debug << "Convert bool to int8_t";  break;
    255     case EOpConvBoolToUint8:   out.debug << "Convert bool to uint8_t"; break;
    256     case EOpConvBoolToInt16:   out.debug << "Convert bool to in16t_t"; break;
    257     case EOpConvBoolToUint16:  out.debug << "Convert bool to uint16_t";break;
    258     case EOpConvBoolToInt:     out.debug << "Convert bool to int"  ;   break;
    259     case EOpConvBoolToUint:    out.debug << "Convert bool to uint";    break;
    260     case EOpConvBoolToInt64:   out.debug << "Convert bool to int64"; break;
    261     case EOpConvBoolToUint64:  out.debug << "Convert bool to uint64";break;
    262     case EOpConvBoolToFloat16: out.debug << "Convert bool to float16_t";   break;
    263     case EOpConvBoolToFloat:   out.debug << "Convert bool to float";   break;
    264     case EOpConvBoolToDouble:  out.debug << "Convert bool to double";   break;
    265 
    266     // int8_t -> (u)int*
    267     case EOpConvInt8ToInt16:   out.debug << "Convert int8_t to int16_t";break;
    268     case EOpConvInt8ToInt:     out.debug << "Convert int8_t to int";    break;
    269     case EOpConvInt8ToInt64:   out.debug << "Convert int8_t to int64";   break;
    270     case EOpConvInt8ToUint8:   out.debug << "Convert int8_t to uint8_t";break;
    271     case EOpConvInt8ToUint16:  out.debug << "Convert int8_t to uint16_t";break;
    272     case EOpConvInt8ToUint:    out.debug << "Convert int8_t to uint";    break;
    273     case EOpConvInt8ToUint64:  out.debug << "Convert int8_t to uint64";   break;
    274 
    275     // uint8_t -> (u)int*
    276     case EOpConvUint8ToInt8:    out.debug << "Convert uint8_t to int8_t";break;
    277     case EOpConvUint8ToInt16:   out.debug << "Convert uint8_t to int16_t";break;
    278     case EOpConvUint8ToInt:     out.debug << "Convert uint8_t to int";    break;
    279     case EOpConvUint8ToInt64:   out.debug << "Convert uint8_t to int64";   break;
    280     case EOpConvUint8ToUint16:  out.debug << "Convert uint8_t to uint16_t";break;
    281     case EOpConvUint8ToUint:    out.debug << "Convert uint8_t to uint";    break;
    282     case EOpConvUint8ToUint64:  out.debug << "Convert uint8_t to uint64";   break;
    283 
    284     // int8_t -> float*
    285     case EOpConvInt8ToFloat16:  out.debug << "Convert int8_t to float16_t";break;
    286     case EOpConvInt8ToFloat:    out.debug << "Convert int8_t to float";    break;
    287     case EOpConvInt8ToDouble:   out.debug << "Convert int8_t to double";   break;
    288 
    289     // uint8_t -> float*
    290     case EOpConvUint8ToFloat16: out.debug << "Convert uint8_t to float16_t";break;
    291     case EOpConvUint8ToFloat:   out.debug << "Convert uint8_t to float";    break;
    292     case EOpConvUint8ToDouble:  out.debug << "Convert uint8_t to double";   break;
    293 
    294     // int16_t -> (u)int*
    295     case EOpConvInt16ToInt8:    out.debug << "Convert int16_t to int8_t";break;
    296     case EOpConvInt16ToInt:     out.debug << "Convert int16_t to int";    break;
    297     case EOpConvInt16ToInt64:   out.debug << "Convert int16_t to int64";   break;
    298     case EOpConvInt16ToUint8:   out.debug << "Convert int16_t to uint8_t";break;
    299     case EOpConvInt16ToUint16:  out.debug << "Convert int16_t to uint16_t";break;
    300     case EOpConvInt16ToUint:    out.debug << "Convert int16_t to uint";    break;
    301     case EOpConvInt16ToUint64:  out.debug << "Convert int16_t to uint64";   break;
    302 
    303     // int16_t -> float*
    304     case EOpConvInt16ToFloat16:  out.debug << "Convert int16_t to float16_t";break;
    305     case EOpConvInt16ToFloat:    out.debug << "Convert int16_t to float";    break;
    306     case EOpConvInt16ToDouble:   out.debug << "Convert int16_t to double";   break;
    307 
    308     // uint16_t -> (u)int*
    309     case EOpConvUint16ToInt8:    out.debug << "Convert uint16_t to int8_t";break;
    310     case EOpConvUint16ToInt16:   out.debug << "Convert uint16_t to int16_t";break;
    311     case EOpConvUint16ToInt:     out.debug << "Convert uint16_t to int";    break;
    312     case EOpConvUint16ToInt64:   out.debug << "Convert uint16_t to int64";   break;
    313     case EOpConvUint16ToUint8:   out.debug << "Convert uint16_t to uint8_t";break;
    314     case EOpConvUint16ToUint:    out.debug << "Convert uint16_t to uint";    break;
    315     case EOpConvUint16ToUint64:  out.debug << "Convert uint16_t to uint64";   break;
    316 
    317     // uint16_t -> float*
    318     case EOpConvUint16ToFloat16: out.debug << "Convert uint16_t to float16_t";break;
    319     case EOpConvUint16ToFloat:   out.debug << "Convert uint16_t to float";    break;
    320     case EOpConvUint16ToDouble:  out.debug << "Convert uint16_t to double";   break;
    321 
    322     // int32_t -> (u)int*
    323     case EOpConvIntToInt8:    out.debug << "Convert int to int8_t";break;
    324     case EOpConvIntToInt16:   out.debug << "Convert int to int16_t";break;
    325     case EOpConvIntToInt64:   out.debug << "Convert int to int64";   break;
    326     case EOpConvIntToUint8:   out.debug << "Convert int to uint8_t";break;
    327     case EOpConvIntToUint16:  out.debug << "Convert int to uint16_t";break;
    328     case EOpConvIntToUint:    out.debug << "Convert int to uint";    break;
    329     case EOpConvIntToUint64:  out.debug << "Convert int to uint64";   break;
    330 
    331     // int32_t -> float*
    332     case EOpConvIntToFloat16:  out.debug << "Convert int to float16_t";break;
    333     case EOpConvIntToFloat:    out.debug << "Convert int to float";    break;
    334     case EOpConvIntToDouble:   out.debug << "Convert int to double";   break;
    335 
    336     // uint32_t -> (u)int*
    337     case EOpConvUintToInt8:    out.debug << "Convert uint to int8_t";break;
    338     case EOpConvUintToInt16:   out.debug << "Convert uint to int16_t";break;
    339     case EOpConvUintToInt:     out.debug << "Convert uint to int";break;
    340     case EOpConvUintToInt64:   out.debug << "Convert uint to int64";   break;
    341     case EOpConvUintToUint8:   out.debug << "Convert uint to uint8_t";break;
    342     case EOpConvUintToUint16:  out.debug << "Convert uint to uint16_t";break;
    343     case EOpConvUintToUint64:  out.debug << "Convert uint to uint64";   break;
    344 
    345     // uint32_t -> float*
    346     case EOpConvUintToFloat16: out.debug << "Convert uint to float16_t";break;
    347     case EOpConvUintToFloat:   out.debug << "Convert uint to float";    break;
    348     case EOpConvUintToDouble:  out.debug << "Convert uint to double";   break;
    349 
    350     // int64 -> (u)int*
    351     case EOpConvInt64ToInt8:    out.debug << "Convert int64 to int8_t";  break;
    352     case EOpConvInt64ToInt16:   out.debug << "Convert int64 to int16_t"; break;
    353     case EOpConvInt64ToInt:     out.debug << "Convert int64 to int";   break;
    354     case EOpConvInt64ToUint8:   out.debug << "Convert int64 to uint8_t";break;
    355     case EOpConvInt64ToUint16:  out.debug << "Convert int64 to uint16_t";break;
    356     case EOpConvInt64ToUint:    out.debug << "Convert int64 to uint";    break;
    357     case EOpConvInt64ToUint64:  out.debug << "Convert int64 to uint64";   break;
    358 
    359      // int64 -> float*
    360     case EOpConvInt64ToFloat16:  out.debug << "Convert int64 to float16_t";break;
    361     case EOpConvInt64ToFloat:    out.debug << "Convert int64 to float";    break;
    362     case EOpConvInt64ToDouble:   out.debug << "Convert int64 to double";   break;
    363 
    364     // uint64 -> (u)int*
    365     case EOpConvUint64ToInt8:    out.debug << "Convert uint64 to int8_t";break;
    366     case EOpConvUint64ToInt16:   out.debug << "Convert uint64 to int16_t";break;
    367     case EOpConvUint64ToInt:     out.debug << "Convert uint64 to int";    break;
    368     case EOpConvUint64ToInt64:   out.debug << "Convert uint64 to int64";   break;
    369     case EOpConvUint64ToUint8:   out.debug << "Convert uint64 to uint8_t";break;
    370     case EOpConvUint64ToUint16:  out.debug << "Convert uint64 to uint16";    break;
    371     case EOpConvUint64ToUint:    out.debug << "Convert uint64 to uint";   break;
    372 
    373     // uint64 -> float*
    374     case EOpConvUint64ToFloat16: out.debug << "Convert uint64 to float16_t";break;
    375     case EOpConvUint64ToFloat:   out.debug << "Convert uint64 to float";    break;
    376     case EOpConvUint64ToDouble:  out.debug << "Convert uint64 to double";   break;
    377 
    378     // float16_t -> int*
    379     case EOpConvFloat16ToInt8:  out.debug << "Convert float16_t to int8_t"; break;
    380     case EOpConvFloat16ToInt16: out.debug << "Convert float16_t to int16_t"; break;
    381     case EOpConvFloat16ToInt:   out.debug << "Convert float16_t to int"; break;
    382     case EOpConvFloat16ToInt64: out.debug << "Convert float16_t to int64"; break;
    383 
    384     // float16_t -> uint*
    385     case EOpConvFloat16ToUint8:  out.debug << "Convert float16_t to uint8_t"; break;
    386     case EOpConvFloat16ToUint16: out.debug << "Convert float16_t to uint16_t"; break;
    387     case EOpConvFloat16ToUint:   out.debug << "Convert float16_t to uint"; break;
    388     case EOpConvFloat16ToUint64: out.debug << "Convert float16_t to uint64"; break;
    389 
    390     // float16_t -> float*
    391     case EOpConvFloat16ToFloat:  out.debug << "Convert float16_t to float"; break;
    392     case EOpConvFloat16ToDouble: out.debug << "Convert float16_t to double"; break;
    393 
    394     // float32 -> float*
    395     case EOpConvFloatToFloat16: out.debug << "Convert float to float16_t"; break;
    396     case EOpConvFloatToDouble:  out.debug << "Convert float to double"; break;
    397 
    398     // float32_t -> int*
    399     case EOpConvFloatToInt8:  out.debug << "Convert float to int8_t"; break;
    400     case EOpConvFloatToInt16: out.debug << "Convert float to int16_t"; break;
    401     case EOpConvFloatToInt:   out.debug << "Convert float to int"; break;
    402     case EOpConvFloatToInt64: out.debug << "Convert float to int64"; break;
    403 
    404     // float32_t -> uint*
    405     case EOpConvFloatToUint8:  out.debug << "Convert float to uint8_t"; break;
    406     case EOpConvFloatToUint16: out.debug << "Convert float to uint16_t"; break;
    407     case EOpConvFloatToUint:   out.debug << "Convert float to uint"; break;
    408     case EOpConvFloatToUint64: out.debug << "Convert float to uint64"; break;
    409 
    410     // double -> float*
    411     case EOpConvDoubleToFloat16: out.debug << "Convert double to float16_t"; break;
    412     case EOpConvDoubleToFloat:   out.debug << "Convert double to float"; break;
    413 
    414     // double -> int*
    415     case EOpConvDoubleToInt8:  out.debug << "Convert double to int8_t"; break;
    416     case EOpConvDoubleToInt16: out.debug << "Convert double to int16_t"; break;
    417     case EOpConvDoubleToInt:   out.debug << "Convert double to int"; break;
    418     case EOpConvDoubleToInt64: out.debug << "Convert double to int64"; break;
    419 
    420     // float32_t -> uint*
    421     case EOpConvDoubleToUint8:  out.debug << "Convert double to uint8_t"; break;
    422     case EOpConvDoubleToUint16: out.debug << "Convert double to uint16_t"; break;
    423     case EOpConvDoubleToUint:   out.debug << "Convert double to uint"; break;
    424     case EOpConvDoubleToUint64: out.debug << "Convert double to uint64"; break;
    425 
    426     case EOpConvUint64ToPtr:  out.debug << "Convert uint64_t to pointer";   break;
    427     case EOpConvPtrToUint64:  out.debug << "Convert pointer to uint64_t";   break;
    428 
    429     case EOpRadians:        out.debug << "radians";              break;
    430     case EOpDegrees:        out.debug << "degrees";              break;
    431     case EOpSin:            out.debug << "sine";                 break;
    432     case EOpCos:            out.debug << "cosine";               break;
    433     case EOpTan:            out.debug << "tangent";              break;
    434     case EOpAsin:           out.debug << "arc sine";             break;
    435     case EOpAcos:           out.debug << "arc cosine";           break;
    436     case EOpAtan:           out.debug << "arc tangent";          break;
    437     case EOpSinh:           out.debug << "hyp. sine";            break;
    438     case EOpCosh:           out.debug << "hyp. cosine";          break;
    439     case EOpTanh:           out.debug << "hyp. tangent";         break;
    440     case EOpAsinh:          out.debug << "arc hyp. sine";        break;
    441     case EOpAcosh:          out.debug << "arc hyp. cosine";      break;
    442     case EOpAtanh:          out.debug << "arc hyp. tangent";     break;
    443 
    444     case EOpExp:            out.debug << "exp";                  break;
    445     case EOpLog:            out.debug << "log";                  break;
    446     case EOpExp2:           out.debug << "exp2";                 break;
    447     case EOpLog2:           out.debug << "log2";                 break;
    448     case EOpSqrt:           out.debug << "sqrt";                 break;
    449     case EOpInverseSqrt:    out.debug << "inverse sqrt";         break;
    450 
    451     case EOpAbs:            out.debug << "Absolute value";       break;
    452     case EOpSign:           out.debug << "Sign";                 break;
    453     case EOpFloor:          out.debug << "Floor";                break;
    454     case EOpTrunc:          out.debug << "trunc";                break;
    455     case EOpRound:          out.debug << "round";                break;
    456     case EOpRoundEven:      out.debug << "roundEven";            break;
    457     case EOpCeil:           out.debug << "Ceiling";              break;
    458     case EOpFract:          out.debug << "Fraction";             break;
    459 
    460     case EOpIsNan:          out.debug << "isnan";                break;
    461     case EOpIsInf:          out.debug << "isinf";                break;
    462 
    463     case EOpFloatBitsToInt: out.debug << "floatBitsToInt";       break;
    464     case EOpFloatBitsToUint:out.debug << "floatBitsToUint";      break;
    465     case EOpIntBitsToFloat: out.debug << "intBitsToFloat";       break;
    466     case EOpUintBitsToFloat:out.debug << "uintBitsToFloat";      break;
    467     case EOpDoubleBitsToInt64:  out.debug << "doubleBitsToInt64";  break;
    468     case EOpDoubleBitsToUint64: out.debug << "doubleBitsToUint64"; break;
    469     case EOpInt64BitsToDouble:  out.debug << "int64BitsToDouble";  break;
    470     case EOpUint64BitsToDouble: out.debug << "uint64BitsToDouble"; break;
    471     case EOpFloat16BitsToInt16:  out.debug << "float16BitsToInt16";  break;
    472     case EOpFloat16BitsToUint16: out.debug << "float16BitsToUint16"; break;
    473     case EOpInt16BitsToFloat16:  out.debug << "int16BitsToFloat16";  break;
    474     case EOpUint16BitsToFloat16: out.debug << "uint16BitsToFloat16"; break;
    475 
    476     case EOpPackSnorm2x16:  out.debug << "packSnorm2x16";        break;
    477     case EOpUnpackSnorm2x16:out.debug << "unpackSnorm2x16";      break;
    478     case EOpPackUnorm2x16:  out.debug << "packUnorm2x16";        break;
    479     case EOpUnpackUnorm2x16:out.debug << "unpackUnorm2x16";      break;
    480     case EOpPackHalf2x16:   out.debug << "packHalf2x16";         break;
    481     case EOpUnpackHalf2x16: out.debug << "unpackHalf2x16";       break;
    482     case EOpPack16:           out.debug << "pack16";                 break;
    483     case EOpPack32:           out.debug << "pack32";                 break;
    484     case EOpPack64:           out.debug << "pack64";                 break;
    485     case EOpUnpack32:         out.debug << "unpack32";               break;
    486     case EOpUnpack16:         out.debug << "unpack16";               break;
    487     case EOpUnpack8:          out.debug << "unpack8";               break;
    488 
    489     case EOpPackSnorm4x8:     out.debug << "PackSnorm4x8";       break;
    490     case EOpUnpackSnorm4x8:   out.debug << "UnpackSnorm4x8";     break;
    491     case EOpPackUnorm4x8:     out.debug << "PackUnorm4x8";       break;
    492     case EOpUnpackUnorm4x8:   out.debug << "UnpackUnorm4x8";     break;
    493     case EOpPackDouble2x32:   out.debug << "PackDouble2x32";     break;
    494     case EOpUnpackDouble2x32: out.debug << "UnpackDouble2x32";   break;
    495 
    496     case EOpPackInt2x32:      out.debug << "packInt2x32";        break;
    497     case EOpUnpackInt2x32:    out.debug << "unpackInt2x32";      break;
    498     case EOpPackUint2x32:     out.debug << "packUint2x32";       break;
    499     case EOpUnpackUint2x32:   out.debug << "unpackUint2x32";     break;
    500 
    501     case EOpPackInt2x16:      out.debug << "packInt2x16";        break;
    502     case EOpUnpackInt2x16:    out.debug << "unpackInt2x16";      break;
    503     case EOpPackUint2x16:     out.debug << "packUint2x16";       break;
    504     case EOpUnpackUint2x16:   out.debug << "unpackUint2x16";     break;
    505 
    506     case EOpPackInt4x16:      out.debug << "packInt4x16";        break;
    507     case EOpUnpackInt4x16:    out.debug << "unpackInt4x16";      break;
    508     case EOpPackUint4x16:     out.debug << "packUint4x16";       break;
    509     case EOpUnpackUint4x16:   out.debug << "unpackUint4x16";     break;
    510     case EOpPackFloat2x16:    out.debug << "packFloat2x16";      break;
    511     case EOpUnpackFloat2x16:  out.debug << "unpackFloat2x16";    break;
    512 
    513     case EOpLength:         out.debug << "length";               break;
    514     case EOpNormalize:      out.debug << "normalize";            break;
    515     case EOpDPdx:           out.debug << "dPdx";                 break;
    516     case EOpDPdy:           out.debug << "dPdy";                 break;
    517     case EOpFwidth:         out.debug << "fwidth";               break;
    518     case EOpDPdxFine:       out.debug << "dPdxFine";             break;
    519     case EOpDPdyFine:       out.debug << "dPdyFine";             break;
    520     case EOpFwidthFine:     out.debug << "fwidthFine";           break;
    521     case EOpDPdxCoarse:     out.debug << "dPdxCoarse";           break;
    522     case EOpDPdyCoarse:     out.debug << "dPdyCoarse";           break;
    523     case EOpFwidthCoarse:   out.debug << "fwidthCoarse";         break;
    524 
    525     case EOpInterpolateAtCentroid: out.debug << "interpolateAtCentroid";  break;
    526 
    527     case EOpDeterminant:    out.debug << "determinant";          break;
    528     case EOpMatrixInverse:  out.debug << "inverse";              break;
    529     case EOpTranspose:      out.debug << "transpose";            break;
    530 
    531     case EOpAny:            out.debug << "any";                  break;
    532     case EOpAll:            out.debug << "all";                  break;
    533 
    534     case EOpArrayLength:    out.debug << "array length";         break;
    535 
    536     case EOpEmitStreamVertex:   out.debug << "EmitStreamVertex";   break;
    537     case EOpEndStreamPrimitive: out.debug << "EndStreamPrimitive"; break;
    538 
    539     case EOpAtomicCounterIncrement: out.debug << "AtomicCounterIncrement";break;
    540     case EOpAtomicCounterDecrement: out.debug << "AtomicCounterDecrement";break;
    541     case EOpAtomicCounter:          out.debug << "AtomicCounter";         break;
    542 
    543     case EOpTextureQuerySize:       out.debug << "textureSize";           break;
    544     case EOpTextureQueryLod:        out.debug << "textureQueryLod";       break;
    545     case EOpTextureQueryLevels:     out.debug << "textureQueryLevels";    break;
    546     case EOpTextureQuerySamples:    out.debug << "textureSamples";        break;
    547     case EOpImageQuerySize:         out.debug << "imageQuerySize";        break;
    548     case EOpImageQuerySamples:      out.debug << "imageQuerySamples";     break;
    549     case EOpImageLoad:              out.debug << "imageLoad";             break;
    550 
    551     case EOpBitFieldReverse:        out.debug << "bitFieldReverse";       break;
    552     case EOpBitCount:               out.debug << "bitCount";              break;
    553     case EOpFindLSB:                out.debug << "findLSB";               break;
    554     case EOpFindMSB:                out.debug << "findMSB";               break;
    555 
    556     case EOpNoise:                  out.debug << "noise";                 break;
    557 
    558     case EOpBallot:                 out.debug << "ballot";                break;
    559     case EOpReadFirstInvocation:    out.debug << "readFirstInvocation";   break;
    560 
    561     case EOpAnyInvocation:          out.debug << "anyInvocation";         break;
    562     case EOpAllInvocations:         out.debug << "allInvocations";        break;
    563     case EOpAllInvocationsEqual:    out.debug << "allInvocationsEqual";   break;
    564 
    565     case EOpSubgroupElect:                   out.debug << "subgroupElect";                   break;
    566     case EOpSubgroupAll:                     out.debug << "subgroupAll";                     break;
    567     case EOpSubgroupAny:                     out.debug << "subgroupAny";                     break;
    568     case EOpSubgroupAllEqual:                out.debug << "subgroupAllEqual";                break;
    569     case EOpSubgroupBroadcast:               out.debug << "subgroupBroadcast";               break;
    570     case EOpSubgroupBroadcastFirst:          out.debug << "subgroupBroadcastFirst";          break;
    571     case EOpSubgroupBallot:                  out.debug << "subgroupBallot";                  break;
    572     case EOpSubgroupInverseBallot:           out.debug << "subgroupInverseBallot";           break;
    573     case EOpSubgroupBallotBitExtract:        out.debug << "subgroupBallotBitExtract";        break;
    574     case EOpSubgroupBallotBitCount:          out.debug << "subgroupBallotBitCount";          break;
    575     case EOpSubgroupBallotInclusiveBitCount: out.debug << "subgroupBallotInclusiveBitCount"; break;
    576     case EOpSubgroupBallotExclusiveBitCount: out.debug << "subgroupBallotExclusiveBitCount"; break;
    577     case EOpSubgroupBallotFindLSB:           out.debug << "subgroupBallotFindLSB";           break;
    578     case EOpSubgroupBallotFindMSB:           out.debug << "subgroupBallotFindMSB";           break;
    579     case EOpSubgroupShuffle:                 out.debug << "subgroupShuffle";                 break;
    580     case EOpSubgroupShuffleXor:              out.debug << "subgroupShuffleXor";              break;
    581     case EOpSubgroupShuffleUp:               out.debug << "subgroupShuffleUp";               break;
    582     case EOpSubgroupShuffleDown:             out.debug << "subgroupShuffleDown";             break;
    583     case EOpSubgroupAdd:                     out.debug << "subgroupAdd";                     break;
    584     case EOpSubgroupMul:                     out.debug << "subgroupMul";                     break;
    585     case EOpSubgroupMin:                     out.debug << "subgroupMin";                     break;
    586     case EOpSubgroupMax:                     out.debug << "subgroupMax";                     break;
    587     case EOpSubgroupAnd:                     out.debug << "subgroupAnd";                     break;
    588     case EOpSubgroupOr:                      out.debug << "subgroupOr";                      break;
    589     case EOpSubgroupXor:                     out.debug << "subgroupXor";                     break;
    590     case EOpSubgroupInclusiveAdd:            out.debug << "subgroupInclusiveAdd";            break;
    591     case EOpSubgroupInclusiveMul:            out.debug << "subgroupInclusiveMul";            break;
    592     case EOpSubgroupInclusiveMin:            out.debug << "subgroupInclusiveMin";            break;
    593     case EOpSubgroupInclusiveMax:            out.debug << "subgroupInclusiveMax";            break;
    594     case EOpSubgroupInclusiveAnd:            out.debug << "subgroupInclusiveAnd";            break;
    595     case EOpSubgroupInclusiveOr:             out.debug << "subgroupInclusiveOr";             break;
    596     case EOpSubgroupInclusiveXor:            out.debug << "subgroupInclusiveXor";            break;
    597     case EOpSubgroupExclusiveAdd:            out.debug << "subgroupExclusiveAdd";            break;
    598     case EOpSubgroupExclusiveMul:            out.debug << "subgroupExclusiveMul";            break;
    599     case EOpSubgroupExclusiveMin:            out.debug << "subgroupExclusiveMin";            break;
    600     case EOpSubgroupExclusiveMax:            out.debug << "subgroupExclusiveMax";            break;
    601     case EOpSubgroupExclusiveAnd:            out.debug << "subgroupExclusiveAnd";            break;
    602     case EOpSubgroupExclusiveOr:             out.debug << "subgroupExclusiveOr";             break;
    603     case EOpSubgroupExclusiveXor:            out.debug << "subgroupExclusiveXor";            break;
    604     case EOpSubgroupClusteredAdd:            out.debug << "subgroupClusteredAdd";            break;
    605     case EOpSubgroupClusteredMul:            out.debug << "subgroupClusteredMul";            break;
    606     case EOpSubgroupClusteredMin:            out.debug << "subgroupClusteredMin";            break;
    607     case EOpSubgroupClusteredMax:            out.debug << "subgroupClusteredMax";            break;
    608     case EOpSubgroupClusteredAnd:            out.debug << "subgroupClusteredAnd";            break;
    609     case EOpSubgroupClusteredOr:             out.debug << "subgroupClusteredOr";             break;
    610     case EOpSubgroupClusteredXor:            out.debug << "subgroupClusteredXor";            break;
    611     case EOpSubgroupQuadBroadcast:           out.debug << "subgroupQuadBroadcast";           break;
    612     case EOpSubgroupQuadSwapHorizontal:      out.debug << "subgroupQuadSwapHorizontal";      break;
    613     case EOpSubgroupQuadSwapVertical:        out.debug << "subgroupQuadSwapVertical";        break;
    614     case EOpSubgroupQuadSwapDiagonal:        out.debug << "subgroupQuadSwapDiagonal";        break;
    615 
    616 #ifdef NV_EXTENSIONS
    617     case EOpSubgroupPartition:                          out.debug << "subgroupPartitionNV";                          break;
    618     case EOpSubgroupPartitionedAdd:                     out.debug << "subgroupPartitionedAddNV";                     break;
    619     case EOpSubgroupPartitionedMul:                     out.debug << "subgroupPartitionedMulNV";                     break;
    620     case EOpSubgroupPartitionedMin:                     out.debug << "subgroupPartitionedMinNV";                     break;
    621     case EOpSubgroupPartitionedMax:                     out.debug << "subgroupPartitionedMaxNV";                     break;
    622     case EOpSubgroupPartitionedAnd:                     out.debug << "subgroupPartitionedAndNV";                     break;
    623     case EOpSubgroupPartitionedOr:                      out.debug << "subgroupPartitionedOrNV";                      break;
    624     case EOpSubgroupPartitionedXor:                     out.debug << "subgroupPartitionedXorNV";                     break;
    625     case EOpSubgroupPartitionedInclusiveAdd:            out.debug << "subgroupPartitionedInclusiveAddNV";            break;
    626     case EOpSubgroupPartitionedInclusiveMul:            out.debug << "subgroupPartitionedInclusiveMulNV";            break;
    627     case EOpSubgroupPartitionedInclusiveMin:            out.debug << "subgroupPartitionedInclusiveMinNV";            break;
    628     case EOpSubgroupPartitionedInclusiveMax:            out.debug << "subgroupPartitionedInclusiveMaxNV";            break;
    629     case EOpSubgroupPartitionedInclusiveAnd:            out.debug << "subgroupPartitionedInclusiveAndNV";            break;
    630     case EOpSubgroupPartitionedInclusiveOr:             out.debug << "subgroupPartitionedInclusiveOrNV";             break;
    631     case EOpSubgroupPartitionedInclusiveXor:            out.debug << "subgroupPartitionedInclusiveXorNV";            break;
    632     case EOpSubgroupPartitionedExclusiveAdd:            out.debug << "subgroupPartitionedExclusiveAddNV";            break;
    633     case EOpSubgroupPartitionedExclusiveMul:            out.debug << "subgroupPartitionedExclusiveMulNV";            break;
    634     case EOpSubgroupPartitionedExclusiveMin:            out.debug << "subgroupPartitionedExclusiveMinNV";            break;
    635     case EOpSubgroupPartitionedExclusiveMax:            out.debug << "subgroupPartitionedExclusiveMaxNV";            break;
    636     case EOpSubgroupPartitionedExclusiveAnd:            out.debug << "subgroupPartitionedExclusiveAndNV";            break;
    637     case EOpSubgroupPartitionedExclusiveOr:             out.debug << "subgroupPartitionedExclusiveOrNV";             break;
    638     case EOpSubgroupPartitionedExclusiveXor:            out.debug << "subgroupPartitionedExclusiveXorNV";            break;
    639 #endif
    640 
    641     case EOpClip:                   out.debug << "clip";                  break;
    642     case EOpIsFinite:               out.debug << "isfinite";              break;
    643     case EOpLog10:                  out.debug << "log10";                 break;
    644     case EOpRcp:                    out.debug << "rcp";                   break;
    645     case EOpSaturate:               out.debug << "saturate";              break;
    646 
    647     case EOpSparseTexelsResident:   out.debug << "sparseTexelsResident";  break;
    648 
    649 #ifdef AMD_EXTENSIONS
    650     case EOpMinInvocations:             out.debug << "minInvocations";              break;
    651     case EOpMaxInvocations:             out.debug << "maxInvocations";              break;
    652     case EOpAddInvocations:             out.debug << "addInvocations";              break;
    653     case EOpMinInvocationsNonUniform:   out.debug << "minInvocationsNonUniform";    break;
    654     case EOpMaxInvocationsNonUniform:   out.debug << "maxInvocationsNonUniform";    break;
    655     case EOpAddInvocationsNonUniform:   out.debug << "addInvocationsNonUniform";    break;
    656 
    657     case EOpMinInvocationsInclusiveScan:            out.debug << "minInvocationsInclusiveScan";             break;
    658     case EOpMaxInvocationsInclusiveScan:            out.debug << "maxInvocationsInclusiveScan";             break;
    659     case EOpAddInvocationsInclusiveScan:            out.debug << "addInvocationsInclusiveScan";             break;
    660     case EOpMinInvocationsInclusiveScanNonUniform:  out.debug << "minInvocationsInclusiveScanNonUniform";   break;
    661     case EOpMaxInvocationsInclusiveScanNonUniform:  out.debug << "maxInvocationsInclusiveScanNonUniform";   break;
    662     case EOpAddInvocationsInclusiveScanNonUniform:  out.debug << "addInvocationsInclusiveScanNonUniform";   break;
    663 
    664     case EOpMinInvocationsExclusiveScan:            out.debug << "minInvocationsExclusiveScan";             break;
    665     case EOpMaxInvocationsExclusiveScan:            out.debug << "maxInvocationsExclusiveScan";             break;
    666     case EOpAddInvocationsExclusiveScan:            out.debug << "addInvocationsExclusiveScan";             break;
    667     case EOpMinInvocationsExclusiveScanNonUniform:  out.debug << "minInvocationsExclusiveScanNonUniform";   break;
    668     case EOpMaxInvocationsExclusiveScanNonUniform:  out.debug << "maxInvocationsExclusiveScanNonUniform";   break;
    669     case EOpAddInvocationsExclusiveScanNonUniform:  out.debug << "addInvocationsExclusiveScanNonUniform";   break;
    670 
    671     case EOpMbcnt:                  out.debug << "mbcnt";                       break;
    672 
    673     case EOpFragmentMaskFetch:      out.debug << "fragmentMaskFetchAMD";        break;
    674     case EOpFragmentFetch:          out.debug << "fragmentFetchAMD";            break;
    675 
    676     case EOpCubeFaceIndex:          out.debug << "cubeFaceIndex";               break;
    677     case EOpCubeFaceCoord:          out.debug << "cubeFaceCoord";               break;
    678 #endif
    679 
    680     case EOpSubpassLoad:   out.debug << "subpassLoad";   break;
    681     case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
    682 
    683     case EOpConstructReference: out.debug << "Construct reference type"; break;
    684 
    685     default: out.debug.message(EPrefixError, "Bad unary op");
    686     }
    687 
    688     out.debug << " (" << node->getCompleteString() << ")";
    689 
    690     out.debug << "\n";
    691 
    692     return true;
    693 }
    694 
    695 bool TOutputTraverser::visitAggregate(TVisit /* visit */, TIntermAggregate* node)
    696 {
    697     TInfoSink& out = infoSink;
    698 
    699     if (node->getOp() == EOpNull) {
    700         out.debug.message(EPrefixError, "node is still EOpNull!");
    701         return true;
    702     }
    703 
    704     OutputTreeText(out, node, depth);
    705 
    706     switch (node->getOp()) {
    707     case EOpSequence:      out.debug << "Sequence\n";       return true;
    708     case EOpLinkerObjects: out.debug << "Linker Objects\n"; return true;
    709     case EOpComma:         out.debug << "Comma";            break;
    710     case EOpFunction:      out.debug << "Function Definition: " << node->getName(); break;
    711     case EOpFunctionCall:  out.debug << "Function Call: "       << node->getName(); break;
    712     case EOpParameters:    out.debug << "Function Parameters: ";                    break;
    713 
    714     case EOpConstructFloat: out.debug << "Construct float"; break;
    715     case EOpConstructDouble:out.debug << "Construct double"; break;
    716 
    717     case EOpConstructVec2:  out.debug << "Construct vec2";  break;
    718     case EOpConstructVec3:  out.debug << "Construct vec3";  break;
    719     case EOpConstructVec4:  out.debug << "Construct vec4";  break;
    720     case EOpConstructDVec2: out.debug << "Construct dvec2";  break;
    721     case EOpConstructDVec3: out.debug << "Construct dvec3";  break;
    722     case EOpConstructDVec4: out.debug << "Construct dvec4";  break;
    723     case EOpConstructBool:  out.debug << "Construct bool";  break;
    724     case EOpConstructBVec2: out.debug << "Construct bvec2"; break;
    725     case EOpConstructBVec3: out.debug << "Construct bvec3"; break;
    726     case EOpConstructBVec4: out.debug << "Construct bvec4"; break;
    727     case EOpConstructInt8:   out.debug << "Construct int8_t";   break;
    728     case EOpConstructI8Vec2: out.debug << "Construct i8vec2"; break;
    729     case EOpConstructI8Vec3: out.debug << "Construct i8vec3"; break;
    730     case EOpConstructI8Vec4: out.debug << "Construct i8vec4"; break;
    731     case EOpConstructInt:   out.debug << "Construct int";   break;
    732     case EOpConstructIVec2: out.debug << "Construct ivec2"; break;
    733     case EOpConstructIVec3: out.debug << "Construct ivec3"; break;
    734     case EOpConstructIVec4: out.debug << "Construct ivec4"; break;
    735     case EOpConstructUint8:    out.debug << "Construct uint8_t";    break;
    736     case EOpConstructU8Vec2:   out.debug << "Construct u8vec2";   break;
    737     case EOpConstructU8Vec3:   out.debug << "Construct u8vec3";   break;
    738     case EOpConstructU8Vec4:   out.debug << "Construct u8vec4";   break;
    739     case EOpConstructUint:    out.debug << "Construct uint";    break;
    740     case EOpConstructUVec2:   out.debug << "Construct uvec2";   break;
    741     case EOpConstructUVec3:   out.debug << "Construct uvec3";   break;
    742     case EOpConstructUVec4:   out.debug << "Construct uvec4";   break;
    743     case EOpConstructInt64:   out.debug << "Construct int64"; break;
    744     case EOpConstructI64Vec2: out.debug << "Construct i64vec2"; break;
    745     case EOpConstructI64Vec3: out.debug << "Construct i64vec3"; break;
    746     case EOpConstructI64Vec4: out.debug << "Construct i64vec4"; break;
    747     case EOpConstructUint64:  out.debug << "Construct uint64"; break;
    748     case EOpConstructU64Vec2: out.debug << "Construct u64vec2"; break;
    749     case EOpConstructU64Vec3: out.debug << "Construct u64vec3"; break;
    750     case EOpConstructU64Vec4: out.debug << "Construct u64vec4"; break;
    751     case EOpConstructInt16:   out.debug << "Construct int16_t"; break;
    752     case EOpConstructI16Vec2: out.debug << "Construct i16vec2"; break;
    753     case EOpConstructI16Vec3: out.debug << "Construct i16vec3"; break;
    754     case EOpConstructI16Vec4: out.debug << "Construct i16vec4"; break;
    755     case EOpConstructUint16:  out.debug << "Construct uint16_t"; break;
    756     case EOpConstructU16Vec2: out.debug << "Construct u16vec2"; break;
    757     case EOpConstructU16Vec3: out.debug << "Construct u16vec3"; break;
    758     case EOpConstructU16Vec4: out.debug << "Construct u16vec4"; break;
    759     case EOpConstructMat2x2:  out.debug << "Construct mat2";    break;
    760     case EOpConstructMat2x3:  out.debug << "Construct mat2x3";  break;
    761     case EOpConstructMat2x4:  out.debug << "Construct mat2x4";  break;
    762     case EOpConstructMat3x2:  out.debug << "Construct mat3x2";  break;
    763     case EOpConstructMat3x3:  out.debug << "Construct mat3";    break;
    764     case EOpConstructMat3x4:  out.debug << "Construct mat3x4";  break;
    765     case EOpConstructMat4x2:  out.debug << "Construct mat4x2";  break;
    766     case EOpConstructMat4x3:  out.debug << "Construct mat4x3";  break;
    767     case EOpConstructMat4x4:  out.debug << "Construct mat4";    break;
    768     case EOpConstructDMat2x2: out.debug << "Construct dmat2";   break;
    769     case EOpConstructDMat2x3: out.debug << "Construct dmat2x3"; break;
    770     case EOpConstructDMat2x4: out.debug << "Construct dmat2x4"; break;
    771     case EOpConstructDMat3x2: out.debug << "Construct dmat3x2"; break;
    772     case EOpConstructDMat3x3: out.debug << "Construct dmat3";   break;
    773     case EOpConstructDMat3x4: out.debug << "Construct dmat3x4"; break;
    774     case EOpConstructDMat4x2: out.debug << "Construct dmat4x2"; break;
    775     case EOpConstructDMat4x3: out.debug << "Construct dmat4x3"; break;
    776     case EOpConstructDMat4x4: out.debug << "Construct dmat4";   break;
    777     case EOpConstructIMat2x2: out.debug << "Construct imat2";   break;
    778     case EOpConstructIMat2x3: out.debug << "Construct imat2x3"; break;
    779     case EOpConstructIMat2x4: out.debug << "Construct imat2x4"; break;
    780     case EOpConstructIMat3x2: out.debug << "Construct imat3x2"; break;
    781     case EOpConstructIMat3x3: out.debug << "Construct imat3";   break;
    782     case EOpConstructIMat3x4: out.debug << "Construct imat3x4"; break;
    783     case EOpConstructIMat4x2: out.debug << "Construct imat4x2"; break;
    784     case EOpConstructIMat4x3: out.debug << "Construct imat4x3"; break;
    785     case EOpConstructIMat4x4: out.debug << "Construct imat4";   break;
    786     case EOpConstructUMat2x2: out.debug << "Construct umat2";   break;
    787     case EOpConstructUMat2x3: out.debug << "Construct umat2x3"; break;
    788     case EOpConstructUMat2x4: out.debug << "Construct umat2x4"; break;
    789     case EOpConstructUMat3x2: out.debug << "Construct umat3x2"; break;
    790     case EOpConstructUMat3x3: out.debug << "Construct umat3";   break;
    791     case EOpConstructUMat3x4: out.debug << "Construct umat3x4"; break;
    792     case EOpConstructUMat4x2: out.debug << "Construct umat4x2"; break;
    793     case EOpConstructUMat4x3: out.debug << "Construct umat4x3"; break;
    794     case EOpConstructUMat4x4: out.debug << "Construct umat4";   break;
    795     case EOpConstructBMat2x2: out.debug << "Construct bmat2";   break;
    796     case EOpConstructBMat2x3: out.debug << "Construct bmat2x3"; break;
    797     case EOpConstructBMat2x4: out.debug << "Construct bmat2x4"; break;
    798     case EOpConstructBMat3x2: out.debug << "Construct bmat3x2"; break;
    799     case EOpConstructBMat3x3: out.debug << "Construct bmat3";   break;
    800     case EOpConstructBMat3x4: out.debug << "Construct bmat3x4"; break;
    801     case EOpConstructBMat4x2: out.debug << "Construct bmat4x2"; break;
    802     case EOpConstructBMat4x3: out.debug << "Construct bmat4x3"; break;
    803     case EOpConstructBMat4x4: out.debug << "Construct bmat4";   break;
    804     case EOpConstructFloat16:   out.debug << "Construct float16_t"; break;
    805     case EOpConstructF16Vec2:   out.debug << "Construct f16vec2";   break;
    806     case EOpConstructF16Vec3:   out.debug << "Construct f16vec3";   break;
    807     case EOpConstructF16Vec4:   out.debug << "Construct f16vec4";   break;
    808     case EOpConstructF16Mat2x2: out.debug << "Construct f16mat2";   break;
    809     case EOpConstructF16Mat2x3: out.debug << "Construct f16mat2x3"; break;
    810     case EOpConstructF16Mat2x4: out.debug << "Construct f16mat2x4"; break;
    811     case EOpConstructF16Mat3x2: out.debug << "Construct f16mat3x2"; break;
    812     case EOpConstructF16Mat3x3: out.debug << "Construct f16mat3";   break;
    813     case EOpConstructF16Mat3x4: out.debug << "Construct f16mat3x4"; break;
    814     case EOpConstructF16Mat4x2: out.debug << "Construct f16mat4x2"; break;
    815     case EOpConstructF16Mat4x3: out.debug << "Construct f16mat4x3"; break;
    816     case EOpConstructF16Mat4x4: out.debug << "Construct f16mat4";   break;
    817     case EOpConstructStruct:  out.debug << "Construct structure";  break;
    818     case EOpConstructTextureSampler: out.debug << "Construct combined texture-sampler"; break;
    819     case EOpConstructReference:  out.debug << "Construct reference";  break;
    820 
    821     case EOpLessThan:         out.debug << "Compare Less Than";             break;
    822     case EOpGreaterThan:      out.debug << "Compare Greater Than";          break;
    823     case EOpLessThanEqual:    out.debug << "Compare Less Than or Equal";    break;
    824     case EOpGreaterThanEqual: out.debug << "Compare Greater Than or Equal"; break;
    825     case EOpVectorEqual:      out.debug << "Equal";                         break;
    826     case EOpVectorNotEqual:   out.debug << "NotEqual";                      break;
    827 
    828     case EOpMod:           out.debug << "mod";         break;
    829     case EOpModf:          out.debug << "modf";        break;
    830     case EOpPow:           out.debug << "pow";         break;
    831 
    832     case EOpAtan:          out.debug << "arc tangent"; break;
    833 
    834     case EOpMin:           out.debug << "min";         break;
    835     case EOpMax:           out.debug << "max";         break;
    836     case EOpClamp:         out.debug << "clamp";       break;
    837     case EOpMix:           out.debug << "mix";         break;
    838     case EOpStep:          out.debug << "step";        break;
    839     case EOpSmoothStep:    out.debug << "smoothstep";  break;
    840 
    841     case EOpDistance:      out.debug << "distance";                break;
    842     case EOpDot:           out.debug << "dot-product";             break;
    843     case EOpCross:         out.debug << "cross-product";           break;
    844     case EOpFaceForward:   out.debug << "face-forward";            break;
    845     case EOpReflect:       out.debug << "reflect";                 break;
    846     case EOpRefract:       out.debug << "refract";                 break;
    847     case EOpMul:           out.debug << "component-wise multiply"; break;
    848     case EOpOuterProduct:  out.debug << "outer product";           break;
    849 
    850     case EOpEmitVertex:    out.debug << "EmitVertex";              break;
    851     case EOpEndPrimitive:  out.debug << "EndPrimitive";            break;
    852 
    853     case EOpBarrier:                    out.debug << "Barrier";                    break;
    854     case EOpMemoryBarrier:              out.debug << "MemoryBarrier";              break;
    855     case EOpMemoryBarrierAtomicCounter: out.debug << "MemoryBarrierAtomicCounter"; break;
    856     case EOpMemoryBarrierBuffer:        out.debug << "MemoryBarrierBuffer";        break;
    857     case EOpMemoryBarrierImage:         out.debug << "MemoryBarrierImage";         break;
    858     case EOpMemoryBarrierShared:        out.debug << "MemoryBarrierShared";        break;
    859     case EOpGroupMemoryBarrier:         out.debug << "GroupMemoryBarrier";         break;
    860 
    861     case EOpReadInvocation:             out.debug << "readInvocation";        break;
    862 
    863 #ifdef AMD_EXTENSIONS
    864     case EOpSwizzleInvocations:         out.debug << "swizzleInvocations";       break;
    865     case EOpSwizzleInvocationsMasked:   out.debug << "swizzleInvocationsMasked"; break;
    866     case EOpWriteInvocation:            out.debug << "writeInvocation";          break;
    867 
    868     case EOpMin3:                       out.debug << "min3";                  break;
    869     case EOpMax3:                       out.debug << "max3";                  break;
    870     case EOpMid3:                       out.debug << "mid3";                  break;
    871 
    872     case EOpTime:                       out.debug << "time";                  break;
    873 #endif
    874 
    875     case EOpAtomicAdd:                  out.debug << "AtomicAdd";             break;
    876     case EOpAtomicMin:                  out.debug << "AtomicMin";             break;
    877     case EOpAtomicMax:                  out.debug << "AtomicMax";             break;
    878     case EOpAtomicAnd:                  out.debug << "AtomicAnd";             break;
    879     case EOpAtomicOr:                   out.debug << "AtomicOr";              break;
    880     case EOpAtomicXor:                  out.debug << "AtomicXor";             break;
    881     case EOpAtomicExchange:             out.debug << "AtomicExchange";        break;
    882     case EOpAtomicCompSwap:             out.debug << "AtomicCompSwap";        break;
    883     case EOpAtomicLoad:                 out.debug << "AtomicLoad";            break;
    884     case EOpAtomicStore:                out.debug << "AtomicStore";           break;
    885 
    886     case EOpAtomicCounterAdd:           out.debug << "AtomicCounterAdd";      break;
    887     case EOpAtomicCounterSubtract:      out.debug << "AtomicCounterSubtract"; break;
    888     case EOpAtomicCounterMin:           out.debug << "AtomicCounterMin";      break;
    889     case EOpAtomicCounterMax:           out.debug << "AtomicCounterMax";      break;
    890     case EOpAtomicCounterAnd:           out.debug << "AtomicCounterAnd";      break;
    891     case EOpAtomicCounterOr:            out.debug << "AtomicCounterOr";       break;
    892     case EOpAtomicCounterXor:           out.debug << "AtomicCounterXor";      break;
    893     case EOpAtomicCounterExchange:      out.debug << "AtomicCounterExchange"; break;
    894     case EOpAtomicCounterCompSwap:      out.debug << "AtomicCounterCompSwap"; break;
    895 
    896     case EOpImageQuerySize:             out.debug << "imageQuerySize";        break;
    897     case EOpImageQuerySamples:          out.debug << "imageQuerySamples";     break;
    898     case EOpImageLoad:                  out.debug << "imageLoad";             break;
    899     case EOpImageStore:                 out.debug << "imageStore";            break;
    900     case EOpImageAtomicAdd:             out.debug << "imageAtomicAdd";        break;
    901     case EOpImageAtomicMin:             out.debug << "imageAtomicMin";        break;
    902     case EOpImageAtomicMax:             out.debug << "imageAtomicMax";        break;
    903     case EOpImageAtomicAnd:             out.debug << "imageAtomicAnd";        break;
    904     case EOpImageAtomicOr:              out.debug << "imageAtomicOr";         break;
    905     case EOpImageAtomicXor:             out.debug << "imageAtomicXor";        break;
    906     case EOpImageAtomicExchange:        out.debug << "imageAtomicExchange";   break;
    907     case EOpImageAtomicCompSwap:        out.debug << "imageAtomicCompSwap";   break;
    908     case EOpImageAtomicLoad:            out.debug << "imageAtomicLoad";       break;
    909     case EOpImageAtomicStore:           out.debug << "imageAtomicStore";      break;
    910 #ifdef AMD_EXTENSIONS
    911     case EOpImageLoadLod:               out.debug << "imageLoadLod";          break;
    912     case EOpImageStoreLod:              out.debug << "imageStoreLod";         break;
    913 #endif
    914 
    915     case EOpTextureQuerySize:           out.debug << "textureSize";           break;
    916     case EOpTextureQueryLod:            out.debug << "textureQueryLod";       break;
    917     case EOpTextureQueryLevels:         out.debug << "textureQueryLevels";    break;
    918     case EOpTextureQuerySamples:        out.debug << "textureSamples";        break;
    919     case EOpTexture:                    out.debug << "texture";               break;
    920     case EOpTextureProj:                out.debug << "textureProj";           break;
    921     case EOpTextureLod:                 out.debug << "textureLod";            break;
    922     case EOpTextureOffset:              out.debug << "textureOffset";         break;
    923     case EOpTextureFetch:               out.debug << "textureFetch";          break;
    924     case EOpTextureFetchOffset:         out.debug << "textureFetchOffset";    break;
    925     case EOpTextureProjOffset:          out.debug << "textureProjOffset";     break;
    926     case EOpTextureLodOffset:           out.debug << "textureLodOffset";      break;
    927     case EOpTextureProjLod:             out.debug << "textureProjLod";        break;
    928     case EOpTextureProjLodOffset:       out.debug << "textureProjLodOffset";  break;
    929     case EOpTextureGrad:                out.debug << "textureGrad";           break;
    930     case EOpTextureGradOffset:          out.debug << "textureGradOffset";     break;
    931     case EOpTextureProjGrad:            out.debug << "textureProjGrad";       break;
    932     case EOpTextureProjGradOffset:      out.debug << "textureProjGradOffset"; break;
    933     case EOpTextureGather:              out.debug << "textureGather";         break;
    934     case EOpTextureGatherOffset:        out.debug << "textureGatherOffset";   break;
    935     case EOpTextureGatherOffsets:       out.debug << "textureGatherOffsets";  break;
    936     case EOpTextureClamp:               out.debug << "textureClamp";          break;
    937     case EOpTextureOffsetClamp:         out.debug << "textureOffsetClamp";    break;
    938     case EOpTextureGradClamp:           out.debug << "textureGradClamp";      break;
    939     case EOpTextureGradOffsetClamp:     out.debug << "textureGradOffsetClamp";  break;
    940 #ifdef AMD_EXTENSIONS
    941     case EOpTextureGatherLod:           out.debug << "textureGatherLod";        break;
    942     case EOpTextureGatherLodOffset:     out.debug << "textureGatherLodOffset";  break;
    943     case EOpTextureGatherLodOffsets:    out.debug << "textureGatherLodOffsets"; break;
    944 #endif
    945 
    946     case EOpSparseTexture:                  out.debug << "sparseTexture";                   break;
    947     case EOpSparseTextureOffset:            out.debug << "sparseTextureOffset";             break;
    948     case EOpSparseTextureLod:               out.debug << "sparseTextureLod";                break;
    949     case EOpSparseTextureLodOffset:         out.debug << "sparseTextureLodOffset";          break;
    950     case EOpSparseTextureFetch:             out.debug << "sparseTexelFetch";                break;
    951     case EOpSparseTextureFetchOffset:       out.debug << "sparseTexelFetchOffset";          break;
    952     case EOpSparseTextureGrad:              out.debug << "sparseTextureGrad";               break;
    953     case EOpSparseTextureGradOffset:        out.debug << "sparseTextureGradOffset";         break;
    954     case EOpSparseTextureGather:            out.debug << "sparseTextureGather";             break;
    955     case EOpSparseTextureGatherOffset:      out.debug << "sparseTextureGatherOffset";       break;
    956     case EOpSparseTextureGatherOffsets:     out.debug << "sparseTextureGatherOffsets";      break;
    957     case EOpSparseImageLoad:                out.debug << "sparseImageLoad";                 break;
    958     case EOpSparseTextureClamp:             out.debug << "sparseTextureClamp";              break;
    959     case EOpSparseTextureOffsetClamp:       out.debug << "sparseTextureOffsetClamp";        break;
    960     case EOpSparseTextureGradClamp:         out.debug << "sparseTextureGradClamp";          break;
    961     case EOpSparseTextureGradOffsetClamp:   out.debug << "sparseTextureGradOffsetClam";     break;
    962 #ifdef AMD_EXTENSIONS
    963     case EOpSparseTextureGatherLod:         out.debug << "sparseTextureGatherLod";          break;
    964     case EOpSparseTextureGatherLodOffset:   out.debug << "sparseTextureGatherLodOffset";    break;
    965     case EOpSparseTextureGatherLodOffsets:  out.debug << "sparseTextureGatherLodOffsets";   break;
    966     case EOpSparseImageLoadLod:             out.debug << "sparseImageLoadLod";              break;
    967 #endif
    968 #ifdef NV_EXTENSIONS
    969     case EOpImageSampleFootprintNV:             out.debug << "imageSampleFootprintNV";          break;
    970     case EOpImageSampleFootprintClampNV:        out.debug << "imageSampleFootprintClampNV";     break;
    971     case EOpImageSampleFootprintLodNV:          out.debug << "imageSampleFootprintLodNV";       break;
    972     case EOpImageSampleFootprintGradNV:         out.debug << "imageSampleFootprintGradNV";      break;
    973     case EOpImageSampleFootprintGradClampNV:    out.debug << "mageSampleFootprintGradClampNV";  break;
    974 #endif
    975     case EOpAddCarry:                   out.debug << "addCarry";              break;
    976     case EOpSubBorrow:                  out.debug << "subBorrow";             break;
    977     case EOpUMulExtended:               out.debug << "uMulExtended";          break;
    978     case EOpIMulExtended:               out.debug << "iMulExtended";          break;
    979     case EOpBitfieldExtract:            out.debug << "bitfieldExtract";       break;
    980     case EOpBitfieldInsert:             out.debug << "bitfieldInsert";        break;
    981 
    982     case EOpFma:                        out.debug << "fma";                   break;
    983     case EOpFrexp:                      out.debug << "frexp";                 break;
    984     case EOpLdexp:                      out.debug << "ldexp";                 break;
    985 
    986     case EOpInterpolateAtSample:   out.debug << "interpolateAtSample";    break;
    987     case EOpInterpolateAtOffset:   out.debug << "interpolateAtOffset";    break;
    988 #ifdef AMD_EXTENSIONS
    989     case EOpInterpolateAtVertex:   out.debug << "interpolateAtVertex";    break;
    990 #endif
    991 
    992     case EOpSinCos:                     out.debug << "sincos";                break;
    993     case EOpGenMul:                     out.debug << "mul";                   break;
    994 
    995     case EOpAllMemoryBarrierWithGroupSync:    out.debug << "AllMemoryBarrierWithGroupSync";    break;
    996     case EOpDeviceMemoryBarrier:              out.debug << "DeviceMemoryBarrier";              break;
    997     case EOpDeviceMemoryBarrierWithGroupSync: out.debug << "DeviceMemoryBarrierWithGroupSync"; break;
    998     case EOpWorkgroupMemoryBarrier:           out.debug << "WorkgroupMemoryBarrier";           break;
    999     case EOpWorkgroupMemoryBarrierWithGroupSync: out.debug << "WorkgroupMemoryBarrierWithGroupSync"; break;
   1000 
   1001     case EOpSubgroupBarrier:                 out.debug << "subgroupBarrier"; break;
   1002     case EOpSubgroupMemoryBarrier:           out.debug << "subgroupMemoryBarrier"; break;
   1003     case EOpSubgroupMemoryBarrierBuffer:     out.debug << "subgroupMemoryBarrierBuffer"; break;
   1004     case EOpSubgroupMemoryBarrierImage:      out.debug << "subgroupMemoryBarrierImage";   break;
   1005     case EOpSubgroupMemoryBarrierShared:     out.debug << "subgroupMemoryBarrierShared"; break;
   1006     case EOpSubgroupElect:                   out.debug << "subgroupElect"; break;
   1007     case EOpSubgroupAll:                     out.debug << "subgroupAll"; break;
   1008     case EOpSubgroupAny:                     out.debug << "subgroupAny"; break;
   1009     case EOpSubgroupAllEqual:                out.debug << "subgroupAllEqual"; break;
   1010     case EOpSubgroupBroadcast:               out.debug << "subgroupBroadcast"; break;
   1011     case EOpSubgroupBroadcastFirst:          out.debug << "subgroupBroadcastFirst"; break;
   1012     case EOpSubgroupBallot:                  out.debug << "subgroupBallot"; break;
   1013     case EOpSubgroupInverseBallot:           out.debug << "subgroupInverseBallot"; break;
   1014     case EOpSubgroupBallotBitExtract:        out.debug << "subgroupBallotBitExtract"; break;
   1015     case EOpSubgroupBallotBitCount:          out.debug << "subgroupBallotBitCount"; break;
   1016     case EOpSubgroupBallotInclusiveBitCount: out.debug << "subgroupBallotInclusiveBitCount"; break;
   1017     case EOpSubgroupBallotExclusiveBitCount: out.debug << "subgroupBallotExclusiveBitCount"; break;
   1018     case EOpSubgroupBallotFindLSB:           out.debug << "subgroupBallotFindLSB"; break;
   1019     case EOpSubgroupBallotFindMSB:           out.debug << "subgroupBallotFindMSB"; break;
   1020     case EOpSubgroupShuffle:                 out.debug << "subgroupShuffle"; break;
   1021     case EOpSubgroupShuffleXor:              out.debug << "subgroupShuffleXor"; break;
   1022     case EOpSubgroupShuffleUp:               out.debug << "subgroupShuffleUp"; break;
   1023     case EOpSubgroupShuffleDown:             out.debug << "subgroupShuffleDown"; break;
   1024     case EOpSubgroupAdd:                     out.debug << "subgroupAdd"; break;
   1025     case EOpSubgroupMul:                     out.debug << "subgroupMul"; break;
   1026     case EOpSubgroupMin:                     out.debug << "subgroupMin"; break;
   1027     case EOpSubgroupMax:                     out.debug << "subgroupMax"; break;
   1028     case EOpSubgroupAnd:                     out.debug << "subgroupAnd"; break;
   1029     case EOpSubgroupOr:                      out.debug << "subgroupOr"; break;
   1030     case EOpSubgroupXor:                     out.debug << "subgroupXor"; break;
   1031     case EOpSubgroupInclusiveAdd:            out.debug << "subgroupInclusiveAdd"; break;
   1032     case EOpSubgroupInclusiveMul:            out.debug << "subgroupInclusiveMul"; break;
   1033     case EOpSubgroupInclusiveMin:            out.debug << "subgroupInclusiveMin"; break;
   1034     case EOpSubgroupInclusiveMax:            out.debug << "subgroupInclusiveMax"; break;
   1035     case EOpSubgroupInclusiveAnd:            out.debug << "subgroupInclusiveAnd"; break;
   1036     case EOpSubgroupInclusiveOr:             out.debug << "subgroupInclusiveOr"; break;
   1037     case EOpSubgroupInclusiveXor:            out.debug << "subgroupInclusiveXor"; break;
   1038     case EOpSubgroupExclusiveAdd:            out.debug << "subgroupExclusiveAdd"; break;
   1039     case EOpSubgroupExclusiveMul:            out.debug << "subgroupExclusiveMul"; break;
   1040     case EOpSubgroupExclusiveMin:            out.debug << "subgroupExclusiveMin"; break;
   1041     case EOpSubgroupExclusiveMax:            out.debug << "subgroupExclusiveMax"; break;
   1042     case EOpSubgroupExclusiveAnd:            out.debug << "subgroupExclusiveAnd"; break;
   1043     case EOpSubgroupExclusiveOr:             out.debug << "subgroupExclusiveOr"; break;
   1044     case EOpSubgroupExclusiveXor:            out.debug << "subgroupExclusiveXor"; break;
   1045     case EOpSubgroupClusteredAdd:            out.debug << "subgroupClusteredAdd"; break;
   1046     case EOpSubgroupClusteredMul:            out.debug << "subgroupClusteredMul"; break;
   1047     case EOpSubgroupClusteredMin:            out.debug << "subgroupClusteredMin"; break;
   1048     case EOpSubgroupClusteredMax:            out.debug << "subgroupClusteredMax"; break;
   1049     case EOpSubgroupClusteredAnd:            out.debug << "subgroupClusteredAnd"; break;
   1050     case EOpSubgroupClusteredOr:             out.debug << "subgroupClusteredOr"; break;
   1051     case EOpSubgroupClusteredXor:            out.debug << "subgroupClusteredXor"; break;
   1052     case EOpSubgroupQuadBroadcast:           out.debug << "subgroupQuadBroadcast"; break;
   1053     case EOpSubgroupQuadSwapHorizontal:      out.debug << "subgroupQuadSwapHorizontal"; break;
   1054     case EOpSubgroupQuadSwapVertical:        out.debug << "subgroupQuadSwapVertical"; break;
   1055     case EOpSubgroupQuadSwapDiagonal:        out.debug << "subgroupQuadSwapDiagonal"; break;
   1056 
   1057     case EOpSubpassLoad:   out.debug << "subpassLoad";   break;
   1058     case EOpSubpassLoadMS: out.debug << "subpassLoadMS"; break;
   1059 
   1060 #ifdef NV_EXTENSIONS
   1061     case EOpTraceNV:                          out.debug << "traceNV"; break;
   1062     case EOpReportIntersectionNV:             out.debug << "reportIntersectionNV"; break;
   1063     case EOpIgnoreIntersectionNV:             out.debug << "ignoreIntersectionNV"; break;
   1064     case EOpTerminateRayNV:                   out.debug << "terminateRayNV"; break;
   1065     case EOpExecuteCallableNV:                out.debug << "executeCallableNV"; break;
   1066     case EOpWritePackedPrimitiveIndices4x8NV: out.debug << "writePackedPrimitiveIndices4x8NV"; break;
   1067 #endif
   1068 
   1069     default: out.debug.message(EPrefixError, "Bad aggregation op");
   1070     }
   1071 
   1072     if (node->getOp() != EOpSequence && node->getOp() != EOpParameters)
   1073         out.debug << " (" << node->getCompleteString() << ")";
   1074 
   1075     out.debug << "\n";
   1076 
   1077     return true;
   1078 }
   1079 
   1080 bool TOutputTraverser::visitSelection(TVisit /* visit */, TIntermSelection* node)
   1081 {
   1082     TInfoSink& out = infoSink;
   1083 
   1084     OutputTreeText(out, node, depth);
   1085 
   1086     out.debug << "Test condition and select";
   1087     out.debug << " (" << node->getCompleteString() << ")";
   1088 
   1089     if (node->getShortCircuit() == false)
   1090         out.debug << ": no shortcircuit";
   1091     if (node->getFlatten())
   1092         out.debug << ": Flatten";
   1093     if (node->getDontFlatten())
   1094         out.debug << ": DontFlatten";
   1095     out.debug << "\n";
   1096 
   1097     ++depth;
   1098 
   1099     OutputTreeText(out, node, depth);
   1100     out.debug << "Condition\n";
   1101     node->getCondition()->traverse(this);
   1102 
   1103     OutputTreeText(out, node, depth);
   1104     if (node->getTrueBlock()) {
   1105         out.debug << "true case\n";
   1106         node->getTrueBlock()->traverse(this);
   1107     } else
   1108         out.debug << "true case is null\n";
   1109 
   1110     if (node->getFalseBlock()) {
   1111         OutputTreeText(out, node, depth);
   1112         out.debug << "false case\n";
   1113         node->getFalseBlock()->traverse(this);
   1114     }
   1115 
   1116     --depth;
   1117 
   1118     return false;
   1119 }
   1120 
   1121 // Print infinities and NaNs, and numbers in a portable way.
   1122 // Goals:
   1123 //   - portable (across IEEE 754 platforms)
   1124 //   - shows all possible IEEE values
   1125 //   - shows simple numbers in a simple way, e.g., no leading/trailing 0s
   1126 //   - shows all digits, no premature rounding
   1127 static void OutputDouble(TInfoSink& out, double value, TOutputTraverser::EExtraOutput extra)
   1128 {
   1129     if (IsInfinity(value)) {
   1130         if (value < 0)
   1131             out.debug << "-1.#INF";
   1132         else
   1133             out.debug << "+1.#INF";
   1134     } else if (IsNan(value))
   1135         out.debug << "1.#IND";
   1136     else {
   1137         const int maxSize = 340;
   1138         char buf[maxSize];
   1139         const char* format = "%f";
   1140         if (fabs(value) > 0.0 && (fabs(value) < 1e-5 || fabs(value) > 1e12))
   1141             format = "%-.13e";
   1142         int len = snprintf(buf, maxSize, format, value);
   1143         assert(len < maxSize);
   1144 
   1145         // remove a leading zero in the 100s slot in exponent; it is not portable
   1146         // pattern:   XX...XXXe+0XX or XX...XXXe-0XX
   1147         if (len > 5) {
   1148             if (buf[len-5] == 'e' && (buf[len-4] == '+' || buf[len-4] == '-') && buf[len-3] == '0') {
   1149                 buf[len-3] = buf[len-2];
   1150                 buf[len-2] = buf[len-1];
   1151                 buf[len-1] = '\0';
   1152             }
   1153         }
   1154 
   1155         out.debug << buf;
   1156 
   1157         switch (extra) {
   1158         case TOutputTraverser::BinaryDoubleOutput:
   1159         {
   1160             out.debug << " : ";
   1161             long long b = *reinterpret_cast<long long*>(&value);
   1162             for (size_t i = 0; i < 8 * sizeof(value); ++i, ++b) {
   1163                 out.debug << ((b & 0x8000000000000000) != 0 ? "1" : "0");
   1164                 b <<= 1;
   1165             }
   1166             break;
   1167         }
   1168         default:
   1169             break;
   1170         }
   1171     }
   1172 }
   1173 
   1174 static void OutputConstantUnion(TInfoSink& out, const TIntermTyped* node, const TConstUnionArray& constUnion,
   1175     TOutputTraverser::EExtraOutput extra, int depth)
   1176 {
   1177     int size = node->getType().computeNumComponents();
   1178 
   1179     for (int i = 0; i < size; i++) {
   1180         OutputTreeText(out, node, depth);
   1181         switch (constUnion[i].getType()) {
   1182         case EbtBool:
   1183             if (constUnion[i].getBConst())
   1184                 out.debug << "true";
   1185             else
   1186                 out.debug << "false";
   1187 
   1188             out.debug << " (" << "const bool" << ")";
   1189 
   1190             out.debug << "\n";
   1191             break;
   1192         case EbtFloat:
   1193         case EbtDouble:
   1194         case EbtFloat16:
   1195             OutputDouble(out, constUnion[i].getDConst(), extra);
   1196             out.debug << "\n";
   1197             break;
   1198         case EbtInt8:
   1199             {
   1200                 const int maxSize = 300;
   1201                 char buf[maxSize];
   1202                 snprintf(buf, maxSize, "%d (%s)", constUnion[i].getI8Const(), "const int8_t");
   1203 
   1204                 out.debug << buf << "\n";
   1205             }
   1206             break;
   1207         case EbtUint8:
   1208             {
   1209                 const int maxSize = 300;
   1210                 char buf[maxSize];
   1211                 snprintf(buf, maxSize, "%u (%s)", constUnion[i].getU8Const(), "const uint8_t");
   1212 
   1213                 out.debug << buf << "\n";
   1214             }
   1215             break;
   1216         case EbtInt16:
   1217             {
   1218                 const int maxSize = 300;
   1219                 char buf[maxSize];
   1220                 snprintf(buf, maxSize, "%d (%s)", constUnion[i].getI16Const(), "const int16_t");
   1221 
   1222                 out.debug << buf << "\n";
   1223             }
   1224             break;
   1225         case EbtUint16:
   1226             {
   1227                 const int maxSize = 300;
   1228                 char buf[maxSize];
   1229                 snprintf(buf, maxSize, "%u (%s)", constUnion[i].getU16Const(), "const uint16_t");
   1230 
   1231                 out.debug << buf << "\n";
   1232             }
   1233             break;
   1234         case EbtInt:
   1235             {
   1236                 const int maxSize = 300;
   1237                 char buf[maxSize];
   1238                 snprintf(buf, maxSize, "%d (%s)", constUnion[i].getIConst(), "const int");
   1239 
   1240                 out.debug << buf << "\n";
   1241             }
   1242             break;
   1243         case EbtUint:
   1244             {
   1245                 const int maxSize = 300;
   1246                 char buf[maxSize];
   1247                 snprintf(buf, maxSize, "%u (%s)", constUnion[i].getUConst(), "const uint");
   1248 
   1249                 out.debug << buf << "\n";
   1250             }
   1251             break;
   1252         case EbtInt64:
   1253             {
   1254                 const int maxSize = 300;
   1255                 char buf[maxSize];
   1256                 snprintf(buf, maxSize, "%lld (%s)", constUnion[i].getI64Const(), "const int64_t");
   1257 
   1258                 out.debug << buf << "\n";
   1259             }
   1260             break;
   1261         case EbtUint64:
   1262             {
   1263                 const int maxSize = 300;
   1264                 char buf[maxSize];
   1265                 snprintf(buf, maxSize, "%llu (%s)", constUnion[i].getU64Const(), "const uint64_t");
   1266 
   1267                 out.debug << buf << "\n";
   1268             }
   1269             break;
   1270         default:
   1271             out.info.message(EPrefixInternalError, "Unknown constant", node->getLoc());
   1272             break;
   1273         }
   1274     }
   1275 }
   1276 
   1277 void TOutputTraverser::visitConstantUnion(TIntermConstantUnion* node)
   1278 {
   1279     OutputTreeText(infoSink, node, depth);
   1280     infoSink.debug << "Constant:\n";
   1281 
   1282     OutputConstantUnion(infoSink, node, node->getConstArray(), extraOutput, depth + 1);
   1283 }
   1284 
   1285 void TOutputTraverser::visitSymbol(TIntermSymbol* node)
   1286 {
   1287     OutputTreeText(infoSink, node, depth);
   1288 
   1289     infoSink.debug << "'" << node->getName() << "' (" << node->getCompleteString() << ")\n";
   1290 
   1291     if (! node->getConstArray().empty())
   1292         OutputConstantUnion(infoSink, node, node->getConstArray(), extraOutput, depth + 1);
   1293     else if (node->getConstSubtree()) {
   1294         incrementDepth(node);
   1295         node->getConstSubtree()->traverse(this);
   1296         decrementDepth();
   1297     }
   1298 }
   1299 
   1300 bool TOutputTraverser::visitLoop(TVisit /* visit */, TIntermLoop* node)
   1301 {
   1302     TInfoSink& out = infoSink;
   1303 
   1304     OutputTreeText(out, node, depth);
   1305 
   1306     out.debug << "Loop with condition ";
   1307     if (! node->testFirst())
   1308         out.debug << "not ";
   1309     out.debug << "tested first";
   1310 
   1311     if (node->getUnroll())
   1312         out.debug << ": Unroll";
   1313     if (node->getDontUnroll())
   1314         out.debug << ": DontUnroll";
   1315     if (node->getLoopDependency()) {
   1316         out.debug << ": Dependency ";
   1317         out.debug << node->getLoopDependency();
   1318     }
   1319     out.debug << "\n";
   1320 
   1321     ++depth;
   1322 
   1323     OutputTreeText(infoSink, node, depth);
   1324     if (node->getTest()) {
   1325         out.debug << "Loop Condition\n";
   1326         node->getTest()->traverse(this);
   1327     } else
   1328         out.debug << "No loop condition\n";
   1329 
   1330     OutputTreeText(infoSink, node, depth);
   1331     if (node->getBody()) {
   1332         out.debug << "Loop Body\n";
   1333         node->getBody()->traverse(this);
   1334     } else
   1335         out.debug << "No loop body\n";
   1336 
   1337     if (node->getTerminal()) {
   1338         OutputTreeText(infoSink, node, depth);
   1339         out.debug << "Loop Terminal Expression\n";
   1340         node->getTerminal()->traverse(this);
   1341     }
   1342 
   1343     --depth;
   1344 
   1345     return false;
   1346 }
   1347 
   1348 bool TOutputTraverser::visitBranch(TVisit /* visit*/, TIntermBranch* node)
   1349 {
   1350     TInfoSink& out = infoSink;
   1351 
   1352     OutputTreeText(out, node, depth);
   1353 
   1354     switch (node->getFlowOp()) {
   1355     case EOpKill:      out.debug << "Branch: Kill";           break;
   1356     case EOpBreak:     out.debug << "Branch: Break";          break;
   1357     case EOpContinue:  out.debug << "Branch: Continue";       break;
   1358     case EOpReturn:    out.debug << "Branch: Return";         break;
   1359     case EOpCase:      out.debug << "case: ";                 break;
   1360     case EOpDefault:   out.debug << "default: ";              break;
   1361     default:               out.debug << "Branch: Unknown Branch"; break;
   1362     }
   1363 
   1364     if (node->getExpression()) {
   1365         out.debug << " with expression\n";
   1366         ++depth;
   1367         node->getExpression()->traverse(this);
   1368         --depth;
   1369     } else
   1370         out.debug << "\n";
   1371 
   1372     return false;
   1373 }
   1374 
   1375 bool TOutputTraverser::visitSwitch(TVisit /* visit */, TIntermSwitch* node)
   1376 {
   1377     TInfoSink& out = infoSink;
   1378 
   1379     OutputTreeText(out, node, depth);
   1380     out.debug << "switch";
   1381 
   1382     if (node->getFlatten())
   1383         out.debug << ": Flatten";
   1384     if (node->getDontFlatten())
   1385         out.debug << ": DontFlatten";
   1386     out.debug << "\n";
   1387 
   1388     OutputTreeText(out, node, depth);
   1389     out.debug << "condition\n";
   1390     ++depth;
   1391     node->getCondition()->traverse(this);
   1392 
   1393     --depth;
   1394     OutputTreeText(out, node, depth);
   1395     out.debug << "body\n";
   1396     ++depth;
   1397     node->getBody()->traverse(this);
   1398 
   1399     --depth;
   1400 
   1401     return false;
   1402 }
   1403 
   1404 //
   1405 // This function is the one to call externally to start the traversal.
   1406 // Individual functions can be initialized to 0 to skip processing of that
   1407 // type of node.  It's children will still be processed.
   1408 //
   1409 void TIntermediate::output(TInfoSink& infoSink, bool tree)
   1410 {
   1411     infoSink.debug << "Shader version: " << version << "\n";
   1412     if (requestedExtensions.size() > 0) {
   1413         for (auto extIt = requestedExtensions.begin(); extIt != requestedExtensions.end(); ++extIt)
   1414             infoSink.debug << "Requested " << *extIt << "\n";
   1415     }
   1416 
   1417     if (xfbMode)
   1418         infoSink.debug << "in xfb mode\n";
   1419 
   1420     switch (language) {
   1421     case EShLangVertex:
   1422         break;
   1423 
   1424     case EShLangTessControl:
   1425         infoSink.debug << "vertices = " << vertices << "\n";
   1426 
   1427         if (inputPrimitive != ElgNone)
   1428             infoSink.debug << "input primitive = " << TQualifier::getGeometryString(inputPrimitive) << "\n";
   1429         if (vertexSpacing != EvsNone)
   1430             infoSink.debug << "vertex spacing = " << TQualifier::getVertexSpacingString(vertexSpacing) << "\n";
   1431         if (vertexOrder != EvoNone)
   1432             infoSink.debug << "triangle order = " << TQualifier::getVertexOrderString(vertexOrder) << "\n";
   1433         break;
   1434 
   1435     case EShLangTessEvaluation:
   1436         infoSink.debug << "input primitive = " << TQualifier::getGeometryString(inputPrimitive) << "\n";
   1437         infoSink.debug << "vertex spacing = " << TQualifier::getVertexSpacingString(vertexSpacing) << "\n";
   1438         infoSink.debug << "triangle order = " << TQualifier::getVertexOrderString(vertexOrder) << "\n";
   1439         if (pointMode)
   1440             infoSink.debug << "using point mode\n";
   1441         break;
   1442 
   1443     case EShLangGeometry:
   1444         infoSink.debug << "invocations = " << invocations << "\n";
   1445         infoSink.debug << "max_vertices = " << vertices << "\n";
   1446         infoSink.debug << "input primitive = " << TQualifier::getGeometryString(inputPrimitive) << "\n";
   1447         infoSink.debug << "output primitive = " << TQualifier::getGeometryString(outputPrimitive) << "\n";
   1448         break;
   1449 
   1450     case EShLangFragment:
   1451         if (pixelCenterInteger)
   1452             infoSink.debug << "gl_FragCoord pixel center is integer\n";
   1453         if (originUpperLeft)
   1454             infoSink.debug << "gl_FragCoord origin is upper left\n";
   1455         if (earlyFragmentTests)
   1456             infoSink.debug << "using early_fragment_tests\n";
   1457         if (postDepthCoverage)
   1458             infoSink.debug << "using post_depth_coverage\n";
   1459         if (depthLayout != EldNone)
   1460             infoSink.debug << "using " << TQualifier::getLayoutDepthString(depthLayout) << "\n";
   1461         if (blendEquations != 0) {
   1462             infoSink.debug << "using";
   1463             // blendEquations is a mask, decode it
   1464             for (TBlendEquationShift be = (TBlendEquationShift)0; be < EBlendCount; be = (TBlendEquationShift)(be + 1)) {
   1465                 if (blendEquations & (1 << be))
   1466                     infoSink.debug << " " << TQualifier::getBlendEquationString(be);
   1467             }
   1468             infoSink.debug << "\n";
   1469         }
   1470         break;
   1471 
   1472 #ifdef NV_EXTENSIONS
   1473     case EShLangMeshNV:
   1474         infoSink.debug << "max_vertices = " << vertices << "\n";
   1475         infoSink.debug << "max_primitives = " << primitives << "\n";
   1476         infoSink.debug << "output primitive = " << TQualifier::getGeometryString(outputPrimitive) << "\n";
   1477         // Fall through
   1478 
   1479     case EShLangTaskNV:
   1480         // Fall through
   1481 #endif
   1482     case EShLangCompute:
   1483         infoSink.debug << "local_size = (" << localSize[0] << ", " << localSize[1] << ", " << localSize[2] << ")\n";
   1484         {
   1485             if (localSizeSpecId[0] != TQualifier::layoutNotSet ||
   1486                 localSizeSpecId[1] != TQualifier::layoutNotSet ||
   1487                 localSizeSpecId[2] != TQualifier::layoutNotSet) {
   1488                 infoSink.debug << "local_size ids = (" <<
   1489                     localSizeSpecId[0] << ", " <<
   1490                     localSizeSpecId[1] << ", " <<
   1491                     localSizeSpecId[2] << ")\n";
   1492             }
   1493         }
   1494         break;
   1495 
   1496     default:
   1497         break;
   1498     }
   1499 
   1500     if (treeRoot == 0 || ! tree)
   1501         return;
   1502 
   1503     TOutputTraverser it(infoSink);
   1504     if (getBinaryDoubleOutput())
   1505         it.setDoubleOutput(TOutputTraverser::BinaryDoubleOutput);
   1506     treeRoot->traverse(&it);
   1507 }
   1508 
   1509 } // end namespace glslang
   1510