• 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, 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     // Image processing2
1116     EOpImageBlockMatchWindowSSDQCOM,
1117     EOpImageBlockMatchWindowSADQCOM,
1118     EOpImageBlockMatchGatherSSDQCOM,
1119     EOpImageBlockMatchGatherSADQCOM,
1120 };
1121 
1122 enum TLinkType {
1123     ELinkNone,
1124     ELinkExport,
1125 };
1126 
1127 class TIntermTraverser;
1128 class TIntermOperator;
1129 class TIntermAggregate;
1130 class TIntermUnary;
1131 class TIntermBinary;
1132 class TIntermConstantUnion;
1133 class TIntermSelection;
1134 class TIntermSwitch;
1135 class TIntermBranch;
1136 class TIntermTyped;
1137 class TIntermMethod;
1138 class TIntermSymbol;
1139 class TIntermLoop;
1140 
1141 } // end namespace glslang
1142 
1143 //
1144 // Base class for the tree nodes
1145 //
1146 // (Put outside the glslang namespace, as it's used as part of the external interface.)
1147 //
1148 class TIntermNode {
1149 public:
POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator ())1150     POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator())
1151 
1152     TIntermNode() { loc.init(); }
getLoc()1153     virtual const glslang::TSourceLoc& getLoc() const { return loc; }
setLoc(const glslang::TSourceLoc & l)1154     virtual void setLoc(const glslang::TSourceLoc& l) { loc = l; }
1155     virtual void traverse(glslang::TIntermTraverser*) = 0;
getAsTyped()1156     virtual       glslang::TIntermTyped*         getAsTyped()               { return nullptr; }
getAsOperator()1157     virtual       glslang::TIntermOperator*      getAsOperator()            { return nullptr; }
getAsConstantUnion()1158     virtual       glslang::TIntermConstantUnion* getAsConstantUnion()       { return nullptr; }
getAsAggregate()1159     virtual       glslang::TIntermAggregate*     getAsAggregate()           { return nullptr; }
getAsUnaryNode()1160     virtual       glslang::TIntermUnary*         getAsUnaryNode()           { return nullptr; }
getAsBinaryNode()1161     virtual       glslang::TIntermBinary*        getAsBinaryNode()          { return nullptr; }
getAsSelectionNode()1162     virtual       glslang::TIntermSelection*     getAsSelectionNode()       { return nullptr; }
getAsSwitchNode()1163     virtual       glslang::TIntermSwitch*        getAsSwitchNode()          { return nullptr; }
getAsMethodNode()1164     virtual       glslang::TIntermMethod*        getAsMethodNode()          { return nullptr; }
getAsSymbolNode()1165     virtual       glslang::TIntermSymbol*        getAsSymbolNode()          { return nullptr; }
getAsBranchNode()1166     virtual       glslang::TIntermBranch*        getAsBranchNode()          { return nullptr; }
getAsLoopNode()1167     virtual       glslang::TIntermLoop*          getAsLoopNode()            { return nullptr; }
1168 
getAsTyped()1169     virtual const glslang::TIntermTyped*         getAsTyped()         const { return nullptr; }
getAsOperator()1170     virtual const glslang::TIntermOperator*      getAsOperator()      const { return nullptr; }
getAsConstantUnion()1171     virtual const glslang::TIntermConstantUnion* getAsConstantUnion() const { return nullptr; }
getAsAggregate()1172     virtual const glslang::TIntermAggregate*     getAsAggregate()     const { return nullptr; }
getAsUnaryNode()1173     virtual const glslang::TIntermUnary*         getAsUnaryNode()     const { return nullptr; }
getAsBinaryNode()1174     virtual const glslang::TIntermBinary*        getAsBinaryNode()    const { return nullptr; }
getAsSelectionNode()1175     virtual const glslang::TIntermSelection*     getAsSelectionNode() const { return nullptr; }
getAsSwitchNode()1176     virtual const glslang::TIntermSwitch*        getAsSwitchNode()    const { return nullptr; }
getAsMethodNode()1177     virtual const glslang::TIntermMethod*        getAsMethodNode()    const { return nullptr; }
getAsSymbolNode()1178     virtual const glslang::TIntermSymbol*        getAsSymbolNode()    const { return nullptr; }
getAsBranchNode()1179     virtual const glslang::TIntermBranch*        getAsBranchNode()    const { return nullptr; }
getAsLoopNode()1180     virtual const glslang::TIntermLoop*          getAsLoopNode()      const { return nullptr; }
~TIntermNode()1181     virtual ~TIntermNode() { }
1182 
1183 protected:
1184     TIntermNode(const TIntermNode&);
1185     TIntermNode& operator=(const TIntermNode&);
1186     glslang::TSourceLoc loc;
1187 };
1188 
1189 namespace glslang {
1190 
1191 //
1192 // This is just to help yacc.
1193 //
1194 struct TIntermNodePair {
1195     TIntermNode* node1;
1196     TIntermNode* node2;
1197 };
1198 
1199 //
1200 // Intermediate class for nodes that have a type.
1201 //
1202 class TIntermTyped : public TIntermNode {
1203 public:
TIntermTyped(const TType & t)1204     TIntermTyped(const TType& t) { type.shallowCopy(t); }
TIntermTyped(TBasicType basicType)1205     TIntermTyped(TBasicType basicType) { TType bt(basicType); type.shallowCopy(bt); }
getAsTyped()1206     virtual       TIntermTyped* getAsTyped()       { return this; }
getAsTyped()1207     virtual const TIntermTyped* getAsTyped() const { return this; }
setType(const TType & t)1208     virtual void setType(const TType& t) { type.shallowCopy(t); }
getType()1209     virtual const TType& getType() const { return type; }
getWritableType()1210     virtual TType& getWritableType() { return type; }
1211 
getBasicType()1212     virtual TBasicType getBasicType() const { return type.getBasicType(); }
getQualifier()1213     virtual TQualifier& getQualifier() { return type.getQualifier(); }
getQualifier()1214     virtual const TQualifier& getQualifier() const { return type.getQualifier(); }
getArraySizes()1215     virtual TArraySizes* getArraySizes() { return type.getArraySizes(); }
getArraySizes()1216     virtual const TArraySizes* getArraySizes() const { return type.getArraySizes(); }
1217     virtual void propagatePrecision(TPrecisionQualifier);
getVectorSize()1218     virtual int getVectorSize() const { return type.getVectorSize(); }
getMatrixCols()1219     virtual int getMatrixCols() const { return type.getMatrixCols(); }
getMatrixRows()1220     virtual int getMatrixRows() const { return type.getMatrixRows(); }
isMatrix()1221     virtual bool isMatrix() const { return type.isMatrix(); }
isArray()1222     virtual bool isArray()  const { return type.isArray(); }
isVector()1223     virtual bool isVector() const { return type.isVector(); }
isScalar()1224     virtual bool isScalar() const { return type.isScalar(); }
isStruct()1225     virtual bool isStruct() const { return type.isStruct(); }
isFloatingDomain()1226     virtual bool isFloatingDomain() const { return type.isFloatingDomain(); }
isIntegerDomain()1227     virtual bool isIntegerDomain() const { return type.isIntegerDomain(); }
isAtomic()1228     bool isAtomic() const { return type.isAtomic(); }
isReference()1229     bool isReference() const { return type.isReference(); }
1230     TString getCompleteString(bool enhanced = false) const { return type.getCompleteString(enhanced); }
1231 
1232 protected:
1233     TIntermTyped& operator=(const TIntermTyped&);
1234     TType type;
1235 };
1236 
1237 //
1238 // Handle for, do-while, and while loops.
1239 //
1240 class TIntermLoop : public TIntermNode {
1241 public:
TIntermLoop(TIntermNode * aBody,TIntermTyped * aTest,TIntermTyped * aTerminal,bool testFirst)1242     TIntermLoop(TIntermNode* aBody, TIntermTyped* aTest, TIntermTyped* aTerminal, bool testFirst) :
1243         body(aBody),
1244         test(aTest),
1245         terminal(aTerminal),
1246         first(testFirst),
1247         unroll(false),
1248         dontUnroll(false),
1249         dependency(0),
1250         minIterations(0),
1251         maxIterations(iterationsInfinite),
1252         iterationMultiple(1),
1253         peelCount(0),
1254         partialCount(0)
1255     { }
1256 
getAsLoopNode()1257     virtual       TIntermLoop* getAsLoopNode() { return this; }
getAsLoopNode()1258     virtual const TIntermLoop* getAsLoopNode() const { return this; }
1259     virtual void traverse(TIntermTraverser*);
getBody()1260     TIntermNode*  getBody() const { return body; }
getTest()1261     TIntermTyped* getTest() const { return test; }
getTerminal()1262     TIntermTyped* getTerminal() const { return terminal; }
testFirst()1263     bool testFirst() const { return first; }
1264 
setUnroll()1265     void setUnroll()     { unroll = true; }
setDontUnroll()1266     void setDontUnroll() {
1267         dontUnroll = true;
1268         peelCount = 0;
1269         partialCount = 0;
1270     }
getUnroll()1271     bool getUnroll()     const { return unroll; }
getDontUnroll()1272     bool getDontUnroll() const { return dontUnroll; }
1273 
1274     static const unsigned int dependencyInfinite = 0xFFFFFFFF;
1275     static const unsigned int iterationsInfinite = 0xFFFFFFFF;
setLoopDependency(int d)1276     void setLoopDependency(int d) { dependency = d; }
getLoopDependency()1277     int getLoopDependency() const { return dependency; }
1278 
setMinIterations(unsigned int v)1279     void setMinIterations(unsigned int v) { minIterations = v; }
getMinIterations()1280     unsigned int getMinIterations() const { return minIterations; }
setMaxIterations(unsigned int v)1281     void setMaxIterations(unsigned int v) { maxIterations = v; }
getMaxIterations()1282     unsigned int getMaxIterations() const { return maxIterations; }
setIterationMultiple(unsigned int v)1283     void setIterationMultiple(unsigned int v) { iterationMultiple = v; }
getIterationMultiple()1284     unsigned int getIterationMultiple() const { return iterationMultiple; }
setPeelCount(unsigned int v)1285     void setPeelCount(unsigned int v) {
1286         peelCount = v;
1287         dontUnroll = false;
1288     }
getPeelCount()1289     unsigned int getPeelCount() const { return peelCount; }
setPartialCount(unsigned int v)1290     void setPartialCount(unsigned int v) {
1291         partialCount = v;
1292         dontUnroll = false;
1293     }
getPartialCount()1294     unsigned int getPartialCount() const { return partialCount; }
1295 
1296 protected:
1297     TIntermNode* body;       // code to loop over
1298     TIntermTyped* test;      // exit condition associated with loop, could be 0 for 'for' loops
1299     TIntermTyped* terminal;  // exists for for-loops
1300     bool first;              // true for while and for, not for do-while
1301     bool unroll;             // true if unroll requested
1302     bool dontUnroll;         // true if request to not unroll
1303     unsigned int dependency; // loop dependency hint; 0 means not set or unknown
1304     unsigned int minIterations;      // as per the SPIR-V specification
1305     unsigned int maxIterations;      // as per the SPIR-V specification
1306     unsigned int iterationMultiple;  // as per the SPIR-V specification
1307     unsigned int peelCount;          // as per the SPIR-V specification
1308     unsigned int partialCount;       // as per the SPIR-V specification
1309 };
1310 
1311 //
1312 // Handle case, break, continue, return, and kill.
1313 //
1314 class TIntermBranch : public TIntermNode {
1315 public:
TIntermBranch(TOperator op,TIntermTyped * e)1316     TIntermBranch(TOperator op, TIntermTyped* e) :
1317         flowOp(op),
1318         expression(e) { }
getAsBranchNode()1319     virtual       TIntermBranch* getAsBranchNode()       { return this; }
getAsBranchNode()1320     virtual const TIntermBranch* getAsBranchNode() const { return this; }
1321     virtual void traverse(TIntermTraverser*);
getFlowOp()1322     TOperator getFlowOp() const { return flowOp; }
getExpression()1323     TIntermTyped* getExpression() const { return expression; }
setExpression(TIntermTyped * pExpression)1324     void setExpression(TIntermTyped* pExpression) { expression = pExpression; }
1325     void updatePrecision(TPrecisionQualifier parentPrecision);
1326 protected:
1327     TOperator flowOp;
1328     TIntermTyped* expression;
1329 };
1330 
1331 //
1332 // Represent method names before seeing their calling signature
1333 // or resolving them to operations.  Just an expression as the base object
1334 // and a textural name.
1335 //
1336 class TIntermMethod : public TIntermTyped {
1337 public:
TIntermMethod(TIntermTyped * o,const TType & t,const TString & m)1338     TIntermMethod(TIntermTyped* o, const TType& t, const TString& m) : TIntermTyped(t), object(o), method(m) { }
getAsMethodNode()1339     virtual       TIntermMethod* getAsMethodNode()       { return this; }
getAsMethodNode()1340     virtual const TIntermMethod* getAsMethodNode() const { return this; }
getMethodName()1341     virtual const TString& getMethodName() const { return method; }
getObject()1342     virtual TIntermTyped* getObject() const { return object; }
1343     virtual void traverse(TIntermTraverser*);
setExport()1344     void setExport() { linkType = ELinkExport; }
1345 protected:
1346     TIntermTyped* object;
1347     TString method;
1348     TLinkType linkType;
1349 };
1350 
1351 //
1352 // Nodes that correspond to symbols or constants in the source code.
1353 //
1354 class TIntermSymbol : public TIntermTyped {
1355 public:
1356     // if symbol is initialized as symbol(sym), the memory comes from the pool allocator of sym. If sym comes from
1357     // per process threadPoolAllocator, then it causes increased memory usage per compile
1358     // it is essential to use "symbol = sym" to assign to symbol
TIntermSymbol(long long i,const TString & n,const TType & t)1359     TIntermSymbol(long long i, const TString& n, const TType& t)
1360         : TIntermTyped(t), id(i), flattenSubset(-1), constSubtree(nullptr) { name = n; }
getId()1361     virtual long long getId() const { return id; }
changeId(long long i)1362     virtual void changeId(long long i) { id = i; }
getName()1363     virtual const TString& getName() const { return name; }
1364     virtual void traverse(TIntermTraverser*);
getAsSymbolNode()1365     virtual       TIntermSymbol* getAsSymbolNode()       { return this; }
getAsSymbolNode()1366     virtual const TIntermSymbol* getAsSymbolNode() const { return this; }
setConstArray(const TConstUnionArray & c)1367     void setConstArray(const TConstUnionArray& c) { constArray = c; }
getConstArray()1368     const TConstUnionArray& getConstArray() const { return constArray; }
setConstSubtree(TIntermTyped * subtree)1369     void setConstSubtree(TIntermTyped* subtree) { constSubtree = subtree; }
getConstSubtree()1370     TIntermTyped* getConstSubtree() const { return constSubtree; }
setFlattenSubset(int subset)1371     void setFlattenSubset(int subset) { flattenSubset = subset; }
1372     virtual const TString& getAccessName() const;
1373 
getFlattenSubset()1374     int getFlattenSubset() const { return flattenSubset; } // -1 means full object
1375 
1376     // This is meant for cases where a node has already been constructed, and
1377     // later on, it becomes necessary to switch to a different symbol.
switchId(long long newId)1378     virtual void switchId(long long newId) { id = newId; }
1379 
1380 protected:
1381     long long id;                // the unique id of the symbol this node represents
1382     int flattenSubset;           // how deeply the flattened object rooted at id has been dereferenced
1383     TString name;                // the name of the symbol this node represents
1384     TConstUnionArray constArray; // if the symbol is a front-end compile-time constant, this is its value
1385     TIntermTyped* constSubtree;
1386 };
1387 
1388 class TIntermConstantUnion : public TIntermTyped {
1389 public:
TIntermConstantUnion(const TConstUnionArray & ua,const TType & t)1390     TIntermConstantUnion(const TConstUnionArray& ua, const TType& t) : TIntermTyped(t), constArray(ua), literal(false) { }
getConstArray()1391     const TConstUnionArray& getConstArray() const { return constArray; }
getAsConstantUnion()1392     virtual       TIntermConstantUnion* getAsConstantUnion()       { return this; }
getAsConstantUnion()1393     virtual const TIntermConstantUnion* getAsConstantUnion() const { return this; }
1394     virtual void traverse(TIntermTraverser*);
1395     virtual TIntermTyped* fold(TOperator, const TIntermTyped*) const;
1396     virtual TIntermTyped* fold(TOperator, const TType&) const;
setLiteral()1397     void setLiteral() { literal = true; }
setExpression()1398     void setExpression() { literal = false; }
isLiteral()1399     bool isLiteral() const { return literal; }
1400 
1401 protected:
1402     TIntermConstantUnion& operator=(const TIntermConstantUnion&);
1403 
1404     const TConstUnionArray constArray;
1405     bool literal;  // true if node represents a literal in the source code
1406 };
1407 
1408 // Represent the independent aspects of a texturing TOperator
1409 struct TCrackedTextureOp {
1410     bool query;
1411     bool proj;
1412     bool lod;
1413     bool fetch;
1414     bool offset;
1415     bool offsets;
1416     bool gather;
1417     bool grad;
1418     bool subpass;
1419     bool lodClamp;
1420     bool fragMask;
1421     bool attachmentEXT;
1422 };
1423 
1424 //
1425 // Intermediate class for node types that hold operators.
1426 //
1427 class TIntermOperator : public TIntermTyped {
1428 public:
getAsOperator()1429     virtual       TIntermOperator* getAsOperator()       { return this; }
getAsOperator()1430     virtual const TIntermOperator* getAsOperator() const { return this; }
getOp()1431     TOperator getOp() const { return op; }
setOp(TOperator newOp)1432     void setOp(TOperator newOp) { op = newOp; }
1433     bool modifiesState() const;
1434     bool isConstructor() const;
isTexture()1435     bool isTexture()  const { return op > EOpTextureGuardBegin  && op < EOpTextureGuardEnd; }
isSampling()1436     bool isSampling() const { return op > EOpSamplingGuardBegin && op < EOpSamplingGuardEnd; }
isImage()1437     bool isImage()    const { return op > EOpImageGuardBegin    && op < EOpImageGuardEnd; }
isSparseTexture()1438     bool isSparseTexture() const { return op > EOpSparseTextureGuardBegin && op < EOpSparseTextureGuardEnd; }
isImageFootprint()1439     bool isImageFootprint() const { return op > EOpImageFootprintGuardBegin && op < EOpImageFootprintGuardEnd; }
isSparseImage()1440     bool isSparseImage()   const { return op == EOpSparseImageLoad; }
isSubgroup()1441     bool isSubgroup() const { return op > EOpSubgroupGuardStart && op < EOpSubgroupGuardStop; }
1442 
setOperationPrecision(TPrecisionQualifier p)1443     void setOperationPrecision(TPrecisionQualifier p) { operationPrecision = p; }
getOperationPrecision()1444     TPrecisionQualifier getOperationPrecision() const { return operationPrecision != EpqNone ?
1445                                                                                      operationPrecision :
1446                                                                                      type.getQualifier().precision; }
getCompleteString()1447     TString getCompleteString() const
1448     {
1449         TString cs = type.getCompleteString();
1450         if (getOperationPrecision() != type.getQualifier().precision) {
1451             cs += ", operation at ";
1452             cs += GetPrecisionQualifierString(getOperationPrecision());
1453         }
1454 
1455         return cs;
1456     }
1457 
1458     // Crack the op into the individual dimensions of texturing operation.
crackTexture(TSampler sampler,TCrackedTextureOp & cracked)1459     void crackTexture(TSampler sampler, TCrackedTextureOp& cracked) const
1460     {
1461         cracked.query = false;
1462         cracked.proj = false;
1463         cracked.lod = false;
1464         cracked.fetch = false;
1465         cracked.offset = false;
1466         cracked.offsets = false;
1467         cracked.gather = false;
1468         cracked.grad = false;
1469         cracked.subpass = false;
1470         cracked.attachmentEXT = false;
1471         cracked.lodClamp = false;
1472         cracked.fragMask = false;
1473 
1474         switch (op) {
1475         case EOpImageQuerySize:
1476         case EOpImageQuerySamples:
1477         case EOpTextureQuerySize:
1478         case EOpTextureQueryLod:
1479         case EOpTextureQueryLevels:
1480         case EOpTextureQuerySamples:
1481         case EOpSparseTexelsResident:
1482             cracked.query = true;
1483             break;
1484         case EOpTexture:
1485         case EOpSparseTexture:
1486             break;
1487         case EOpTextureProj:
1488             cracked.proj = true;
1489             break;
1490         case EOpTextureLod:
1491         case EOpSparseTextureLod:
1492             cracked.lod = true;
1493             break;
1494         case EOpTextureOffset:
1495         case EOpSparseTextureOffset:
1496             cracked.offset = true;
1497             break;
1498         case EOpTextureFetch:
1499         case EOpSparseTextureFetch:
1500             cracked.fetch = true;
1501             if (sampler.is1D() || (sampler.dim == Esd2D && ! sampler.isMultiSample()) || sampler.dim == Esd3D)
1502                 cracked.lod = true;
1503             break;
1504         case EOpTextureFetchOffset:
1505         case EOpSparseTextureFetchOffset:
1506             cracked.fetch = true;
1507             cracked.offset = true;
1508             if (sampler.is1D() || (sampler.dim == Esd2D && ! sampler.isMultiSample()) || sampler.dim == Esd3D)
1509                 cracked.lod = true;
1510             break;
1511         case EOpTextureProjOffset:
1512             cracked.offset = true;
1513             cracked.proj = true;
1514             break;
1515         case EOpTextureLodOffset:
1516         case EOpSparseTextureLodOffset:
1517             cracked.offset = true;
1518             cracked.lod = true;
1519             break;
1520         case EOpTextureProjLod:
1521             cracked.lod = true;
1522             cracked.proj = true;
1523             break;
1524         case EOpTextureProjLodOffset:
1525             cracked.offset = true;
1526             cracked.lod = true;
1527             cracked.proj = true;
1528             break;
1529         case EOpTextureGrad:
1530         case EOpSparseTextureGrad:
1531             cracked.grad = true;
1532             break;
1533         case EOpTextureGradOffset:
1534         case EOpSparseTextureGradOffset:
1535             cracked.grad = true;
1536             cracked.offset = true;
1537             break;
1538         case EOpTextureProjGrad:
1539             cracked.grad = true;
1540             cracked.proj = true;
1541             break;
1542         case EOpTextureProjGradOffset:
1543             cracked.grad = true;
1544             cracked.offset = true;
1545             cracked.proj = true;
1546             break;
1547         case EOpTextureClamp:
1548         case EOpSparseTextureClamp:
1549             cracked.lodClamp = true;
1550             break;
1551         case EOpTextureOffsetClamp:
1552         case EOpSparseTextureOffsetClamp:
1553             cracked.offset = true;
1554             cracked.lodClamp = true;
1555             break;
1556         case EOpTextureGradClamp:
1557         case EOpSparseTextureGradClamp:
1558             cracked.grad = true;
1559             cracked.lodClamp = true;
1560             break;
1561         case EOpTextureGradOffsetClamp:
1562         case EOpSparseTextureGradOffsetClamp:
1563             cracked.grad = true;
1564             cracked.offset = true;
1565             cracked.lodClamp = true;
1566             break;
1567         case EOpTextureGather:
1568         case EOpSparseTextureGather:
1569             cracked.gather = true;
1570             break;
1571         case EOpTextureGatherOffset:
1572         case EOpSparseTextureGatherOffset:
1573             cracked.gather = true;
1574             cracked.offset = true;
1575             break;
1576         case EOpTextureGatherOffsets:
1577         case EOpSparseTextureGatherOffsets:
1578             cracked.gather = true;
1579             cracked.offsets = true;
1580             break;
1581         case EOpTextureGatherLod:
1582         case EOpSparseTextureGatherLod:
1583             cracked.gather = true;
1584             cracked.lod    = true;
1585             break;
1586         case EOpTextureGatherLodOffset:
1587         case EOpSparseTextureGatherLodOffset:
1588             cracked.gather = true;
1589             cracked.offset = true;
1590             cracked.lod    = true;
1591             break;
1592         case EOpTextureGatherLodOffsets:
1593         case EOpSparseTextureGatherLodOffsets:
1594             cracked.gather  = true;
1595             cracked.offsets = true;
1596             cracked.lod     = true;
1597             break;
1598         case EOpImageLoadLod:
1599         case EOpImageStoreLod:
1600         case EOpSparseImageLoadLod:
1601             cracked.lod = true;
1602             break;
1603         case EOpFragmentMaskFetch:
1604             cracked.subpass = sampler.dim == EsdSubpass;
1605             cracked.fragMask = true;
1606             break;
1607         case EOpFragmentFetch:
1608             cracked.subpass = sampler.dim == EsdSubpass;
1609             cracked.fragMask = true;
1610             break;
1611         case EOpImageSampleFootprintNV:
1612             break;
1613         case EOpImageSampleFootprintClampNV:
1614             cracked.lodClamp = true;
1615             break;
1616         case EOpImageSampleFootprintLodNV:
1617             cracked.lod = true;
1618             break;
1619         case EOpImageSampleFootprintGradNV:
1620             cracked.grad = true;
1621             break;
1622         case EOpImageSampleFootprintGradClampNV:
1623             cracked.lodClamp = true;
1624             cracked.grad = true;
1625             break;
1626         case EOpSubpassLoad:
1627         case EOpSubpassLoadMS:
1628             cracked.subpass = true;
1629             break;
1630         case EOpColorAttachmentReadEXT:
1631             cracked.attachmentEXT = true;
1632             break;
1633         default:
1634             break;
1635         }
1636     }
1637 
1638 protected:
TIntermOperator(TOperator o)1639     TIntermOperator(TOperator o) : TIntermTyped(EbtFloat), op(o), operationPrecision(EpqNone) {}
TIntermOperator(TOperator o,TType & t)1640     TIntermOperator(TOperator o, TType& t) : TIntermTyped(t), op(o), operationPrecision(EpqNone) {}
1641     TOperator op;
1642     // The result precision is in the inherited TType, and is usually meant to be both
1643     // the operation precision and the result precision. However, some more complex things,
1644     // like built-in function calls, distinguish between the two, in which case non-EqpNone
1645     // 'operationPrecision' overrides the result precision as far as operation precision
1646     // is concerned.
1647     TPrecisionQualifier operationPrecision;
1648 };
1649 
1650 //
1651 // Nodes for all the basic binary math operators.
1652 //
1653 class TIntermBinary : public TIntermOperator {
1654 public:
TIntermBinary(TOperator o)1655     TIntermBinary(TOperator o) : TIntermOperator(o) {}
1656     virtual void traverse(TIntermTraverser*);
setLeft(TIntermTyped * n)1657     virtual void setLeft(TIntermTyped* n) { left = n; }
setRight(TIntermTyped * n)1658     virtual void setRight(TIntermTyped* n) { right = n; }
getLeft()1659     virtual TIntermTyped* getLeft() const { return left; }
getRight()1660     virtual TIntermTyped* getRight() const { return right; }
getAsBinaryNode()1661     virtual       TIntermBinary* getAsBinaryNode()       { return this; }
getAsBinaryNode()1662     virtual const TIntermBinary* getAsBinaryNode() const { return this; }
1663     virtual void updatePrecision();
1664 protected:
1665     TIntermTyped* left;
1666     TIntermTyped* right;
1667 };
1668 
1669 //
1670 // Nodes for unary math operators.
1671 //
1672 class TIntermUnary : public TIntermOperator {
1673 public:
TIntermUnary(TOperator o,TType & t)1674     TIntermUnary(TOperator o, TType& t) : TIntermOperator(o, t), operand(nullptr) {}
TIntermUnary(TOperator o)1675     TIntermUnary(TOperator o) : TIntermOperator(o), operand(nullptr) {}
1676     virtual void traverse(TIntermTraverser*);
setOperand(TIntermTyped * o)1677     virtual void setOperand(TIntermTyped* o) { operand = o; }
getOperand()1678     virtual       TIntermTyped* getOperand() { return operand; }
getOperand()1679     virtual const TIntermTyped* getOperand() const { return operand; }
getAsUnaryNode()1680     virtual       TIntermUnary* getAsUnaryNode()       { return this; }
getAsUnaryNode()1681     virtual const TIntermUnary* getAsUnaryNode() const { return this; }
1682     virtual void updatePrecision();
setSpirvInstruction(const TSpirvInstruction & inst)1683     void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; }
getSpirvInstruction()1684     const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
1685 protected:
1686     TIntermTyped* operand;
1687     TSpirvInstruction spirvInst;
1688 };
1689 
1690 typedef TVector<TIntermNode*> TIntermSequence;
1691 typedef TVector<TStorageQualifier> TQualifierList;
1692 //
1693 // Nodes that operate on an arbitrary sized set of children.
1694 //
1695 class TIntermAggregate : public TIntermOperator {
1696 public:
TIntermAggregate()1697     TIntermAggregate() : TIntermOperator(EOpNull), userDefined(false), pragmaTable(nullptr) { }
TIntermAggregate(TOperator o)1698     TIntermAggregate(TOperator o) : TIntermOperator(o), pragmaTable(nullptr) { }
~TIntermAggregate()1699     ~TIntermAggregate() { delete pragmaTable; }
getAsAggregate()1700     virtual       TIntermAggregate* getAsAggregate()       { return this; }
getAsAggregate()1701     virtual const TIntermAggregate* getAsAggregate() const { return this; }
1702     virtual void updatePrecision();
setOperator(TOperator o)1703     virtual void setOperator(TOperator o) { op = o; }
getSequence()1704     virtual       TIntermSequence& getSequence()       { return sequence; }
getSequence()1705     virtual const TIntermSequence& getSequence() const { return sequence; }
setName(const TString & n)1706     virtual void setName(const TString& n) { name = n; }
getName()1707     virtual const TString& getName() const { return name; }
1708     virtual void traverse(TIntermTraverser*);
setUserDefined()1709     virtual void setUserDefined() { userDefined = true; }
isUserDefined()1710     virtual bool isUserDefined() { return userDefined; }
getQualifierList()1711     virtual TQualifierList& getQualifierList() { return qualifier; }
getQualifierList()1712     virtual const TQualifierList& getQualifierList() const { return qualifier; }
setOptimize(bool o)1713     void setOptimize(bool o) { optimize = o; }
setDebug(bool d)1714     void setDebug(bool d) { debug = d; }
getOptimize()1715     bool getOptimize() const { return optimize; }
getDebug()1716     bool getDebug() const { return debug; }
1717     void setPragmaTable(const TPragmaTable& pTable);
getPragmaTable()1718     const TPragmaTable& getPragmaTable() const { return *pragmaTable; }
setSpirvInstruction(const TSpirvInstruction & inst)1719     void setSpirvInstruction(const TSpirvInstruction& inst) { spirvInst = inst; }
getSpirvInstruction()1720     const TSpirvInstruction& getSpirvInstruction() const { return spirvInst; }
1721 
setLinkType(TLinkType l)1722     void setLinkType(TLinkType l) { linkType = l; }
getLinkType()1723     TLinkType getLinkType() const { return linkType; }
1724 protected:
1725     TIntermAggregate(const TIntermAggregate&); // disallow copy constructor
1726     TIntermAggregate& operator=(const TIntermAggregate&); // disallow assignment operator
1727     TIntermSequence sequence;
1728     TQualifierList qualifier;
1729     TString name;
1730     bool userDefined; // used for user defined function names
1731     bool optimize;
1732     bool debug;
1733     TPragmaTable* pragmaTable;
1734     TSpirvInstruction spirvInst;
1735     TLinkType linkType = ELinkNone;
1736 };
1737 
1738 //
1739 // For if tests.
1740 //
1741 class TIntermSelection : public TIntermTyped {
1742 public:
TIntermSelection(TIntermTyped * cond,TIntermNode * trueB,TIntermNode * falseB)1743     TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB) :
1744         TIntermTyped(EbtVoid), condition(cond), trueBlock(trueB), falseBlock(falseB),
1745         shortCircuit(true),
1746         flatten(false), dontFlatten(false) {}
TIntermSelection(TIntermTyped * cond,TIntermNode * trueB,TIntermNode * falseB,const TType & type)1747     TIntermSelection(TIntermTyped* cond, TIntermNode* trueB, TIntermNode* falseB, const TType& type) :
1748         TIntermTyped(type), condition(cond), trueBlock(trueB), falseBlock(falseB),
1749         shortCircuit(true),
1750         flatten(false), dontFlatten(false) {}
1751     virtual void traverse(TIntermTraverser*);
getCondition()1752     virtual TIntermTyped* getCondition() const { return condition; }
setCondition(TIntermTyped * c)1753     virtual void setCondition(TIntermTyped* c) { condition = c; }
getTrueBlock()1754     virtual TIntermNode* getTrueBlock() const { return trueBlock; }
setTrueBlock(TIntermTyped * tb)1755     virtual void setTrueBlock(TIntermTyped* tb) { trueBlock = tb; }
getFalseBlock()1756     virtual TIntermNode* getFalseBlock() const { return falseBlock; }
setFalseBlock(TIntermTyped * fb)1757     virtual void setFalseBlock(TIntermTyped* fb) { falseBlock = fb; }
getAsSelectionNode()1758     virtual       TIntermSelection* getAsSelectionNode()       { return this; }
getAsSelectionNode()1759     virtual const TIntermSelection* getAsSelectionNode() const { return this; }
1760 
setNoShortCircuit()1761     void setNoShortCircuit() { shortCircuit = false; }
getShortCircuit()1762     bool getShortCircuit() const { return shortCircuit; }
1763 
setFlatten()1764     void setFlatten()     { flatten = true; }
setDontFlatten()1765     void setDontFlatten() { dontFlatten = true; }
getFlatten()1766     bool getFlatten()     const { return flatten; }
getDontFlatten()1767     bool getDontFlatten() const { return dontFlatten; }
1768 
1769 protected:
1770     TIntermTyped* condition;
1771     TIntermNode* trueBlock;
1772     TIntermNode* falseBlock;
1773     bool shortCircuit; // normally all if-then-else and all GLSL ?: short-circuit, but HLSL ?: does not
1774     bool flatten;      // true if flatten requested
1775     bool dontFlatten;  // true if requested to not flatten
1776 };
1777 
1778 //
1779 // For switch statements.  Designed use is that a switch will have sequence of nodes
1780 // that are either case/default nodes or a *single* node that represents all the code
1781 // in between (if any) consecutive case/defaults.  So, a traversal need only deal with
1782 // 0 or 1 nodes per case/default statement.
1783 //
1784 class TIntermSwitch : public TIntermNode {
1785 public:
TIntermSwitch(TIntermTyped * cond,TIntermAggregate * b)1786     TIntermSwitch(TIntermTyped* cond, TIntermAggregate* b) : condition(cond), body(b),
1787         flatten(false), dontFlatten(false) {}
1788     virtual void traverse(TIntermTraverser*);
getCondition()1789     virtual TIntermNode* getCondition() const { return condition; }
getBody()1790     virtual TIntermAggregate* getBody() const { return body; }
getAsSwitchNode()1791     virtual       TIntermSwitch* getAsSwitchNode()       { return this; }
getAsSwitchNode()1792     virtual const TIntermSwitch* getAsSwitchNode() const { return this; }
1793 
setFlatten()1794     void setFlatten()     { flatten = true; }
setDontFlatten()1795     void setDontFlatten() { dontFlatten = true; }
getFlatten()1796     bool getFlatten()     const { return flatten; }
getDontFlatten()1797     bool getDontFlatten() const { return dontFlatten; }
1798 
1799 protected:
1800     TIntermTyped* condition;
1801     TIntermAggregate* body;
1802     bool flatten;     // true if flatten requested
1803     bool dontFlatten; // true if requested to not flatten
1804 };
1805 
1806 enum TVisit
1807 {
1808     EvPreVisit,
1809     EvInVisit,
1810     EvPostVisit
1811 };
1812 
1813 //
1814 // For traversing the tree.  User should derive from this,
1815 // put their traversal specific data in it, and then pass
1816 // it to a Traverse method.
1817 //
1818 // When using this, just fill in the methods for nodes you want visited.
1819 // Return false from a pre-visit to skip visiting that node's subtree.
1820 //
1821 // Explicitly set postVisit to true if you want post visiting, otherwise,
1822 // filled in methods will only be called at pre-visit time (before processing
1823 // the subtree).  Similarly for inVisit for in-order visiting of nodes with
1824 // multiple children.
1825 //
1826 // If you only want post-visits, explicitly turn off preVisit (and inVisit)
1827 // and turn on postVisit.
1828 //
1829 // In general, for the visit*() methods, return true from interior nodes
1830 // to have the traversal continue on to children.
1831 //
1832 // If you process children yourself, or don't want them processed, return false.
1833 //
1834 class TIntermTraverser {
1835 public:
POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator ())1836     POOL_ALLOCATOR_NEW_DELETE(glslang::GetThreadPoolAllocator())
1837     TIntermTraverser(bool preVisit = true, bool inVisit = false, bool postVisit = false, bool rightToLeft = false) :
1838             preVisit(preVisit),
1839             inVisit(inVisit),
1840             postVisit(postVisit),
1841             rightToLeft(rightToLeft),
1842             depth(0),
1843             maxDepth(0) { }
~TIntermTraverser()1844     virtual ~TIntermTraverser() { }
1845 
visitSymbol(TIntermSymbol *)1846     virtual void visitSymbol(TIntermSymbol*)               { }
visitConstantUnion(TIntermConstantUnion *)1847     virtual void visitConstantUnion(TIntermConstantUnion*) { }
visitBinary(TVisit,TIntermBinary *)1848     virtual bool visitBinary(TVisit, TIntermBinary*)       { return true; }
visitUnary(TVisit,TIntermUnary *)1849     virtual bool visitUnary(TVisit, TIntermUnary*)         { return true; }
visitSelection(TVisit,TIntermSelection *)1850     virtual bool visitSelection(TVisit, TIntermSelection*) { return true; }
visitAggregate(TVisit,TIntermAggregate *)1851     virtual bool visitAggregate(TVisit, TIntermAggregate*) { return true; }
visitLoop(TVisit,TIntermLoop *)1852     virtual bool visitLoop(TVisit, TIntermLoop*)           { return true; }
visitBranch(TVisit,TIntermBranch *)1853     virtual bool visitBranch(TVisit, TIntermBranch*)       { return true; }
visitSwitch(TVisit,TIntermSwitch *)1854     virtual bool visitSwitch(TVisit, TIntermSwitch*)       { return true; }
1855 
getMaxDepth()1856     int getMaxDepth() const { return maxDepth; }
1857 
incrementDepth(TIntermNode * current)1858     void incrementDepth(TIntermNode *current)
1859     {
1860         depth++;
1861         maxDepth = (std::max)(maxDepth, depth);
1862         path.push_back(current);
1863     }
1864 
decrementDepth()1865     void decrementDepth()
1866     {
1867         depth--;
1868         path.pop_back();
1869     }
1870 
getParentNode()1871     TIntermNode *getParentNode()
1872     {
1873         return path.size() == 0 ? nullptr : path.back();
1874     }
1875 
1876     const bool preVisit;
1877     const bool inVisit;
1878     const bool postVisit;
1879     const bool rightToLeft;
1880 
1881 protected:
1882     TIntermTraverser& operator=(TIntermTraverser&);
1883 
1884     int depth;
1885     int maxDepth;
1886 
1887     // All the nodes from root to the current node's parent during traversing.
1888     TVector<TIntermNode *> path;
1889 };
1890 
1891 // KHR_vulkan_glsl says "Two arrays sized with specialization constants are the same type only if
1892 // sized with the same symbol, involving no operations"
SameSpecializationConstants(TIntermTyped * node1,TIntermTyped * node2)1893 inline bool SameSpecializationConstants(TIntermTyped* node1, TIntermTyped* node2)
1894 {
1895     return node1->getAsSymbolNode() && node2->getAsSymbolNode() &&
1896            node1->getAsSymbolNode()->getId() == node2->getAsSymbolNode()->getId();
1897 }
1898 
1899 } // end namespace glslang
1900 
1901 #endif // __INTERMEDIATE_H
1902