• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright (C) 2002-2005  3Dlabs Inc. Ltd.
3 // Copyright (C) 2012-2016 LunarG, Inc.
4 // Copyright (C) 2017 ARM Limited.
5 // Modifications Copyright (C) 2020 Advanced Micro Devices, Inc. All rights reserved.
6 //
7 // All rights reserved.
8 //
9 // Redistribution and use in source and binary forms, with or without
10 // modification, are permitted provided that the following conditions
11 // are met:
12 //
13 //    Redistributions of source code must retain the above copyright
14 //    notice, this list of conditions and the following disclaimer.
15 //
16 //    Redistributions in binary form must reproduce the above
17 //    copyright notice, this list of conditions and the following
18 //    disclaimer in the documentation and/or other materials provided
19 //    with the distribution.
20 //
21 //    Neither the name of 3Dlabs Inc. Ltd. nor the names of its
22 //    contributors may be used to endorse or promote products derived
23 //    from this software without specific prior written permission.
24 //
25 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
26 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
27 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
28 // FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
29 // COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
30 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
31 // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
33 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
35 // ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
36 // POSSIBILITY OF SUCH DAMAGE.
37 //
38 
39 //
40 // Definition of the in-memory high-level intermediate representation
41 // of shaders.  This is a tree that parser creates.
42 //
43 // Nodes in the tree are defined as a hierarchy of classes derived from
44 // TIntermNode. Each is a node in a tree.  There is no preset branching factor;
45 // each node can have it's own type of list of children.
46 //
47 
48 #ifndef __INTERMEDIATE_H
49 #define __INTERMEDIATE_H
50 
51 #if defined(_MSC_VER) && _MSC_VER >= 1900
52     #pragma warning(disable : 4464) // relative include path contains '..'
53     #pragma warning(disable : 5026) // 'glslang::TIntermUnary': move constructor was implicitly defined as deleted
54 #endif
55 
56 #include "../Include/Common.h"
57 #include "../Include/Types.h"
58 #include "../Include/ConstantUnion.h"
59 
60 namespace glslang {
61 
62 class TIntermediate;
63 
64 //
65 // Operators used by the high-level (parse tree) representation.
66 //
67 enum TOperator {
68     EOpNull,            // if in a node, should only mean a node is still being built
69     EOpSequence,        // denotes a list of statements, or parameters, etc.
70     EOpScope,           // Used by debugging to denote a scoped list of statements
71     EOpLinkerObjects,   // for aggregate node of objects the linker may need, if not reference by the rest of the AST
72     EOpFunctionCall,
73     EOpFunction,        // For function definition
74     EOpParameters,      // an aggregate listing the parameters to a function
75 #ifndef GLSLANG_WEB
76     EOpSpirvInst,
77 #endif
78 
79     //
80     // Unary operators
81     //
82 
83     EOpNegative,
84     EOpLogicalNot,
85     EOpVectorLogicalNot,
86     EOpBitwiseNot,
87 
88     EOpPostIncrement,
89     EOpPostDecrement,
90     EOpPreIncrement,
91     EOpPreDecrement,
92 
93     EOpCopyObject,
94 
95     EOpDeclare,        // Used by debugging to force declaration of variable in correct scope
96 
97     // (u)int* -> bool
98     EOpConvInt8ToBool,
99     EOpConvUint8ToBool,
100     EOpConvInt16ToBool,
101     EOpConvUint16ToBool,
102     EOpConvIntToBool,
103     EOpConvUintToBool,
104     EOpConvInt64ToBool,
105     EOpConvUint64ToBool,
106 
107     // float* -> bool
108     EOpConvFloat16ToBool,
109     EOpConvFloatToBool,
110     EOpConvDoubleToBool,
111 
112     // bool -> (u)int*
113     EOpConvBoolToInt8,
114     EOpConvBoolToUint8,
115     EOpConvBoolToInt16,
116     EOpConvBoolToUint16,
117     EOpConvBoolToInt,
118     EOpConvBoolToUint,
119     EOpConvBoolToInt64,
120     EOpConvBoolToUint64,
121 
122     // bool -> float*
123     EOpConvBoolToFloat16,
124     EOpConvBoolToFloat,
125     EOpConvBoolToDouble,
126 
127     // int8_t -> (u)int*
128     EOpConvInt8ToInt16,
129     EOpConvInt8ToInt,
130     EOpConvInt8ToInt64,
131     EOpConvInt8ToUint8,
132     EOpConvInt8ToUint16,
133     EOpConvInt8ToUint,
134     EOpConvInt8ToUint64,
135 
136     // uint8_t -> (u)int*
137     EOpConvUint8ToInt8,
138     EOpConvUint8ToInt16,
139     EOpConvUint8ToInt,
140     EOpConvUint8ToInt64,
141     EOpConvUint8ToUint16,
142     EOpConvUint8ToUint,
143     EOpConvUint8ToUint64,
144 
145     // int8_t -> float*
146     EOpConvInt8ToFloat16,
147     EOpConvInt8ToFloat,
148     EOpConvInt8ToDouble,
149 
150     // uint8_t -> float*
151     EOpConvUint8ToFloat16,
152     EOpConvUint8ToFloat,
153     EOpConvUint8ToDouble,
154 
155     // int16_t -> (u)int*
156     EOpConvInt16ToInt8,
157     EOpConvInt16ToInt,
158     EOpConvInt16ToInt64,
159     EOpConvInt16ToUint8,
160     EOpConvInt16ToUint16,
161     EOpConvInt16ToUint,
162     EOpConvInt16ToUint64,
163 
164     // uint16_t -> (u)int*
165     EOpConvUint16ToInt8,
166     EOpConvUint16ToInt16,
167     EOpConvUint16ToInt,
168     EOpConvUint16ToInt64,
169     EOpConvUint16ToUint8,
170     EOpConvUint16ToUint,
171     EOpConvUint16ToUint64,
172 
173     // int16_t -> float*
174     EOpConvInt16ToFloat16,
175     EOpConvInt16ToFloat,
176     EOpConvInt16ToDouble,
177 
178     // uint16_t -> float*
179     EOpConvUint16ToFloat16,
180     EOpConvUint16ToFloat,
181     EOpConvUint16ToDouble,
182 
183     // int32_t -> (u)int*
184     EOpConvIntToInt8,
185     EOpConvIntToInt16,
186     EOpConvIntToInt64,
187     EOpConvIntToUint8,
188     EOpConvIntToUint16,
189     EOpConvIntToUint,
190     EOpConvIntToUint64,
191 
192     // uint32_t -> (u)int*
193     EOpConvUintToInt8,
194     EOpConvUintToInt16,
195     EOpConvUintToInt,
196     EOpConvUintToInt64,
197     EOpConvUintToUint8,
198     EOpConvUintToUint16,
199     EOpConvUintToUint64,
200 
201     // int32_t -> float*
202     EOpConvIntToFloat16,
203     EOpConvIntToFloat,
204     EOpConvIntToDouble,
205 
206     // uint32_t -> float*
207     EOpConvUintToFloat16,
208     EOpConvUintToFloat,
209     EOpConvUintToDouble,
210 
211     // int64_t -> (u)int*
212     EOpConvInt64ToInt8,
213     EOpConvInt64ToInt16,
214     EOpConvInt64ToInt,
215     EOpConvInt64ToUint8,
216     EOpConvInt64ToUint16,
217     EOpConvInt64ToUint,
218     EOpConvInt64ToUint64,
219 
220     // uint64_t -> (u)int*
221     EOpConvUint64ToInt8,
222     EOpConvUint64ToInt16,
223     EOpConvUint64ToInt,
224     EOpConvUint64ToInt64,
225     EOpConvUint64ToUint8,
226     EOpConvUint64ToUint16,
227     EOpConvUint64ToUint,
228 
229     // int64_t -> float*
230     EOpConvInt64ToFloat16,
231     EOpConvInt64ToFloat,
232     EOpConvInt64ToDouble,
233 
234     // uint64_t -> float*
235     EOpConvUint64ToFloat16,
236     EOpConvUint64ToFloat,
237     EOpConvUint64ToDouble,
238 
239     // float16_t -> (u)int*
240     EOpConvFloat16ToInt8,
241     EOpConvFloat16ToInt16,
242     EOpConvFloat16ToInt,
243     EOpConvFloat16ToInt64,
244     EOpConvFloat16ToUint8,
245     EOpConvFloat16ToUint16,
246     EOpConvFloat16ToUint,
247     EOpConvFloat16ToUint64,
248 
249     // float16_t -> float*
250     EOpConvFloat16ToFloat,
251     EOpConvFloat16ToDouble,
252 
253     // float -> (u)int*
254     EOpConvFloatToInt8,
255     EOpConvFloatToInt16,
256     EOpConvFloatToInt,
257     EOpConvFloatToInt64,
258     EOpConvFloatToUint8,
259     EOpConvFloatToUint16,
260     EOpConvFloatToUint,
261     EOpConvFloatToUint64,
262 
263     // float -> float*
264     EOpConvFloatToFloat16,
265     EOpConvFloatToDouble,
266 
267     // float64 _t-> (u)int*
268     EOpConvDoubleToInt8,
269     EOpConvDoubleToInt16,
270     EOpConvDoubleToInt,
271     EOpConvDoubleToInt64,
272     EOpConvDoubleToUint8,
273     EOpConvDoubleToUint16,
274     EOpConvDoubleToUint,
275     EOpConvDoubleToUint64,
276 
277     // float64_t -> float*
278     EOpConvDoubleToFloat16,
279     EOpConvDoubleToFloat,
280 
281     // uint64_t <-> pointer
282     EOpConvUint64ToPtr,
283     EOpConvPtrToUint64,
284 
285     // uvec2 <-> pointer
286     EOpConvUvec2ToPtr,
287     EOpConvPtrToUvec2,
288 
289     // uint64_t -> accelerationStructureEXT
290     EOpConvUint64ToAccStruct,
291 
292     // uvec2 -> accelerationStructureEXT
293     EOpConvUvec2ToAccStruct,
294 
295     //
296     // binary operations
297     //
298 
299     EOpAdd,
300     EOpSub,
301     EOpMul,
302     EOpDiv,
303     EOpMod,
304     EOpRightShift,
305     EOpLeftShift,
306     EOpAnd,
307     EOpInclusiveOr,
308     EOpExclusiveOr,
309     EOpEqual,
310     EOpNotEqual,
311     EOpVectorEqual,
312     EOpVectorNotEqual,
313     EOpLessThan,
314     EOpGreaterThan,
315     EOpLessThanEqual,
316     EOpGreaterThanEqual,
317     EOpComma,
318 
319     EOpVectorTimesScalar,
320     EOpVectorTimesMatrix,
321     EOpMatrixTimesVector,
322     EOpMatrixTimesScalar,
323 
324     EOpLogicalOr,
325     EOpLogicalXor,
326     EOpLogicalAnd,
327 
328     EOpIndexDirect,
329     EOpIndexIndirect,
330     EOpIndexDirectStruct,
331 
332     EOpVectorSwizzle,
333 
334     EOpMethod,
335     EOpScoping,
336 
337     //
338     // Built-in functions mapped to operators
339     //
340 
341     EOpRadians,
342     EOpDegrees,
343     EOpSin,
344     EOpCos,
345     EOpTan,
346     EOpAsin,
347     EOpAcos,
348     EOpAtan,
349     EOpSinh,
350     EOpCosh,
351     EOpTanh,
352     EOpAsinh,
353     EOpAcosh,
354     EOpAtanh,
355 
356     EOpPow,
357     EOpExp,
358     EOpLog,
359     EOpExp2,
360     EOpLog2,
361     EOpSqrt,
362     EOpInverseSqrt,
363 
364     EOpAbs,
365     EOpSign,
366     EOpFloor,
367     EOpTrunc,
368     EOpRound,
369     EOpRoundEven,
370     EOpCeil,
371     EOpFract,
372     EOpModf,
373     EOpMin,
374     EOpMax,
375     EOpClamp,
376     EOpMix,
377     EOpStep,
378     EOpSmoothStep,
379 
380     EOpIsNan,
381     EOpIsInf,
382 
383     EOpFma,
384 
385     EOpFrexp,
386     EOpLdexp,
387 
388     EOpFloatBitsToInt,
389     EOpFloatBitsToUint,
390     EOpIntBitsToFloat,
391     EOpUintBitsToFloat,
392     EOpDoubleBitsToInt64,
393     EOpDoubleBitsToUint64,
394     EOpInt64BitsToDouble,
395     EOpUint64BitsToDouble,
396     EOpFloat16BitsToInt16,
397     EOpFloat16BitsToUint16,
398     EOpInt16BitsToFloat16,
399     EOpUint16BitsToFloat16,
400     EOpPackSnorm2x16,
401     EOpUnpackSnorm2x16,
402     EOpPackUnorm2x16,
403     EOpUnpackUnorm2x16,
404     EOpPackSnorm4x8,
405     EOpUnpackSnorm4x8,
406     EOpPackUnorm4x8,
407     EOpUnpackUnorm4x8,
408     EOpPackHalf2x16,
409     EOpUnpackHalf2x16,
410     EOpPackDouble2x32,
411     EOpUnpackDouble2x32,
412     EOpPackInt2x32,
413     EOpUnpackInt2x32,
414     EOpPackUint2x32,
415     EOpUnpackUint2x32,
416     EOpPackFloat2x16,
417     EOpUnpackFloat2x16,
418     EOpPackInt2x16,
419     EOpUnpackInt2x16,
420     EOpPackUint2x16,
421     EOpUnpackUint2x16,
422     EOpPackInt4x16,
423     EOpUnpackInt4x16,
424     EOpPackUint4x16,
425     EOpUnpackUint4x16,
426     EOpPack16,
427     EOpPack32,
428     EOpPack64,
429     EOpUnpack32,
430     EOpUnpack16,
431     EOpUnpack8,
432 
433     EOpLength,
434     EOpDistance,
435     EOpDot,
436     EOpCross,
437     EOpNormalize,
438     EOpFaceForward,
439     EOpReflect,
440     EOpRefract,
441 
442     EOpMin3,
443     EOpMax3,
444     EOpMid3,
445 
446     EOpDPdx,            // Fragment only
447     EOpDPdy,            // Fragment only
448     EOpFwidth,          // Fragment only
449     EOpDPdxFine,        // Fragment only
450     EOpDPdyFine,        // Fragment only
451     EOpFwidthFine,      // Fragment only
452     EOpDPdxCoarse,      // Fragment only
453     EOpDPdyCoarse,      // Fragment only
454     EOpFwidthCoarse,    // Fragment only
455 
456     EOpInterpolateAtCentroid, // Fragment only
457     EOpInterpolateAtSample,   // Fragment only
458     EOpInterpolateAtOffset,   // Fragment only
459     EOpInterpolateAtVertex,
460 
461     EOpMatrixTimesMatrix,
462     EOpOuterProduct,
463     EOpDeterminant,
464     EOpMatrixInverse,
465     EOpTranspose,
466 
467     EOpFtransform,
468 
469     EOpNoise,
470 
471     EOpEmitVertex,           // geometry only
472     EOpEndPrimitive,         // geometry only
473     EOpEmitStreamVertex,     // geometry only
474     EOpEndStreamPrimitive,   // geometry only
475 
476     EOpBarrier,
477     EOpMemoryBarrier,
478     EOpMemoryBarrierAtomicCounter,
479     EOpMemoryBarrierBuffer,
480     EOpMemoryBarrierImage,
481     EOpMemoryBarrierShared,  // compute only
482     EOpGroupMemoryBarrier,   // compute only
483 
484     EOpBallot,
485     EOpReadInvocation,
486     EOpReadFirstInvocation,
487 
488     EOpAnyInvocation,
489     EOpAllInvocations,
490     EOpAllInvocationsEqual,
491 
492     EOpSubgroupGuardStart,
493     EOpSubgroupBarrier,
494     EOpSubgroupMemoryBarrier,
495     EOpSubgroupMemoryBarrierBuffer,
496     EOpSubgroupMemoryBarrierImage,
497     EOpSubgroupMemoryBarrierShared, // compute only
498     EOpSubgroupElect,
499     EOpSubgroupAll,
500     EOpSubgroupAny,
501     EOpSubgroupAllEqual,
502     EOpSubgroupBroadcast,
503     EOpSubgroupBroadcastFirst,
504     EOpSubgroupBallot,
505     EOpSubgroupInverseBallot,
506     EOpSubgroupBallotBitExtract,
507     EOpSubgroupBallotBitCount,
508     EOpSubgroupBallotInclusiveBitCount,
509     EOpSubgroupBallotExclusiveBitCount,
510     EOpSubgroupBallotFindLSB,
511     EOpSubgroupBallotFindMSB,
512     EOpSubgroupShuffle,
513     EOpSubgroupShuffleXor,
514     EOpSubgroupShuffleUp,
515     EOpSubgroupShuffleDown,
516     EOpSubgroupAdd,
517     EOpSubgroupMul,
518     EOpSubgroupMin,
519     EOpSubgroupMax,
520     EOpSubgroupAnd,
521     EOpSubgroupOr,
522     EOpSubgroupXor,
523     EOpSubgroupInclusiveAdd,
524     EOpSubgroupInclusiveMul,
525     EOpSubgroupInclusiveMin,
526     EOpSubgroupInclusiveMax,
527     EOpSubgroupInclusiveAnd,
528     EOpSubgroupInclusiveOr,
529     EOpSubgroupInclusiveXor,
530     EOpSubgroupExclusiveAdd,
531     EOpSubgroupExclusiveMul,
532     EOpSubgroupExclusiveMin,
533     EOpSubgroupExclusiveMax,
534     EOpSubgroupExclusiveAnd,
535     EOpSubgroupExclusiveOr,
536     EOpSubgroupExclusiveXor,
537     EOpSubgroupClusteredAdd,
538     EOpSubgroupClusteredMul,
539     EOpSubgroupClusteredMin,
540     EOpSubgroupClusteredMax,
541     EOpSubgroupClusteredAnd,
542     EOpSubgroupClusteredOr,
543     EOpSubgroupClusteredXor,
544     EOpSubgroupQuadBroadcast,
545     EOpSubgroupQuadSwapHorizontal,
546     EOpSubgroupQuadSwapVertical,
547     EOpSubgroupQuadSwapDiagonal,
548 
549     EOpSubgroupPartition,
550     EOpSubgroupPartitionedAdd,
551     EOpSubgroupPartitionedMul,
552     EOpSubgroupPartitionedMin,
553     EOpSubgroupPartitionedMax,
554     EOpSubgroupPartitionedAnd,
555     EOpSubgroupPartitionedOr,
556     EOpSubgroupPartitionedXor,
557     EOpSubgroupPartitionedInclusiveAdd,
558     EOpSubgroupPartitionedInclusiveMul,
559     EOpSubgroupPartitionedInclusiveMin,
560     EOpSubgroupPartitionedInclusiveMax,
561     EOpSubgroupPartitionedInclusiveAnd,
562     EOpSubgroupPartitionedInclusiveOr,
563     EOpSubgroupPartitionedInclusiveXor,
564     EOpSubgroupPartitionedExclusiveAdd,
565     EOpSubgroupPartitionedExclusiveMul,
566     EOpSubgroupPartitionedExclusiveMin,
567     EOpSubgroupPartitionedExclusiveMax,
568     EOpSubgroupPartitionedExclusiveAnd,
569     EOpSubgroupPartitionedExclusiveOr,
570     EOpSubgroupPartitionedExclusiveXor,
571 
572     EOpSubgroupGuardStop,
573 
574     EOpMinInvocations,
575     EOpMaxInvocations,
576     EOpAddInvocations,
577     EOpMinInvocationsNonUniform,
578     EOpMaxInvocationsNonUniform,
579     EOpAddInvocationsNonUniform,
580     EOpMinInvocationsInclusiveScan,
581     EOpMaxInvocationsInclusiveScan,
582     EOpAddInvocationsInclusiveScan,
583     EOpMinInvocationsInclusiveScanNonUniform,
584     EOpMaxInvocationsInclusiveScanNonUniform,
585     EOpAddInvocationsInclusiveScanNonUniform,
586     EOpMinInvocationsExclusiveScan,
587     EOpMaxInvocationsExclusiveScan,
588     EOpAddInvocationsExclusiveScan,
589     EOpMinInvocationsExclusiveScanNonUniform,
590     EOpMaxInvocationsExclusiveScanNonUniform,
591     EOpAddInvocationsExclusiveScanNonUniform,
592     EOpSwizzleInvocations,
593     EOpSwizzleInvocationsMasked,
594     EOpWriteInvocation,
595     EOpMbcnt,
596 
597     EOpCubeFaceIndex,
598     EOpCubeFaceCoord,
599     EOpTime,
600 
601     EOpAtomicAdd,
602     EOpAtomicSubtract,
603     EOpAtomicMin,
604     EOpAtomicMax,
605     EOpAtomicAnd,
606     EOpAtomicOr,
607     EOpAtomicXor,
608     EOpAtomicExchange,
609     EOpAtomicCompSwap,
610     EOpAtomicLoad,
611     EOpAtomicStore,
612 
613     EOpAtomicCounterIncrement, // results in pre-increment value
614     EOpAtomicCounterDecrement, // results in post-decrement value
615     EOpAtomicCounter,
616     EOpAtomicCounterAdd,
617     EOpAtomicCounterSubtract,
618     EOpAtomicCounterMin,
619     EOpAtomicCounterMax,
620     EOpAtomicCounterAnd,
621     EOpAtomicCounterOr,
622     EOpAtomicCounterXor,
623     EOpAtomicCounterExchange,
624     EOpAtomicCounterCompSwap,
625 
626     EOpAny,
627     EOpAll,
628 
629     EOpCooperativeMatrixLoad,
630     EOpCooperativeMatrixStore,
631     EOpCooperativeMatrixMulAdd,
632 
633     EOpBeginInvocationInterlock, // Fragment only
634     EOpEndInvocationInterlock, // Fragment only
635 
636     EOpIsHelperInvocation,
637 
638     EOpDebugPrintf,
639 
640     //
641     // Branch
642     //
643 
644     EOpKill,                // Fragment only
645     EOpTerminateInvocation, // Fragment only
646     EOpDemote,              // Fragment only
647     EOpTerminateRayKHR,         // Any-hit only
648     EOpIgnoreIntersectionKHR,   // Any-hit only
649     EOpReturn,
650     EOpBreak,
651     EOpContinue,
652     EOpCase,
653     EOpDefault,
654 
655     //
656     // Constructors
657     //
658 
659     EOpConstructGuardStart,
660     EOpConstructInt,          // these first scalar forms also identify what implicit conversion is needed
661     EOpConstructUint,
662     EOpConstructInt8,
663     EOpConstructUint8,
664     EOpConstructInt16,
665     EOpConstructUint16,
666     EOpConstructInt64,
667     EOpConstructUint64,
668     EOpConstructBool,
669     EOpConstructFloat,
670     EOpConstructDouble,
671     // Keep vector and matrix constructors in a consistent relative order for
672     // TParseContext::constructBuiltIn, which converts between 8/16/32 bit
673     // vector constructors
674     EOpConstructVec2,
675     EOpConstructVec3,
676     EOpConstructVec4,
677     EOpConstructMat2x2,
678     EOpConstructMat2x3,
679     EOpConstructMat2x4,
680     EOpConstructMat3x2,
681     EOpConstructMat3x3,
682     EOpConstructMat3x4,
683     EOpConstructMat4x2,
684     EOpConstructMat4x3,
685     EOpConstructMat4x4,
686     EOpConstructDVec2,
687     EOpConstructDVec3,
688     EOpConstructDVec4,
689     EOpConstructBVec2,
690     EOpConstructBVec3,
691     EOpConstructBVec4,
692     EOpConstructI8Vec2,
693     EOpConstructI8Vec3,
694     EOpConstructI8Vec4,
695     EOpConstructU8Vec2,
696     EOpConstructU8Vec3,
697     EOpConstructU8Vec4,
698     EOpConstructI16Vec2,
699     EOpConstructI16Vec3,
700     EOpConstructI16Vec4,
701     EOpConstructU16Vec2,
702     EOpConstructU16Vec3,
703     EOpConstructU16Vec4,
704     EOpConstructIVec2,
705     EOpConstructIVec3,
706     EOpConstructIVec4,
707     EOpConstructUVec2,
708     EOpConstructUVec3,
709     EOpConstructUVec4,
710     EOpConstructI64Vec2,
711     EOpConstructI64Vec3,
712     EOpConstructI64Vec4,
713     EOpConstructU64Vec2,
714     EOpConstructU64Vec3,
715     EOpConstructU64Vec4,
716     EOpConstructDMat2x2,
717     EOpConstructDMat2x3,
718     EOpConstructDMat2x4,
719     EOpConstructDMat3x2,
720     EOpConstructDMat3x3,
721     EOpConstructDMat3x4,
722     EOpConstructDMat4x2,
723     EOpConstructDMat4x3,
724     EOpConstructDMat4x4,
725     EOpConstructIMat2x2,
726     EOpConstructIMat2x3,
727     EOpConstructIMat2x4,
728     EOpConstructIMat3x2,
729     EOpConstructIMat3x3,
730     EOpConstructIMat3x4,
731     EOpConstructIMat4x2,
732     EOpConstructIMat4x3,
733     EOpConstructIMat4x4,
734     EOpConstructUMat2x2,
735     EOpConstructUMat2x3,
736     EOpConstructUMat2x4,
737     EOpConstructUMat3x2,
738     EOpConstructUMat3x3,
739     EOpConstructUMat3x4,
740     EOpConstructUMat4x2,
741     EOpConstructUMat4x3,
742     EOpConstructUMat4x4,
743     EOpConstructBMat2x2,
744     EOpConstructBMat2x3,
745     EOpConstructBMat2x4,
746     EOpConstructBMat3x2,
747     EOpConstructBMat3x3,
748     EOpConstructBMat3x4,
749     EOpConstructBMat4x2,
750     EOpConstructBMat4x3,
751     EOpConstructBMat4x4,
752     EOpConstructFloat16,
753     EOpConstructF16Vec2,
754     EOpConstructF16Vec3,
755     EOpConstructF16Vec4,
756     EOpConstructF16Mat2x2,
757     EOpConstructF16Mat2x3,
758     EOpConstructF16Mat2x4,
759     EOpConstructF16Mat3x2,
760     EOpConstructF16Mat3x3,
761     EOpConstructF16Mat3x4,
762     EOpConstructF16Mat4x2,
763     EOpConstructF16Mat4x3,
764     EOpConstructF16Mat4x4,
765     EOpConstructStruct,
766     EOpConstructTextureSampler,
767     EOpConstructNonuniform,     // expected to be transformed away, not present in final AST
768     EOpConstructReference,
769     EOpConstructCooperativeMatrix,
770     EOpConstructAccStruct,
771     EOpConstructGuardEnd,
772 
773     //
774     // moves
775     //
776 
777     EOpAssign,
778     EOpAddAssign,
779     EOpSubAssign,
780     EOpMulAssign,
781     EOpVectorTimesMatrixAssign,
782     EOpVectorTimesScalarAssign,
783     EOpMatrixTimesScalarAssign,
784     EOpMatrixTimesMatrixAssign,
785     EOpDivAssign,
786     EOpModAssign,
787     EOpAndAssign,
788     EOpInclusiveOrAssign,
789     EOpExclusiveOrAssign,
790     EOpLeftShiftAssign,
791     EOpRightShiftAssign,
792 
793     //
794     // Array operators
795     //
796 
797     // Can apply to arrays, vectors, or matrices.
798     // Can be decomposed to a constant at compile time, but this does not always happen,
799     // due to link-time effects. So, consumer can expect either a link-time sized or
800     // run-time sized array.
801     EOpArrayLength,
802 
803     //
804     // Image operations
805     //
806 
807     EOpImageGuardBegin,
808 
809     EOpImageQuerySize,
810     EOpImageQuerySamples,
811     EOpImageLoad,
812     EOpImageStore,
813     EOpImageLoadLod,
814     EOpImageStoreLod,
815     EOpImageAtomicAdd,
816     EOpImageAtomicMin,
817     EOpImageAtomicMax,
818     EOpImageAtomicAnd,
819     EOpImageAtomicOr,
820     EOpImageAtomicXor,
821     EOpImageAtomicExchange,
822     EOpImageAtomicCompSwap,
823     EOpImageAtomicLoad,
824     EOpImageAtomicStore,
825 
826     EOpSubpassLoad,
827     EOpSubpassLoadMS,
828     EOpSparseImageLoad,
829     EOpSparseImageLoadLod,
830 
831     EOpImageGuardEnd,
832 
833     //
834     // Texture operations
835     //
836 
837     EOpTextureGuardBegin,
838 
839     EOpTextureQuerySize,
840     EOpTextureQueryLod,
841     EOpTextureQueryLevels,
842     EOpTextureQuerySamples,
843 
844     EOpSamplingGuardBegin,
845 
846     EOpTexture,
847     EOpTextureProj,
848     EOpTextureLod,
849     EOpTextureOffset,
850     EOpTextureFetch,
851     EOpTextureFetchOffset,
852     EOpTextureProjOffset,
853     EOpTextureLodOffset,
854     EOpTextureProjLod,
855     EOpTextureProjLodOffset,
856     EOpTextureGrad,
857     EOpTextureGradOffset,
858     EOpTextureProjGrad,
859     EOpTextureProjGradOffset,
860     EOpTextureGather,
861     EOpTextureGatherOffset,
862     EOpTextureGatherOffsets,
863     EOpTextureClamp,
864     EOpTextureOffsetClamp,
865     EOpTextureGradClamp,
866     EOpTextureGradOffsetClamp,
867     EOpTextureGatherLod,
868     EOpTextureGatherLodOffset,
869     EOpTextureGatherLodOffsets,
870     EOpFragmentMaskFetch,
871     EOpFragmentFetch,
872 
873     EOpSparseTextureGuardBegin,
874 
875     EOpSparseTexture,
876     EOpSparseTextureLod,
877     EOpSparseTextureOffset,
878     EOpSparseTextureFetch,
879     EOpSparseTextureFetchOffset,
880     EOpSparseTextureLodOffset,
881     EOpSparseTextureGrad,
882     EOpSparseTextureGradOffset,
883     EOpSparseTextureGather,
884     EOpSparseTextureGatherOffset,
885     EOpSparseTextureGatherOffsets,
886     EOpSparseTexelsResident,
887     EOpSparseTextureClamp,
888     EOpSparseTextureOffsetClamp,
889     EOpSparseTextureGradClamp,
890     EOpSparseTextureGradOffsetClamp,
891     EOpSparseTextureGatherLod,
892     EOpSparseTextureGatherLodOffset,
893     EOpSparseTextureGatherLodOffsets,
894 
895     EOpSparseTextureGuardEnd,
896 
897     EOpImageFootprintGuardBegin,
898     EOpImageSampleFootprintNV,
899     EOpImageSampleFootprintClampNV,
900     EOpImageSampleFootprintLodNV,
901     EOpImageSampleFootprintGradNV,
902     EOpImageSampleFootprintGradClampNV,
903     EOpImageFootprintGuardEnd,
904     EOpSamplingGuardEnd,
905     EOpTextureGuardEnd,
906 
907     //
908     // Integer operations
909     //
910 
911     EOpAddCarry,
912     EOpSubBorrow,
913     EOpUMulExtended,
914     EOpIMulExtended,
915     EOpBitfieldExtract,
916     EOpBitfieldInsert,
917     EOpBitFieldReverse,
918     EOpBitCount,
919     EOpFindLSB,
920     EOpFindMSB,
921 
922     EOpCountLeadingZeros,
923     EOpCountTrailingZeros,
924     EOpAbsDifference,
925     EOpAddSaturate,
926     EOpSubSaturate,
927     EOpAverage,
928     EOpAverageRounded,
929     EOpMul32x16,
930 
931     EOpTraceNV,
932     EOpTraceRayMotionNV,
933     EOpTraceKHR,
934     EOpReportIntersection,
935     EOpIgnoreIntersectionNV,
936     EOpTerminateRayNV,
937     EOpExecuteCallableNV,
938     EOpExecuteCallableKHR,
939     EOpWritePackedPrimitiveIndices4x8NV,
940     EOpEmitMeshTasksEXT,
941     EOpSetMeshOutputsEXT,
942 
943     //
944     // GL_EXT_ray_query operations
945     //
946 
947     EOpRayQueryInitialize,
948     EOpRayQueryTerminate,
949     EOpRayQueryGenerateIntersection,
950     EOpRayQueryConfirmIntersection,
951     EOpRayQueryProceed,
952     EOpRayQueryGetIntersectionType,
953     EOpRayQueryGetRayTMin,
954     EOpRayQueryGetRayFlags,
955     EOpRayQueryGetIntersectionT,
956     EOpRayQueryGetIntersectionInstanceCustomIndex,
957     EOpRayQueryGetIntersectionInstanceId,
958     EOpRayQueryGetIntersectionInstanceShaderBindingTableRecordOffset,
959     EOpRayQueryGetIntersectionGeometryIndex,
960     EOpRayQueryGetIntersectionPrimitiveIndex,
961     EOpRayQueryGetIntersectionBarycentrics,
962     EOpRayQueryGetIntersectionFrontFace,
963     EOpRayQueryGetIntersectionCandidateAABBOpaque,
964     EOpRayQueryGetIntersectionObjectRayDirection,
965     EOpRayQueryGetIntersectionObjectRayOrigin,
966     EOpRayQueryGetWorldRayDirection,
967     EOpRayQueryGetWorldRayOrigin,
968     EOpRayQueryGetIntersectionObjectToWorld,
969     EOpRayQueryGetIntersectionWorldToObject,
970 
971     //
972     // HLSL operations
973     //
974 
975     EOpClip,                // discard if input value < 0
976     EOpIsFinite,
977     EOpLog10,               // base 10 log
978     EOpRcp,                 // 1/x
979     EOpSaturate,            // clamp from 0 to 1
980     EOpSinCos,              // sin and cos in out parameters
981     EOpGenMul,              // mul(x,y) on any of mat/vec/scalars
982     EOpDst,                 // x = 1, y=src0.y * src1.y, z=src0.z, w=src1.w
983     EOpInterlockedAdd,      // atomic ops, but uses [optional] out arg instead of return
984     EOpInterlockedAnd,      // ...
985     EOpInterlockedCompareExchange, // ...
986     EOpInterlockedCompareStore,    // ...
987     EOpInterlockedExchange, // ...
988     EOpInterlockedMax,      // ...
989     EOpInterlockedMin,      // ...
990     EOpInterlockedOr,       // ...
991     EOpInterlockedXor,      // ...
992     EOpAllMemoryBarrierWithGroupSync,    // memory barriers without non-hlsl AST equivalents
993     EOpDeviceMemoryBarrier,              // ...
994     EOpDeviceMemoryBarrierWithGroupSync, // ...
995     EOpWorkgroupMemoryBarrier,           // ...
996     EOpWorkgroupMemoryBarrierWithGroupSync, // ...
997     EOpEvaluateAttributeSnapped,         // InterpolateAtOffset with int position on 16x16 grid
998     EOpF32tof16,                         // HLSL conversion: half of a PackHalf2x16
999     EOpF16tof32,                         // HLSL conversion: half of an UnpackHalf2x16
1000     EOpLit,                              // HLSL lighting coefficient vector
1001     EOpTextureBias,                      // HLSL texture bias: will be lowered to EOpTexture
1002     EOpAsDouble,                         // slightly different from EOpUint64BitsToDouble
1003     EOpD3DCOLORtoUBYTE4,                 // convert and swizzle 4-component color to UBYTE4 range
1004 
1005     EOpMethodSample,                     // Texture object methods.  These are translated to existing
1006     EOpMethodSampleBias,                 // AST methods, and exist to represent HLSL semantics until that
1007     EOpMethodSampleCmp,                  // translation is performed.  See HlslParseContext::decomposeSampleMethods().
1008     EOpMethodSampleCmpLevelZero,         // ...
1009     EOpMethodSampleGrad,                 // ...
1010     EOpMethodSampleLevel,                // ...
1011     EOpMethodLoad,                       // ...
1012     EOpMethodGetDimensions,              // ...
1013     EOpMethodGetSamplePosition,          // ...
1014     EOpMethodGather,                     // ...
1015     EOpMethodCalculateLevelOfDetail,     // ...
1016     EOpMethodCalculateLevelOfDetailUnclamped,     // ...
1017 
1018     // Load already defined above for textures
1019     EOpMethodLoad2,                      // Structure buffer object methods.  These are translated to existing
1020     EOpMethodLoad3,                      // AST methods, and exist to represent HLSL semantics until that
1021     EOpMethodLoad4,                      // translation is performed.  See HlslParseContext::decomposeSampleMethods().
1022     EOpMethodStore,                      // ...
1023     EOpMethodStore2,                     // ...
1024     EOpMethodStore3,                     // ...
1025     EOpMethodStore4,                     // ...
1026     EOpMethodIncrementCounter,           // ...
1027     EOpMethodDecrementCounter,           // ...
1028     // EOpMethodAppend is defined for geo shaders below
1029     EOpMethodConsume,
1030 
1031     // SM5 texture methods
1032     EOpMethodGatherRed,                  // These are covered under the above EOpMethodSample comment about
1033     EOpMethodGatherGreen,                // translation to existing AST opcodes.  They exist temporarily
1034     EOpMethodGatherBlue,                 // because HLSL arguments are slightly different.
1035     EOpMethodGatherAlpha,                // ...
1036     EOpMethodGatherCmp,                  // ...
1037     EOpMethodGatherCmpRed,               // ...
1038     EOpMethodGatherCmpGreen,             // ...
1039     EOpMethodGatherCmpBlue,              // ...
1040     EOpMethodGatherCmpAlpha,             // ...
1041 
1042     // geometry methods
1043     EOpMethodAppend,                     // Geometry shader methods
1044     EOpMethodRestartStrip,               // ...
1045 
1046     // matrix
1047     EOpMatrixSwizzle,                    // select multiple matrix components (non-column)
1048 
1049     // SM6 wave ops
1050     EOpWaveGetLaneCount,                 // Will decompose to gl_SubgroupSize.
1051     EOpWaveGetLaneIndex,                 // Will decompose to gl_SubgroupInvocationID.
1052     EOpWaveActiveCountBits,              // Will decompose to subgroupBallotBitCount(subgroupBallot()).
1053     EOpWavePrefixCountBits,              // Will decompose to subgroupBallotInclusiveBitCount(subgroupBallot()).
1054 
1055     // Shader Clock Ops
1056     EOpReadClockSubgroupKHR,
1057     EOpReadClockDeviceKHR,
1058 };
1059 
1060 class TIntermTraverser;
1061 class TIntermOperator;
1062 class TIntermAggregate;
1063 class TIntermUnary;
1064 class TIntermBinary;
1065 class TIntermConstantUnion;
1066 class TIntermSelection;
1067 class TIntermSwitch;
1068 class TIntermBranch;
1069 class TIntermTyped;
1070 class TIntermMethod;
1071 class TIntermSymbol;
1072 class TIntermLoop;
1073 
1074 } // end namespace glslang
1075 
1076 //
1077 // Base class for the tree nodes
1078 //
1079 // (Put outside the glslang namespace, as it's used as part of the external interface.)
1080 //
1081 class TIntermNode {
1082 public:
POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator ())1083     POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator())
1084 
1085     TIntermNode() { loc.init(); }
getLoc()1086     virtual const glslang::TSourceLoc& getLoc() const { return loc; }
setLoc(const glslang::TSourceLoc & l)1087     virtual void setLoc(const glslang::TSourceLoc& l) { loc = l; }
1088     virtual void traverse(glslang::TIntermTraverser*) = 0;
getAsTyped()1089     virtual       glslang::TIntermTyped*         getAsTyped()               { return nullptr; }
getAsOperator()1090     virtual       glslang::TIntermOperator*      getAsOperator()            { return nullptr; }
getAsConstantUnion()1091     virtual       glslang::TIntermConstantUnion* getAsConstantUnion()       { return nullptr; }
getAsAggregate()1092     virtual       glslang::TIntermAggregate*     getAsAggregate()           { return nullptr; }
getAsUnaryNode()1093     virtual       glslang::TIntermUnary*         getAsUnaryNode()           { return nullptr; }
getAsBinaryNode()1094     virtual       glslang::TIntermBinary*        getAsBinaryNode()          { return nullptr; }
getAsSelectionNode()1095     virtual       glslang::TIntermSelection*     getAsSelectionNode()       { return nullptr; }
getAsSwitchNode()1096     virtual       glslang::TIntermSwitch*        getAsSwitchNode()          { return nullptr; }
getAsMethodNode()1097     virtual       glslang::TIntermMethod*        getAsMethodNode()          { return nullptr; }
getAsSymbolNode()1098     virtual       glslang::TIntermSymbol*        getAsSymbolNode()          { return nullptr; }
getAsBranchNode()1099     virtual       glslang::TIntermBranch*        getAsBranchNode()          { return nullptr; }
getAsLoopNode()1100     virtual       glslang::TIntermLoop*          getAsLoopNode()            { return nullptr; }
1101 
getAsTyped()1102     virtual const glslang::TIntermTyped*         getAsTyped()         const { return nullptr; }
getAsOperator()1103     virtual const glslang::TIntermOperator*      getAsOperator()      const { return nullptr; }
getAsConstantUnion()1104     virtual const glslang::TIntermConstantUnion* getAsConstantUnion() const { return nullptr; }
getAsAggregate()1105     virtual const glslang::TIntermAggregate*     getAsAggregate()     const { return nullptr; }
getAsUnaryNode()1106     virtual const glslang::TIntermUnary*         getAsUnaryNode()     const { return nullptr; }
getAsBinaryNode()1107     virtual const glslang::TIntermBinary*        getAsBinaryNode()    const { return nullptr; }
getAsSelectionNode()1108     virtual const glslang::TIntermSelection*     getAsSelectionNode() const { return nullptr; }
getAsSwitchNode()1109     virtual const glslang::TIntermSwitch*        getAsSwitchNode()    const { return nullptr; }
getAsMethodNode()1110     virtual const glslang::TIntermMethod*        getAsMethodNode()    const { return nullptr; }
getAsSymbolNode()1111     virtual const glslang::TIntermSymbol*        getAsSymbolNode()    const { return nullptr; }
getAsBranchNode()1112     virtual const glslang::TIntermBranch*        getAsBranchNode()    const { return nullptr; }
getAsLoopNode()1113     virtual const glslang::TIntermLoop*          getAsLoopNode()      const { return nullptr; }
~TIntermNode()1114     virtual ~TIntermNode() { }
1115 
1116 protected:
1117     TIntermNode(const TIntermNode&);
1118     TIntermNode& operator=(const TIntermNode&);
1119     glslang::TSourceLoc loc;
1120 };
1121 
1122 namespace glslang {
1123 
1124 //
1125 // This is just to help yacc.
1126 //
1127 struct TIntermNodePair {
1128     TIntermNode* node1;
1129     TIntermNode* node2;
1130 };
1131 
1132 //
1133 // Intermediate class for nodes that have a type.
1134 //
1135 class TIntermTyped : public TIntermNode {
1136 public:
TIntermTyped(const TType & t)1137     TIntermTyped(const TType& t) { type.shallowCopy(t); }
TIntermTyped(TBasicType basicType)1138     TIntermTyped(TBasicType basicType) { TType bt(basicType); type.shallowCopy(bt); }
getAsTyped()1139     virtual       TIntermTyped* getAsTyped()       { return this; }
getAsTyped()1140     virtual const TIntermTyped* getAsTyped() const { return this; }
setType(const TType & t)1141     virtual void setType(const TType& t) { type.shallowCopy(t); }
getType()1142     virtual const TType& getType() const { return type; }
getWritableType()1143     virtual TType& getWritableType() { return type; }
1144 
getBasicType()1145     virtual TBasicType getBasicType() const { return type.getBasicType(); }
getQualifier()1146     virtual TQualifier& getQualifier() { return type.getQualifier(); }
getQualifier()1147     virtual const TQualifier& getQualifier() const { return type.getQualifier(); }
getArraySizes()1148     virtual TArraySizes* getArraySizes() { return type.getArraySizes(); }
getArraySizes()1149     virtual const TArraySizes* getArraySizes() const { return type.getArraySizes(); }
1150     virtual void propagatePrecision(TPrecisionQualifier);
getVectorSize()1151     virtual int getVectorSize() const { return type.getVectorSize(); }
getMatrixCols()1152     virtual int getMatrixCols() const { return type.getMatrixCols(); }
getMatrixRows()1153     virtual int getMatrixRows() const { return type.getMatrixRows(); }
isMatrix()1154     virtual bool isMatrix() const { return type.isMatrix(); }
isArray()1155     virtual bool isArray()  const { return type.isArray(); }
isVector()1156     virtual bool isVector() const { return type.isVector(); }
isScalar()1157     virtual bool isScalar() const { return type.isScalar(); }
isStruct()1158     virtual bool isStruct() const { return type.isStruct(); }
isFloatingDomain()1159     virtual bool isFloatingDomain() const { return type.isFloatingDomain(); }
isIntegerDomain()1160     virtual bool isIntegerDomain() const { return type.isIntegerDomain(); }
isAtomic()1161     bool isAtomic() const { return type.isAtomic(); }
isReference()1162     bool isReference() const { return type.isReference(); }
1163     TString getCompleteString(bool enhanced = false) const { return type.getCompleteString(enhanced); }
1164 
1165 protected:
1166     TIntermTyped& operator=(const TIntermTyped&);
1167     TType type;
1168 };
1169 
1170 //
1171 // Handle for, do-while, and while loops.
1172 //
1173 class TIntermLoop : public TIntermNode {
1174 public:
TIntermLoop(TIntermNode * aBody,TIntermTyped * aTest,TIntermTyped * aTerminal,bool testFirst)1175     TIntermLoop(TIntermNode* aBody, TIntermTyped* aTest, TIntermTyped* aTerminal, bool testFirst) :
1176         body(aBody),
1177         test(aTest),
1178         terminal(aTerminal),
1179         first(testFirst),
1180         unroll(false),
1181         dontUnroll(false),
1182         dependency(0),
1183         minIterations(0),
1184         maxIterations(iterationsInfinite),
1185         iterationMultiple(1),
1186         peelCount(0),
1187         partialCount(0)
1188     { }
1189 
getAsLoopNode()1190     virtual       TIntermLoop* getAsLoopNode() { return this; }
getAsLoopNode()1191     virtual const TIntermLoop* getAsLoopNode() const { return this; }
1192     virtual void traverse(TIntermTraverser*);
getBody()1193     TIntermNode*  getBody() const { return body; }
getTest()1194     TIntermTyped* getTest() const { return test; }
getTerminal()1195     TIntermTyped* getTerminal() const { return terminal; }
testFirst()1196     bool testFirst() const { return first; }
1197 
setUnroll()1198     void setUnroll()     { unroll = true; }
setDontUnroll()1199     void setDontUnroll() {
1200         dontUnroll = true;
1201         peelCount = 0;
1202         partialCount = 0;
1203     }
getUnroll()1204     bool getUnroll()     const { return unroll; }
getDontUnroll()1205     bool getDontUnroll() const { return dontUnroll; }
1206 
1207     static const unsigned int dependencyInfinite = 0xFFFFFFFF;
1208     static const unsigned int iterationsInfinite = 0xFFFFFFFF;
setLoopDependency(int d)1209     void setLoopDependency(int d) { dependency = d; }
getLoopDependency()1210     int getLoopDependency() const { return dependency; }
1211 
setMinIterations(unsigned int v)1212     void setMinIterations(unsigned int v) { minIterations = v; }
getMinIterations()1213     unsigned int getMinIterations() const { return minIterations; }
setMaxIterations(unsigned int v)1214     void setMaxIterations(unsigned int v) { maxIterations = v; }
getMaxIterations()1215     unsigned int getMaxIterations() const { return maxIterations; }
setIterationMultiple(unsigned int v)1216     void setIterationMultiple(unsigned int v) { iterationMultiple = v; }
getIterationMultiple()1217     unsigned int getIterationMultiple() const { return iterationMultiple; }
setPeelCount(unsigned int v)1218     void setPeelCount(unsigned int v) {
1219         peelCount = v;
1220         dontUnroll = false;
1221     }
getPeelCount()1222     unsigned int getPeelCount() const { return peelCount; }
setPartialCount(unsigned int v)1223     void setPartialCount(unsigned int v) {
1224         partialCount = v;
1225         dontUnroll = false;
1226     }
getPartialCount()1227     unsigned int getPartialCount() const { return partialCount; }
1228 
1229 protected:
1230     TIntermNode* body;       // code to loop over
1231     TIntermTyped* test;      // exit condition associated with loop, could be 0 for 'for' loops
1232     TIntermTyped* terminal;  // exists for for-loops
1233     bool first;              // true for while and for, not for do-while
1234     bool unroll;             // true if unroll requested
1235     bool dontUnroll;         // true if request to not unroll
1236     unsigned int dependency; // loop dependency hint; 0 means not set or unknown
1237     unsigned int minIterations;      // as per the SPIR-V specification
1238     unsigned int maxIterations;      // as per the SPIR-V specification
1239     unsigned int iterationMultiple;  // as per the SPIR-V specification
1240     unsigned int peelCount;          // as per the SPIR-V specification
1241     unsigned int partialCount;       // as per the SPIR-V specification
1242 };
1243 
1244 //
1245 // Handle case, break, continue, return, and kill.
1246 //
1247 class TIntermBranch : public TIntermNode {
1248 public:
TIntermBranch(TOperator op,TIntermTyped * e)1249     TIntermBranch(TOperator op, TIntermTyped* e) :
1250         flowOp(op),
1251         expression(e) { }
getAsBranchNode()1252     virtual       TIntermBranch* getAsBranchNode()       { return this; }
getAsBranchNode()1253     virtual const TIntermBranch* getAsBranchNode() const { return this; }
1254     virtual void traverse(TIntermTraverser*);
getFlowOp()1255     TOperator getFlowOp() const { return flowOp; }
getExpression()1256     TIntermTyped* getExpression() const { return expression; }
setExpression(TIntermTyped * pExpression)1257     void setExpression(TIntermTyped* pExpression) { expression = pExpression; }
1258     void updatePrecision(TPrecisionQualifier parentPrecision);
1259 protected:
1260     TOperator flowOp;
1261     TIntermTyped* expression;
1262 };
1263 
1264 //
1265 // Represent method names before seeing their calling signature
1266 // or resolving them to operations.  Just an expression as the base object
1267 // and a textural name.
1268 //
1269 class TIntermMethod : public TIntermTyped {
1270 public:
TIntermMethod(TIntermTyped * o,const TType & t,const TString & m)1271     TIntermMethod(TIntermTyped* o, const TType& t, const TString& m) : TIntermTyped(t), object(o), method(m) { }
getAsMethodNode()1272     virtual       TIntermMethod* getAsMethodNode()       { return this; }
getAsMethodNode()1273     virtual const TIntermMethod* getAsMethodNode() const { return this; }
getMethodName()1274     virtual const TString& getMethodName() const { return method; }
getObject()1275     virtual TIntermTyped* getObject() const { return object; }
1276     virtual void traverse(TIntermTraverser*);
1277 protected:
1278     TIntermTyped* object;
1279     TString method;
1280 };
1281 
1282 //
1283 // Nodes that correspond to symbols or constants in the source code.
1284 //
1285 class TIntermSymbol : public TIntermTyped {
1286 public:
1287     // if symbol is initialized as symbol(sym), the memory comes from the pool allocator of sym. If sym comes from
1288     // per process threadPoolAllocator, then it causes increased memory usage per compile
1289     // it is essential to use "symbol = sym" to assign to symbol
TIntermSymbol(long long i,const TString & n,const TType & t)1290     TIntermSymbol(long long i, const TString& n, const TType& t)
1291         : TIntermTyped(t), id(i),
1292 #ifndef GLSLANG_WEB
1293         flattenSubset(-1),
1294 #endif
1295         constSubtree(nullptr)
1296           { name = n; }
getId()1297     virtual long long getId() const { return id; }
changeId(long long i)1298     virtual void changeId(long long i) { id = i; }
getName()1299     virtual const TString& getName() const { return name; }
1300     virtual void traverse(TIntermTraverser*);
getAsSymbolNode()1301     virtual       TIntermSymbol* getAsSymbolNode()       { return this; }
getAsSymbolNode()1302     virtual const TIntermSymbol* getAsSymbolNode() const { return this; }
setConstArray(const TConstUnionArray & c)1303     void setConstArray(const TConstUnionArray& c) { constArray = c; }
getConstArray()1304     const TConstUnionArray& getConstArray() const { return constArray; }
setConstSubtree(TIntermTyped * subtree)1305     void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; }
getConstSubtree()1306     TIntermTyped* getConstSubtree() const { return constSubtree; }
1307 #ifndef GLSLANG_WEB
setFlattenSubset(int subset)1308     void setFlattenSubset(int subset) { flattenSubset = subset; }
1309     virtual const TString& getAccessName() const;
1310 
getFlattenSubset()1311     int getFlattenSubset() const { return flattenSubset; } // -1 means full object
1312 #endif
1313 
1314     // This is meant for cases where a node has already been constructed, and
1315     // later on, it becomes necessary to switch to a different symbol.
switchId(long long newId)1316     virtual void switchId(long long newId) { id = newId; }
1317 
1318 protected:
1319     long long id;                // the unique id of the symbol this node represents
1320 #ifndef GLSLANG_WEB
1321     int flattenSubset;           // how deeply the flattened object rooted at id has been dereferenced
1322 #endif
1323     TString name;                // the name of the symbol this node represents
1324     TConstUnionArray constArray; // if the symbol is a front-end compile-time constant, this is its value
1325     TIntermTyped* constSubtree;
1326 };
1327 
1328 class TIntermConstantUnion : public TIntermTyped {
1329 public:
TIntermConstantUnion(const TConstUnionArray & ua,const TType & t)1330     TIntermConstantUnion(const TConstUnionArray& ua, const TType& t) : TIntermTyped(t), constArray(ua), literal(false) { }
getConstArray()1331     const TConstUnionArray& getConstArray() const { return constArray; }
getAsConstantUnion()1332     virtual       TIntermConstantUnion* getAsConstantUnion()       { return this; }
getAsConstantUnion()1333     virtual const TIntermConstantUnion* getAsConstantUnion() const { return this; }
1334     virtual void traverse(TIntermTraverser*);
1335     virtual TIntermTyped* fold(TOperator, const TIntermTyped*) const;
1336     virtual TIntermTyped* fold(TOperator, const TType&) const;
setLiteral()1337     void setLiteral() { literal = true; }
setExpression()1338     void setExpression() { literal = false; }
isLiteral()1339     bool isLiteral() const { return literal; }
1340 
1341 protected:
1342     TIntermConstantUnion& operator=(const TIntermConstantUnion&);
1343 
1344     const TConstUnionArray constArray;
1345     bool literal;  // true if node represents a literal in the source code
1346 };
1347 
1348 // Represent the independent aspects of a texturing TOperator
1349 struct TCrackedTextureOp {
1350     bool query;
1351     bool proj;
1352     bool lod;
1353     bool fetch;
1354     bool offset;
1355     bool offsets;
1356     bool gather;
1357     bool grad;
1358     bool subpass;
1359     bool lodClamp;
1360     bool fragMask;
1361 };
1362 
1363 //
1364 // Intermediate class for node types that hold operators.
1365 //
1366 class TIntermOperator : public TIntermTyped {
1367 public:
getAsOperator()1368     virtual       TIntermOperator* getAsOperator()       { return this; }
getAsOperator()1369     virtual const TIntermOperator* getAsOperator() const { return this; }
getOp()1370     TOperator getOp() const { return op; }
setOp(TOperator newOp)1371     void setOp(TOperator newOp) { op = newOp; }
1372     bool modifiesState() const;
1373     bool isConstructor() const;
isTexture()1374     bool isTexture()  const { return op > EOpTextureGuardBegin  && op < EOpTextureGuardEnd; }
isSampling()1375     bool isSampling() const { return op > EOpSamplingGuardBegin && op < EOpSamplingGuardEnd; }
1376 #ifdef GLSLANG_WEB
isImage()1377     bool isImage()          const { return false; }
isSparseTexture()1378     bool isSparseTexture()  const { return false; }
isImageFootprint()1379     bool isImageFootprint() const { return false; }
isSparseImage()1380     bool isSparseImage()    const { return false; }
isSubgroup()1381     bool isSubgroup()       const { return false; }
1382 #else
isImage()1383     bool isImage()    const { return op > EOpImageGuardBegin    && op < EOpImageGuardEnd; }
isSparseTexture()1384     bool isSparseTexture() const { return op > EOpSparseTextureGuardBegin && op < EOpSparseTextureGuardEnd; }
isImageFootprint()1385     bool isImageFootprint() const { return op > EOpImageFootprintGuardBegin && op < EOpImageFootprintGuardEnd; }
isSparseImage()1386     bool isSparseImage()   const { return op == EOpSparseImageLoad; }
isSubgroup()1387     bool isSubgroup() const { return op > EOpSubgroupGuardStart && op < EOpSubgroupGuardStop; }
1388 #endif
1389 
setOperationPrecision(TPrecisionQualifier p)1390     void setOperationPrecision(TPrecisionQualifier p) { operationPrecision = p; }
getOperationPrecision()1391     TPrecisionQualifier getOperationPrecision() const { return operationPrecision != EpqNone ?
1392                                                                                      operationPrecision :
1393                                                                                      type.getQualifier().precision; }
getCompleteString()1394     TString getCompleteString() const
1395     {
1396         TString cs = type.getCompleteString();
1397         if (getOperationPrecision() != type.getQualifier().precision) {
1398             cs += ", operation at ";
1399             cs += GetPrecisionQualifierString(getOperationPrecision());
1400         }
1401 
1402         return cs;
1403     }
1404 
1405     // Crack the op into the individual dimensions of texturing operation.
crackTexture(TSampler sampler,TCrackedTextureOp & cracked)1406     void crackTexture(TSampler sampler, TCrackedTextureOp& cracked) const
1407     {
1408         cracked.query = false;
1409         cracked.proj = false;
1410         cracked.lod = false;
1411         cracked.fetch = false;
1412         cracked.offset = false;
1413         cracked.offsets = false;
1414         cracked.gather = false;
1415         cracked.grad = false;
1416         cracked.subpass = false;
1417         cracked.lodClamp = false;
1418         cracked.fragMask = false;
1419 
1420         switch (op) {
1421         case EOpImageQuerySize:
1422         case EOpImageQuerySamples:
1423         case EOpTextureQuerySize:
1424         case EOpTextureQueryLod:
1425         case EOpTextureQueryLevels:
1426         case EOpTextureQuerySamples:
1427         case EOpSparseTexelsResident:
1428             cracked.query = true;
1429             break;
1430         case EOpTexture:
1431         case EOpSparseTexture:
1432             break;
1433         case EOpTextureProj:
1434             cracked.proj = true;
1435             break;
1436         case EOpTextureLod:
1437         case EOpSparseTextureLod:
1438             cracked.lod = true;
1439             break;
1440         case EOpTextureOffset:
1441         case EOpSparseTextureOffset:
1442             cracked.offset = true;
1443             break;
1444         case EOpTextureFetch:
1445         case EOpSparseTextureFetch:
1446             cracked.fetch = true;
1447             if (sampler.is1D() || (sampler.dim == Esd2D && ! sampler.isMultiSample()) || sampler.dim == Esd3D)
1448                 cracked.lod = true;
1449             break;
1450         case EOpTextureFetchOffset:
1451         case EOpSparseTextureFetchOffset:
1452             cracked.fetch = true;
1453             cracked.offset = true;
1454             if (sampler.is1D() || (sampler.dim == Esd2D && ! sampler.isMultiSample()) || sampler.dim == Esd3D)
1455                 cracked.lod = true;
1456             break;
1457         case EOpTextureProjOffset:
1458             cracked.offset = true;
1459             cracked.proj = true;
1460             break;
1461         case EOpTextureLodOffset:
1462         case EOpSparseTextureLodOffset:
1463             cracked.offset = true;
1464             cracked.lod = true;
1465             break;
1466         case EOpTextureProjLod:
1467             cracked.lod = true;
1468             cracked.proj = true;
1469             break;
1470         case EOpTextureProjLodOffset:
1471             cracked.offset = true;
1472             cracked.lod = true;
1473             cracked.proj = true;
1474             break;
1475         case EOpTextureGrad:
1476         case EOpSparseTextureGrad:
1477             cracked.grad = true;
1478             break;
1479         case EOpTextureGradOffset:
1480         case EOpSparseTextureGradOffset:
1481             cracked.grad = true;
1482             cracked.offset = true;
1483             break;
1484         case EOpTextureProjGrad:
1485             cracked.grad = true;
1486             cracked.proj = true;
1487             break;
1488         case EOpTextureProjGradOffset:
1489             cracked.grad = true;
1490             cracked.offset = true;
1491             cracked.proj = true;
1492             break;
1493 #ifndef GLSLANG_WEB
1494         case EOpTextureClamp:
1495         case EOpSparseTextureClamp:
1496             cracked.lodClamp = true;
1497             break;
1498         case EOpTextureOffsetClamp:
1499         case EOpSparseTextureOffsetClamp:
1500             cracked.offset = true;
1501             cracked.lodClamp = true;
1502             break;
1503         case EOpTextureGradClamp:
1504         case EOpSparseTextureGradClamp:
1505             cracked.grad = true;
1506             cracked.lodClamp = true;
1507             break;
1508         case EOpTextureGradOffsetClamp:
1509         case EOpSparseTextureGradOffsetClamp:
1510             cracked.grad = true;
1511             cracked.offset = true;
1512             cracked.lodClamp = true;
1513             break;
1514         case EOpTextureGather:
1515         case EOpSparseTextureGather:
1516             cracked.gather = true;
1517             break;
1518         case EOpTextureGatherOffset:
1519         case EOpSparseTextureGatherOffset:
1520             cracked.gather = true;
1521             cracked.offset = true;
1522             break;
1523         case EOpTextureGatherOffsets:
1524         case EOpSparseTextureGatherOffsets:
1525             cracked.gather = true;
1526             cracked.offsets = true;
1527             break;
1528         case EOpTextureGatherLod:
1529         case EOpSparseTextureGatherLod:
1530             cracked.gather = true;
1531             cracked.lod    = true;
1532             break;
1533         case EOpTextureGatherLodOffset:
1534         case EOpSparseTextureGatherLodOffset:
1535             cracked.gather = true;
1536             cracked.offset = true;
1537             cracked.lod    = true;
1538             break;
1539         case EOpTextureGatherLodOffsets:
1540         case EOpSparseTextureGatherLodOffsets:
1541             cracked.gather  = true;
1542             cracked.offsets = true;
1543             cracked.lod     = true;
1544             break;
1545         case EOpImageLoadLod:
1546         case EOpImageStoreLod:
1547         case EOpSparseImageLoadLod:
1548             cracked.lod = true;
1549             break;
1550         case EOpFragmentMaskFetch:
1551             cracked.subpass = sampler.dim == EsdSubpass;
1552             cracked.fragMask = true;
1553             break;
1554         case EOpFragmentFetch:
1555             cracked.subpass = sampler.dim == EsdSubpass;
1556             cracked.fragMask = true;
1557             break;
1558         case EOpImageSampleFootprintNV:
1559             break;
1560         case EOpImageSampleFootprintClampNV:
1561             cracked.lodClamp = true;
1562             break;
1563         case EOpImageSampleFootprintLodNV:
1564             cracked.lod = true;
1565             break;
1566         case EOpImageSampleFootprintGradNV:
1567             cracked.grad = true;
1568             break;
1569         case EOpImageSampleFootprintGradClampNV:
1570             cracked.lodClamp = true;
1571             cracked.grad = true;
1572             break;
1573         case EOpSubpassLoad:
1574         case EOpSubpassLoadMS:
1575             cracked.subpass = true;
1576             break;
1577 #endif
1578         default:
1579             break;
1580         }
1581     }
1582 
1583 protected:
TIntermOperator(TOperator o)1584     TIntermOperator(TOperator o) : TIntermTyped(EbtFloat), op(o), operationPrecision(EpqNone) {}
TIntermOperator(TOperator o,TType & t)1585     TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o), operationPrecision(EpqNone) {}
1586     TOperator op;
1587     // The result precision is in the inherited TType, and is usually meant to be both
1588     // the operation precision and the result precision. However, some more complex things,
1589     // like built-in function calls, distinguish between the two, in which case non-EqpNone
1590     // 'operationPrecision' overrides the result precision as far as operation precision
1591     // is concerned.
1592     TPrecisionQualifier operationPrecision;
1593 };
1594 
1595 //
1596 // Nodes for all the basic binary math operators.
1597 //
1598 class TIntermBinary : public TIntermOperator {
1599 public:
TIntermBinary(TOperator o)1600     TIntermBinary(TOperator o) : TIntermOperator(o) {}
1601     virtual void traverse(TIntermTraverser*);
setLeft(TIntermTyped * n)1602     virtual void setLeft(TIntermTyped* n) { left = n; }
setRight(TIntermTyped * n)1603     virtual void setRight(TIntermTyped* n) { right = n; }
getLeft()1604     virtual TIntermTyped* getLeft() const { return left; }
getRight()1605     virtual TIntermTyped* getRight() const { return right; }
getAsBinaryNode()1606     virtual       TIntermBinary* getAsBinaryNode()       { return this; }
getAsBinaryNode()1607     virtual const TIntermBinary* getAsBinaryNode() const { return this; }
1608     virtual void updatePrecision();
1609 protected:
1610     TIntermTyped* left;
1611     TIntermTyped* right;
1612 };
1613 
1614 //
1615 // Nodes for unary math operators.
1616 //
1617 class TIntermUnary : public TIntermOperator {
1618 public:
TIntermUnary(TOperator o,TType & t)1619     TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(nullptr) {}
TIntermUnary(TOperator o)1620     TIntermUnary(TOperator o) : TIntermOperator(o), operand(nullptr) {}
1621     virtual void traverse(TIntermTraverser*);
setOperand(TIntermTyped * o)1622     virtual void setOperand(TIntermTyped* o) { operand = o; }
getOperand()1623     virtual       TIntermTyped* getOperand() { return operand; }
getOperand()1624     virtual const TIntermTyped* getOperand() const { return operand; }
getAsUnaryNode()1625     virtual       TIntermUnary* getAsUnaryNode()       { return this; }
getAsUnaryNode()1626     virtual const TIntermUnary* getAsUnaryNode() const { return this; }
1627     virtual void updatePrecision();
1628 #ifndef GLSLANG_WEB
setSpirvInstruction(const TSpirvInstruction & inst)1629     void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; }
getSpirvInstruction()1630     const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
1631 #endif
1632 protected:
1633     TIntermTyped* operand;
1634 #ifndef GLSLANG_WEB
1635     TSpirvInstruction spirvInst;
1636 #endif
1637 };
1638 
1639 typedef TVector<TIntermNode*> TIntermSequence;
1640 typedef TVector<TStorageQualifier> TQualifierList;
1641 //
1642 // Nodes that operate on an arbitrary sized set of children.
1643 //
1644 class TIntermAggregate : public TIntermOperator {
1645 public:
TIntermAggregate()1646     TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(nullptr) { }
TIntermAggregate(TOperator o)1647     TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(nullptr) { }
~TIntermAggregate()1648     ~TIntermAggregate() { delete pragmaTable; }
getAsAggregate()1649     virtual       TIntermAggregate* getAsAggregate()       { return this; }
getAsAggregate()1650     virtual const TIntermAggregate* getAsAggregate() const { return this; }
1651     virtual void updatePrecision();
setOperator(TOperator o)1652     virtual void setOperator(TOperator o) { op = o; }
getSequence()1653     virtual       TIntermSequence& getSequence()       { return sequence; }
getSequence()1654     virtual const TIntermSequence& getSequence() const { return sequence; }
setName(const TString & n)1655     virtual void setName(const TString& n) { name = n; }
getName()1656     virtual const TString& getName() const { return name; }
1657     virtual void traverse(TIntermTraverser*);
setUserDefined()1658     virtual void setUserDefined() { userDefined = true; }
isUserDefined()1659     virtual bool isUserDefined() { return userDefined; }
getQualifierList()1660     virtual TQualifierList& getQualifierList() { return qualifier; }
getQualifierList()1661     virtual const TQualifierList& getQualifierList() const { return qualifier; }
setOptimize(bool o)1662     void setOptimize(bool o) { optimize = o; }
setDebug(bool d)1663     void setDebug(bool d) { debug = d; }
getOptimize()1664     bool getOptimize() const { return optimize; }
getDebug()1665     bool getDebug() const { return debug; }
1666     void setPragmaTable(const TPragmaTable& pTable);
getPragmaTable()1667     const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
1668 #ifndef GLSLANG_WEB
setSpirvInstruction(const TSpirvInstruction & inst)1669     void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; }
getSpirvInstruction()1670     const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
1671 #endif
1672 protected:
1673     TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
1674     TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
1675     TIntermSequence sequence;
1676     TQualifierList qualifier;
1677     TString name;
1678     bool userDefined; // used for user defined function names
1679     bool optimize;
1680     bool debug;
1681     TPragmaTable* pragmaTable;
1682 #ifndef GLSLANG_WEB
1683     TSpirvInstruction spirvInst;
1684 #endif
1685 };
1686 
1687 //
1688 // For if tests.
1689 //
1690 class TIntermSelection : public TIntermTyped {
1691 public:
TIntermSelection(TIntermTyped * cond,TIntermNode * trueB,TIntermNode * falseB)1692     TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
1693         TIntermTyped(EbtVoid), condition(cond), trueBlock(trueB), falseBlock(falseB),
1694         shortCircuit(true),
1695         flatten(false), dontFlatten(false) {}
TIntermSelection(TIntermTyped * cond,TIntermNode * trueB,TIntermNode * falseB,const TType & type)1696     TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
1697         TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB),
1698         shortCircuit(true),
1699         flatten(false), dontFlatten(false) {}
1700     virtual void traverse(TIntermTraverser*);
getCondition()1701     virtual TIntermTyped* getCondition() const { return condition; }
setCondition(TIntermTyped * c)1702     virtual void setCondition(TIntermTyped* c) { condition = c; }
getTrueBlock()1703     virtual TIntermNode* getTrueBlock() const { return trueBlock; }
setTrueBlock(TIntermTyped * tb)1704     virtual void setTrueBlock(TIntermTyped* tb) { trueBlock = tb; }
getFalseBlock()1705     virtual TIntermNode* getFalseBlock() const { return falseBlock; }
setFalseBlock(TIntermTyped * fb)1706     virtual void setFalseBlock(TIntermTyped* fb) { falseBlock = fb; }
getAsSelectionNode()1707     virtual       TIntermSelection* getAsSelectionNode()       { return this; }
getAsSelectionNode()1708     virtual const TIntermSelection* getAsSelectionNode() const { return this; }
1709 
setNoShortCircuit()1710     void setNoShortCircuit() { shortCircuit = false; }
getShortCircuit()1711     bool getShortCircuit() const { return shortCircuit; }
1712 
setFlatten()1713     void setFlatten()     { flatten = true; }
setDontFlatten()1714     void setDontFlatten() { dontFlatten = true; }
getFlatten()1715     bool getFlatten()     const { return flatten; }
getDontFlatten()1716     bool getDontFlatten() const { return dontFlatten; }
1717 
1718 protected:
1719     TIntermTyped* condition;
1720     TIntermNode* trueBlock;
1721     TIntermNode* falseBlock;
1722     bool shortCircuit; // normally all if-then-else and all GLSL ?: short-circuit, but HLSL ?: does not
1723     bool flatten;      // true if flatten requested
1724     bool dontFlatten;  // true if requested to not flatten
1725 };
1726 
1727 //
1728 // For switch statements.  Designed use is that a switch will have sequence of nodes
1729 // that are either case/default nodes or a *single* node that represents all the code
1730 // in between (if any) consecutive case/defaults.  So, a traversal need only deal with
1731 // 0 or 1 nodes per case/default statement.
1732 //
1733 class TIntermSwitch : public TIntermNode {
1734 public:
TIntermSwitch(TIntermTyped * cond,TIntermAggregate * b)1735     TIntermSwitch(TIntermTyped* cond, TIntermAggregate* b) : condition(cond), body(b),
1736         flatten(false), dontFlatten(false) {}
1737     virtual void traverse(TIntermTraverser*);
getCondition()1738     virtual TIntermNode* getCondition() const { return condition; }
getBody()1739     virtual TIntermAggregate* getBody() const { return body; }
getAsSwitchNode()1740     virtual       TIntermSwitch* getAsSwitchNode()       { return this; }
getAsSwitchNode()1741     virtual const TIntermSwitch* getAsSwitchNode() const { return this; }
1742 
setFlatten()1743     void setFlatten()     { flatten = true; }
setDontFlatten()1744     void setDontFlatten() { dontFlatten = true; }
getFlatten()1745     bool getFlatten()     const { return flatten; }
getDontFlatten()1746     bool getDontFlatten() const { return dontFlatten; }
1747 
1748 protected:
1749     TIntermTyped* condition;
1750     TIntermAggregate* body;
1751     bool flatten;     // true if flatten requested
1752     bool dontFlatten; // true if requested to not flatten
1753 };
1754 
1755 enum TVisit
1756 {
1757     EvPreVisit,
1758     EvInVisit,
1759     EvPostVisit
1760 };
1761 
1762 //
1763 // For traversing the tree.  User should derive from this,
1764 // put their traversal specific data in it, and then pass
1765 // it to a Traverse method.
1766 //
1767 // When using this, just fill in the methods for nodes you want visited.
1768 // Return false from a pre-visit to skip visiting that node's subtree.
1769 //
1770 // Explicitly set postVisit to true if you want post visiting, otherwise,
1771 // filled in methods will only be called at pre-visit time (before processing
1772 // the subtree).  Similarly for inVisit for in-order visiting of nodes with
1773 // multiple children.
1774 //
1775 // If you only want post-visits, explicitly turn off preVisit (and inVisit)
1776 // and turn on postVisit.
1777 //
1778 // In general, for the visit*() methods, return true from interior nodes
1779 // to have the traversal continue on to children.
1780 //
1781 // If you process children yourself, or don't want them processed, return false.
1782 //
1783 class TIntermTraverser {
1784 public:
POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator ())1785     POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator())
1786     TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
1787             preVisit(preVisit),
1788             inVisit(inVisit),
1789             postVisit(postVisit),
1790             rightToLeft(rightToLeft),
1791             depth(0),
1792             maxDepth(0) { }
~TIntermTraverser()1793     virtual ~TIntermTraverser() { }
1794 
visitSymbol(TIntermSymbol *)1795     virtual void visitSymbol(TIntermSymbol*)               { }
visitConstantUnion(TIntermConstantUnion *)1796     virtual void visitConstantUnion(TIntermConstantUnion*) { }
visitBinary(TVisit,TIntermBinary *)1797     virtual bool visitBinary(TVisit, TIntermBinary*)       { return true; }
visitUnary(TVisit,TIntermUnary *)1798     virtual bool visitUnary(TVisit, TIntermUnary*)         { return true; }
visitSelection(TVisit,TIntermSelection *)1799     virtual bool visitSelection(TVisit, TIntermSelection*) { return true; }
visitAggregate(TVisit,TIntermAggregate *)1800     virtual bool visitAggregate(TVisit, TIntermAggregate*) { return true; }
visitLoop(TVisit,TIntermLoop *)1801     virtual bool visitLoop(TVisit, TIntermLoop*)           { return true; }
visitBranch(TVisit,TIntermBranch *)1802     virtual bool visitBranch(TVisit, TIntermBranch*)       { return true; }
visitSwitch(TVisit,TIntermSwitch *)1803     virtual bool visitSwitch(TVisit, TIntermSwitch*)       { return true; }
1804 
getMaxDepth()1805     int getMaxDepth() const { return maxDepth; }
1806 
incrementDepth(TIntermNode * current)1807     void incrementDepth(TIntermNode *current)
1808     {
1809         depth++;
1810         maxDepth = (std::max)(maxDepth, depth);
1811         path.push_back(current);
1812     }
1813 
decrementDepth()1814     void decrementDepth()
1815     {
1816         depth--;
1817         path.pop_back();
1818     }
1819 
getParentNode()1820     TIntermNode *getParentNode()
1821     {
1822         return path.size() == 0 ? nullptr : path.back();
1823     }
1824 
1825     const bool preVisit;
1826     const bool inVisit;
1827     const bool postVisit;
1828     const bool rightToLeft;
1829 
1830 protected:
1831     TIntermTraverser& operator=(TIntermTraverser&);
1832 
1833     int depth;
1834     int maxDepth;
1835 
1836     // All the nodes from root to the current node's parent during traversing.
1837     TVector<TIntermNode *> path;
1838 };
1839 
1840 // KHR_vulkan_glsl says "Two arrays sized with specialization constants are the same type only if
1841 // sized with the same symbol, involving no operations"
SameSpecializationConstants(TIntermTyped * node1,TIntermTyped * node2)1842 inline bool SameSpecializationConstants(TIntermTyped* node1, TIntermTyped* node2)
1843 {
1844     return node1->getAsSymbolNode() && node2->getAsSymbolNode() &&
1845            node1->getAsSymbolNode()->getId() == node2->getAsSymbolNode()->getId();
1846 }
1847 
1848 } // end namespace glslang
1849 
1850 #endif // __INTERMEDIATE_H
1851