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