Bug Summary

File:root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp
Warning:line 279, column 13
Undefined or garbage value returned to caller

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name util.cpp -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -ffp-contract=off -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -target-feature +sse2 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/gfx/angle/targets/translator -fcoverage-compilation-dir=/root/firefox-clang/obj-x86_64-pc-linux-gnu/gfx/angle/targets/translator -resource-dir /usr/lib/llvm-21/lib/clang/21 -include /root/firefox-clang/config/gcc_hidden.h -include /root/firefox-clang/obj-x86_64-pc-linux-gnu/mozilla-config.h -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/stl_wrappers -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/system_wrappers -U _FORTIFY_SOURCE -D _FORTIFY_SOURCE=2 -D _GLIBCXX_ASSERTIONS -D DEBUG=1 -D ANGLE_PLATFORM_EXPORT= -D __NDK_FPABI__= -D ANGLE_SKIP_DXGI_1_2_CHECK -D ANGLE_ENABLE_KEYEDMUTEX -D ANGLE_TRANSLATOR_ESSL_ONLY -D ANGLE_DISABLE_POOL_ALLOC -D ANGLE_ENABLE_APPLE_WORKAROUNDS -D ANGLE_ENABLE_ESSL -D ANGLE_ENABLE_GLSL -D ANGLE_ENABLE_HLSL -D ANGLE_ENABLE_SHARE_CONTEXT_LOCK=1 -D ANGLE_VMA_VERSION=2003000 -D CR_CLANG_REVISION="llvmorg-16-init-6578-g0d30e92f-2" -D DYNAMIC_ANNOTATIONS_ENABLED=0 -D NOMINMAX -D UNICODE -D WINVER=0x0A00 -D _ATL_NO_OPENGL -D _CRT_NONSTDC_NO_WARNINGS -D _CRT_RAND_S -D _CRT_SECURE_NO_DEPRECATE -D _HAS_EXCEPTIONS=0 -D _SCL_SECURE_NO_DEPRECATE -D _SECURE_ATL -D _UNICODE -D _WINSOCK_DEPRECATED_NO_WARNINGS -I /root/firefox-clang/gfx/angle/targets/translator -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/gfx/angle/targets/translator -I /root/firefox-clang/gfx/angle/checkout/include -I /root/firefox-clang/gfx/angle/checkout/src -I /root/firefox-clang/gfx/angle/checkout/src/common/third_party/base -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nspr -I /root/firefox-clang/obj-x86_64-pc-linux-gnu/dist/include/nss -D MOZILLA_CLIENT -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/x86_64-linux-gnu/c++/14 -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../include/c++/14/backward -internal-isystem /usr/lib/llvm-21/lib/clang/21/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-error=pessimizing-move -Wno-error=large-by-value-copy=128 -Wno-error=implicit-int-float-conversion -Wno-error=thread-safety-analysis -Wno-error=tautological-type-limit-compare -Wno-invalid-offsetof -Wno-range-loop-analysis -Wno-deprecated-anon-enum-enum-conversion -Wno-deprecated-enum-enum-conversion -Wno-deprecated-this-capture -Wno-inline-new-delete -Wno-error=deprecated-declarations -Wno-error=array-bounds -Wno-error=free-nonheap-object -Wno-error=atomic-alignment -Wno-error=deprecated-builtins -Wno-psabi -Wno-error=builtin-macro-redefined -Wno-vla-cxx-extension -Wno-unknown-warning-option -Wno-final-dtor-non-final-class -Wno-implicit-const-int-float-conversion -Wno-range-loop-construct -fdeprecated-macro -ferror-limit 19 -fstrict-flex-arrays=1 -stack-protector 2 -fstack-clash-protection -ftrivial-auto-var-init=pattern -fno-rtti -fgnuc-version=4.2.1 -fskip-odr-check-in-gmf -fno-sized-deallocation -fno-aligned-allocation -vectorize-loops -vectorize-slp -analyzer-checker optin.performance.Padding -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2025-06-27-100320-3286336-1 -x c++ /root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp
1//
2// Copyright 2010 The ANGLE Project Authors. All rights reserved.
3// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
6
7#include "compiler/translator/util.h"
8
9#include <limits>
10
11#include "common/utilities.h"
12#include "compiler/preprocessor/numeric_lex.h"
13#include "compiler/translator/ImmutableStringBuilder.h"
14#include "compiler/translator/SymbolTable.h"
15
16bool atoi_clamp(const char *str, unsigned int *value)
17{
18 bool success = angle::pp::numeric_lex_int(str, value);
19 if (!success)
20 *value = std::numeric_limits<unsigned int>::max();
21 return success;
22}
23
24namespace sh
25{
26
27namespace
28{
29// [primarySize-1][secondarySize-1] is the GL type with a basic type of float.
30constexpr GLenum kFloatGLType[4][4] = {
31 // float1xS only makes sense for S == 1
32 {
33 GL_FLOAT0x1406,
34 GL_NONE0,
35 GL_NONE0,
36 GL_NONE0,
37 },
38 // float2xS is vec2 for S == 1, and mat2xS o.w.
39 {
40 GL_FLOAT_VEC20x8B50,
41 GL_FLOAT_MAT20x8B5A,
42 GL_FLOAT_MAT2x30x8B65,
43 GL_FLOAT_MAT2x40x8B66,
44 },
45 // float3xS is vec3 for S == 1, and mat3xS o.w.
46 {
47 GL_FLOAT_VEC30x8B51,
48 GL_FLOAT_MAT3x20x8B67,
49 GL_FLOAT_MAT30x8B5B,
50 GL_FLOAT_MAT3x40x8B68,
51 },
52 // float4xS is vec4 for S == 1, and mat4xS o.w.
53 {
54 GL_FLOAT_VEC40x8B52,
55 GL_FLOAT_MAT4x20x8B69,
56 GL_FLOAT_MAT4x30x8B6A,
57 GL_FLOAT_MAT40x8B5C,
58 },
59};
60// [primarySize-1] is the GL type with a basic type of int.
61constexpr GLenum kIntGLType[4] = {GL_INT0x1404, GL_INT_VEC20x8B53, GL_INT_VEC30x8B54, GL_INT_VEC40x8B55};
62// [primarySize-1] is the GL type with a basic type of uint.
63constexpr GLenum kUIntGLType[4] = {GL_UNSIGNED_INT0x1405, GL_UNSIGNED_INT_VEC20x8DC6, GL_UNSIGNED_INT_VEC30x8DC7,
64 GL_UNSIGNED_INT_VEC40x8DC8};
65// [primarySize-1] is the GL type with a basic type of bool.
66constexpr GLenum kBoolGLType[4] = {GL_BOOL0x8B56, GL_BOOL_VEC20x8B57, GL_BOOL_VEC30x8B58, GL_BOOL_VEC40x8B59};
67
68bool IsInterpolationIn(TQualifier qualifier)
69{
70 switch (qualifier)
71 {
72 case EvqSmoothIn:
73 case EvqFlatIn:
74 case EvqNoPerspectiveIn:
75 case EvqCentroidIn:
76 case EvqSampleIn:
77 return true;
78 default:
79 return false;
80 }
81}
82
83bool IsInterpolationOut(TQualifier qualifier)
84{
85 switch (qualifier)
86 {
87 case EvqSmoothOut:
88 case EvqFlatOut:
89 case EvqNoPerspectiveOut:
90 case EvqCentroidOut:
91 case EvqSampleOut:
92 return true;
93 default:
94 return false;
95 }
96}
97} // anonymous namespace
98
99float NumericLexFloat32OutOfRangeToInfinity(const std::string &str)
100{
101 // Parses a decimal string using scientific notation into a floating point number.
102 // Out-of-range values are converted to infinity. Values that are too small to be
103 // represented are converted to zero.
104
105 // The mantissa in decimal scientific notation. The magnitude of the mantissa integer does not
106 // matter.
107 unsigned int decimalMantissa = 0;
108 size_t i = 0;
109 bool decimalPointSeen = false;
110 bool nonZeroSeenInMantissa = false;
111
112 // The exponent offset reflects the position of the decimal point.
113 int exponentOffset = -1;
114
115 // This is just a counter for how many decimal digits are written to decimalMantissa.
116 int mantissaDecimalDigits = 0;
117
118 while (i < str.length())
119 {
120 const char c = str[i];
121 if (c == 'e' || c == 'E')
122 {
123 break;
124 }
125 if (c == '.')
126 {
127 decimalPointSeen = true;
128 ++i;
129 continue;
130 }
131
132 unsigned int digit = static_cast<unsigned int>(c - '0');
133 ASSERT(digit < 10u)(digit < 10u ? static_cast<void>(0) : (!((::gl::priv
::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL))) ? static_cast
<void>(0) : ::gl::priv::LogMessageVoidify() & (::gl
::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
, __FUNCTION__, 133, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
<< ":" << 133 << "): " << "digit < 10u"
))
;
134 if (digit != 0u)
135 {
136 nonZeroSeenInMantissa = true;
137 }
138 if (nonZeroSeenInMantissa)
139 {
140 // Add bits to the mantissa until space runs out in 32-bit int. This should be
141 // enough precision to make the resulting binary mantissa accurate to 1 ULP.
142 if (decimalMantissa <= (std::numeric_limits<unsigned int>::max() - 9u) / 10u)
143 {
144 decimalMantissa = decimalMantissa * 10u + digit;
145 ++mantissaDecimalDigits;
146 }
147 if (!decimalPointSeen)
148 {
149 ++exponentOffset;
150 }
151 }
152 else if (decimalPointSeen)
153 {
154 --exponentOffset;
155 }
156 ++i;
157 }
158 if (decimalMantissa == 0)
159 {
160 return 0.0f;
161 }
162 int exponent = 0;
163 if (i < str.length())
164 {
165 ASSERT(str[i] == 'e' || str[i] == 'E')(str[i] == 'e' || str[i] == 'E' ? static_cast<void>(0) :
(!((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL
))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify
() & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
, __FUNCTION__, 165, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
<< ":" << 165 << "): " << "str[i] == 'e' || str[i] == 'E'"
))
;
166 ++i;
167 bool exponentOutOfRange = false;
168 bool negativeExponent = false;
169 if (str[i] == '-')
170 {
171 negativeExponent = true;
172 ++i;
173 }
174 else if (str[i] == '+')
175 {
176 ++i;
177 }
178 while (i < str.length())
179 {
180 const char c = str[i];
181 unsigned int digit = static_cast<unsigned int>(c - '0');
182 ASSERT(digit < 10u)(digit < 10u ? static_cast<void>(0) : (!((::gl::priv
::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL))) ? static_cast
<void>(0) : ::gl::priv::LogMessageVoidify() & (::gl
::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
, __FUNCTION__, 182, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
<< ":" << 182 << "): " << "digit < 10u"
))
;
183 if (exponent <= (std::numeric_limits<int>::max() - 9) / 10)
184 {
185 exponent = exponent * 10 + digit;
186 }
187 else
188 {
189 exponentOutOfRange = true;
190 }
191 ++i;
192 }
193 if (negativeExponent)
194 {
195 exponent = -exponent;
196 }
197 if (exponentOutOfRange)
198 {
199 if (negativeExponent)
200 {
201 return 0.0f;
202 }
203 else
204 {
205 return std::numeric_limits<float>::infinity();
206 }
207 }
208 }
209 // Do the calculation in 64-bit to avoid overflow.
210 long long exponentLong =
211 static_cast<long long>(exponent) + static_cast<long long>(exponentOffset);
212 if (exponentLong > std::numeric_limits<float>::max_exponent10)
213 {
214 return std::numeric_limits<float>::infinity();
215 }
216 else if (exponentLong < std::numeric_limits<float>::min_exponent10)
217 {
218 return 0.0f;
219 }
220 // The exponent is in range, so we need to actually evaluate the float.
221 exponent = static_cast<int>(exponentLong);
222 double value = decimalMantissa;
223
224 // Calculate the exponent offset to normalize the mantissa.
225 int normalizationExponentOffset = 1 - mantissaDecimalDigits;
226 // Apply the exponent.
227 value *= std::pow(10.0, static_cast<double>(exponent + normalizationExponentOffset));
228 if (value > static_cast<double>(std::numeric_limits<float>::max()))
229 {
230 return std::numeric_limits<float>::infinity();
231 }
232 if (value < static_cast<double>(std::numeric_limits<float>::min()))
233 {
234 return 0.0f;
235 }
236 return static_cast<float>(value);
237}
238
239bool strtof_clamp(const std::string &str, float *value)
240{
241 // Custom float parsing that can handle the following corner cases:
242 // 1. The decimal mantissa is very small but the exponent is very large, putting the resulting
243 // number inside the float range.
244 // 2. The decimal mantissa is very large but the exponent is very small, putting the resulting
245 // number inside the float range.
246 // 3. The value is out-of-range and should be evaluated as infinity.
247 // 4. The value is too small and should be evaluated as zero.
248 // See ESSL 3.00.6 section 4.1.4 for the relevant specification.
249 *value = NumericLexFloat32OutOfRangeToInfinity(str);
250 return !gl::isInf(*value);
251}
252
253GLenum GLVariableType(const TType &type)
254{
255 switch (type.getBasicType())
1
Control jumps to 'case EbtBool:' at line 275
256 {
257 case EbtFloat:
258 ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4)(type.getNominalSize() >= 1 && type.getNominalSize
() <= 4 ? static_cast<void>(0) : (!((::gl::priv::ShouldCreatePlatformLogMessage
(::gl::LOG_FATAL))) ? static_cast<void>(0) : ::gl::priv
::LogMessageVoidify() & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
, __FUNCTION__, 258, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
<< ":" << 258 << "): " << "type.getNominalSize() >= 1 && type.getNominalSize() <= 4"
))
;
259 ASSERT(type.getSecondarySize() >= 1 && type.getSecondarySize() <= 4)(type.getSecondarySize() >= 1 && type.getSecondarySize
() <= 4 ? static_cast<void>(0) : (!((::gl::priv::ShouldCreatePlatformLogMessage
(::gl::LOG_FATAL))) ? static_cast<void>(0) : ::gl::priv
::LogMessageVoidify() & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
, __FUNCTION__, 259, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
<< ":" << 259 << "): " << "type.getSecondarySize() >= 1 && type.getSecondarySize() <= 4"
))
;
260
261 return kFloatGLType[type.getNominalSize() - 1][type.getSecondarySize() - 1];
262
263 case EbtInt:
264 ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4)(type.getNominalSize() >= 1 && type.getNominalSize
() <= 4 ? static_cast<void>(0) : (!((::gl::priv::ShouldCreatePlatformLogMessage
(::gl::LOG_FATAL))) ? static_cast<void>(0) : ::gl::priv
::LogMessageVoidify() & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
, __FUNCTION__, 264, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
<< ":" << 264 << "): " << "type.getNominalSize() >= 1 && type.getNominalSize() <= 4"
))
;
265 ASSERT(type.getSecondarySize() == 1)(type.getSecondarySize() == 1 ? static_cast<void>(0) : (
!((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL
))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify
() & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
, __FUNCTION__, 265, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
<< ":" << 265 << "): " << "type.getSecondarySize() == 1"
))
;
266
267 return kIntGLType[type.getNominalSize() - 1];
268
269 case EbtUInt:
270 ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4)(type.getNominalSize() >= 1 && type.getNominalSize
() <= 4 ? static_cast<void>(0) : (!((::gl::priv::ShouldCreatePlatformLogMessage
(::gl::LOG_FATAL))) ? static_cast<void>(0) : ::gl::priv
::LogMessageVoidify() & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
, __FUNCTION__, 270, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
<< ":" << 270 << "): " << "type.getNominalSize() >= 1 && type.getNominalSize() <= 4"
))
;
271 ASSERT(type.getSecondarySize() == 1)(type.getSecondarySize() == 1 ? static_cast<void>(0) : (
!((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL
))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify
() & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
, __FUNCTION__, 271, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
<< ":" << 271 << "): " << "type.getSecondarySize() == 1"
))
;
272
273 return kUIntGLType[type.getNominalSize() - 1];
274
275 case EbtBool:
276 ASSERT(type.getNominalSize() >= 1 && type.getNominalSize() <= 4)(type.getNominalSize() >= 1 && type.getNominalSize
() <= 4 ? static_cast<void>(0) : (!((::gl::priv::ShouldCreatePlatformLogMessage
(::gl::LOG_FATAL))) ? static_cast<void>(0) : ::gl::priv
::LogMessageVoidify() & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
, __FUNCTION__, 276, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
<< ":" << 276 << "): " << "type.getNominalSize() >= 1 && type.getNominalSize() <= 4"
))
;
2
Assuming the condition is false
3
Assuming the condition is true
4
'?' condition is true
277 ASSERT(type.getSecondarySize() == 1)(type.getSecondarySize() == 1 ? static_cast<void>(0) : (
!((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL
))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify
() & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
, __FUNCTION__, 277, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
<< ":" << 277 << "): " << "type.getSecondarySize() == 1"
))
;
5
Assuming the condition is true
6
'?' condition is true
278
279 return kBoolGLType[type.getNominalSize() - 1];
7
Undefined or garbage value returned to caller
280
281 case EbtSampler2D:
282 return GL_SAMPLER_2D0x8B5E;
283 case EbtSampler3D:
284 return GL_SAMPLER_3D0x8B5F;
285 case EbtSamplerCube:
286 return GL_SAMPLER_CUBE0x8B60;
287 case EbtSamplerExternalOES:
288 return GL_SAMPLER_EXTERNAL_OES0x8D66;
289 case EbtSamplerExternal2DY2YEXT:
290 return GL_SAMPLER_EXTERNAL_2D_Y2Y_EXT0x8BE7;
291 case EbtSampler2DRect:
292 return GL_SAMPLER_2D_RECT_ANGLE0x8B63;
293 case EbtSampler2DArray:
294 return GL_SAMPLER_2D_ARRAY0x8DC1;
295 case EbtSampler2DMS:
296 return GL_SAMPLER_2D_MULTISAMPLE0x9108;
297 case EbtSampler2DMSArray:
298 return GL_SAMPLER_2D_MULTISAMPLE_ARRAY0x910B;
299 case EbtSamplerCubeArray:
300 return GL_SAMPLER_CUBE_MAP_ARRAY0x900C;
301 case EbtSamplerBuffer:
302 return GL_SAMPLER_BUFFER0x8DC2;
303 case EbtISampler2D:
304 return GL_INT_SAMPLER_2D0x8DCA;
305 case EbtISampler3D:
306 return GL_INT_SAMPLER_3D0x8DCB;
307 case EbtISamplerCube:
308 return GL_INT_SAMPLER_CUBE0x8DCC;
309 case EbtISampler2DArray:
310 return GL_INT_SAMPLER_2D_ARRAY0x8DCF;
311 case EbtISampler2DMS:
312 return GL_INT_SAMPLER_2D_MULTISAMPLE0x9109;
313 case EbtISampler2DMSArray:
314 return GL_INT_SAMPLER_2D_MULTISAMPLE_ARRAY0x910C;
315 case EbtISamplerCubeArray:
316 return GL_INT_SAMPLER_CUBE_MAP_ARRAY0x900E;
317 case EbtISamplerBuffer:
318 return GL_INT_SAMPLER_BUFFER0x8DD0;
319 case EbtUSampler2D:
320 return GL_UNSIGNED_INT_SAMPLER_2D0x8DD2;
321 case EbtUSampler3D:
322 return GL_UNSIGNED_INT_SAMPLER_3D0x8DD3;
323 case EbtUSamplerCube:
324 return GL_UNSIGNED_INT_SAMPLER_CUBE0x8DD4;
325 case EbtUSampler2DArray:
326 return GL_UNSIGNED_INT_SAMPLER_2D_ARRAY0x8DD7;
327 case EbtUSampler2DMS:
328 return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE0x910A;
329 case EbtUSampler2DMSArray:
330 return GL_UNSIGNED_INT_SAMPLER_2D_MULTISAMPLE_ARRAY0x910D;
331 case EbtUSamplerCubeArray:
332 return GL_UNSIGNED_INT_SAMPLER_CUBE_MAP_ARRAY0x900F;
333 case EbtUSamplerBuffer:
334 return GL_UNSIGNED_INT_SAMPLER_BUFFER0x8DD8;
335 case EbtSampler2DShadow:
336 return GL_SAMPLER_2D_SHADOW0x8B62;
337 case EbtSamplerCubeShadow:
338 return GL_SAMPLER_CUBE_SHADOW0x8DC5;
339 case EbtSampler2DArrayShadow:
340 return GL_SAMPLER_2D_ARRAY_SHADOW0x8DC4;
341 case EbtSamplerCubeArrayShadow:
342 return GL_SAMPLER_CUBE_MAP_ARRAY_SHADOW0x900D;
343 case EbtImage2D:
344 return GL_IMAGE_2D0x904D;
345 case EbtIImage2D:
346 return GL_INT_IMAGE_2D0x9058;
347 case EbtUImage2D:
348 return GL_UNSIGNED_INT_IMAGE_2D0x9063;
349 case EbtImage2DArray:
350 return GL_IMAGE_2D_ARRAY0x9053;
351 case EbtIImage2DArray:
352 return GL_INT_IMAGE_2D_ARRAY0x905E;
353 case EbtUImage2DArray:
354 return GL_UNSIGNED_INT_IMAGE_2D_ARRAY0x9069;
355 case EbtImage3D:
356 return GL_IMAGE_3D0x904E;
357 case EbtIImage3D:
358 return GL_INT_IMAGE_3D0x9059;
359 case EbtUImage3D:
360 return GL_UNSIGNED_INT_IMAGE_3D0x9064;
361 case EbtImageCube:
362 return GL_IMAGE_CUBE0x9050;
363 case EbtIImageCube:
364 return GL_INT_IMAGE_CUBE0x905B;
365 case EbtUImageCube:
366 return GL_UNSIGNED_INT_IMAGE_CUBE0x9066;
367 case EbtImageCubeArray:
368 return GL_IMAGE_CUBE_MAP_ARRAY0x9054;
369 case EbtIImageCubeArray:
370 return GL_INT_IMAGE_CUBE_MAP_ARRAY0x905F;
371 case EbtUImageCubeArray:
372 return GL_UNSIGNED_INT_IMAGE_CUBE_MAP_ARRAY0x906A;
373 case EbtImageBuffer:
374 return GL_IMAGE_BUFFER0x9051;
375 case EbtIImageBuffer:
376 return GL_INT_IMAGE_BUFFER0x905C;
377 case EbtUImageBuffer:
378 return GL_UNSIGNED_INT_IMAGE_BUFFER0x9067;
379 case EbtAtomicCounter:
380 return GL_UNSIGNED_INT_ATOMIC_COUNTER0x92DB;
381 case EbtSamplerVideoWEBGL:
382 return GL_SAMPLER_VIDEO_IMAGE_WEBGL0x9249;
383 case EbtPixelLocalANGLE:
384 case EbtIPixelLocalANGLE:
385 case EbtUPixelLocalANGLE:
386 // TODO(anglebug.com/7279): For now, we can expect PLS handles to be rewritten to images
387 // before anyone calls into here.
388 [[fallthrough]];
389 default:
390 UNREACHABLE()do { !((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL
))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify
() & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
, __FUNCTION__, 390, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
<< ":" << 390 << ")"; } while (0)
;
391 return GL_NONE0;
392 }
393}
394
395GLenum GLVariablePrecision(const TType &type)
396{
397 if (type.getBasicType() == EbtFloat)
398 {
399 switch (type.getPrecision())
400 {
401 case EbpHigh:
402 return GL_HIGH_FLOAT0x8DF2;
403 case EbpMedium:
404 return GL_MEDIUM_FLOAT0x8DF1;
405 case EbpLow:
406 return GL_LOW_FLOAT0x8DF0;
407 case EbpUndefined:
408 // Desktop specs do not use precision
409 return GL_NONE0;
410 default:
411 UNREACHABLE()do { !((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL
))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify
() & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
, __FUNCTION__, 411, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
<< ":" << 411 << ")"; } while (0)
;
412 }
413 }
414 else if (type.getBasicType() == EbtInt || type.getBasicType() == EbtUInt)
415 {
416 switch (type.getPrecision())
417 {
418 case EbpHigh:
419 return GL_HIGH_INT0x8DF5;
420 case EbpMedium:
421 return GL_MEDIUM_INT0x8DF4;
422 case EbpLow:
423 return GL_LOW_INT0x8DF3;
424 case EbpUndefined:
425 // Desktop specs do not use precision
426 return GL_NONE0;
427 default:
428 UNREACHABLE()do { !((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL
))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify
() & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
, __FUNCTION__, 428, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
<< ":" << 428 << ")"; } while (0)
;
429 }
430 }
431
432 // Other types (boolean, sampler) don't have a precision
433 return GL_NONE0;
434}
435
436ImmutableString ArrayString(const TType &type)
437{
438 if (!type.isArray())
439 return ImmutableString("");
440
441 const TSpan<const unsigned int> &arraySizes = type.getArraySizes();
442 constexpr const size_t kMaxDecimalDigitsPerSize = 10u;
443 ImmutableStringBuilder arrayString(arraySizes.size() * (kMaxDecimalDigitsPerSize + 2u));
444 for (auto arraySizeIter = arraySizes.rbegin(); arraySizeIter != arraySizes.rend();
445 ++arraySizeIter)
446 {
447 arrayString << "[";
448 if (*arraySizeIter > 0)
449 {
450 arrayString.appendDecimal(*arraySizeIter);
451 }
452 arrayString << "]";
453 }
454 return arrayString;
455}
456
457ImmutableString GetTypeName(const TType &type, ShHashFunction64 hashFunction, NameMap *nameMap)
458{
459 if (type.getBasicType() == EbtStruct)
460 return HashName(type.getStruct(), hashFunction, nameMap);
461 else
462 return ImmutableString(type.getBuiltInTypeNameString());
463}
464
465bool IsVaryingOut(TQualifier qualifier)
466{
467 switch (qualifier)
468 {
469 case EvqVaryingOut:
470 case EvqSmoothOut:
471 case EvqFlatOut:
472 case EvqNoPerspectiveOut:
473 case EvqCentroidOut:
474 case EvqVertexOut:
475 case EvqGeometryOut:
476 case EvqTessControlOut:
477 case EvqTessEvaluationOut:
478 case EvqSampleOut:
479 case EvqPatchOut:
480 return true;
481
482 default:
483 break;
484 }
485
486 return false;
487}
488
489bool IsVaryingIn(TQualifier qualifier)
490{
491 switch (qualifier)
492 {
493 case EvqVaryingIn:
494 case EvqSmoothIn:
495 case EvqFlatIn:
496 case EvqNoPerspectiveIn:
497 case EvqCentroidIn:
498 case EvqFragmentIn:
499 case EvqGeometryIn:
500 case EvqTessControlIn:
501 case EvqTessEvaluationIn:
502 case EvqSampleIn:
503 case EvqPatchIn:
504 return true;
505
506 default:
507 break;
508 }
509
510 return false;
511}
512
513bool IsVarying(TQualifier qualifier)
514{
515 return IsVaryingIn(qualifier) || IsVaryingOut(qualifier);
516}
517
518bool IsMatrixGLType(GLenum type)
519{
520 switch (type)
521 {
522 case GL_FLOAT_MAT20x8B5A:
523 case GL_FLOAT_MAT30x8B5B:
524 case GL_FLOAT_MAT40x8B5C:
525 case GL_FLOAT_MAT2x30x8B65:
526 case GL_FLOAT_MAT2x40x8B66:
527 case GL_FLOAT_MAT3x20x8B67:
528 case GL_FLOAT_MAT3x40x8B68:
529 case GL_FLOAT_MAT4x20x8B69:
530 case GL_FLOAT_MAT4x30x8B6A:
531 return true;
532 default:
533 return false;
534 }
535}
536
537bool IsGeometryShaderInput(GLenum shaderType, TQualifier qualifier)
538{
539 return (qualifier == EvqGeometryIn) ||
540 ((shaderType == GL_GEOMETRY_SHADER_EXT0x8DD9) && IsInterpolationIn(qualifier));
541}
542
543bool IsTessellationControlShaderInput(GLenum shaderType, TQualifier qualifier)
544{
545 return qualifier == EvqTessControlIn ||
546 ((shaderType == GL_TESS_CONTROL_SHADER0x8E88) && IsInterpolationIn(qualifier));
547}
548
549bool IsTessellationControlShaderOutput(GLenum shaderType, TQualifier qualifier)
550{
551 return qualifier == EvqTessControlOut ||
552 ((shaderType == GL_TESS_CONTROL_SHADER0x8E88) && IsInterpolationOut(qualifier));
553}
554
555bool IsTessellationEvaluationShaderInput(GLenum shaderType, TQualifier qualifier)
556{
557 return qualifier == EvqTessEvaluationIn ||
558 ((shaderType == GL_TESS_EVALUATION_SHADER0x8E87) && IsInterpolationIn(qualifier));
559}
560
561InterpolationType GetInterpolationType(TQualifier qualifier)
562{
563 switch (qualifier)
564 {
565 case EvqFlatIn:
566 case EvqFlatOut:
567 // The auxiliary storage qualifier patch is not used for interpolation
568 // it is a compile-time error to use interpolation qualifiers with patch
569 case EvqPatchIn:
570 case EvqPatchOut:
571 return INTERPOLATION_FLAT;
572
573 case EvqNoPerspectiveIn:
574 case EvqNoPerspectiveOut:
575 return INTERPOLATION_NOPERSPECTIVE;
576
577 case EvqSmoothIn:
578 case EvqSmoothOut:
579 case EvqVertexOut:
580 case EvqFragmentIn:
581 case EvqVaryingIn:
582 case EvqVaryingOut:
583 case EvqGeometryIn:
584 case EvqGeometryOut:
585 case EvqTessControlIn:
586 case EvqTessControlOut:
587 case EvqTessEvaluationIn:
588 case EvqTessEvaluationOut:
589 return INTERPOLATION_SMOOTH;
590
591 case EvqCentroidIn:
592 case EvqCentroidOut:
593 return INTERPOLATION_CENTROID;
594
595 case EvqSampleIn:
596 case EvqSampleOut:
597 return INTERPOLATION_SAMPLE;
598 default:
599 UNREACHABLE()do { !((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL
))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify
() & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
, __FUNCTION__, 599, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
<< ":" << 599 << ")"; } while (0)
;
600 return INTERPOLATION_SMOOTH;
601 }
602}
603
604// a field may not have qualifer without in or out.
605InterpolationType GetFieldInterpolationType(TQualifier qualifier)
606{
607 switch (qualifier)
608 {
609 case EvqFlat:
610 return INTERPOLATION_FLAT;
611 case EvqNoPerspective:
612 return INTERPOLATION_NOPERSPECTIVE;
613 case EvqSmooth:
614 return INTERPOLATION_SMOOTH;
615 case EvqCentroid:
616 return INTERPOLATION_CENTROID;
617 default:
618 return GetInterpolationType(qualifier);
619 }
620}
621
622TType GetShaderVariableBasicType(const sh::ShaderVariable &var)
623{
624 switch (var.type)
625 {
626 case GL_BOOL0x8B56:
627 return TType(EbtBool);
628 case GL_BOOL_VEC20x8B57:
629 return TType(EbtBool, 2);
630 case GL_BOOL_VEC30x8B58:
631 return TType(EbtBool, 3);
632 case GL_BOOL_VEC40x8B59:
633 return TType(EbtBool, 4);
634 case GL_FLOAT0x1406:
635 return TType(EbtFloat);
636 case GL_FLOAT_VEC20x8B50:
637 return TType(EbtFloat, 2);
638 case GL_FLOAT_VEC30x8B51:
639 return TType(EbtFloat, 3);
640 case GL_FLOAT_VEC40x8B52:
641 return TType(EbtFloat, 4);
642 case GL_FLOAT_MAT20x8B5A:
643 return TType(EbtFloat, 2, 2);
644 case GL_FLOAT_MAT30x8B5B:
645 return TType(EbtFloat, 3, 3);
646 case GL_FLOAT_MAT40x8B5C:
647 return TType(EbtFloat, 4, 4);
648 case GL_FLOAT_MAT2x30x8B65:
649 return TType(EbtFloat, 2, 3);
650 case GL_FLOAT_MAT2x40x8B66:
651 return TType(EbtFloat, 2, 4);
652 case GL_FLOAT_MAT3x20x8B67:
653 return TType(EbtFloat, 3, 2);
654 case GL_FLOAT_MAT3x40x8B68:
655 return TType(EbtFloat, 3, 4);
656 case GL_FLOAT_MAT4x20x8B69:
657 return TType(EbtFloat, 4, 2);
658 case GL_FLOAT_MAT4x30x8B6A:
659 return TType(EbtFloat, 4, 3);
660 case GL_INT0x1404:
661 return TType(EbtInt);
662 case GL_INT_VEC20x8B53:
663 return TType(EbtInt, 2);
664 case GL_INT_VEC30x8B54:
665 return TType(EbtInt, 3);
666 case GL_INT_VEC40x8B55:
667 return TType(EbtInt, 4);
668 case GL_UNSIGNED_INT0x1405:
669 return TType(EbtUInt);
670 case GL_UNSIGNED_INT_VEC20x8DC6:
671 return TType(EbtUInt, 2);
672 case GL_UNSIGNED_INT_VEC30x8DC7:
673 return TType(EbtUInt, 3);
674 case GL_UNSIGNED_INT_VEC40x8DC8:
675 return TType(EbtUInt, 4);
676 default:
677 UNREACHABLE()do { !((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL
))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify
() & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
, __FUNCTION__, 677, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
<< ":" << 677 << ")"; } while (0)
;
678 return TType();
679 }
680}
681
682void DeclareGlobalVariable(TIntermBlock *root, const TVariable *variable)
683{
684 TIntermDeclaration *declaration = new TIntermDeclaration();
685 declaration->appendDeclarator(new TIntermSymbol(variable));
686
687 TIntermSequence *globalSequence = root->getSequence();
688 globalSequence->insert(globalSequence->begin(), declaration);
689}
690
691// GLSL ES 1.0.17 4.6.1 The Invariant Qualifier
692bool CanBeInvariantESSL1(TQualifier qualifier)
693{
694 return IsVaryingIn(qualifier) || IsVaryingOut(qualifier) ||
695 IsBuiltinOutputVariable(qualifier) ||
696 (IsBuiltinFragmentInputVariable(qualifier) && qualifier != EvqFrontFacing);
697}
698
699// GLSL ES 3.00 Revision 6, 4.6.1 The Invariant Qualifier
700// GLSL ES 3.10 Revision 4, 4.8.1 The Invariant Qualifier
701bool CanBeInvariantESSL3OrGreater(TQualifier qualifier)
702{
703 return IsVaryingOut(qualifier) || qualifier == EvqFragmentOut ||
704 IsBuiltinOutputVariable(qualifier) || qualifier == EvqFragmentInOut;
705}
706
707bool IsBuiltinOutputVariable(TQualifier qualifier)
708{
709 switch (qualifier)
710 {
711 case EvqPosition:
712 case EvqPointSize:
713 case EvqFragDepth:
714 case EvqFragColor:
715 case EvqSecondaryFragColorEXT:
716 case EvqFragData:
717 case EvqSecondaryFragDataEXT:
718 case EvqClipDistance:
719 case EvqCullDistance:
720 case EvqLastFragData:
721 case EvqSampleMask:
722 return true;
723 default:
724 break;
725 }
726 return false;
727}
728
729bool IsBuiltinFragmentInputVariable(TQualifier qualifier)
730{
731 switch (qualifier)
732 {
733 case EvqFragCoord:
734 case EvqPointCoord:
735 case EvqFrontFacing:
736 case EvqHelperInvocation:
737 case EvqLastFragData:
738 return true;
739 default:
740 break;
741 }
742 return false;
743}
744
745bool IsShaderOutput(TQualifier qualifier)
746{
747 return IsVaryingOut(qualifier) || IsBuiltinOutputVariable(qualifier);
748}
749
750bool IsFragmentOutput(TQualifier qualifier)
751{
752 switch (qualifier)
753 {
754 case EvqFragmentOut:
755 case EvqFragmentInOut:
756 return true;
757 default:
758 return false;
759 }
760}
761
762bool IsOutputESSL(ShShaderOutput output)
763{
764 return output == SH_ESSL_OUTPUT;
765}
766
767bool IsOutputGLSL(ShShaderOutput output)
768{
769 switch (output)
770 {
771 case SH_GLSL_130_OUTPUT:
772 case SH_GLSL_140_OUTPUT:
773 case SH_GLSL_150_CORE_OUTPUT:
774 case SH_GLSL_330_CORE_OUTPUT:
775 case SH_GLSL_400_CORE_OUTPUT:
776 case SH_GLSL_410_CORE_OUTPUT:
777 case SH_GLSL_420_CORE_OUTPUT:
778 case SH_GLSL_430_CORE_OUTPUT:
779 case SH_GLSL_440_CORE_OUTPUT:
780 case SH_GLSL_450_CORE_OUTPUT:
781 case SH_GLSL_COMPATIBILITY_OUTPUT:
782 return true;
783 default:
784 break;
785 }
786 return false;
787}
788bool IsOutputHLSL(ShShaderOutput output)
789{
790 switch (output)
791 {
792 case SH_HLSL_3_0_OUTPUT:
793 case SH_HLSL_4_1_OUTPUT:
794 case SH_HLSL_4_0_FL9_3_OUTPUT:
795 return true;
796 default:
797 break;
798 }
799 return false;
800}
801bool IsOutputVulkan(ShShaderOutput output)
802{
803 return output == SH_SPIRV_VULKAN_OUTPUT;
804}
805bool IsOutputMetal(ShShaderOutput output)
806{
807 return output == SH_SPIRV_METAL_OUTPUT;
808}
809bool IsOutputMetalDirect(ShShaderOutput output)
810{
811 return output == SH_MSL_METAL_OUTPUT;
812}
813
814bool IsInShaderStorageBlock(TIntermTyped *node)
815{
816 TIntermSwizzle *swizzleNode = node->getAsSwizzleNode();
817 if (swizzleNode)
818 {
819 return IsInShaderStorageBlock(swizzleNode->getOperand());
820 }
821
822 TIntermBinary *binaryNode = node->getAsBinaryNode();
823 if (binaryNode)
824 {
825 switch (binaryNode->getOp())
826 {
827 case EOpIndexDirectInterfaceBlock:
828 case EOpIndexIndirect:
829 case EOpIndexDirect:
830 case EOpIndexDirectStruct:
831 return IsInShaderStorageBlock(binaryNode->getLeft());
832 default:
833 return false;
834 }
835 }
836
837 const TType &type = node->getType();
838 return type.getQualifier() == EvqBuffer;
839}
840
841GLenum GetImageInternalFormatType(TLayoutImageInternalFormat iifq)
842{
843 switch (iifq)
844 {
845 case EiifRGBA32F:
846 return GL_RGBA32F0x8814;
847 case EiifRGBA16F:
848 return GL_RGBA16F0x881A;
849 case EiifR32F:
850 return GL_R32F0x822E;
851 case EiifRGBA32UI:
852 return GL_RGBA32UI0x8D70;
853 case EiifRGBA16UI:
854 return GL_RGBA16UI0x8D76;
855 case EiifRGBA8UI:
856 return GL_RGBA8UI0x8D7C;
857 case EiifR32UI:
858 return GL_R32UI0x8236;
859 case EiifRGBA32I:
860 return GL_RGBA32I0x8D82;
861 case EiifRGBA16I:
862 return GL_RGBA16I0x8D88;
863 case EiifRGBA8I:
864 return GL_RGBA8I0x8D8E;
865 case EiifR32I:
866 return GL_R32I0x8235;
867 case EiifRGBA8:
868 return GL_RGBA80x8058;
869 case EiifRGBA8_SNORM:
870 return GL_RGBA8_SNORM0x8F97;
871 default:
872 return GL_NONE0;
873 }
874}
875
876bool IsSpecWithFunctionBodyNewScope(ShShaderSpec shaderSpec, int shaderVersion)
877{
878 return (shaderVersion == 100 && !sh::IsWebGLBasedSpec(shaderSpec));
879}
880
881ImplicitTypeConversion GetConversion(TBasicType t1, TBasicType t2)
882{
883 if (t1 == t2)
884 return ImplicitTypeConversion::Same;
885
886 switch (t1)
887 {
888 case EbtInt:
889 switch (t2)
890 {
891 case EbtInt:
892 UNREACHABLE()do { !((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL
))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify
() & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
, __FUNCTION__, 892, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
<< ":" << 892 << ")"; } while (0)
;
893 break;
894 case EbtUInt:
895 return ImplicitTypeConversion::Invalid;
896 case EbtFloat:
897 return ImplicitTypeConversion::Left;
898 default:
899 return ImplicitTypeConversion::Invalid;
900 }
901 break;
902 case EbtUInt:
903 switch (t2)
904 {
905 case EbtInt:
906 return ImplicitTypeConversion::Invalid;
907 case EbtUInt:
908 UNREACHABLE()do { !((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL
))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify
() & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
, __FUNCTION__, 908, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
<< ":" << 908 << ")"; } while (0)
;
909 break;
910 case EbtFloat:
911 return ImplicitTypeConversion::Left;
912 default:
913 return ImplicitTypeConversion::Invalid;
914 }
915 break;
916 case EbtFloat:
917 switch (t2)
918 {
919 case EbtInt:
920 case EbtUInt:
921 return ImplicitTypeConversion::Right;
922 case EbtFloat:
923 UNREACHABLE()do { !((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL
))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify
() & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
, __FUNCTION__, 923, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
<< ":" << 923 << ")"; } while (0)
;
924 break;
925 default:
926 return ImplicitTypeConversion::Invalid;
927 }
928 break;
929 default:
930 return ImplicitTypeConversion::Invalid;
931 }
932 return ImplicitTypeConversion::Invalid;
933}
934
935bool IsValidImplicitConversion(sh::ImplicitTypeConversion conversion, TOperator op)
936{
937 switch (conversion)
938 {
939 case sh::ImplicitTypeConversion::Same:
940 return true;
941 case sh::ImplicitTypeConversion::Left:
942 switch (op)
943 {
944 case EOpEqual:
945 case EOpNotEqual:
946 case EOpLessThan:
947 case EOpGreaterThan:
948 case EOpLessThanEqual:
949 case EOpGreaterThanEqual:
950 case EOpAdd:
951 case EOpSub:
952 case EOpMul:
953 case EOpDiv:
954 return true;
955 default:
956 break;
957 }
958 break;
959 case sh::ImplicitTypeConversion::Right:
960 switch (op)
961 {
962 case EOpAssign:
963 case EOpInitialize:
964 case EOpEqual:
965 case EOpNotEqual:
966 case EOpLessThan:
967 case EOpGreaterThan:
968 case EOpLessThanEqual:
969 case EOpGreaterThanEqual:
970 case EOpAdd:
971 case EOpSub:
972 case EOpMul:
973 case EOpDiv:
974 case EOpAddAssign:
975 case EOpSubAssign:
976 case EOpMulAssign:
977 case EOpDivAssign:
978 return true;
979 default:
980 break;
981 }
982 break;
983 case sh::ImplicitTypeConversion::Invalid:
984 break;
985 }
986 return false;
987}
988
989bool IsPrecisionApplicableToType(TBasicType type)
990{
991 switch (type)
992 {
993 case EbtInt:
994 case EbtUInt:
995 case EbtFloat:
996 // TODO: find all types where precision is applicable; for example samplers.
997 // http://anglebug.com/6132
998 return true;
999 default:
1000 return false;
1001 }
1002}
1003
1004bool IsRedeclarableBuiltIn(const ImmutableString &name)
1005{
1006 return name == "gl_ClipDistance" || name == "gl_CullDistance" || name == "gl_LastFragData" ||
1007 name == "gl_PerVertex" || name == "gl_Position" || name == "gl_PointSize";
1008}
1009
1010size_t FindFieldIndex(const TFieldList &fieldList, const char *fieldName)
1011{
1012 for (size_t fieldIndex = 0; fieldIndex < fieldList.size(); ++fieldIndex)
1013 {
1014 if (strcmp(fieldList[fieldIndex]->name().data(), fieldName) == 0)
1015 {
1016 return fieldIndex;
1017 }
1018 }
1019 UNREACHABLE()do { !((::gl::priv::ShouldCreatePlatformLogMessage(::gl::LOG_FATAL
))) ? static_cast<void>(0) : ::gl::priv::LogMessageVoidify
() & (::gl::LogMessage("/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
, __FUNCTION__, 1019, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/util.cpp"
<< ":" << 1019 << ")"; } while (0)
;
1020 return 0;
1021}
1022
1023} // namespace sh