Bug Summary

File:root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp
Warning:line 1012, column 5
Called C++ object pointer is null

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 IntermNode.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/IntermNode.cpp
1//
2// Copyright 2002 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//
8// Build the intermediate representation.
9//
10
11#include <float.h>
12#include <limits.h>
13#include <math.h>
14#include <stdlib.h>
15#include <algorithm>
16#include <vector>
17
18#include "common/mathutil.h"
19#include "common/matrix_utils.h"
20#include "common/utilities.h"
21#include "compiler/translator/Diagnostics.h"
22#include "compiler/translator/ImmutableString.h"
23#include "compiler/translator/IntermNode.h"
24#include "compiler/translator/SymbolTable.h"
25#include "compiler/translator/util.h"
26
27namespace sh
28{
29
30namespace
31{
32
33const float kPi = 3.14159265358979323846f;
34const float kDegreesToRadiansMultiplier = kPi / 180.0f;
35const float kRadiansToDegreesMultiplier = 180.0f / kPi;
36
37TPrecision GetHigherPrecision(TPrecision left, TPrecision right)
38{
39 return left > right ? left : right;
40}
41
42TConstantUnion *Vectorize(const TConstantUnion &constant, size_t size)
43{
44 TConstantUnion *constUnion = new TConstantUnion[size];
45 for (size_t i = 0; i < size; ++i)
46 constUnion[i] = constant;
47
48 return constUnion;
49}
50
51void UndefinedConstantFoldingError(const TSourceLoc &loc,
52 const TFunction *function,
53 TBasicType basicType,
54 TDiagnostics *diagnostics,
55 TConstantUnion *result)
56{
57 diagnostics->warning(loc, "operation result is undefined for the values passed in",
58 function->name().data());
59
60 switch (basicType)
61 {
62 case EbtFloat:
63 result->setFConst(0.0f);
64 break;
65 case EbtInt:
66 result->setIConst(0);
67 break;
68 case EbtUInt:
69 result->setUConst(0u);
70 break;
71 case EbtBool:
72 result->setBConst(false);
73 break;
74 default:
75 break;
76 }
77}
78
79float VectorLength(const TConstantUnion *paramArray, size_t paramArraySize)
80{
81 float result = 0.0f;
82 for (size_t i = 0; i < paramArraySize; i++)
83 {
84 float f = paramArray[i].getFConst();
85 result += f * f;
86 }
87 return sqrtf(result);
88}
89
90float VectorDotProduct(const TConstantUnion *paramArray1,
91 const TConstantUnion *paramArray2,
92 size_t paramArraySize)
93{
94 float result = 0.0f;
95 for (size_t i = 0; i < paramArraySize; i++)
96 result += paramArray1[i].getFConst() * paramArray2[i].getFConst();
97 return result;
98}
99
100TIntermTyped *CreateFoldedNode(const TConstantUnion *constArray, const TIntermTyped *originalNode)
101{
102 ASSERT(constArray != nullptr)(constArray != nullptr ? 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/IntermNode.cpp"
, __FUNCTION__, 102, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 102 << "): " << "constArray != nullptr"
))
;
103 // Note that we inherit whatever qualifier the folded node had. Nodes may be constant folded
104 // without being qualified as constant.
105 TIntermTyped *folded = new TIntermConstantUnion(constArray, originalNode->getType());
106 folded->setLine(originalNode->getLine());
107 return folded;
108}
109
110angle::Matrix<float> GetMatrix(const TConstantUnion *paramArray,
111 const unsigned int rows,
112 const unsigned int cols)
113{
114 std::vector<float> elements;
115 for (size_t i = 0; i < rows * cols; i++)
116 elements.push_back(paramArray[i].getFConst());
117 // Transpose is used since the Matrix constructor expects arguments in row-major order,
118 // whereas the paramArray is in column-major order. Rows/cols parameters are also flipped below
119 // so that the created matrix will have the expected dimensions after the transpose.
120 return angle::Matrix<float>(elements, cols, rows).transpose();
121}
122
123angle::Matrix<float> GetMatrix(const TConstantUnion *paramArray, const unsigned int size)
124{
125 std::vector<float> elements;
126 for (size_t i = 0; i < size * size; i++)
127 elements.push_back(paramArray[i].getFConst());
128 // Transpose is used since the Matrix constructor expects arguments in row-major order,
129 // whereas the paramArray is in column-major order.
130 return angle::Matrix<float>(elements, size).transpose();
131}
132
133void SetUnionArrayFromMatrix(const angle::Matrix<float> &m, TConstantUnion *resultArray)
134{
135 // Transpose is used since the input Matrix is in row-major order,
136 // whereas the actual result should be in column-major order.
137 angle::Matrix<float> result = m.transpose();
138 std::vector<float> resultElements = result.elements();
139 for (size_t i = 0; i < resultElements.size(); i++)
140 resultArray[i].setFConst(resultElements[i]);
141}
142
143bool CanFoldAggregateBuiltInOp(TOperator op)
144{
145 switch (op)
146 {
147 case EOpAtan:
148 case EOpPow:
149 case EOpMod:
150 case EOpMin:
151 case EOpMax:
152 case EOpClamp:
153 case EOpMix:
154 case EOpStep:
155 case EOpSmoothstep:
156 case EOpFma:
157 case EOpLdexp:
158 case EOpMatrixCompMult:
159 case EOpOuterProduct:
160 case EOpEqualComponentWise:
161 case EOpNotEqualComponentWise:
162 case EOpLessThanComponentWise:
163 case EOpLessThanEqualComponentWise:
164 case EOpGreaterThanComponentWise:
165 case EOpGreaterThanEqualComponentWise:
166 case EOpDistance:
167 case EOpDot:
168 case EOpCross:
169 case EOpFaceforward:
170 case EOpReflect:
171 case EOpRefract:
172 case EOpBitfieldExtract:
173 case EOpBitfieldInsert:
174 case EOpDFdx:
175 case EOpDFdy:
176 case EOpFwidth:
177 return true;
178 default:
179 return false;
180 }
181}
182
183void PropagatePrecisionIfApplicable(TIntermTyped *node, TPrecision precision)
184{
185 if (precision == EbpUndefined || node->getPrecision() != EbpUndefined)
186 {
187 return;
188 }
189
190 if (IsPrecisionApplicableToType(node->getBasicType()))
191 {
192 node->propagatePrecision(precision);
193 }
194}
195
196} // namespace
197
198////////////////////////////////////////////////////////////////
199//
200// Member functions of the nodes used for building the tree.
201//
202////////////////////////////////////////////////////////////////
203
204TIntermExpression::TIntermExpression(const TType &t) : TIntermTyped(), mType(t) {}
205
206#define REPLACE_IF_IS(node, type, original, replacement)do { if (node == original) { node = static_cast<type *>
(replacement); return true; } } while (0)
\
207 do \
208 { \
209 if (node == original) \
210 { \
211 node = static_cast<type *>(replacement); \
212 return true; \
213 } \
214 } while (0)
215
216size_t TIntermSymbol::getChildCount() const
217{
218 return 0;
219}
220
221TIntermNode *TIntermSymbol::getChildNode(size_t index) const
222{
223 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/IntermNode.cpp"
, __FUNCTION__, 223, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 223 << ")"; } while (0)
;
224 return nullptr;
225}
226
227size_t TIntermConstantUnion::getChildCount() const
228{
229 return 0;
230}
231
232TIntermNode *TIntermConstantUnion::getChildNode(size_t index) const
233{
234 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/IntermNode.cpp"
, __FUNCTION__, 234, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 234 << ")"; } while (0)
;
235 return nullptr;
236}
237
238size_t TIntermLoop::getChildCount() const
239{
240 return (mInit ? 1 : 0) + (mCond ? 1 : 0) + (mExpr ? 1 : 0) + (mBody ? 1 : 0);
241}
242
243TIntermNode *TIntermLoop::getChildNode(size_t index) const
244{
245 TIntermNode *children[4];
246 unsigned int childIndex = 0;
247 if (mInit)
248 {
249 children[childIndex] = mInit;
250 ++childIndex;
251 }
252 if (mCond)
253 {
254 children[childIndex] = mCond;
255 ++childIndex;
256 }
257 if (mExpr)
258 {
259 children[childIndex] = mExpr;
260 ++childIndex;
261 }
262 if (mBody)
263 {
264 children[childIndex] = mBody;
265 ++childIndex;
266 }
267 ASSERT(index < childIndex)(index < childIndex ? 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/IntermNode.cpp"
, __FUNCTION__, 267, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 267 << "): " << "index < childIndex"
))
;
268 return children[index];
269}
270
271bool TIntermLoop::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
272{
273 ASSERT(original != nullptr)(original != nullptr ? 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/IntermNode.cpp"
, __FUNCTION__, 273, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 273 << "): " << "original != nullptr"
))
; // This risks replacing multiple children.
274 REPLACE_IF_IS(mInit, TIntermNode, original, replacement)do { if (mInit == original) { mInit = static_cast<TIntermNode
*>(replacement); return true; } } while (0)
;
275 REPLACE_IF_IS(mCond, TIntermTyped, original, replacement)do { if (mCond == original) { mCond = static_cast<TIntermTyped
*>(replacement); return true; } } while (0)
;
276 REPLACE_IF_IS(mExpr, TIntermTyped, original, replacement)do { if (mExpr == original) { mExpr = static_cast<TIntermTyped
*>(replacement); return true; } } while (0)
;
277 REPLACE_IF_IS(mBody, TIntermBlock, original, replacement)do { if (mBody == original) { mBody = static_cast<TIntermBlock
*>(replacement); return true; } } while (0)
;
278 return false;
279}
280
281TIntermBranch::TIntermBranch(const TIntermBranch &node)
282 : TIntermBranch(node.mFlowOp, node.mExpression ? node.mExpression->deepCopy() : nullptr)
283{}
284
285size_t TIntermBranch::getChildCount() const
286{
287 return (mExpression ? 1 : 0);
288}
289
290TIntermNode *TIntermBranch::getChildNode(size_t index) const
291{
292 ASSERT(mExpression)(mExpression ? 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/IntermNode.cpp"
, __FUNCTION__, 292, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 292 << "): " << "mExpression"
))
;
293 ASSERT(index == 0)(index == 0 ? 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/IntermNode.cpp"
, __FUNCTION__, 293, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 293 << "): " << "index == 0"
))
;
294 return mExpression;
295}
296
297bool TIntermBranch::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
298{
299 REPLACE_IF_IS(mExpression, TIntermTyped, original, replacement)do { if (mExpression == original) { mExpression = static_cast
<TIntermTyped *>(replacement); return true; } } while (
0)
;
300 return false;
301}
302
303size_t TIntermSwizzle::getChildCount() const
304{
305 return 1;
306}
307
308TIntermNode *TIntermSwizzle::getChildNode(size_t index) const
309{
310 ASSERT(mOperand)(mOperand ? 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/IntermNode.cpp"
, __FUNCTION__, 310, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 310 << "): " << "mOperand"
))
;
311 ASSERT(index == 0)(index == 0 ? 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/IntermNode.cpp"
, __FUNCTION__, 311, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 311 << "): " << "index == 0"
))
;
312 return mOperand;
313}
314
315bool TIntermSwizzle::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
316{
317 ASSERT(original->getAsTyped()->getType() == replacement->getAsTyped()->getType())(original->getAsTyped()->getType() == replacement->getAsTyped
()->getType() ? 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/IntermNode.cpp"
, __FUNCTION__, 317, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 317 << "): " << "original->getAsTyped()->getType() == replacement->getAsTyped()->getType()"
))
;
318 REPLACE_IF_IS(mOperand, TIntermTyped, original, replacement)do { if (mOperand == original) { mOperand = static_cast<TIntermTyped
*>(replacement); return true; } } while (0)
;
319 return false;
320}
321
322size_t TIntermBinary::getChildCount() const
323{
324 return 2;
325}
326
327TIntermNode *TIntermBinary::getChildNode(size_t index) const
328{
329 ASSERT(index < 2)(index < 2 ? 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/IntermNode.cpp"
, __FUNCTION__, 329, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 329 << "): " << "index < 2"
))
;
330 if (index == 0)
331 {
332 return mLeft;
333 }
334 return mRight;
335}
336
337bool TIntermBinary::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
338{
339 REPLACE_IF_IS(mLeft, TIntermTyped, original, replacement)do { if (mLeft == original) { mLeft = static_cast<TIntermTyped
*>(replacement); return true; } } while (0)
;
340 REPLACE_IF_IS(mRight, TIntermTyped, original, replacement)do { if (mRight == original) { mRight = static_cast<TIntermTyped
*>(replacement); return true; } } while (0)
;
341 return false;
342}
343
344size_t TIntermUnary::getChildCount() const
345{
346 return 1;
347}
348
349TIntermNode *TIntermUnary::getChildNode(size_t index) const
350{
351 ASSERT(mOperand)(mOperand ? 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/IntermNode.cpp"
, __FUNCTION__, 351, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 351 << "): " << "mOperand"
))
;
352 ASSERT(index == 0)(index == 0 ? 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/IntermNode.cpp"
, __FUNCTION__, 352, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 352 << "): " << "index == 0"
))
;
353 return mOperand;
354}
355
356bool TIntermUnary::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
357{
358 ASSERT(original->getAsTyped()->getType() == replacement->getAsTyped()->getType())(original->getAsTyped()->getType() == replacement->getAsTyped
()->getType() ? 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/IntermNode.cpp"
, __FUNCTION__, 358, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 358 << "): " << "original->getAsTyped()->getType() == replacement->getAsTyped()->getType()"
))
;
359 REPLACE_IF_IS(mOperand, TIntermTyped, original, replacement)do { if (mOperand == original) { mOperand = static_cast<TIntermTyped
*>(replacement); return true; } } while (0)
;
360 return false;
361}
362
363size_t TIntermGlobalQualifierDeclaration::getChildCount() const
364{
365 return 1;
366}
367
368TIntermNode *TIntermGlobalQualifierDeclaration::getChildNode(size_t index) const
369{
370 ASSERT(mSymbol)(mSymbol ? 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/IntermNode.cpp"
, __FUNCTION__, 370, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 370 << "): " << "mSymbol")
)
;
371 ASSERT(index == 0)(index == 0 ? 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/IntermNode.cpp"
, __FUNCTION__, 371, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 371 << "): " << "index == 0"
))
;
372 return mSymbol;
373}
374
375bool TIntermGlobalQualifierDeclaration::replaceChildNode(TIntermNode *original,
376 TIntermNode *replacement)
377{
378 REPLACE_IF_IS(mSymbol, TIntermSymbol, original, replacement)do { if (mSymbol == original) { mSymbol = static_cast<TIntermSymbol
*>(replacement); return true; } } while (0)
;
379 return false;
380}
381
382size_t TIntermFunctionDefinition::getChildCount() const
383{
384 return 2;
385}
386
387TIntermNode *TIntermFunctionDefinition::getChildNode(size_t index) const
388{
389 ASSERT(index < 2)(index < 2 ? 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/IntermNode.cpp"
, __FUNCTION__, 389, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 389 << "): " << "index < 2"
))
;
390 if (index == 0)
391 {
392 return mPrototype;
393 }
394 return mBody;
395}
396
397bool TIntermFunctionDefinition::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
398{
399 REPLACE_IF_IS(mPrototype, TIntermFunctionPrototype, original, replacement)do { if (mPrototype == original) { mPrototype = static_cast<
TIntermFunctionPrototype *>(replacement); return true; } }
while (0)
;
400 REPLACE_IF_IS(mBody, TIntermBlock, original, replacement)do { if (mBody == original) { mBody = static_cast<TIntermBlock
*>(replacement); return true; } } while (0)
;
401 return false;
402}
403
404size_t TIntermAggregate::getChildCount() const
405{
406 return mArguments.size();
407}
408
409TIntermNode *TIntermAggregate::getChildNode(size_t index) const
410{
411 return mArguments[index];
412}
413
414bool TIntermAggregate::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
415{
416 return replaceChildNodeInternal(original, replacement);
417}
418
419TIntermBlock::TIntermBlock(const TIntermBlock &node)
420{
421 for (TIntermNode *intermNode : node.mStatements)
422 {
423 mStatements.push_back(intermNode->deepCopy());
424 }
425
426 ASSERT(!node.mIsTreeRoot)(!node.mIsTreeRoot ? 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/IntermNode.cpp"
, __FUNCTION__, 426, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 426 << "): " << "!node.mIsTreeRoot"
))
;
427 mIsTreeRoot = false;
428}
429
430TIntermBlock::TIntermBlock(std::initializer_list<TIntermNode *> stmts)
431{
432 for (TIntermNode *stmt : stmts)
433 {
434 appendStatement(stmt);
435 }
436}
437
438size_t TIntermBlock::getChildCount() const
439{
440 return mStatements.size();
441}
442
443TIntermNode *TIntermBlock::getChildNode(size_t index) const
444{
445 return mStatements[index];
446}
447
448bool TIntermBlock::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
449{
450 return replaceChildNodeInternal(original, replacement);
451}
452
453void TIntermBlock::replaceAllChildren(const TIntermSequence &newStatements)
454{
455 mStatements.clear();
456 mStatements.insert(mStatements.begin(), newStatements.begin(), newStatements.end());
457}
458
459size_t TIntermFunctionPrototype::getChildCount() const
460{
461 return 0;
462}
463
464TIntermNode *TIntermFunctionPrototype::getChildNode(size_t index) const
465{
466 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/IntermNode.cpp"
, __FUNCTION__, 466, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 466 << ")"; } while (0)
;
467 return nullptr;
468}
469
470bool TIntermFunctionPrototype::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
471{
472 return false;
473}
474
475TIntermDeclaration::TIntermDeclaration(const TVariable *var, TIntermTyped *initExpr)
476{
477 if (initExpr)
478 {
479 appendDeclarator(
480 new TIntermBinary(TOperator::EOpInitialize, new TIntermSymbol(var), initExpr));
481 }
482 else
483 {
484 appendDeclarator(new TIntermSymbol(var));
485 }
486}
487
488TIntermDeclaration::TIntermDeclaration(std::initializer_list<const TVariable *> declarators)
489 : TIntermDeclaration()
490{
491 for (const TVariable *d : declarators)
492 {
493 appendDeclarator(new TIntermSymbol(d));
494 }
495}
496
497TIntermDeclaration::TIntermDeclaration(std::initializer_list<TIntermTyped *> declarators)
498 : TIntermDeclaration()
499{
500 for (TIntermTyped *d : declarators)
1
Assuming '__begin1' is not equal to '__end1'
2
'd' initialized here
501 {
502 appendDeclarator(d);
3
Passing value via 1st parameter 'declarator'
4
Calling 'TIntermDeclaration::appendDeclarator'
503 }
504}
505
506size_t TIntermDeclaration::getChildCount() const
507{
508 return mDeclarators.size();
509}
510
511TIntermNode *TIntermDeclaration::getChildNode(size_t index) const
512{
513 return mDeclarators[index];
514}
515
516bool TIntermDeclaration::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
517{
518 return replaceChildNodeInternal(original, replacement);
519}
520
521TIntermDeclaration::TIntermDeclaration(const TIntermDeclaration &node)
522{
523 for (TIntermNode *intermNode : node.mDeclarators)
524 {
525 mDeclarators.push_back(intermNode->deepCopy());
526 }
527}
528
529bool TIntermAggregateBase::replaceChildNodeInternal(TIntermNode *original, TIntermNode *replacement)
530{
531 for (size_t ii = 0; ii < getSequence()->size(); ++ii)
532 {
533 REPLACE_IF_IS((*getSequence())[ii], TIntermNode, original, replacement)do { if ((*getSequence())[ii] == original) { (*getSequence())
[ii] = static_cast<TIntermNode *>(replacement); return true
; } } while (0)
;
534 }
535 return false;
536}
537
538bool TIntermAggregateBase::replaceChildNodeWithMultiple(TIntermNode *original,
539 const TIntermSequence &replacements)
540{
541 for (auto it = getSequence()->begin(); it < getSequence()->end(); ++it)
542 {
543 if (*it == original)
544 {
545 it = getSequence()->erase(it);
546 getSequence()->insert(it, replacements.begin(), replacements.end());
547 return true;
548 }
549 }
550 return false;
551}
552
553bool TIntermAggregateBase::insertChildNodes(TIntermSequence::size_type position,
554 const TIntermSequence &insertions)
555{
556 if (position > getSequence()->size())
557 {
558 return false;
559 }
560 auto it = getSequence()->begin() + position;
561 getSequence()->insert(it, insertions.begin(), insertions.end());
562 return true;
563}
564
565TIntermSymbol::TIntermSymbol(const TVariable *variable) : TIntermTyped(), mVariable(variable) {}
566
567bool TIntermSymbol::hasConstantValue() const
568{
569 return variable().getConstPointer() != nullptr;
570}
571
572const TConstantUnion *TIntermSymbol::getConstantValue() const
573{
574 return variable().getConstPointer();
575}
576
577const TSymbolUniqueId &TIntermSymbol::uniqueId() const
578{
579 return mVariable->uniqueId();
580}
581
582ImmutableString TIntermSymbol::getName() const
583{
584 return mVariable->name();
585}
586
587const TType &TIntermSymbol::getType() const
588{
589 return mVariable->getType();
590}
591
592void TIntermSymbol::propagatePrecision(TPrecision precision)
593{
594 // Every declared variable should already have a precision. Some built-ins don't have a defined
595 // precision. This is not asserted however:
596 //
597 // - A shader with no precision specified either globally or on a variable will fail with a
598 // compilation error later on.
599 // - Transformations declaring variables without precision will be caught by AST validation.
600}
601
602TIntermAggregate *TIntermAggregate::CreateFunctionCall(const TFunction &func,
603 TIntermSequence *arguments)
604{
605 return new TIntermAggregate(&func, func.getReturnType(), EOpCallFunctionInAST, arguments);
606}
607
608TIntermAggregate *TIntermAggregate::CreateRawFunctionCall(const TFunction &func,
609 TIntermSequence *arguments)
610{
611 return new TIntermAggregate(&func, func.getReturnType(), EOpCallInternalRawFunction, arguments);
612}
613
614TIntermAggregate *TIntermAggregate::CreateBuiltInFunctionCall(const TFunction &func,
615 TIntermSequence *arguments)
616{
617 // Every built-in function should have an op.
618 ASSERT(func.getBuiltInOp() != EOpNull)(func.getBuiltInOp() != EOpNull ? 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/IntermNode.cpp"
, __FUNCTION__, 618, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 618 << "): " << "func.getBuiltInOp() != EOpNull"
))
;
619 return new TIntermAggregate(&func, func.getReturnType(), func.getBuiltInOp(), arguments);
620}
621
622TIntermAggregate *TIntermAggregate::CreateConstructor(const TType &type, TIntermSequence *arguments)
623{
624 return new TIntermAggregate(nullptr, type, EOpConstruct, arguments);
625}
626
627TIntermAggregate *TIntermAggregate::CreateConstructor(
628 const TType &type,
629 const std::initializer_list<TIntermNode *> &arguments)
630{
631 TIntermSequence argSequence(arguments);
632 return CreateConstructor(type, &argSequence);
633}
634
635TIntermAggregate::TIntermAggregate(const TFunction *func,
636 const TType &type,
637 TOperator op,
638 TIntermSequence *arguments)
639 : TIntermOperator(op, type), mUseEmulatedFunction(false), mFunction(func)
640{
641 if (arguments != nullptr)
642 {
643 mArguments.swap(*arguments);
644 }
645 ASSERT(mFunction == nullptr || mFunction->symbolType() != SymbolType::Empty)(mFunction == nullptr || mFunction->symbolType() != SymbolType
::Empty ? 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/IntermNode.cpp"
, __FUNCTION__, 645, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 645 << "): " << "mFunction == nullptr || mFunction->symbolType() != SymbolType::Empty"
))
;
646 setPrecisionAndQualifier();
647}
648
649void TIntermAggregate::setPrecisionAndQualifier()
650{
651 mType.setQualifier(EvqTemporary);
652 if ((!BuiltInGroup::IsBuiltIn(mOp) && !isFunctionCall()) || BuiltInGroup::IsMath(mOp))
653 {
654 if (areChildrenConstQualified())
655 {
656 mType.setQualifier(EvqConst);
657 }
658 }
659
660 propagatePrecision(derivePrecision());
661}
662
663bool TIntermAggregate::areChildrenConstQualified()
664{
665 for (TIntermNode *arg : mArguments)
666 {
667 TIntermTyped *typedArg = arg->getAsTyped();
668 if (typedArg && typedArg->getQualifier() != EvqConst)
669 {
670 return false;
671 }
672 }
673 return true;
674}
675
676// Derive precision from children nodes
677TPrecision TIntermAggregate::derivePrecision() const
678{
679 if (getBasicType() == EbtBool || getBasicType() == EbtVoid || getBasicType() == EbtStruct)
680 {
681 return EbpUndefined;
682 }
683
684 // For AST function calls, take the qualifier from the declared one.
685 if (isFunctionCall())
686 {
687 return mType.getPrecision();
688 }
689
690 // Some built-ins explicitly specify their precision.
691 switch (mOp)
692 {
693 case EOpBitfieldExtract:
694 return mArguments[0]->getAsTyped()->getPrecision();
695 case EOpBitfieldInsert:
696 return GetHigherPrecision(mArguments[0]->getAsTyped()->getPrecision(),
697 mArguments[1]->getAsTyped()->getPrecision());
698 case EOpTextureSize:
699 case EOpImageSize:
700 case EOpUaddCarry:
701 case EOpUsubBorrow:
702 case EOpUmulExtended:
703 case EOpImulExtended:
704 case EOpFrexp:
705 case EOpLdexp:
706 return EbpHigh;
707 default:
708 break;
709 }
710
711 // The rest of the math operations and constructors get their precision from their arguments.
712 if (BuiltInGroup::IsMath(mOp) || mOp == EOpConstruct)
713 {
714 TPrecision precision = EbpUndefined;
715 for (TIntermNode *argument : mArguments)
716 {
717 precision = GetHigherPrecision(argument->getAsTyped()->getPrecision(), precision);
718 }
719 return precision;
720 }
721
722 // Atomic operations return highp.
723 if (BuiltInGroup::IsImageAtomic(mOp) || BuiltInGroup::IsAtomicCounter(mOp) ||
724 BuiltInGroup::IsAtomicMemory(mOp))
725 {
726 return EbpHigh;
727 }
728
729 // Texture functions return the same precision as that of the sampler (textureSize returns
730 // highp, but that's handled above). imageLoad similar takes the precision of the image. The
731 // same is true for dFd*, interpolateAt* and subpassLoad operations.
732 if (BuiltInGroup::IsTexture(mOp) || BuiltInGroup::IsImageLoad(mOp) ||
733 BuiltInGroup::IsDerivativesFS(mOp) || BuiltInGroup::IsInterpolationFS(mOp) ||
734 mOp == EOpSubpassLoad)
735 {
736 return mArguments[0]->getAsTyped()->getPrecision();
737 }
738
739 // Every possibility must be explicitly handled, except for desktop-GLSL-specific built-ins
740 // for which precision does't matter.
741 return EbpUndefined;
742}
743
744// Propagate precision to children nodes that don't already have it defined.
745void TIntermAggregate::propagatePrecision(TPrecision precision)
746{
747 mType.setPrecision(precision);
748
749 // For constructors, propagate precision to arguments.
750 if (isConstructor())
751 {
752 for (TIntermNode *arg : mArguments)
753 {
754 PropagatePrecisionIfApplicable(arg->getAsTyped(), precision);
755 }
756 return;
757 }
758
759 // For function calls, propagate precision of each parameter to its corresponding argument.
760 if (isFunctionCall())
761 {
762 for (size_t paramIndex = 0; paramIndex < mFunction->getParamCount(); ++paramIndex)
763 {
764 const TVariable *paramVariable = mFunction->getParam(paramIndex);
765 PropagatePrecisionIfApplicable(mArguments[paramIndex]->getAsTyped(),
766 paramVariable->getType().getPrecision());
767 }
768 return;
769 }
770
771 // Some built-ins explicitly specify the precision of their parameters.
772 switch (mOp)
773 {
774 case EOpUaddCarry:
775 case EOpUsubBorrow:
776 case EOpUmulExtended:
777 case EOpImulExtended:
778 PropagatePrecisionIfApplicable(mArguments[0]->getAsTyped(), EbpHigh);
779 PropagatePrecisionIfApplicable(mArguments[1]->getAsTyped(), EbpHigh);
780 break;
781 case EOpFindMSB:
782 case EOpFrexp:
783 case EOpLdexp:
784 PropagatePrecisionIfApplicable(mArguments[0]->getAsTyped(), EbpHigh);
785 break;
786 default:
787 break;
788 }
789}
790
791const char *TIntermAggregate::functionName() const
792{
793 ASSERT(!isConstructor())(!isConstructor() ? 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/IntermNode.cpp"
, __FUNCTION__, 793, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 793 << "): " << "!isConstructor()"
))
;
794 switch (mOp)
795 {
796 case EOpCallInternalRawFunction:
797 case EOpCallFunctionInAST:
798 return mFunction->name().data();
799 default:
800 if (BuiltInGroup::IsBuiltIn(mOp))
801 {
802 return mFunction->name().data();
803 }
804 return GetOperatorString(mOp);
805 }
806}
807
808bool TIntermAggregate::hasConstantValue() const
809{
810 if (!isConstructor())
811 {
812 return false;
813 }
814 for (TIntermNode *constructorArg : mArguments)
815 {
816 if (!constructorArg->getAsTyped()->hasConstantValue())
817 {
818 return false;
819 }
820 }
821 return true;
822}
823
824bool TIntermAggregate::isConstantNullValue() const
825{
826 if (!isConstructor())
827 {
828 return false;
829 }
830 for (TIntermNode *constructorArg : mArguments)
831 {
832 if (!constructorArg->getAsTyped()->isConstantNullValue())
833 {
834 return false;
835 }
836 }
837 return true;
838}
839
840const TConstantUnion *TIntermAggregate::getConstantValue() const
841{
842 if (!hasConstantValue())
843 {
844 return nullptr;
845 }
846 ASSERT(isConstructor())(isConstructor() ? 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/IntermNode.cpp"
, __FUNCTION__, 846, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 846 << "): " << "isConstructor()"
))
;
847 ASSERT(mArguments.size() > 0u)(mArguments.size() > 0u ? 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/IntermNode.cpp"
, __FUNCTION__, 847, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 847 << "): " << "mArguments.size() > 0u"
))
;
848
849 TConstantUnion *constArray = nullptr;
850 if (isArray())
851 {
852 size_t elementSize = mArguments.front()->getAsTyped()->getType().getObjectSize();
853 constArray = new TConstantUnion[elementSize * getOutermostArraySize()];
854
855 size_t elementOffset = 0u;
856 for (TIntermNode *constructorArg : mArguments)
857 {
858 const TConstantUnion *elementConstArray =
859 constructorArg->getAsTyped()->getConstantValue();
860 ASSERT(elementConstArray)(elementConstArray ? 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/IntermNode.cpp"
, __FUNCTION__, 860, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 860 << "): " << "elementConstArray"
))
;
861 size_t elementSizeBytes = sizeof(TConstantUnion) * elementSize;
862 memcpy(static_cast<void *>(&constArray[elementOffset]),
863 static_cast<const void *>(elementConstArray), elementSizeBytes);
864 elementOffset += elementSize;
865 }
866 return constArray;
867 }
868
869 size_t resultSize = getType().getObjectSize();
870 constArray = new TConstantUnion[resultSize];
871 TBasicType basicType = getBasicType();
872
873 size_t resultIndex = 0u;
874
875 if (mArguments.size() == 1u)
876 {
877 TIntermNode *argument = mArguments.front();
878 TIntermTyped *argumentTyped = argument->getAsTyped();
879 const TConstantUnion *argumentConstantValue = argumentTyped->getConstantValue();
880 // Check the special case of constructing a matrix diagonal from a single scalar,
881 // or a vector from a single scalar.
882 if (argumentTyped->getType().getObjectSize() == 1u)
883 {
884 if (isMatrix())
885 {
886 const uint8_t resultCols = getType().getCols();
887 const uint8_t resultRows = getType().getRows();
888 for (uint8_t col = 0; col < resultCols; ++col)
889 {
890 for (uint8_t row = 0; row < resultRows; ++row)
891 {
892 if (col == row)
893 {
894 constArray[resultIndex].cast(basicType, argumentConstantValue[0]);
895 }
896 else
897 {
898 constArray[resultIndex].setFConst(0.0f);
899 }
900 ++resultIndex;
901 }
902 }
903 }
904 else
905 {
906 while (resultIndex < resultSize)
907 {
908 constArray[resultIndex].cast(basicType, argumentConstantValue[0]);
909 ++resultIndex;
910 }
911 }
912 ASSERT(resultIndex == resultSize)(resultIndex == resultSize ? 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/IntermNode.cpp"
, __FUNCTION__, 912, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 912 << "): " << "resultIndex == resultSize"
))
;
913 return constArray;
914 }
915 else if (isMatrix() && argumentTyped->isMatrix())
916 {
917 // The special case of constructing a matrix from a matrix.
918 const uint8_t argumentCols = argumentTyped->getType().getCols();
919 const uint8_t argumentRows = argumentTyped->getType().getRows();
920 const uint8_t resultCols = getType().getCols();
921 const uint8_t resultRows = getType().getRows();
922 for (uint8_t col = 0; col < resultCols; ++col)
923 {
924 for (uint8_t row = 0; row < resultRows; ++row)
925 {
926 if (col < argumentCols && row < argumentRows)
927 {
928 constArray[resultIndex].cast(
929 basicType, argumentConstantValue[col * argumentRows + row]);
930 }
931 else if (col == row)
932 {
933 constArray[resultIndex].setFConst(1.0f);
934 }
935 else
936 {
937 constArray[resultIndex].setFConst(0.0f);
938 }
939 ++resultIndex;
940 }
941 }
942 ASSERT(resultIndex == resultSize)(resultIndex == resultSize ? 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/IntermNode.cpp"
, __FUNCTION__, 942, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 942 << "): " << "resultIndex == resultSize"
))
;
943 return constArray;
944 }
945 }
946
947 for (TIntermNode *argument : mArguments)
948 {
949 TIntermTyped *argumentTyped = argument->getAsTyped();
950 size_t argumentSize = argumentTyped->getType().getObjectSize();
951 const TConstantUnion *argumentConstantValue = argumentTyped->getConstantValue();
952 for (size_t i = 0u; i < argumentSize; ++i)
953 {
954 if (resultIndex >= resultSize)
955 break;
956 constArray[resultIndex].cast(basicType, argumentConstantValue[i]);
957 ++resultIndex;
958 }
959 }
960 ASSERT(resultIndex == resultSize)(resultIndex == resultSize ? 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/IntermNode.cpp"
, __FUNCTION__, 960, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 960 << "): " << "resultIndex == resultSize"
))
;
961 return constArray;
962}
963
964bool TIntermAggregate::hasSideEffects() const
965{
966 if (getQualifier() == EvqConst)
967 {
968 return false;
969 }
970
971 // If the function itself is known to have a side effect, the expression has a side effect.
972 const bool calledFunctionHasSideEffects =
973 mFunction != nullptr && !mFunction->isKnownToNotHaveSideEffects();
974
975 if (calledFunctionHasSideEffects)
976 {
977 return true;
978 }
979
980 // Otherwise it only has a side effect if one of the arguments does.
981 for (TIntermNode *arg : mArguments)
982 {
983 if (arg->getAsTyped()->hasSideEffects())
984 {
985 return true;
986 }
987 }
988 return false;
989}
990
991void TIntermBlock::appendStatement(TIntermNode *statement)
992{
993 // Declaration nodes with no children can appear if it was an empty declaration or if all the
994 // declarators just added constants to the symbol table instead of generating code. We still
995 // need to add the declaration to the AST in that case because it might be relevant to the
996 // validity of switch/case.
997 if (statement != nullptr)
998 {
999 mStatements.push_back(statement);
1000 }
1001}
1002
1003void TIntermBlock::insertStatement(size_t insertPosition, TIntermNode *statement)
1004{
1005 ASSERT(statement != nullptr)(statement != nullptr ? 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/IntermNode.cpp"
, __FUNCTION__, 1005, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1005 << "): " << "statement != nullptr"
))
;
1006 mStatements.insert(mStatements.begin() + insertPosition, statement);
1007}
1008
1009void TIntermDeclaration::appendDeclarator(TIntermTyped *declarator)
1010{
1011 ASSERT(declarator != nullptr)(declarator != nullptr ? 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/IntermNode.cpp"
, __FUNCTION__, 1011, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1011 << "): " << "declarator != nullptr"
))
;
5
Assuming pointer value is null
6
'?' condition is false
7
Assuming the condition is true
8
'?' condition is true
1012 ASSERT(declarator->getAsSymbolNode() != nullptr ||(declarator->getAsSymbolNode() != nullptr || (declarator->
getAsBinaryNode() != nullptr && declarator->getAsBinaryNode
()->getOp() == EOpInitialize) ? 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/IntermNode.cpp"
, __FUNCTION__, 1014, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1014 << "): " << "declarator->getAsSymbolNode() != nullptr || (declarator->getAsBinaryNode() != nullptr && declarator->getAsBinaryNode()->getOp() == EOpInitialize)"
))
9
Called C++ object pointer is null
1013 (declarator->getAsBinaryNode() != nullptr &&(declarator->getAsSymbolNode() != nullptr || (declarator->
getAsBinaryNode() != nullptr && declarator->getAsBinaryNode
()->getOp() == EOpInitialize) ? 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/IntermNode.cpp"
, __FUNCTION__, 1014, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1014 << "): " << "declarator->getAsSymbolNode() != nullptr || (declarator->getAsBinaryNode() != nullptr && declarator->getAsBinaryNode()->getOp() == EOpInitialize)"
))
1014 declarator->getAsBinaryNode()->getOp() == EOpInitialize))(declarator->getAsSymbolNode() != nullptr || (declarator->
getAsBinaryNode() != nullptr && declarator->getAsBinaryNode
()->getOp() == EOpInitialize) ? 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/IntermNode.cpp"
, __FUNCTION__, 1014, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1014 << "): " << "declarator->getAsSymbolNode() != nullptr || (declarator->getAsBinaryNode() != nullptr && declarator->getAsBinaryNode()->getOp() == EOpInitialize)"
))
;
1015 ASSERT(mDeclarators.empty() ||(mDeclarators.empty() || declarator->getType().sameNonArrayType
(mDeclarators.back()->getAsTyped()->getType()) ? 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/IntermNode.cpp"
, __FUNCTION__, 1016, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1016 << "): " << "mDeclarators.empty() || declarator->getType().sameNonArrayType(mDeclarators.back()->getAsTyped()->getType())"
))
1016 declarator->getType().sameNonArrayType(mDeclarators.back()->getAsTyped()->getType()))(mDeclarators.empty() || declarator->getType().sameNonArrayType
(mDeclarators.back()->getAsTyped()->getType()) ? 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/IntermNode.cpp"
, __FUNCTION__, 1016, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1016 << "): " << "mDeclarators.empty() || declarator->getType().sameNonArrayType(mDeclarators.back()->getAsTyped()->getType())"
))
;
1017 mDeclarators.push_back(declarator);
1018}
1019
1020size_t TIntermTernary::getChildCount() const
1021{
1022 return 3;
1023}
1024
1025TIntermNode *TIntermTernary::getChildNode(size_t index) const
1026{
1027 ASSERT(index < 3)(index < 3 ? 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/IntermNode.cpp"
, __FUNCTION__, 1027, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1027 << "): " << "index < 3"
))
;
1028 if (index == 0)
1029 {
1030 return mCondition;
1031 }
1032 if (index == 1)
1033 {
1034 return mTrueExpression;
1035 }
1036 return mFalseExpression;
1037}
1038
1039bool TIntermTernary::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
1040{
1041 REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement)do { if (mCondition == original) { mCondition = static_cast<
TIntermTyped *>(replacement); return true; } } while (0)
;
1042 REPLACE_IF_IS(mTrueExpression, TIntermTyped, original, replacement)do { if (mTrueExpression == original) { mTrueExpression = static_cast
<TIntermTyped *>(replacement); return true; } } while (
0)
;
1043 REPLACE_IF_IS(mFalseExpression, TIntermTyped, original, replacement)do { if (mFalseExpression == original) { mFalseExpression = static_cast
<TIntermTyped *>(replacement); return true; } } while (
0)
;
1044 return false;
1045}
1046
1047size_t TIntermIfElse::getChildCount() const
1048{
1049 return 1 + (mTrueBlock ? 1 : 0) + (mFalseBlock ? 1 : 0);
1050}
1051
1052TIntermNode *TIntermIfElse::getChildNode(size_t index) const
1053{
1054 if (index == 0)
1055 {
1056 return mCondition;
1057 }
1058 if (mTrueBlock && index == 1)
1059 {
1060 return mTrueBlock;
1061 }
1062 return mFalseBlock;
1063}
1064
1065bool TIntermIfElse::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
1066{
1067 REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement)do { if (mCondition == original) { mCondition = static_cast<
TIntermTyped *>(replacement); return true; } } while (0)
;
1068 REPLACE_IF_IS(mTrueBlock, TIntermBlock, original, replacement)do { if (mTrueBlock == original) { mTrueBlock = static_cast<
TIntermBlock *>(replacement); return true; } } while (0)
;
1069 REPLACE_IF_IS(mFalseBlock, TIntermBlock, original, replacement)do { if (mFalseBlock == original) { mFalseBlock = static_cast
<TIntermBlock *>(replacement); return true; } } while (
0)
;
1070 return false;
1071}
1072
1073size_t TIntermSwitch::getChildCount() const
1074{
1075 return 2;
1076}
1077
1078TIntermNode *TIntermSwitch::getChildNode(size_t index) const
1079{
1080 ASSERT(index < 2)(index < 2 ? 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/IntermNode.cpp"
, __FUNCTION__, 1080, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1080 << "): " << "index < 2"
))
;
1081 if (index == 0)
1082 {
1083 return mInit;
1084 }
1085 return mStatementList;
1086}
1087
1088bool TIntermSwitch::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
1089{
1090 REPLACE_IF_IS(mInit, TIntermTyped, original, replacement)do { if (mInit == original) { mInit = static_cast<TIntermTyped
*>(replacement); return true; } } while (0)
;
1091 REPLACE_IF_IS(mStatementList, TIntermBlock, original, replacement)do { if (mStatementList == original) { mStatementList = static_cast
<TIntermBlock *>(replacement); return true; } } while (
0)
;
1092 ASSERT(mStatementList)(mStatementList ? 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/IntermNode.cpp"
, __FUNCTION__, 1092, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1092 << "): " << "mStatementList"
))
;
1093 return false;
1094}
1095
1096TIntermCase::TIntermCase(const TIntermCase &node) : TIntermCase(node.mCondition->deepCopy()) {}
1097
1098size_t TIntermCase::getChildCount() const
1099{
1100 return (mCondition ? 1 : 0);
1101}
1102
1103TIntermNode *TIntermCase::getChildNode(size_t index) const
1104{
1105 ASSERT(index == 0)(index == 0 ? 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/IntermNode.cpp"
, __FUNCTION__, 1105, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1105 << "): " << "index == 0"
))
;
1106 ASSERT(mCondition)(mCondition ? 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/IntermNode.cpp"
, __FUNCTION__, 1106, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1106 << "): " << "mCondition"
))
;
1107 return mCondition;
1108}
1109
1110bool TIntermCase::replaceChildNode(TIntermNode *original, TIntermNode *replacement)
1111{
1112 REPLACE_IF_IS(mCondition, TIntermTyped, original, replacement)do { if (mCondition == original) { mCondition = static_cast<
TIntermTyped *>(replacement); return true; } } while (0)
;
1113 return false;
1114}
1115
1116TIntermTyped::TIntermTyped() : mIsPrecise(false) {}
1117TIntermTyped::TIntermTyped(const TIntermTyped &node) : TIntermTyped()
1118{
1119 // Copy constructor is disallowed for TIntermNode in order to disallow it for subclasses that
1120 // don't explicitly allow it, so normal TIntermNode constructor is used to construct the copy.
1121 // We need to manually copy any fields of TIntermNode.
1122 mLine = node.mLine;
1123
1124 // Once deteremined, the tree is not expected to transform.
1125 ASSERT(!mIsPrecise)(!mIsPrecise ? 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/IntermNode.cpp"
, __FUNCTION__, 1125, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1125 << "): " << "!mIsPrecise"
))
;
1126}
1127
1128bool TIntermTyped::hasConstantValue() const
1129{
1130 return false;
1131}
1132
1133bool TIntermTyped::isConstantNullValue() const
1134{
1135 return false;
1136}
1137
1138const TConstantUnion *TIntermTyped::getConstantValue() const
1139{
1140 return nullptr;
1141}
1142
1143TPrecision TIntermTyped::derivePrecision() const
1144{
1145 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/IntermNode.cpp"
, __FUNCTION__, 1145, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1145 << ")"; } while (0)
;
1146 return EbpUndefined;
1147}
1148
1149void TIntermTyped::propagatePrecision(TPrecision precision)
1150{
1151 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/IntermNode.cpp"
, __FUNCTION__, 1151, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1151 << ")"; } while (0)
;
1152}
1153
1154TIntermConstantUnion::TIntermConstantUnion(const TIntermConstantUnion &node)
1155 : TIntermExpression(node)
1156{
1157 mUnionArrayPointer = node.mUnionArrayPointer;
1158}
1159
1160TIntermFunctionPrototype::TIntermFunctionPrototype(const TFunction *function)
1161 : TIntermTyped(), mFunction(function)
1162{
1163 ASSERT(mFunction->symbolType() != SymbolType::Empty)(mFunction->symbolType() != SymbolType::Empty ? 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/IntermNode.cpp"
, __FUNCTION__, 1163, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1163 << "): " << "mFunction->symbolType() != SymbolType::Empty"
))
;
1164}
1165
1166const TType &TIntermFunctionPrototype::getType() const
1167{
1168 return mFunction->getReturnType();
1169}
1170
1171TIntermAggregate::TIntermAggregate(const TIntermAggregate &node)
1172 : TIntermOperator(node),
1173 mUseEmulatedFunction(node.mUseEmulatedFunction),
1174 mFunction(node.mFunction)
1175{
1176 for (TIntermNode *arg : node.mArguments)
1177 {
1178 TIntermTyped *typedArg = arg->getAsTyped();
1179 ASSERT(typedArg != nullptr)(typedArg != nullptr ? 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/IntermNode.cpp"
, __FUNCTION__, 1179, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1179 << "): " << "typedArg != nullptr"
))
;
1180 TIntermTyped *argCopy = typedArg->deepCopy();
1181 mArguments.push_back(argCopy);
1182 }
1183}
1184
1185TIntermAggregate *TIntermAggregate::shallowCopy() const
1186{
1187 TIntermSequence copySeq;
1188 copySeq.insert(copySeq.begin(), getSequence()->begin(), getSequence()->end());
1189 TIntermAggregate *copyNode = new TIntermAggregate(mFunction, mType, mOp, &copySeq);
1190 copyNode->setLine(mLine);
1191 return copyNode;
1192}
1193
1194TIntermSwizzle::TIntermSwizzle(const TIntermSwizzle &node) : TIntermExpression(node)
1195{
1196 TIntermTyped *operandCopy = node.mOperand->deepCopy();
1197 ASSERT(operandCopy != nullptr)(operandCopy != nullptr ? 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/IntermNode.cpp"
, __FUNCTION__, 1197, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1197 << "): " << "operandCopy != nullptr"
))
;
1198 mOperand = operandCopy;
1199 mSwizzleOffsets = node.mSwizzleOffsets;
1200 mHasFoldedDuplicateOffsets = node.mHasFoldedDuplicateOffsets;
1201}
1202
1203TIntermBinary::TIntermBinary(const TIntermBinary &node) : TIntermOperator(node)
1204{
1205 TIntermTyped *leftCopy = node.mLeft->deepCopy();
1206 TIntermTyped *rightCopy = node.mRight->deepCopy();
1207 ASSERT(leftCopy != nullptr && rightCopy != nullptr)(leftCopy != nullptr && rightCopy != nullptr ? 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/IntermNode.cpp"
, __FUNCTION__, 1207, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1207 << "): " << "leftCopy != nullptr && rightCopy != nullptr"
))
;
1208 mLeft = leftCopy;
1209 mRight = rightCopy;
1210}
1211
1212TIntermUnary::TIntermUnary(const TIntermUnary &node)
1213 : TIntermOperator(node),
1214 mUseEmulatedFunction(node.mUseEmulatedFunction),
1215 mFunction(node.mFunction)
1216{
1217 TIntermTyped *operandCopy = node.mOperand->deepCopy();
1218 ASSERT(operandCopy != nullptr)(operandCopy != nullptr ? 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/IntermNode.cpp"
, __FUNCTION__, 1218, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1218 << "): " << "operandCopy != nullptr"
))
;
1219 mOperand = operandCopy;
1220}
1221
1222TIntermTernary::TIntermTernary(const TIntermTernary &node) : TIntermExpression(node)
1223{
1224 TIntermTyped *conditionCopy = node.mCondition->deepCopy();
1225 TIntermTyped *trueCopy = node.mTrueExpression->deepCopy();
1226 TIntermTyped *falseCopy = node.mFalseExpression->deepCopy();
1227 ASSERT(conditionCopy != nullptr && trueCopy != nullptr && falseCopy != nullptr)(conditionCopy != nullptr && trueCopy != nullptr &&
falseCopy != nullptr ? 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/IntermNode.cpp"
, __FUNCTION__, 1227, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1227 << "): " << "conditionCopy != nullptr && trueCopy != nullptr && falseCopy != nullptr"
))
;
1228 mCondition = conditionCopy;
1229 mTrueExpression = trueCopy;
1230 mFalseExpression = falseCopy;
1231}
1232
1233bool TIntermOperator::isAssignment() const
1234{
1235 return IsAssignment(mOp);
1236}
1237
1238bool TIntermOperator::isMultiplication() const
1239{
1240 switch (mOp)
1241 {
1242 case EOpMul:
1243 case EOpMatrixTimesMatrix:
1244 case EOpMatrixTimesVector:
1245 case EOpMatrixTimesScalar:
1246 case EOpVectorTimesMatrix:
1247 case EOpVectorTimesScalar:
1248 return true;
1249 default:
1250 return false;
1251 }
1252}
1253
1254bool TIntermOperator::isConstructor() const
1255{
1256 return (mOp == EOpConstruct);
1257}
1258
1259bool TIntermOperator::isFunctionCall() const
1260{
1261 switch (mOp)
1262 {
1263 case EOpCallFunctionInAST:
1264 case EOpCallInternalRawFunction:
1265 return true;
1266 default:
1267 return false;
1268 }
1269}
1270
1271TOperator TIntermBinary::GetMulOpBasedOnOperands(const TType &left, const TType &right)
1272{
1273 if (left.isMatrix())
1274 {
1275 if (right.isMatrix())
1276 {
1277 return EOpMatrixTimesMatrix;
1278 }
1279 else
1280 {
1281 if (right.isVector())
1282 {
1283 return EOpMatrixTimesVector;
1284 }
1285 else
1286 {
1287 return EOpMatrixTimesScalar;
1288 }
1289 }
1290 }
1291 else
1292 {
1293 if (right.isMatrix())
1294 {
1295 if (left.isVector())
1296 {
1297 return EOpVectorTimesMatrix;
1298 }
1299 else
1300 {
1301 return EOpMatrixTimesScalar;
1302 }
1303 }
1304 else
1305 {
1306 // Neither operand is a matrix.
1307 if (left.isVector() == right.isVector())
1308 {
1309 // Leave as component product.
1310 return EOpMul;
1311 }
1312 else
1313 {
1314 return EOpVectorTimesScalar;
1315 }
1316 }
1317 }
1318}
1319
1320TOperator TIntermBinary::GetMulAssignOpBasedOnOperands(const TType &left, const TType &right)
1321{
1322 if (left.isMatrix())
1323 {
1324 if (right.isMatrix())
1325 {
1326 return EOpMatrixTimesMatrixAssign;
1327 }
1328 else
1329 {
1330 // right should be scalar, but this may not be validated yet.
1331 return EOpMatrixTimesScalarAssign;
1332 }
1333 }
1334 else
1335 {
1336 if (right.isMatrix())
1337 {
1338 // Left should be a vector, but this may not be validated yet.
1339 return EOpVectorTimesMatrixAssign;
1340 }
1341 else
1342 {
1343 // Neither operand is a matrix.
1344 if (left.isVector() == right.isVector())
1345 {
1346 // Leave as component product.
1347 return EOpMulAssign;
1348 }
1349 else
1350 {
1351 // left should be vector and right should be scalar, but this may not be validated
1352 // yet.
1353 return EOpVectorTimesScalarAssign;
1354 }
1355 }
1356 }
1357}
1358
1359//
1360// Make sure the type of a unary operator is appropriate for its
1361// combination of operation and operand type.
1362//
1363void TIntermUnary::promote()
1364{
1365 if (mOp == EOpArrayLength)
1366 {
1367 // Special case: the qualifier of .length() doesn't depend on the operand qualifier.
1368 setType(TType(EbtInt, EbpHigh, EvqConst));
1369 return;
1370 }
1371
1372 TQualifier resultQualifier = EvqTemporary;
1373 if (mOperand->getQualifier() == EvqConst)
1374 resultQualifier = EvqConst;
1375
1376 TType resultType = mOperand->getType();
1377 resultType.setQualifier(resultQualifier);
1378
1379 // Result is an intermediate value, so make sure it's identified as such.
1380 resultType.setInterfaceBlock(nullptr);
1381
1382 // Override type properties for special built-ins. Precision is determined later by
1383 // |derivePrecision|.
1384 switch (mOp)
1385 {
1386 case EOpFloatBitsToInt:
1387 resultType.setBasicType(EbtInt);
1388 break;
1389 case EOpFloatBitsToUint:
1390 resultType.setBasicType(EbtUInt);
1391 break;
1392 case EOpIntBitsToFloat:
1393 case EOpUintBitsToFloat:
1394 resultType.setBasicType(EbtFloat);
1395 break;
1396 case EOpPackSnorm2x16:
1397 case EOpPackUnorm2x16:
1398 case EOpPackHalf2x16:
1399 case EOpPackUnorm4x8:
1400 case EOpPackSnorm4x8:
1401 resultType.setBasicType(EbtUInt);
1402 resultType.setPrimarySize(1);
1403 break;
1404 case EOpUnpackSnorm2x16:
1405 case EOpUnpackUnorm2x16:
1406 case EOpUnpackHalf2x16:
1407 resultType.setBasicType(EbtFloat);
1408 resultType.setPrimarySize(2);
1409 break;
1410 case EOpUnpackUnorm4x8:
1411 case EOpUnpackSnorm4x8:
1412 resultType.setBasicType(EbtFloat);
1413 resultType.setPrimarySize(4);
1414 break;
1415 case EOpAny:
1416 case EOpAll:
1417 resultType.setBasicType(EbtBool);
1418 resultType.setPrimarySize(1);
1419 break;
1420 case EOpLength:
1421 case EOpDeterminant:
1422 resultType.setBasicType(EbtFloat);
1423 resultType.setPrimarySize(1);
1424 resultType.setSecondarySize(1);
1425 break;
1426 case EOpTranspose:
1427 ASSERT(resultType.getBasicType() == EbtFloat)(resultType.getBasicType() == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 1427, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1427 << "): " << "resultType.getBasicType() == EbtFloat"
))
;
1428 resultType.setPrimarySize(mOperand->getType().getRows());
1429 resultType.setSecondarySize(mOperand->getType().getCols());
1430 break;
1431 case EOpIsinf:
1432 case EOpIsnan:
1433 resultType.setBasicType(EbtBool);
1434 break;
1435 case EOpBitCount:
1436 case EOpFindLSB:
1437 case EOpFindMSB:
1438 resultType.setBasicType(EbtInt);
1439 break;
1440 default:
1441 break;
1442 }
1443
1444 setType(resultType);
1445 propagatePrecision(derivePrecision());
1446}
1447
1448// Derive precision from children nodes
1449TPrecision TIntermUnary::derivePrecision() const
1450{
1451 // Unary operators generally derive their precision from their operand, except for a few
1452 // built-ins where this is overriden.
1453 switch (mOp)
1454 {
1455 case EOpArrayLength:
1456 case EOpFloatBitsToInt:
1457 case EOpFloatBitsToUint:
1458 case EOpIntBitsToFloat:
1459 case EOpUintBitsToFloat:
1460 case EOpPackSnorm2x16:
1461 case EOpPackUnorm2x16:
1462 case EOpPackHalf2x16:
1463 case EOpPackUnorm4x8:
1464 case EOpPackSnorm4x8:
1465 case EOpUnpackSnorm2x16:
1466 case EOpUnpackUnorm2x16:
1467 case EOpBitfieldReverse:
1468 return EbpHigh;
1469 case EOpUnpackHalf2x16:
1470 case EOpUnpackUnorm4x8:
1471 case EOpUnpackSnorm4x8:
1472 return EbpMedium;
1473 case EOpBitCount:
1474 case EOpFindLSB:
1475 case EOpFindMSB:
1476 return EbpLow;
1477 case EOpAny:
1478 case EOpAll:
1479 case EOpIsinf:
1480 case EOpIsnan:
1481 return EbpUndefined;
1482 default:
1483 return mOperand->getPrecision();
1484 }
1485}
1486
1487void TIntermUnary::propagatePrecision(TPrecision precision)
1488{
1489 mType.setPrecision(precision);
1490
1491 // Generally precision of the operand and the precision of the result match. A few built-ins
1492 // are exceptional.
1493 switch (mOp)
1494 {
1495 case EOpArrayLength:
1496 case EOpPackSnorm2x16:
1497 case EOpPackUnorm2x16:
1498 case EOpPackUnorm4x8:
1499 case EOpPackSnorm4x8:
1500 case EOpPackHalf2x16:
1501 case EOpBitCount:
1502 case EOpFindLSB:
1503 case EOpFindMSB:
1504 case EOpIsinf:
1505 case EOpIsnan:
1506 // Precision of result does not affect the operand in any way.
1507 break;
1508 case EOpFloatBitsToInt:
1509 case EOpFloatBitsToUint:
1510 case EOpIntBitsToFloat:
1511 case EOpUintBitsToFloat:
1512 case EOpUnpackSnorm2x16:
1513 case EOpUnpackUnorm2x16:
1514 case EOpUnpackUnorm4x8:
1515 case EOpUnpackSnorm4x8:
1516 case EOpUnpackHalf2x16:
1517 case EOpBitfieldReverse:
1518 PropagatePrecisionIfApplicable(mOperand, EbpHigh);
1519 break;
1520 default:
1521 PropagatePrecisionIfApplicable(mOperand, precision);
1522 }
1523}
1524
1525TIntermSwizzle::TIntermSwizzle(TIntermTyped *operand, const TVector<int> &swizzleOffsets)
1526 : TIntermExpression(TType(EbtFloat, EbpUndefined)),
1527 mOperand(operand),
1528 mSwizzleOffsets(swizzleOffsets),
1529 mHasFoldedDuplicateOffsets(false)
1530{
1531 ASSERT(mOperand)(mOperand ? 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/IntermNode.cpp"
, __FUNCTION__, 1531, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1531 << "): " << "mOperand"
))
;
1532 ASSERT(mOperand->getType().isVector())(mOperand->getType().isVector() ? 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/IntermNode.cpp"
, __FUNCTION__, 1532, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1532 << "): " << "mOperand->getType().isVector()"
))
;
1533 ASSERT(mSwizzleOffsets.size() <= 4)(mSwizzleOffsets.size() <= 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/IntermNode.cpp"
, __FUNCTION__, 1533, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1533 << "): " << "mSwizzleOffsets.size() <= 4"
))
;
1534 promote();
1535}
1536
1537TIntermUnary::TIntermUnary(TOperator op, TIntermTyped *operand, const TFunction *function)
1538 : TIntermOperator(op), mOperand(operand), mUseEmulatedFunction(false), mFunction(function)
1539{
1540 ASSERT(mOperand)(mOperand ? 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/IntermNode.cpp"
, __FUNCTION__, 1540, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1540 << "): " << "mOperand"
))
;
1541 ASSERT(!BuiltInGroup::IsBuiltIn(op) || (function != nullptr && function->getBuiltInOp() == op))(!BuiltInGroup::IsBuiltIn(op) || (function != nullptr &&
function->getBuiltInOp() == op) ? 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/IntermNode.cpp"
, __FUNCTION__, 1541, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1541 << "): " << "!BuiltInGroup::IsBuiltIn(op) || (function != nullptr && function->getBuiltInOp() == op)"
))
;
1542 promote();
1543}
1544
1545TIntermBinary::TIntermBinary(TOperator op, TIntermTyped *left, TIntermTyped *right)
1546 : TIntermOperator(op), mLeft(left), mRight(right)
1547{
1548 ASSERT(mLeft)(mLeft ? 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/IntermNode.cpp"
, __FUNCTION__, 1548, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1548 << "): " << "mLeft"))
;
1549 ASSERT(mRight)(mRight ? 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/IntermNode.cpp"
, __FUNCTION__, 1549, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1549 << "): " << "mRight")
)
;
1550 promote();
1551}
1552
1553TIntermBinary *TIntermBinary::CreateComma(TIntermTyped *left,
1554 TIntermTyped *right,
1555 int shaderVersion)
1556{
1557 TIntermBinary *node = new TIntermBinary(EOpComma, left, right);
1558 node->getTypePointer()->setQualifier(GetCommaQualifier(shaderVersion, left, right));
1559 return node;
1560}
1561
1562TIntermGlobalQualifierDeclaration::TIntermGlobalQualifierDeclaration(TIntermSymbol *symbol,
1563 bool isPrecise,
1564 const TSourceLoc &line)
1565 : TIntermNode(), mSymbol(symbol), mIsPrecise(isPrecise)
1566{
1567 ASSERT(symbol)(symbol ? 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/IntermNode.cpp"
, __FUNCTION__, 1567, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1567 << "): " << "symbol")
)
;
1568 setLine(line);
1569}
1570
1571TIntermGlobalQualifierDeclaration::TIntermGlobalQualifierDeclaration(
1572 const TIntermGlobalQualifierDeclaration &node)
1573 : TIntermGlobalQualifierDeclaration(static_cast<TIntermSymbol *>(node.mSymbol->deepCopy()),
1574 node.mIsPrecise,
1575 node.mLine)
1576{}
1577
1578TIntermTernary::TIntermTernary(TIntermTyped *cond,
1579 TIntermTyped *trueExpression,
1580 TIntermTyped *falseExpression)
1581 : TIntermExpression(trueExpression->getType()),
1582 mCondition(cond),
1583 mTrueExpression(trueExpression),
1584 mFalseExpression(falseExpression)
1585{
1586 ASSERT(mCondition)(mCondition ? 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/IntermNode.cpp"
, __FUNCTION__, 1586, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1586 << "): " << "mCondition"
))
;
1587 ASSERT(mTrueExpression)(mTrueExpression ? 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/IntermNode.cpp"
, __FUNCTION__, 1587, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1587 << "): " << "mTrueExpression"
))
;
1588 ASSERT(mFalseExpression)(mFalseExpression ? 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/IntermNode.cpp"
, __FUNCTION__, 1588, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1588 << "): " << "mFalseExpression"
))
;
1589 getTypePointer()->setQualifier(
1590 TIntermTernary::DetermineQualifier(cond, trueExpression, falseExpression));
1591
1592 propagatePrecision(derivePrecision());
1593}
1594
1595TIntermLoop::TIntermLoop(TLoopType type,
1596 TIntermNode *init,
1597 TIntermTyped *cond,
1598 TIntermTyped *expr,
1599 TIntermBlock *body)
1600 : mType(type), mInit(init), mCond(cond), mExpr(expr), mBody(body)
1601{
1602 // Declaration nodes with no children can appear if all the declarators just added constants to
1603 // the symbol table instead of generating code. They're no-ops so don't add them to the tree.
1604 if (mInit && mInit->getAsDeclarationNode() &&
1605 mInit->getAsDeclarationNode()->getSequence()->empty())
1606 {
1607 mInit = nullptr;
1608 }
1609}
1610
1611TIntermLoop::TIntermLoop(const TIntermLoop &node)
1612 : TIntermLoop(node.mType,
1613 node.mInit ? node.mInit->deepCopy() : nullptr,
1614 node.mCond ? node.mCond->deepCopy() : nullptr,
1615 node.mExpr ? node.mExpr->deepCopy() : nullptr,
1616 node.mBody ? node.mBody->deepCopy() : nullptr)
1617{}
1618
1619TIntermIfElse::TIntermIfElse(TIntermTyped *cond, TIntermBlock *trueB, TIntermBlock *falseB)
1620 : TIntermNode(), mCondition(cond), mTrueBlock(trueB), mFalseBlock(falseB)
1621{
1622 ASSERT(mCondition)(mCondition ? 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/IntermNode.cpp"
, __FUNCTION__, 1622, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1622 << "): " << "mCondition"
))
;
1623 // Prune empty false blocks so that there won't be unnecessary operations done on it.
1624 if (mFalseBlock && mFalseBlock->getSequence()->empty())
1625 {
1626 mFalseBlock = nullptr;
1627 }
1628}
1629
1630TIntermIfElse::TIntermIfElse(const TIntermIfElse &node)
1631 : TIntermIfElse(node.mCondition->deepCopy(),
1632 node.mTrueBlock->deepCopy(),
1633 node.mFalseBlock ? node.mFalseBlock->deepCopy() : nullptr)
1634{}
1635
1636TIntermSwitch::TIntermSwitch(TIntermTyped *init, TIntermBlock *statementList)
1637 : TIntermNode(), mInit(init), mStatementList(statementList)
1638{
1639 ASSERT(mInit)(mInit ? 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/IntermNode.cpp"
, __FUNCTION__, 1639, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1639 << "): " << "mInit"))
;
1640 ASSERT(mStatementList)(mStatementList ? 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/IntermNode.cpp"
, __FUNCTION__, 1640, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1640 << "): " << "mStatementList"
))
;
1641}
1642
1643TIntermSwitch::TIntermSwitch(const TIntermSwitch &node)
1644 : TIntermSwitch(node.mInit->deepCopy(), node.mStatementList->deepCopy())
1645{}
1646
1647void TIntermSwitch::setStatementList(TIntermBlock *statementList)
1648{
1649 ASSERT(statementList)(statementList ? 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/IntermNode.cpp"
, __FUNCTION__, 1649, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1649 << "): " << "statementList"
))
;
1650 mStatementList = statementList;
1651}
1652
1653// static
1654TQualifier TIntermTernary::DetermineQualifier(TIntermTyped *cond,
1655 TIntermTyped *trueExpression,
1656 TIntermTyped *falseExpression)
1657{
1658 if (cond->getQualifier() == EvqConst && trueExpression->getQualifier() == EvqConst &&
1659 falseExpression->getQualifier() == EvqConst)
1660 {
1661 return EvqConst;
1662 }
1663 return EvqTemporary;
1664}
1665
1666// Derive precision from children nodes
1667TPrecision TIntermTernary::derivePrecision() const
1668{
1669 return GetHigherPrecision(mTrueExpression->getPrecision(), mFalseExpression->getPrecision());
1670}
1671
1672void TIntermTernary::propagatePrecision(TPrecision precision)
1673{
1674 mType.setPrecision(precision);
1675
1676 PropagatePrecisionIfApplicable(mTrueExpression, precision);
1677 PropagatePrecisionIfApplicable(mFalseExpression, precision);
1678}
1679
1680TIntermTyped *TIntermTernary::fold(TDiagnostics * /* diagnostics */)
1681{
1682 if (mCondition->getAsConstantUnion())
1683 {
1684 if (mCondition->getAsConstantUnion()->getBConst(0))
1685 {
1686 return mTrueExpression;
1687 }
1688 else
1689 {
1690 return mFalseExpression;
1691 }
1692 }
1693 return this;
1694}
1695
1696void TIntermSwizzle::promote()
1697{
1698 TQualifier resultQualifier = EvqTemporary;
1699 if (mOperand->getQualifier() == EvqConst)
1700 resultQualifier = EvqConst;
1701
1702 size_t numFields = mSwizzleOffsets.size();
1703 setType(TType(mOperand->getBasicType(), EbpUndefined, resultQualifier,
1704 static_cast<uint8_t>(numFields)));
1705 propagatePrecision(derivePrecision());
1706}
1707
1708// Derive precision from children nodes
1709TPrecision TIntermSwizzle::derivePrecision() const
1710{
1711 return mOperand->getPrecision();
1712}
1713
1714void TIntermSwizzle::propagatePrecision(TPrecision precision)
1715{
1716 mType.setPrecision(precision);
1717
1718 PropagatePrecisionIfApplicable(mOperand, precision);
1719}
1720
1721bool TIntermSwizzle::hasDuplicateOffsets() const
1722{
1723 if (mHasFoldedDuplicateOffsets)
1724 {
1725 return true;
1726 }
1727 int offsetCount[4] = {0u, 0u, 0u, 0u};
1728 for (const auto offset : mSwizzleOffsets)
1729 {
1730 offsetCount[offset]++;
1731 if (offsetCount[offset] > 1)
1732 {
1733 return true;
1734 }
1735 }
1736 return false;
1737}
1738
1739void TIntermSwizzle::setHasFoldedDuplicateOffsets(bool hasFoldedDuplicateOffsets)
1740{
1741 mHasFoldedDuplicateOffsets = hasFoldedDuplicateOffsets;
1742}
1743
1744bool TIntermSwizzle::offsetsMatch(int offset) const
1745{
1746 return mSwizzleOffsets.size() == 1 && mSwizzleOffsets[0] == offset;
1747}
1748
1749void TIntermSwizzle::writeOffsetsAsXYZW(TInfoSinkBase *out) const
1750{
1751 for (const int offset : mSwizzleOffsets)
1752 {
1753 switch (offset)
1754 {
1755 case 0:
1756 *out << "x";
1757 break;
1758 case 1:
1759 *out << "y";
1760 break;
1761 case 2:
1762 *out << "z";
1763 break;
1764 case 3:
1765 *out << "w";
1766 break;
1767 default:
1768 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/IntermNode.cpp"
, __FUNCTION__, 1768, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1768 << ")"; } while (0)
;
1769 }
1770 }
1771}
1772
1773TQualifier TIntermBinary::GetCommaQualifier(int shaderVersion,
1774 const TIntermTyped *left,
1775 const TIntermTyped *right)
1776{
1777 // ESSL3.00 section 12.43: The result of a sequence operator is not a constant-expression.
1778 if (shaderVersion >= 300 || left->getQualifier() != EvqConst ||
1779 right->getQualifier() != EvqConst)
1780 {
1781 return EvqTemporary;
1782 }
1783 return EvqConst;
1784}
1785
1786// Establishes the type of the result of the binary operation.
1787void TIntermBinary::promote()
1788{
1789 ASSERT(!isMultiplication() ||(!isMultiplication() || mOp == GetMulOpBasedOnOperands(mLeft->
getType(), mRight->getType()) ? 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/IntermNode.cpp"
, __FUNCTION__, 1790, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1790 << "): " << "!isMultiplication() || mOp == GetMulOpBasedOnOperands(mLeft->getType(), mRight->getType())"
))
1790 mOp == GetMulOpBasedOnOperands(mLeft->getType(), mRight->getType()))(!isMultiplication() || mOp == GetMulOpBasedOnOperands(mLeft->
getType(), mRight->getType()) ? 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/IntermNode.cpp"
, __FUNCTION__, 1790, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1790 << "): " << "!isMultiplication() || mOp == GetMulOpBasedOnOperands(mLeft->getType(), mRight->getType())"
))
;
1791
1792 // Comma is handled as a special case. Note that the comma node qualifier depends on the shader
1793 // version and so is not being set here.
1794 if (mOp == EOpComma)
1795 {
1796 setType(mRight->getType());
1797 return;
1798 }
1799
1800 // Base assumption: just make the type the same as the left
1801 // operand. Then only deviations from this need be coded.
1802 setType(mLeft->getType());
1803
1804 TQualifier resultQualifier = EvqConst;
1805 // Binary operations results in temporary variables unless both
1806 // operands are const. If initializing a specialization constant, make the declarator also
1807 // EvqSpecConst.
1808 const bool isSpecConstInit = mOp == EOpInitialize && mLeft->getQualifier() == EvqSpecConst;
1809 const bool isEitherNonConst =
1810 mLeft->getQualifier() != EvqConst || mRight->getQualifier() != EvqConst;
1811 if (!isSpecConstInit && isEitherNonConst)
1812 {
1813 resultQualifier = EvqTemporary;
1814 getTypePointer()->setQualifier(EvqTemporary);
1815 }
1816
1817 // Result is an intermediate value, so make sure it's identified as such. That's not true for
1818 // interface block arrays being indexed.
1819 if (mOp != EOpIndexDirect && mOp != EOpIndexIndirect)
1820 {
1821 getTypePointer()->setInterfaceBlock(nullptr);
1822 }
1823
1824 // Handle indexing ops.
1825 switch (mOp)
1826 {
1827 case EOpIndexDirect:
1828 case EOpIndexIndirect:
1829 if (mLeft->isArray())
1830 {
1831 mType.toArrayElementType();
1832 }
1833 else if (mLeft->isMatrix())
1834 {
1835 mType.toMatrixColumnType();
1836 }
1837 else if (mLeft->isVector())
1838 {
1839 mType.toComponentType();
1840 }
1841 else
1842 {
1843 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/IntermNode.cpp"
, __FUNCTION__, 1843, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1843 << ")"; } while (0)
;
1844 }
1845 return;
1846 case EOpIndexDirectStruct:
1847 {
1848 const TFieldList &fields = mLeft->getType().getStruct()->fields();
1849 const int fieldIndex = mRight->getAsConstantUnion()->getIConst(0);
1850 setType(*fields[fieldIndex]->type());
1851 getTypePointer()->setQualifier(resultQualifier);
1852 return;
1853 }
1854 case EOpIndexDirectInterfaceBlock:
1855 {
1856 const TFieldList &fields = mLeft->getType().getInterfaceBlock()->fields();
1857 const int fieldIndex = mRight->getAsConstantUnion()->getIConst(0);
1858 setType(*fields[fieldIndex]->type());
1859 getTypePointer()->setQualifier(resultQualifier);
1860 return;
1861 }
1862 default:
1863 break;
1864 }
1865
1866 ASSERT(mLeft->isArray() == mRight->isArray())(mLeft->isArray() == mRight->isArray() ? 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/IntermNode.cpp"
, __FUNCTION__, 1866, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1866 << "): " << "mLeft->isArray() == mRight->isArray()"
))
;
1867
1868 const uint8_t nominalSize = std::max(mLeft->getNominalSize(), mRight->getNominalSize());
1869
1870 switch (mOp)
1871 {
1872 case EOpMul:
1873 break;
1874 case EOpMatrixTimesScalar:
1875 if (mRight->isMatrix())
1876 {
1877 getTypePointer()->setPrimarySize(mRight->getCols());
1878 getTypePointer()->setSecondarySize(mRight->getRows());
1879 }
1880 break;
1881 case EOpMatrixTimesVector:
1882 getTypePointer()->setPrimarySize(mLeft->getRows());
1883 getTypePointer()->setSecondarySize(1);
1884 break;
1885 case EOpMatrixTimesMatrix:
1886 getTypePointer()->setPrimarySize(mRight->getCols());
1887 getTypePointer()->setSecondarySize(mLeft->getRows());
1888 break;
1889 case EOpVectorTimesScalar:
1890 getTypePointer()->setPrimarySize(nominalSize);
1891 break;
1892 case EOpVectorTimesMatrix:
1893 getTypePointer()->setPrimarySize(mRight->getCols());
1894 ASSERT(getType().getSecondarySize() == 1)(getType().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/IntermNode.cpp"
, __FUNCTION__, 1894, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1894 << "): " << "getType().getSecondarySize() == 1"
))
;
1895 break;
1896 case EOpMulAssign:
1897 case EOpVectorTimesScalarAssign:
1898 case EOpVectorTimesMatrixAssign:
1899 case EOpMatrixTimesScalarAssign:
1900 case EOpMatrixTimesMatrixAssign:
1901 ASSERT(mOp == GetMulAssignOpBasedOnOperands(mLeft->getType(), mRight->getType()))(mOp == GetMulAssignOpBasedOnOperands(mLeft->getType(), mRight
->getType()) ? 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/IntermNode.cpp"
, __FUNCTION__, 1901, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1901 << "): " << "mOp == GetMulAssignOpBasedOnOperands(mLeft->getType(), mRight->getType())"
))
;
1902 break;
1903 case EOpAssign:
1904 case EOpInitialize:
1905 ASSERT((mLeft->getNominalSize() == mRight->getNominalSize()) &&((mLeft->getNominalSize() == mRight->getNominalSize()) &&
(mLeft->getSecondarySize() == mRight->getSecondarySize
()) ? 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/IntermNode.cpp"
, __FUNCTION__, 1906, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1906 << "): " << "(mLeft->getNominalSize() == mRight->getNominalSize()) && (mLeft->getSecondarySize() == mRight->getSecondarySize())"
))
1906 (mLeft->getSecondarySize() == mRight->getSecondarySize()))((mLeft->getNominalSize() == mRight->getNominalSize()) &&
(mLeft->getSecondarySize() == mRight->getSecondarySize
()) ? 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/IntermNode.cpp"
, __FUNCTION__, 1906, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1906 << "): " << "(mLeft->getNominalSize() == mRight->getNominalSize()) && (mLeft->getSecondarySize() == mRight->getSecondarySize())"
))
;
1907 break;
1908 case EOpAdd:
1909 case EOpSub:
1910 case EOpDiv:
1911 case EOpIMod:
1912 case EOpBitShiftLeft:
1913 case EOpBitShiftRight:
1914 case EOpBitwiseAnd:
1915 case EOpBitwiseXor:
1916 case EOpBitwiseOr:
1917 case EOpAddAssign:
1918 case EOpSubAssign:
1919 case EOpDivAssign:
1920 case EOpIModAssign:
1921 case EOpBitShiftLeftAssign:
1922 case EOpBitShiftRightAssign:
1923 case EOpBitwiseAndAssign:
1924 case EOpBitwiseXorAssign:
1925 case EOpBitwiseOrAssign:
1926 {
1927 ASSERT(!mLeft->isArray() && !mRight->isArray())(!mLeft->isArray() && !mRight->isArray() ? 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/IntermNode.cpp"
, __FUNCTION__, 1927, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1927 << "): " << "!mLeft->isArray() && !mRight->isArray()"
))
;
1928 const uint8_t secondarySize =
1929 std::max(mLeft->getSecondarySize(), mRight->getSecondarySize());
1930 getTypePointer()->setPrimarySize(nominalSize);
1931 getTypePointer()->setSecondarySize(secondarySize);
1932 break;
1933 }
1934 case EOpEqual:
1935 case EOpNotEqual:
1936 case EOpLessThan:
1937 case EOpGreaterThan:
1938 case EOpLessThanEqual:
1939 case EOpGreaterThanEqual:
1940 ASSERT((mLeft->getNominalSize() == mRight->getNominalSize()) &&((mLeft->getNominalSize() == mRight->getNominalSize()) &&
(mLeft->getSecondarySize() == mRight->getSecondarySize
()) ? 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/IntermNode.cpp"
, __FUNCTION__, 1941, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1941 << "): " << "(mLeft->getNominalSize() == mRight->getNominalSize()) && (mLeft->getSecondarySize() == mRight->getSecondarySize())"
))
1941 (mLeft->getSecondarySize() == mRight->getSecondarySize()))((mLeft->getNominalSize() == mRight->getNominalSize()) &&
(mLeft->getSecondarySize() == mRight->getSecondarySize
()) ? 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/IntermNode.cpp"
, __FUNCTION__, 1941, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1941 << "): " << "(mLeft->getNominalSize() == mRight->getNominalSize()) && (mLeft->getSecondarySize() == mRight->getSecondarySize())"
))
;
1942 setType(TType(EbtBool, EbpUndefined, resultQualifier));
1943 break;
1944
1945 //
1946 // And and Or operate on conditionals
1947 //
1948 case EOpLogicalAnd:
1949 case EOpLogicalXor:
1950 case EOpLogicalOr:
1951 ASSERT(mLeft->getBasicType() == EbtBool && mRight->getBasicType() == EbtBool)(mLeft->getBasicType() == EbtBool && mRight->getBasicType
() == EbtBool ? 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/IntermNode.cpp"
, __FUNCTION__, 1951, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1951 << "): " << "mLeft->getBasicType() == EbtBool && mRight->getBasicType() == EbtBool"
))
;
1952 break;
1953
1954 case EOpIndexDirect:
1955 case EOpIndexIndirect:
1956 case EOpIndexDirectInterfaceBlock:
1957 case EOpIndexDirectStruct:
1958 // These ops should be already fully handled.
1959 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/IntermNode.cpp"
, __FUNCTION__, 1959, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1959 << ")"; } while (0)
;
1960 break;
1961 default:
1962 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/IntermNode.cpp"
, __FUNCTION__, 1962, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 1962 << ")"; } while (0)
;
1963 break;
1964 }
1965
1966 propagatePrecision(derivePrecision());
1967}
1968
1969// Derive precision from children nodes
1970TPrecision TIntermBinary::derivePrecision() const
1971{
1972 // Assignments use the type and precision of the lvalue-expression
1973 // GLSL ES spec section 5.8: Assignments
1974 // "The assignment operator stores the value of rvalue-expression into the l-value and returns
1975 // an r-value with the type and precision of lvalue-expression."
1976 if (IsAssignment(mOp))
1977 {
1978 return mLeft->getPrecision();
1979 }
1980
1981 const TPrecision higherPrecision =
1982 GetHigherPrecision(mLeft->getPrecision(), mRight->getPrecision());
1983
1984 switch (mOp)
1985 {
1986 case EOpComma:
1987 // Comma takes the right node's value.
1988 return mRight->getPrecision();
1989
1990 case EOpIndexDirect:
1991 case EOpIndexIndirect:
1992 case EOpBitShiftLeft:
1993 case EOpBitShiftRight:
1994 // When indexing an array, the precision of the array is preserved (which is the left
1995 // node).
1996 // For shift operations, the precision is derived from the expression being shifted
1997 // (which is also the left node).
1998 return mLeft->getPrecision();
1999
2000 case EOpIndexDirectStruct:
2001 case EOpIndexDirectInterfaceBlock:
2002 {
2003 // When selecting the field of a block, the precision is taken from the field's
2004 // declaration.
2005 const TFieldList &fields = mOp == EOpIndexDirectStruct
2006 ? mLeft->getType().getStruct()->fields()
2007 : mLeft->getType().getInterfaceBlock()->fields();
2008 const int fieldIndex = mRight->getAsConstantUnion()->getIConst(0);
2009 return fields[fieldIndex]->type()->getPrecision();
2010 }
2011
2012 case EOpEqual:
2013 case EOpNotEqual:
2014 case EOpLessThan:
2015 case EOpGreaterThan:
2016 case EOpLessThanEqual:
2017 case EOpGreaterThanEqual:
2018 case EOpLogicalAnd:
2019 case EOpLogicalXor:
2020 case EOpLogicalOr:
2021 // No precision specified on bool results.
2022 return EbpUndefined;
2023
2024 default:
2025 // All other operations are evaluated at the higher of the two operands' precisions.
2026 return higherPrecision;
2027 }
2028}
2029
2030void TIntermBinary::propagatePrecision(TPrecision precision)
2031{
2032 getTypePointer()->setPrecision(precision);
2033
2034 if (mOp != EOpComma)
2035 {
2036 PropagatePrecisionIfApplicable(mLeft, precision);
2037 }
2038
2039 if (mOp != EOpIndexDirect && mOp != EOpIndexIndirect && mOp != EOpIndexDirectStruct &&
2040 mOp != EOpIndexDirectInterfaceBlock)
2041 {
2042 PropagatePrecisionIfApplicable(mRight, precision);
2043 }
2044
2045 // For indices, always apply highp. This is purely for the purpose of making sure constant and
2046 // constructor nodes are also given a precision, so if they are hoisted to a temp variable,
2047 // there would be a precision to apply to that variable.
2048 if (mOp == EOpIndexDirect || mOp == EOpIndexIndirect)
2049 {
2050 PropagatePrecisionIfApplicable(mRight, EbpHigh);
2051 }
2052}
2053
2054bool TIntermConstantUnion::hasConstantValue() const
2055{
2056 return true;
2057}
2058
2059bool TIntermConstantUnion::isConstantNullValue() const
2060{
2061 const size_t size = mType.getObjectSize();
2062 for (size_t index = 0; index < size; ++index)
2063 {
2064 if (!mUnionArrayPointer[index].isZero())
2065 {
2066 return false;
2067 }
2068 }
2069 return true;
2070}
2071
2072const TConstantUnion *TIntermConstantUnion::getConstantValue() const
2073{
2074 return mUnionArrayPointer;
2075}
2076
2077const TConstantUnion *TIntermConstantUnion::FoldIndexing(const TType &type,
2078 const TConstantUnion *constArray,
2079 int index)
2080{
2081 if (type.isArray())
2082 {
2083 ASSERT(index < static_cast<int>(type.getOutermostArraySize()))(index < static_cast<int>(type.getOutermostArraySize
()) ? 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/IntermNode.cpp"
, __FUNCTION__, 2083, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2083 << "): " << "index < static_cast<int>(type.getOutermostArraySize())"
))
;
2084 TType arrayElementType(type);
2085 arrayElementType.toArrayElementType();
2086 size_t arrayElementSize = arrayElementType.getObjectSize();
2087 return &constArray[arrayElementSize * index];
2088 }
2089 else if (type.isMatrix())
2090 {
2091 ASSERT(index < type.getCols())(index < type.getCols() ? 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/IntermNode.cpp"
, __FUNCTION__, 2091, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2091 << "): " << "index < type.getCols()"
))
;
2092 const uint8_t size = type.getRows();
2093 return &constArray[size * index];
2094 }
2095 else if (type.isVector())
2096 {
2097 ASSERT(index < type.getNominalSize())(index < type.getNominalSize() ? 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/IntermNode.cpp"
, __FUNCTION__, 2097, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2097 << "): " << "index < type.getNominalSize()"
))
;
2098 return &constArray[index];
2099 }
2100 else
2101 {
2102 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/IntermNode.cpp"
, __FUNCTION__, 2102, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2102 << ")"; } while (0)
;
2103 return nullptr;
2104 }
2105}
2106
2107TIntermTyped *TIntermSwizzle::fold(TDiagnostics * /* diagnostics */)
2108{
2109 TIntermSwizzle *operandSwizzle = mOperand->getAsSwizzleNode();
2110 if (operandSwizzle)
2111 {
2112 // We need to fold the two swizzles into one, so that repeated swizzling can't cause stack
2113 // overflow in ParseContext::checkCanBeLValue().
2114 bool hadDuplicateOffsets = operandSwizzle->hasDuplicateOffsets();
2115 TVector<int> foldedOffsets;
2116 for (int offset : mSwizzleOffsets)
2117 {
2118 // Offset should already be validated.
2119 ASSERT(static_cast<size_t>(offset) < operandSwizzle->mSwizzleOffsets.size())(static_cast<size_t>(offset) < operandSwizzle->mSwizzleOffsets
.size() ? 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/IntermNode.cpp"
, __FUNCTION__, 2119, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2119 << "): " << "static_cast<size_t>(offset) < operandSwizzle->mSwizzleOffsets.size()"
))
;
2120 foldedOffsets.push_back(operandSwizzle->mSwizzleOffsets[offset]);
2121 }
2122 operandSwizzle->mSwizzleOffsets = foldedOffsets;
2123 operandSwizzle->setType(getType());
2124 operandSwizzle->setHasFoldedDuplicateOffsets(hadDuplicateOffsets);
2125 return operandSwizzle;
2126 }
2127 TIntermConstantUnion *operandConstant = mOperand->getAsConstantUnion();
2128 if (operandConstant == nullptr)
2129 {
2130 return this;
2131 }
2132
2133 TConstantUnion *constArray = new TConstantUnion[mSwizzleOffsets.size()];
2134 for (size_t i = 0; i < mSwizzleOffsets.size(); ++i)
2135 {
2136 constArray[i] = *TIntermConstantUnion::FoldIndexing(
2137 operandConstant->getType(), operandConstant->getConstantValue(), mSwizzleOffsets.at(i));
2138 }
2139 return CreateFoldedNode(constArray, this);
2140}
2141
2142TIntermTyped *TIntermBinary::fold(TDiagnostics *diagnostics)
2143{
2144 const TConstantUnion *rightConstant = mRight->getConstantValue();
2145 switch (mOp)
2146 {
2147 case EOpComma:
2148 {
2149 if (mLeft->hasSideEffects())
2150 {
2151 return this;
2152 }
2153 return mRight;
2154 }
2155 case EOpIndexDirect:
2156 case EOpIndexDirectStruct:
2157 {
2158 if (rightConstant == nullptr)
2159 {
2160 return this;
2161 }
2162 size_t index = static_cast<size_t>(rightConstant->getIConst());
2163 TIntermAggregate *leftAggregate = mLeft->getAsAggregate();
2164 if (leftAggregate && leftAggregate->isConstructor() && leftAggregate->isArray() &&
2165 !leftAggregate->hasSideEffects())
2166 {
2167 ASSERT(index < leftAggregate->getSequence()->size())(index < leftAggregate->getSequence()->size() ? 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/IntermNode.cpp"
, __FUNCTION__, 2167, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2167 << "): " << "index < leftAggregate->getSequence()->size()"
))
;
2168 // This transformation can't add complexity as we're eliminating the constructor
2169 // entirely.
2170 return leftAggregate->getSequence()->at(index)->getAsTyped();
2171 }
2172
2173 // If the indexed value is already a constant union, we can't increase duplication of
2174 // data by folding the indexing. Also fold the node in case it's generally beneficial to
2175 // replace this type of node with a constant union even if that would mean duplicating
2176 // data.
2177 if (mLeft->getAsConstantUnion() || getType().canReplaceWithConstantUnion())
2178 {
2179 const TConstantUnion *constantValue = getConstantValue();
2180 if (constantValue == nullptr)
2181 {
2182 return this;
2183 }
2184 return CreateFoldedNode(constantValue, this);
2185 }
2186 return this;
2187 }
2188 case EOpIndexIndirect:
2189 case EOpIndexDirectInterfaceBlock:
2190 case EOpInitialize:
2191 // Can never be constant folded.
2192 return this;
2193 default:
2194 {
2195 if (rightConstant == nullptr)
2196 {
2197 return this;
2198 }
2199 const TConstantUnion *leftConstant = mLeft->getConstantValue();
2200 if (leftConstant == nullptr)
2201 {
2202 return this;
2203 }
2204 const TConstantUnion *constArray =
2205 TIntermConstantUnion::FoldBinary(mOp, leftConstant, mLeft->getType(), rightConstant,
2206 mRight->getType(), diagnostics, mLeft->getLine());
2207 if (!constArray)
2208 {
2209 return this;
2210 }
2211 return CreateFoldedNode(constArray, this);
2212 }
2213 }
2214}
2215
2216bool TIntermBinary::hasConstantValue() const
2217{
2218 switch (mOp)
2219 {
2220 case EOpIndexDirect:
2221 case EOpIndexDirectStruct:
2222 {
2223 if (mLeft->hasConstantValue() && mRight->hasConstantValue())
2224 {
2225 return true;
2226 }
2227 break;
2228 }
2229 default:
2230 break;
2231 }
2232 return false;
2233}
2234
2235const TConstantUnion *TIntermBinary::getConstantValue() const
2236{
2237 if (!hasConstantValue())
2238 {
2239 return nullptr;
2240 }
2241
2242 const TConstantUnion *leftConstantValue = mLeft->getConstantValue();
2243 int index = mRight->getConstantValue()->getIConst();
2244 const TConstantUnion *constIndexingResult = nullptr;
2245 if (mOp == EOpIndexDirect)
2246 {
2247 constIndexingResult =
2248 TIntermConstantUnion::FoldIndexing(mLeft->getType(), leftConstantValue, index);
2249 }
2250 else
2251 {
2252 ASSERT(mOp == EOpIndexDirectStruct)(mOp == EOpIndexDirectStruct ? 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/IntermNode.cpp"
, __FUNCTION__, 2252, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2252 << "): " << "mOp == EOpIndexDirectStruct"
))
;
2253 const TFieldList &fields = mLeft->getType().getStruct()->fields();
2254
2255 size_t previousFieldsSize = 0;
2256 for (int i = 0; i < index; ++i)
2257 {
2258 previousFieldsSize += fields[i]->type()->getObjectSize();
2259 }
2260 constIndexingResult = leftConstantValue + previousFieldsSize;
2261 }
2262 return constIndexingResult;
2263}
2264
2265const ImmutableString &TIntermBinary::getIndexStructFieldName() const
2266{
2267 ASSERT(mOp == EOpIndexDirectStruct)(mOp == EOpIndexDirectStruct ? 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/IntermNode.cpp"
, __FUNCTION__, 2267, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2267 << "): " << "mOp == EOpIndexDirectStruct"
))
;
2268
2269 const TType &lhsType = mLeft->getType();
2270 const TStructure *structure = lhsType.getStruct();
2271 const int index = mRight->getAsConstantUnion()->getIConst(0);
2272
2273 return structure->fields()[index]->name();
2274}
2275
2276TIntermTyped *TIntermUnary::fold(TDiagnostics *diagnostics)
2277{
2278 TConstantUnion *constArray = nullptr;
2279
2280 if (mOp == EOpArrayLength)
2281 {
2282 // The size of runtime-sized arrays may only be determined at runtime.
2283 if (mOperand->hasSideEffects() || mOperand->getType().isUnsizedArray())
2284 {
2285 return this;
2286 }
2287 constArray = new TConstantUnion[1];
2288 constArray->setIConst(mOperand->getOutermostArraySize());
2289 }
2290 else
2291 {
2292 TIntermConstantUnion *operandConstant = mOperand->getAsConstantUnion();
2293 if (operandConstant == nullptr)
2294 {
2295 return this;
2296 }
2297
2298 switch (mOp)
2299 {
2300 case EOpAny:
2301 case EOpAll:
2302 case EOpLength:
2303 case EOpTranspose:
2304 case EOpDeterminant:
2305 case EOpInverse:
2306 case EOpPackSnorm2x16:
2307 case EOpUnpackSnorm2x16:
2308 case EOpPackUnorm2x16:
2309 case EOpUnpackUnorm2x16:
2310 case EOpPackHalf2x16:
2311 case EOpUnpackHalf2x16:
2312 case EOpPackUnorm4x8:
2313 case EOpPackSnorm4x8:
2314 case EOpUnpackUnorm4x8:
2315 case EOpUnpackSnorm4x8:
2316 constArray = operandConstant->foldUnaryNonComponentWise(mOp);
2317 break;
2318 default:
2319 constArray = operandConstant->foldUnaryComponentWise(mOp, mFunction, diagnostics);
2320 break;
2321 }
2322 }
2323 if (constArray == nullptr)
2324 {
2325 return this;
2326 }
2327 return CreateFoldedNode(constArray, this);
2328}
2329
2330TIntermTyped *TIntermAggregate::fold(TDiagnostics *diagnostics)
2331{
2332 // Make sure that all params are constant before actual constant folding.
2333 for (auto *param : *getSequence())
2334 {
2335 if (param->getAsConstantUnion() == nullptr)
2336 {
2337 return this;
2338 }
2339 }
2340 const TConstantUnion *constArray = nullptr;
2341 if (isConstructor())
2342 {
2343 if (mType.canReplaceWithConstantUnion())
2344 {
2345 constArray = getConstantValue();
2346 if (constArray && mType.getBasicType() == EbtUInt)
2347 {
2348 // Check if we converted a negative float to uint and issue a warning in that case.
2349 size_t sizeRemaining = mType.getObjectSize();
2350 for (TIntermNode *arg : mArguments)
2351 {
2352 TIntermTyped *typedArg = arg->getAsTyped();
2353 if (typedArg->getBasicType() == EbtFloat)
2354 {
2355 const TConstantUnion *argValue = typedArg->getConstantValue();
2356 size_t castSize =
2357 std::min(typedArg->getType().getObjectSize(), sizeRemaining);
2358 for (size_t i = 0; i < castSize; ++i)
2359 {
2360 if (argValue[i].getFConst() < 0.0f)
2361 {
2362 // ESSL 3.00.6 section 5.4.1.
2363 diagnostics->warning(
2364 mLine, "casting a negative float to uint is undefined",
2365 mType.getBuiltInTypeNameString());
2366 }
2367 }
2368 }
2369 sizeRemaining -= typedArg->getType().getObjectSize();
2370 }
2371 }
2372 }
2373 }
2374 else if (CanFoldAggregateBuiltInOp(mOp))
2375 {
2376 constArray = TIntermConstantUnion::FoldAggregateBuiltIn(this, diagnostics);
2377 }
2378 if (constArray == nullptr)
2379 {
2380 return this;
2381 }
2382 return CreateFoldedNode(constArray, this);
2383}
2384
2385//
2386// The fold functions see if an operation on a constant can be done in place,
2387// without generating run-time code.
2388//
2389// Returns the constant value to keep using or nullptr.
2390//
2391const TConstantUnion *TIntermConstantUnion::FoldBinary(TOperator op,
2392 const TConstantUnion *leftArray,
2393 const TType &leftType,
2394 const TConstantUnion *rightArray,
2395 const TType &rightType,
2396 TDiagnostics *diagnostics,
2397 const TSourceLoc &line)
2398{
2399 ASSERT(leftArray && rightArray)(leftArray && rightArray ? 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/IntermNode.cpp"
, __FUNCTION__, 2399, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2399 << "): " << "leftArray && rightArray"
))
;
2400
2401 size_t objectSize = leftType.getObjectSize();
2402
2403 // for a case like float f = vec4(2, 3, 4, 5) + 1.2;
2404 if (rightType.getObjectSize() == 1 && objectSize > 1)
2405 {
2406 rightArray = Vectorize(*rightArray, objectSize);
2407 }
2408 else if (rightType.getObjectSize() > 1 && objectSize == 1)
2409 {
2410 // for a case like float f = 1.2 + vec4(2, 3, 4, 5);
2411 leftArray = Vectorize(*leftArray, rightType.getObjectSize());
2412 objectSize = rightType.getObjectSize();
2413 }
2414
2415 TConstantUnion *resultArray = nullptr;
2416
2417 switch (op)
2418 {
2419 case EOpAdd:
2420 resultArray = new TConstantUnion[objectSize];
2421 for (size_t i = 0; i < objectSize; i++)
2422 resultArray[i] =
2423 TConstantUnion::add(leftArray[i], rightArray[i], diagnostics, line);
2424 break;
2425 case EOpSub:
2426 resultArray = new TConstantUnion[objectSize];
2427 for (size_t i = 0; i < objectSize; i++)
2428 resultArray[i] =
2429 TConstantUnion::sub(leftArray[i], rightArray[i], diagnostics, line);
2430 break;
2431
2432 case EOpMul:
2433 case EOpVectorTimesScalar:
2434 case EOpMatrixTimesScalar:
2435 resultArray = new TConstantUnion[objectSize];
2436 for (size_t i = 0; i < objectSize; i++)
2437 resultArray[i] =
2438 TConstantUnion::mul(leftArray[i], rightArray[i], diagnostics, line);
2439 break;
2440
2441 case EOpMatrixTimesMatrix:
2442 {
2443 // TODO(jmadll): This code should check for overflows.
2444 ASSERT(leftType.getBasicType() == EbtFloat && rightType.getBasicType() == EbtFloat)(leftType.getBasicType() == EbtFloat && rightType.getBasicType
() == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 2444, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2444 << "): " << "leftType.getBasicType() == EbtFloat && rightType.getBasicType() == EbtFloat"
))
;
2445
2446 const uint8_t leftCols = leftType.getCols();
2447 const uint8_t leftRows = leftType.getRows();
2448 const uint8_t rightCols = rightType.getCols();
2449 const uint8_t rightRows = rightType.getRows();
2450 const uint8_t resultCols = rightCols;
2451 const uint8_t resultRows = leftRows;
2452
2453 resultArray = new TConstantUnion[resultCols * resultRows];
2454 for (uint8_t row = 0; row < resultRows; row++)
2455 {
2456 for (uint8_t column = 0; column < resultCols; column++)
2457 {
2458 resultArray[resultRows * column + row].setFConst(0.0f);
2459 for (uint8_t i = 0; i < leftCols; i++)
2460 {
2461 resultArray[resultRows * column + row].setFConst(
2462 resultArray[resultRows * column + row].getFConst() +
2463 leftArray[i * leftRows + row].getFConst() *
2464 rightArray[column * rightRows + i].getFConst());
2465 }
2466 }
2467 }
2468 }
2469 break;
2470
2471 case EOpDiv:
2472 case EOpIMod:
2473 {
2474 resultArray = new TConstantUnion[objectSize];
2475 for (size_t i = 0; i < objectSize; i++)
2476 {
2477 if (IsFloatDivision(leftType.getBasicType(), rightType.getBasicType()))
2478 {
2479 // Float division requested, possibly with implicit conversion
2480 ASSERT(op == EOpDiv)(op == EOpDiv ? 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/IntermNode.cpp"
, __FUNCTION__, 2480, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2480 << "): " << "op == EOpDiv"
))
;
2481 float dividend = leftArray[i].getFConst();
2482 float divisor = rightArray[i].getFConst();
2483
2484 if (divisor == 0.0f)
2485 {
2486 if (dividend == 0.0f)
2487 {
2488 diagnostics->warning(line,
2489 "Zero divided by zero during constant "
2490 "folding generated NaN",
2491 "/");
2492 resultArray[i].setFConst(std::numeric_limits<float>::quiet_NaN());
2493 }
2494 else
2495 {
2496 diagnostics->warning(line, "Divide by zero during constant folding",
2497 "/");
2498 bool negativeResult = std::signbit(dividend) != std::signbit(divisor);
2499 resultArray[i].setFConst(negativeResult
2500 ? -std::numeric_limits<float>::infinity()
2501 : std::numeric_limits<float>::infinity());
2502 }
2503 }
2504 else if (gl::isInf(dividend) && gl::isInf(divisor))
2505 {
2506 diagnostics->warning(line,
2507 "Infinity divided by infinity during constant "
2508 "folding generated NaN",
2509 "/");
2510 resultArray[i].setFConst(std::numeric_limits<float>::quiet_NaN());
2511 }
2512 else
2513 {
2514 float result = dividend / divisor;
2515 if (!gl::isInf(dividend) && gl::isInf(result))
2516 {
2517 diagnostics->warning(
2518 line, "Constant folded division overflowed to infinity", "/");
2519 }
2520 resultArray[i].setFConst(result);
2521 }
2522 }
2523 else
2524 {
2525 // Types are either both int or both uint
2526 switch (leftType.getBasicType())
2527 {
2528 case EbtInt:
2529 {
2530 if (rightArray[i] == 0)
2531 {
2532 diagnostics->warning(
2533 line, "Divide by zero error during constant folding", "/");
2534 resultArray[i].setIConst(INT_MAX2147483647);
2535 }
2536 else
2537 {
2538 int lhs = leftArray[i].getIConst();
2539 int divisor = rightArray[i].getIConst();
2540 if (op == EOpDiv)
2541 {
2542 // Check for the special case where the minimum
2543 // representable number is divided by -1. If left alone this
2544 // leads to integer overflow in C++. ESSL 3.00.6
2545 // section 4.1.3 Integers: "However, for the case where the
2546 // minimum representable value is divided by -1, it is
2547 // allowed to return either the minimum representable value
2548 // or the maximum representable value."
2549 if (lhs == -0x7fffffff - 1 && divisor == -1)
2550 {
2551 resultArray[i].setIConst(0x7fffffff);
2552 }
2553 else
2554 {
2555 resultArray[i].setIConst(lhs / divisor);
2556 }
2557 }
2558 else
2559 {
2560 ASSERT(op == EOpIMod)(op == EOpIMod ? 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/IntermNode.cpp"
, __FUNCTION__, 2560, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2560 << "): " << "op == EOpIMod"
))
;
2561 if (lhs < 0 || divisor < 0)
2562 {
2563 // ESSL 3.00.6 section 5.9: Results of modulus are
2564 // undefined when either one of the operands is
2565 // negative.
2566 diagnostics->warning(line,
2567 "Negative modulus operator operand "
2568 "encountered during constant folding. "
2569 "Results are undefined.",
2570 "%");
2571 resultArray[i].setIConst(0);
2572 }
2573 else
2574 {
2575 resultArray[i].setIConst(lhs % divisor);
2576 }
2577 }
2578 }
2579 break;
2580 }
2581 case EbtUInt:
2582 {
2583 if (rightArray[i] == 0)
2584 {
2585 diagnostics->warning(
2586 line, "Divide by zero error during constant folding", "/");
2587 resultArray[i].setUConst(UINT_MAX(2147483647 *2U +1U));
2588 }
2589 else
2590 {
2591 if (op == EOpDiv)
2592 {
2593 resultArray[i].setUConst(leftArray[i].getUConst() /
2594 rightArray[i].getUConst());
2595 }
2596 else
2597 {
2598 ASSERT(op == EOpIMod)(op == EOpIMod ? 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/IntermNode.cpp"
, __FUNCTION__, 2598, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2598 << "): " << "op == EOpIMod"
))
;
2599 resultArray[i].setUConst(leftArray[i].getUConst() %
2600 rightArray[i].getUConst());
2601 }
2602 }
2603 break;
2604 }
2605 default:
2606 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/IntermNode.cpp"
, __FUNCTION__, 2606, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2606 << ")"; } while (0)
;
2607 return nullptr;
2608 }
2609 }
2610 }
2611 }
2612 break;
2613
2614 case EOpMatrixTimesVector:
2615 {
2616 // TODO(jmadll): This code should check for overflows.
2617 ASSERT(rightType.getBasicType() == EbtFloat)(rightType.getBasicType() == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 2617, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2617 << "): " << "rightType.getBasicType() == EbtFloat"
))
;
2618
2619 const uint8_t matrixCols = leftType.getCols();
2620 const uint8_t matrixRows = leftType.getRows();
2621
2622 resultArray = new TConstantUnion[matrixRows];
2623
2624 for (uint8_t matrixRow = 0; matrixRow < matrixRows; matrixRow++)
2625 {
2626 resultArray[matrixRow].setFConst(0.0f);
2627 for (uint8_t col = 0; col < matrixCols; col++)
2628 {
2629 resultArray[matrixRow].setFConst(
2630 resultArray[matrixRow].getFConst() +
2631 leftArray[col * matrixRows + matrixRow].getFConst() *
2632 rightArray[col].getFConst());
2633 }
2634 }
2635 }
2636 break;
2637
2638 case EOpVectorTimesMatrix:
2639 {
2640 // TODO(jmadll): This code should check for overflows.
2641 ASSERT(leftType.getBasicType() == EbtFloat)(leftType.getBasicType() == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 2641, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2641 << "): " << "leftType.getBasicType() == EbtFloat"
))
;
2642
2643 const uint8_t matrixCols = rightType.getCols();
2644 const uint8_t matrixRows = rightType.getRows();
2645
2646 resultArray = new TConstantUnion[matrixCols];
2647
2648 for (uint8_t matrixCol = 0; matrixCol < matrixCols; matrixCol++)
2649 {
2650 resultArray[matrixCol].setFConst(0.0f);
2651 for (uint8_t matrixRow = 0; matrixRow < matrixRows; matrixRow++)
2652 {
2653 resultArray[matrixCol].setFConst(
2654 resultArray[matrixCol].getFConst() +
2655 leftArray[matrixRow].getFConst() *
2656 rightArray[matrixCol * matrixRows + matrixRow].getFConst());
2657 }
2658 }
2659 }
2660 break;
2661
2662 case EOpLogicalAnd:
2663 {
2664 resultArray = new TConstantUnion[objectSize];
2665 for (size_t i = 0; i < objectSize; i++)
2666 {
2667 resultArray[i] = leftArray[i] && rightArray[i];
2668 }
2669 }
2670 break;
2671
2672 case EOpLogicalOr:
2673 {
2674 resultArray = new TConstantUnion[objectSize];
2675 for (size_t i = 0; i < objectSize; i++)
2676 {
2677 resultArray[i] = leftArray[i] || rightArray[i];
2678 }
2679 }
2680 break;
2681
2682 case EOpLogicalXor:
2683 {
2684 ASSERT(leftType.getBasicType() == EbtBool)(leftType.getBasicType() == EbtBool ? 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/IntermNode.cpp"
, __FUNCTION__, 2684, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2684 << "): " << "leftType.getBasicType() == EbtBool"
))
;
2685 resultArray = new TConstantUnion[objectSize];
2686 for (size_t i = 0; i < objectSize; i++)
2687 {
2688 resultArray[i].setBConst(leftArray[i] != rightArray[i]);
2689 }
2690 }
2691 break;
2692
2693 case EOpBitwiseAnd:
2694 resultArray = new TConstantUnion[objectSize];
2695 for (size_t i = 0; i < objectSize; i++)
2696 resultArray[i] = leftArray[i] & rightArray[i];
2697 break;
2698 case EOpBitwiseXor:
2699 resultArray = new TConstantUnion[objectSize];
2700 for (size_t i = 0; i < objectSize; i++)
2701 resultArray[i] = leftArray[i] ^ rightArray[i];
2702 break;
2703 case EOpBitwiseOr:
2704 resultArray = new TConstantUnion[objectSize];
2705 for (size_t i = 0; i < objectSize; i++)
2706 resultArray[i] = leftArray[i] | rightArray[i];
2707 break;
2708 case EOpBitShiftLeft:
2709 resultArray = new TConstantUnion[objectSize];
2710 for (size_t i = 0; i < objectSize; i++)
2711 resultArray[i] =
2712 TConstantUnion::lshift(leftArray[i], rightArray[i], diagnostics, line);
2713 break;
2714 case EOpBitShiftRight:
2715 resultArray = new TConstantUnion[objectSize];
2716 for (size_t i = 0; i < objectSize; i++)
2717 resultArray[i] =
2718 TConstantUnion::rshift(leftArray[i], rightArray[i], diagnostics, line);
2719 break;
2720
2721 case EOpLessThan:
2722 ASSERT(objectSize == 1)(objectSize == 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/IntermNode.cpp"
, __FUNCTION__, 2722, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2722 << "): " << "objectSize == 1"
))
;
2723 resultArray = new TConstantUnion[1];
2724 resultArray->setBConst(*leftArray < *rightArray);
2725 break;
2726
2727 case EOpGreaterThan:
2728 ASSERT(objectSize == 1)(objectSize == 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/IntermNode.cpp"
, __FUNCTION__, 2728, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2728 << "): " << "objectSize == 1"
))
;
2729 resultArray = new TConstantUnion[1];
2730 resultArray->setBConst(*leftArray > *rightArray);
2731 break;
2732
2733 case EOpLessThanEqual:
2734 ASSERT(objectSize == 1)(objectSize == 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/IntermNode.cpp"
, __FUNCTION__, 2734, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2734 << "): " << "objectSize == 1"
))
;
2735 resultArray = new TConstantUnion[1];
2736 resultArray->setBConst(!(*leftArray > *rightArray));
2737 break;
2738
2739 case EOpGreaterThanEqual:
2740 ASSERT(objectSize == 1)(objectSize == 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/IntermNode.cpp"
, __FUNCTION__, 2740, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2740 << "): " << "objectSize == 1"
))
;
2741 resultArray = new TConstantUnion[1];
2742 resultArray->setBConst(!(*leftArray < *rightArray));
2743 break;
2744
2745 case EOpEqual:
2746 case EOpNotEqual:
2747 {
2748 resultArray = new TConstantUnion[1];
2749 bool equal = true;
2750 for (size_t i = 0; i < objectSize; i++)
2751 {
2752 if (leftArray[i] != rightArray[i])
2753 {
2754 equal = false;
2755 break; // break out of for loop
2756 }
2757 }
2758 if (op == EOpEqual)
2759 {
2760 resultArray->setBConst(equal);
2761 }
2762 else
2763 {
2764 resultArray->setBConst(!equal);
2765 }
2766 }
2767 break;
2768
2769 default:
2770 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/IntermNode.cpp"
, __FUNCTION__, 2770, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2770 << ")"; } while (0)
;
2771 return nullptr;
2772 }
2773 return resultArray;
2774}
2775
2776// The fold functions do operations on a constant at GLSL compile time, without generating run-time
2777// code. Returns the constant value to keep using. Nullptr should not be returned.
2778TConstantUnion *TIntermConstantUnion::foldUnaryNonComponentWise(TOperator op)
2779{
2780 // Do operations where the return type may have a different number of components compared to the
2781 // operand type.
2782
2783 const TConstantUnion *operandArray = getConstantValue();
2784 ASSERT(operandArray)(operandArray ? 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/IntermNode.cpp"
, __FUNCTION__, 2784, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2784 << "): " << "operandArray"
))
;
2785
2786 size_t objectSize = getType().getObjectSize();
2787 TConstantUnion *resultArray = nullptr;
2788 switch (op)
2789 {
2790 case EOpAny:
2791 ASSERT(getType().getBasicType() == EbtBool)(getType().getBasicType() == EbtBool ? 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/IntermNode.cpp"
, __FUNCTION__, 2791, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2791 << "): " << "getType().getBasicType() == EbtBool"
))
;
2792 resultArray = new TConstantUnion();
2793 resultArray->setBConst(false);
2794 for (size_t i = 0; i < objectSize; i++)
2795 {
2796 if (operandArray[i].getBConst())
2797 {
2798 resultArray->setBConst(true);
2799 break;
2800 }
2801 }
2802 break;
2803
2804 case EOpAll:
2805 ASSERT(getType().getBasicType() == EbtBool)(getType().getBasicType() == EbtBool ? 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/IntermNode.cpp"
, __FUNCTION__, 2805, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2805 << "): " << "getType().getBasicType() == EbtBool"
))
;
2806 resultArray = new TConstantUnion();
2807 resultArray->setBConst(true);
2808 for (size_t i = 0; i < objectSize; i++)
2809 {
2810 if (!operandArray[i].getBConst())
2811 {
2812 resultArray->setBConst(false);
2813 break;
2814 }
2815 }
2816 break;
2817
2818 case EOpLength:
2819 ASSERT(getType().getBasicType() == EbtFloat)(getType().getBasicType() == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 2819, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2819 << "): " << "getType().getBasicType() == EbtFloat"
))
;
2820 resultArray = new TConstantUnion();
2821 resultArray->setFConst(VectorLength(operandArray, objectSize));
2822 break;
2823
2824 case EOpTranspose:
2825 {
2826 ASSERT(getType().getBasicType() == EbtFloat)(getType().getBasicType() == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 2826, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2826 << "): " << "getType().getBasicType() == EbtFloat"
))
;
2827 resultArray = new TConstantUnion[objectSize];
2828 angle::Matrix<float> result =
2829 GetMatrix(operandArray, getType().getRows(), getType().getCols()).transpose();
2830 SetUnionArrayFromMatrix(result, resultArray);
2831 break;
2832 }
2833
2834 case EOpDeterminant:
2835 {
2836 ASSERT(getType().getBasicType() == EbtFloat)(getType().getBasicType() == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 2836, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2836 << "): " << "getType().getBasicType() == EbtFloat"
))
;
2837 const uint8_t size = getType().getNominalSize();
2838 ASSERT(size >= 2 && size <= 4)(size >= 2 && size <= 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/IntermNode.cpp"
, __FUNCTION__, 2838, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2838 << "): " << "size >= 2 && size <= 4"
))
;
2839 resultArray = new TConstantUnion();
2840 resultArray->setFConst(GetMatrix(operandArray, size).determinant());
2841 break;
2842 }
2843
2844 case EOpInverse:
2845 {
2846 ASSERT(getType().getBasicType() == EbtFloat)(getType().getBasicType() == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 2846, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2846 << "): " << "getType().getBasicType() == EbtFloat"
))
;
2847 const uint8_t size = getType().getNominalSize();
2848 ASSERT(size >= 2 && size <= 4)(size >= 2 && size <= 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/IntermNode.cpp"
, __FUNCTION__, 2848, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2848 << "): " << "size >= 2 && size <= 4"
))
;
2849 resultArray = new TConstantUnion[objectSize];
2850 angle::Matrix<float> result = GetMatrix(operandArray, size).inverse();
2851 SetUnionArrayFromMatrix(result, resultArray);
2852 break;
2853 }
2854
2855 case EOpPackSnorm2x16:
2856 ASSERT(getType().getBasicType() == EbtFloat)(getType().getBasicType() == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 2856, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2856 << "): " << "getType().getBasicType() == EbtFloat"
))
;
2857 ASSERT(getType().getNominalSize() == 2)(getType().getNominalSize() == 2 ? 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/IntermNode.cpp"
, __FUNCTION__, 2857, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2857 << "): " << "getType().getNominalSize() == 2"
))
;
2858 resultArray = new TConstantUnion();
2859 resultArray->setUConst(
2860 gl::packSnorm2x16(operandArray[0].getFConst(), operandArray[1].getFConst()));
2861 break;
2862
2863 case EOpUnpackSnorm2x16:
2864 {
2865 ASSERT(getType().getBasicType() == EbtUInt)(getType().getBasicType() == EbtUInt ? 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/IntermNode.cpp"
, __FUNCTION__, 2865, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2865 << "): " << "getType().getBasicType() == EbtUInt"
))
;
2866 resultArray = new TConstantUnion[2];
2867 float f1, f2;
2868 gl::unpackSnorm2x16(operandArray[0].getUConst(), &f1, &f2);
2869 resultArray[0].setFConst(f1);
2870 resultArray[1].setFConst(f2);
2871 break;
2872 }
2873
2874 case EOpPackUnorm2x16:
2875 ASSERT(getType().getBasicType() == EbtFloat)(getType().getBasicType() == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 2875, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2875 << "): " << "getType().getBasicType() == EbtFloat"
))
;
2876 ASSERT(getType().getNominalSize() == 2)(getType().getNominalSize() == 2 ? 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/IntermNode.cpp"
, __FUNCTION__, 2876, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2876 << "): " << "getType().getNominalSize() == 2"
))
;
2877 resultArray = new TConstantUnion();
2878 resultArray->setUConst(
2879 gl::packUnorm2x16(operandArray[0].getFConst(), operandArray[1].getFConst()));
2880 break;
2881
2882 case EOpUnpackUnorm2x16:
2883 {
2884 ASSERT(getType().getBasicType() == EbtUInt)(getType().getBasicType() == EbtUInt ? 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/IntermNode.cpp"
, __FUNCTION__, 2884, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2884 << "): " << "getType().getBasicType() == EbtUInt"
))
;
2885 resultArray = new TConstantUnion[2];
2886 float f1, f2;
2887 gl::unpackUnorm2x16(operandArray[0].getUConst(), &f1, &f2);
2888 resultArray[0].setFConst(f1);
2889 resultArray[1].setFConst(f2);
2890 break;
2891 }
2892
2893 case EOpPackHalf2x16:
2894 ASSERT(getType().getBasicType() == EbtFloat)(getType().getBasicType() == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 2894, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2894 << "): " << "getType().getBasicType() == EbtFloat"
))
;
2895 ASSERT(getType().getNominalSize() == 2)(getType().getNominalSize() == 2 ? 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/IntermNode.cpp"
, __FUNCTION__, 2895, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2895 << "): " << "getType().getNominalSize() == 2"
))
;
2896 resultArray = new TConstantUnion();
2897 resultArray->setUConst(
2898 gl::packHalf2x16(operandArray[0].getFConst(), operandArray[1].getFConst()));
2899 break;
2900
2901 case EOpUnpackHalf2x16:
2902 {
2903 ASSERT(getType().getBasicType() == EbtUInt)(getType().getBasicType() == EbtUInt ? 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/IntermNode.cpp"
, __FUNCTION__, 2903, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2903 << "): " << "getType().getBasicType() == EbtUInt"
))
;
2904 resultArray = new TConstantUnion[2];
2905 float f1, f2;
2906 gl::unpackHalf2x16(operandArray[0].getUConst(), &f1, &f2);
2907 resultArray[0].setFConst(f1);
2908 resultArray[1].setFConst(f2);
2909 break;
2910 }
2911
2912 case EOpPackUnorm4x8:
2913 {
2914 ASSERT(getType().getBasicType() == EbtFloat)(getType().getBasicType() == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 2914, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2914 << "): " << "getType().getBasicType() == EbtFloat"
))
;
2915 resultArray = new TConstantUnion();
2916 resultArray->setUConst(
2917 gl::PackUnorm4x8(operandArray[0].getFConst(), operandArray[1].getFConst(),
2918 operandArray[2].getFConst(), operandArray[3].getFConst()));
2919 break;
2920 }
2921 case EOpPackSnorm4x8:
2922 {
2923 ASSERT(getType().getBasicType() == EbtFloat)(getType().getBasicType() == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 2923, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2923 << "): " << "getType().getBasicType() == EbtFloat"
))
;
2924 resultArray = new TConstantUnion();
2925 resultArray->setUConst(
2926 gl::PackSnorm4x8(operandArray[0].getFConst(), operandArray[1].getFConst(),
2927 operandArray[2].getFConst(), operandArray[3].getFConst()));
2928 break;
2929 }
2930 case EOpUnpackUnorm4x8:
2931 {
2932 ASSERT(getType().getBasicType() == EbtUInt)(getType().getBasicType() == EbtUInt ? 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/IntermNode.cpp"
, __FUNCTION__, 2932, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2932 << "): " << "getType().getBasicType() == EbtUInt"
))
;
2933 resultArray = new TConstantUnion[4];
2934 float f[4];
2935 gl::UnpackUnorm4x8(operandArray[0].getUConst(), f);
2936 for (size_t i = 0; i < 4; ++i)
2937 {
2938 resultArray[i].setFConst(f[i]);
2939 }
2940 break;
2941 }
2942 case EOpUnpackSnorm4x8:
2943 {
2944 ASSERT(getType().getBasicType() == EbtUInt)(getType().getBasicType() == EbtUInt ? 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/IntermNode.cpp"
, __FUNCTION__, 2944, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2944 << "): " << "getType().getBasicType() == EbtUInt"
))
;
2945 resultArray = new TConstantUnion[4];
2946 float f[4];
2947 gl::UnpackSnorm4x8(operandArray[0].getUConst(), f);
2948 for (size_t i = 0; i < 4; ++i)
2949 {
2950 resultArray[i].setFConst(f[i]);
2951 }
2952 break;
2953 }
2954
2955 default:
2956 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/IntermNode.cpp"
, __FUNCTION__, 2956, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2956 << ")"; } while (0)
;
2957 break;
2958 }
2959
2960 return resultArray;
2961}
2962
2963TConstantUnion *TIntermConstantUnion::foldUnaryComponentWise(TOperator op,
2964 const TFunction *function,
2965 TDiagnostics *diagnostics)
2966{
2967 // Do unary operations where each component of the result is computed based on the corresponding
2968 // component of the operand. Also folds normalize, though the divisor in that case takes all
2969 // components into account.
2970
2971 const TConstantUnion *operandArray = getConstantValue();
2972 ASSERT(operandArray)(operandArray ? 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/IntermNode.cpp"
, __FUNCTION__, 2972, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 2972 << "): " << "operandArray"
))
;
2973
2974 size_t objectSize = getType().getObjectSize();
2975
2976 TConstantUnion *resultArray = new TConstantUnion[objectSize];
2977 for (size_t i = 0; i < objectSize; i++)
2978 {
2979 switch (op)
2980 {
2981 case EOpNegative:
2982 switch (getType().getBasicType())
2983 {
2984 case EbtFloat:
2985 resultArray[i].setFConst(-operandArray[i].getFConst());
2986 break;
2987 case EbtInt:
2988 if (operandArray[i] == std::numeric_limits<int>::min())
2989 {
2990 // The minimum representable integer doesn't have a positive
2991 // counterpart, rather the negation overflows and in ESSL is supposed to
2992 // wrap back to the minimum representable integer. Make sure that we
2993 // don't actually let the negation overflow, which has undefined
2994 // behavior in C++.
2995 resultArray[i].setIConst(std::numeric_limits<int>::min());
2996 }
2997 else
2998 {
2999 resultArray[i].setIConst(-operandArray[i].getIConst());
3000 }
3001 break;
3002 case EbtUInt:
3003 if (operandArray[i] == 0x80000000u)
3004 {
3005 resultArray[i].setUConst(0x80000000u);
3006 }
3007 else
3008 {
3009 resultArray[i].setUConst(static_cast<unsigned int>(
3010 -static_cast<int>(operandArray[i].getUConst())));
3011 }
3012 break;
3013 default:
3014 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/IntermNode.cpp"
, __FUNCTION__, 3014, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3014 << ")"; } while (0)
;
3015 return nullptr;
3016 }
3017 break;
3018
3019 case EOpPositive:
3020 switch (getType().getBasicType())
3021 {
3022 case EbtFloat:
3023 resultArray[i].setFConst(operandArray[i].getFConst());
3024 break;
3025 case EbtInt:
3026 resultArray[i].setIConst(operandArray[i].getIConst());
3027 break;
3028 case EbtUInt:
3029 resultArray[i].setUConst(static_cast<unsigned int>(
3030 static_cast<int>(operandArray[i].getUConst())));
3031 break;
3032 default:
3033 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/IntermNode.cpp"
, __FUNCTION__, 3033, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3033 << ")"; } while (0)
;
3034 return nullptr;
3035 }
3036 break;
3037
3038 case EOpLogicalNot:
3039 switch (getType().getBasicType())
3040 {
3041 case EbtBool:
3042 resultArray[i].setBConst(!operandArray[i].getBConst());
3043 break;
3044 default:
3045 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/IntermNode.cpp"
, __FUNCTION__, 3045, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3045 << ")"; } while (0)
;
3046 return nullptr;
3047 }
3048 break;
3049
3050 case EOpBitwiseNot:
3051 switch (getType().getBasicType())
3052 {
3053 case EbtInt:
3054 resultArray[i].setIConst(~operandArray[i].getIConst());
3055 break;
3056 case EbtUInt:
3057 resultArray[i].setUConst(~operandArray[i].getUConst());
3058 break;
3059 default:
3060 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/IntermNode.cpp"
, __FUNCTION__, 3060, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3060 << ")"; } while (0)
;
3061 return nullptr;
3062 }
3063 break;
3064
3065 case EOpRadians:
3066 ASSERT(getType().getBasicType() == EbtFloat)(getType().getBasicType() == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 3066, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3066 << "): " << "getType().getBasicType() == EbtFloat"
))
;
3067 resultArray[i].setFConst(kDegreesToRadiansMultiplier * operandArray[i].getFConst());
3068 break;
3069
3070 case EOpDegrees:
3071 ASSERT(getType().getBasicType() == EbtFloat)(getType().getBasicType() == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 3071, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3071 << "): " << "getType().getBasicType() == EbtFloat"
))
;
3072 resultArray[i].setFConst(kRadiansToDegreesMultiplier * operandArray[i].getFConst());
3073 break;
3074
3075 case EOpSin:
3076 foldFloatTypeUnary(operandArray[i], &sinf, &resultArray[i]);
3077 break;
3078
3079 case EOpCos:
3080 foldFloatTypeUnary(operandArray[i], &cosf, &resultArray[i]);
3081 break;
3082
3083 case EOpTan:
3084 foldFloatTypeUnary(operandArray[i], &tanf, &resultArray[i]);
3085 break;
3086
3087 case EOpAsin:
3088 // For asin(x), results are undefined if |x| > 1, we are choosing to set result to
3089 // 0.
3090 if (fabsf(operandArray[i].getFConst()) > 1.0f)
3091 UndefinedConstantFoldingError(getLine(), function, getType().getBasicType(),
3092 diagnostics, &resultArray[i]);
3093 else
3094 foldFloatTypeUnary(operandArray[i], &asinf, &resultArray[i]);
3095 break;
3096
3097 case EOpAcos:
3098 // For acos(x), results are undefined if |x| > 1, we are choosing to set result to
3099 // 0.
3100 if (fabsf(operandArray[i].getFConst()) > 1.0f)
3101 UndefinedConstantFoldingError(getLine(), function, getType().getBasicType(),
3102 diagnostics, &resultArray[i]);
3103 else
3104 foldFloatTypeUnary(operandArray[i], &acosf, &resultArray[i]);
3105 break;
3106
3107 case EOpAtan:
3108 foldFloatTypeUnary(operandArray[i], &atanf, &resultArray[i]);
3109 break;
3110
3111 case EOpSinh:
3112 foldFloatTypeUnary(operandArray[i], &sinhf, &resultArray[i]);
3113 break;
3114
3115 case EOpCosh:
3116 foldFloatTypeUnary(operandArray[i], &coshf, &resultArray[i]);
3117 break;
3118
3119 case EOpTanh:
3120 foldFloatTypeUnary(operandArray[i], &tanhf, &resultArray[i]);
3121 break;
3122
3123 case EOpAsinh:
3124 foldFloatTypeUnary(operandArray[i], &asinhf, &resultArray[i]);
3125 break;
3126
3127 case EOpAcosh:
3128 // For acosh(x), results are undefined if x < 1, we are choosing to set result to 0.
3129 if (operandArray[i].getFConst() < 1.0f)
3130 UndefinedConstantFoldingError(getLine(), function, getType().getBasicType(),
3131 diagnostics, &resultArray[i]);
3132 else
3133 foldFloatTypeUnary(operandArray[i], &acoshf, &resultArray[i]);
3134 break;
3135
3136 case EOpAtanh:
3137 // For atanh(x), results are undefined if |x| >= 1, we are choosing to set result to
3138 // 0.
3139 if (fabsf(operandArray[i].getFConst()) >= 1.0f)
3140 UndefinedConstantFoldingError(getLine(), function, getType().getBasicType(),
3141 diagnostics, &resultArray[i]);
3142 else
3143 foldFloatTypeUnary(operandArray[i], &atanhf, &resultArray[i]);
3144 break;
3145
3146 case EOpAbs:
3147 switch (getType().getBasicType())
3148 {
3149 case EbtFloat:
3150 resultArray[i].setFConst(fabsf(operandArray[i].getFConst()));
3151 break;
3152 case EbtInt:
3153 resultArray[i].setIConst(abs(operandArray[i].getIConst()));
3154 break;
3155 default:
3156 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/IntermNode.cpp"
, __FUNCTION__, 3156, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3156 << ")"; } while (0)
;
3157 return nullptr;
3158 }
3159 break;
3160
3161 case EOpSign:
3162 switch (getType().getBasicType())
3163 {
3164 case EbtFloat:
3165 {
3166 float fConst = operandArray[i].getFConst();
3167 float fResult = 0.0f;
3168 if (fConst > 0.0f)
3169 fResult = 1.0f;
3170 else if (fConst < 0.0f)
3171 fResult = -1.0f;
3172 resultArray[i].setFConst(fResult);
3173 break;
3174 }
3175 case EbtInt:
3176 {
3177 int iConst = operandArray[i].getIConst();
3178 int iResult = 0;
3179 if (iConst > 0)
3180 iResult = 1;
3181 else if (iConst < 0)
3182 iResult = -1;
3183 resultArray[i].setIConst(iResult);
3184 break;
3185 }
3186 default:
3187 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/IntermNode.cpp"
, __FUNCTION__, 3187, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3187 << ")"; } while (0)
;
3188 return nullptr;
3189 }
3190 break;
3191
3192 case EOpFloor:
3193 foldFloatTypeUnary(operandArray[i], &floorf, &resultArray[i]);
3194 break;
3195
3196 case EOpTrunc:
3197 foldFloatTypeUnary(operandArray[i], &truncf, &resultArray[i]);
3198 break;
3199
3200 case EOpRound:
3201 foldFloatTypeUnary(operandArray[i], &roundf, &resultArray[i]);
3202 break;
3203
3204 case EOpRoundEven:
3205 {
3206 ASSERT(getType().getBasicType() == EbtFloat)(getType().getBasicType() == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 3206, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3206 << "): " << "getType().getBasicType() == EbtFloat"
))
;
3207 float x = operandArray[i].getFConst();
3208 float result;
3209 float fractPart = modff(x, &result);
3210 if (fabsf(fractPart) == 0.5f)
3211 result = 2.0f * roundf(x / 2.0f);
3212 else
3213 result = roundf(x);
3214 resultArray[i].setFConst(result);
3215 break;
3216 }
3217
3218 case EOpCeil:
3219 foldFloatTypeUnary(operandArray[i], &ceilf, &resultArray[i]);
3220 break;
3221
3222 case EOpFract:
3223 {
3224 ASSERT(getType().getBasicType() == EbtFloat)(getType().getBasicType() == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 3224, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3224 << "): " << "getType().getBasicType() == EbtFloat"
))
;
3225 float x = operandArray[i].getFConst();
3226 resultArray[i].setFConst(x - floorf(x));
3227 break;
3228 }
3229
3230 case EOpIsnan:
3231 ASSERT(getType().getBasicType() == EbtFloat)(getType().getBasicType() == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 3231, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3231 << "): " << "getType().getBasicType() == EbtFloat"
))
;
3232 resultArray[i].setBConst(gl::isNaN(operandArray[0].getFConst()));
3233 break;
3234
3235 case EOpIsinf:
3236 ASSERT(getType().getBasicType() == EbtFloat)(getType().getBasicType() == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 3236, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3236 << "): " << "getType().getBasicType() == EbtFloat"
))
;
3237 resultArray[i].setBConst(gl::isInf(operandArray[0].getFConst()));
3238 break;
3239
3240 case EOpFloatBitsToInt:
3241 ASSERT(getType().getBasicType() == EbtFloat)(getType().getBasicType() == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 3241, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3241 << "): " << "getType().getBasicType() == EbtFloat"
))
;
3242 resultArray[i].setIConst(gl::bitCast<int32_t>(operandArray[0].getFConst()));
3243 break;
3244
3245 case EOpFloatBitsToUint:
3246 ASSERT(getType().getBasicType() == EbtFloat)(getType().getBasicType() == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 3246, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3246 << "): " << "getType().getBasicType() == EbtFloat"
))
;
3247 resultArray[i].setUConst(gl::bitCast<uint32_t>(operandArray[0].getFConst()));
3248 break;
3249
3250 case EOpIntBitsToFloat:
3251 ASSERT(getType().getBasicType() == EbtInt)(getType().getBasicType() == EbtInt ? 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/IntermNode.cpp"
, __FUNCTION__, 3251, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3251 << "): " << "getType().getBasicType() == EbtInt"
))
;
3252 resultArray[i].setFConst(gl::bitCast<float>(operandArray[0].getIConst()));
3253 break;
3254
3255 case EOpUintBitsToFloat:
3256 ASSERT(getType().getBasicType() == EbtUInt)(getType().getBasicType() == EbtUInt ? 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/IntermNode.cpp"
, __FUNCTION__, 3256, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3256 << "): " << "getType().getBasicType() == EbtUInt"
))
;
3257 resultArray[i].setFConst(gl::bitCast<float>(operandArray[0].getUConst()));
3258 break;
3259
3260 case EOpExp:
3261 foldFloatTypeUnary(operandArray[i], &expf, &resultArray[i]);
3262 break;
3263
3264 case EOpLog:
3265 // For log(x), results are undefined if x <= 0, we are choosing to set result to 0.
3266 if (operandArray[i].getFConst() <= 0.0f)
3267 UndefinedConstantFoldingError(getLine(), function, getType().getBasicType(),
3268 diagnostics, &resultArray[i]);
3269 else
3270 foldFloatTypeUnary(operandArray[i], &logf, &resultArray[i]);
3271 break;
3272
3273 case EOpExp2:
3274 foldFloatTypeUnary(operandArray[i], &exp2f, &resultArray[i]);
3275 break;
3276
3277 case EOpLog2:
3278 // For log2(x), results are undefined if x <= 0, we are choosing to set result to 0.
3279 // And log2f is not available on some plarforms like old android, so just using
3280 // log(x)/log(2) here.
3281 if (operandArray[i].getFConst() <= 0.0f)
3282 UndefinedConstantFoldingError(getLine(), function, getType().getBasicType(),
3283 diagnostics, &resultArray[i]);
3284 else
3285 {
3286 foldFloatTypeUnary(operandArray[i], &logf, &resultArray[i]);
3287 resultArray[i].setFConst(resultArray[i].getFConst() / logf(2.0f));
3288 }
3289 break;
3290
3291 case EOpSqrt:
3292 // For sqrt(x), results are undefined if x < 0, we are choosing to set result to 0.
3293 if (operandArray[i].getFConst() < 0.0f)
3294 UndefinedConstantFoldingError(getLine(), function, getType().getBasicType(),
3295 diagnostics, &resultArray[i]);
3296 else
3297 foldFloatTypeUnary(operandArray[i], &sqrtf, &resultArray[i]);
3298 break;
3299
3300 case EOpInversesqrt:
3301 // There is no stdlib built-in function equavalent for GLES built-in inversesqrt(),
3302 // so getting the square root first using builtin function sqrt() and then taking
3303 // its inverse.
3304 // Also, for inversesqrt(x), results are undefined if x <= 0, we are choosing to set
3305 // result to 0.
3306 if (operandArray[i].getFConst() <= 0.0f)
3307 UndefinedConstantFoldingError(getLine(), function, getType().getBasicType(),
3308 diagnostics, &resultArray[i]);
3309 else
3310 {
3311 foldFloatTypeUnary(operandArray[i], &sqrtf, &resultArray[i]);
3312 resultArray[i].setFConst(1.0f / resultArray[i].getFConst());
3313 }
3314 break;
3315
3316 case EOpNotComponentWise:
3317 ASSERT(getType().getBasicType() == EbtBool)(getType().getBasicType() == EbtBool ? 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/IntermNode.cpp"
, __FUNCTION__, 3317, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3317 << "): " << "getType().getBasicType() == EbtBool"
))
;
3318 resultArray[i].setBConst(!operandArray[i].getBConst());
3319 break;
3320
3321 case EOpNormalize:
3322 {
3323 ASSERT(getType().getBasicType() == EbtFloat)(getType().getBasicType() == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 3323, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3323 << "): " << "getType().getBasicType() == EbtFloat"
))
;
3324 float x = operandArray[i].getFConst();
3325 float length = VectorLength(operandArray, objectSize);
3326 if (length != 0.0f)
3327 resultArray[i].setFConst(x / length);
3328 else
3329 UndefinedConstantFoldingError(getLine(), function, getType().getBasicType(),
3330 diagnostics, &resultArray[i]);
3331 break;
3332 }
3333 case EOpBitfieldReverse:
3334 {
3335 uint32_t value;
3336 if (getType().getBasicType() == EbtInt)
3337 {
3338 value = static_cast<uint32_t>(operandArray[i].getIConst());
3339 }
3340 else
3341 {
3342 ASSERT(getType().getBasicType() == EbtUInt)(getType().getBasicType() == EbtUInt ? 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/IntermNode.cpp"
, __FUNCTION__, 3342, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3342 << "): " << "getType().getBasicType() == EbtUInt"
))
;
3343 value = operandArray[i].getUConst();
3344 }
3345 uint32_t result = gl::BitfieldReverse(value);
3346 if (getType().getBasicType() == EbtInt)
3347 {
3348 resultArray[i].setIConst(static_cast<int32_t>(result));
3349 }
3350 else
3351 {
3352 resultArray[i].setUConst(result);
3353 }
3354 break;
3355 }
3356 case EOpBitCount:
3357 {
3358 uint32_t value;
3359 if (getType().getBasicType() == EbtInt)
3360 {
3361 value = static_cast<uint32_t>(operandArray[i].getIConst());
3362 }
3363 else
3364 {
3365 ASSERT(getType().getBasicType() == EbtUInt)(getType().getBasicType() == EbtUInt ? 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/IntermNode.cpp"
, __FUNCTION__, 3365, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3365 << "): " << "getType().getBasicType() == EbtUInt"
))
;
3366 value = operandArray[i].getUConst();
3367 }
3368 int result = gl::BitCount(value);
3369 resultArray[i].setIConst(result);
3370 break;
3371 }
3372 case EOpFindLSB:
3373 {
3374 uint32_t value;
3375 if (getType().getBasicType() == EbtInt)
3376 {
3377 value = static_cast<uint32_t>(operandArray[i].getIConst());
3378 }
3379 else
3380 {
3381 ASSERT(getType().getBasicType() == EbtUInt)(getType().getBasicType() == EbtUInt ? 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/IntermNode.cpp"
, __FUNCTION__, 3381, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3381 << "): " << "getType().getBasicType() == EbtUInt"
))
;
3382 value = operandArray[i].getUConst();
3383 }
3384 resultArray[i].setIConst(gl::FindLSB(value));
3385 break;
3386 }
3387 case EOpFindMSB:
3388 {
3389 uint32_t value;
3390 if (getType().getBasicType() == EbtInt)
3391 {
3392 int intValue = operandArray[i].getIConst();
3393 value = static_cast<uint32_t>(intValue);
3394 if (intValue < 0)
3395 {
3396 // Look for zero instead of one in value. This also handles the intValue ==
3397 // -1 special case, where the return value needs to be -1.
3398 value = ~value;
3399 }
3400 }
3401 else
3402 {
3403 ASSERT(getType().getBasicType() == EbtUInt)(getType().getBasicType() == EbtUInt ? 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/IntermNode.cpp"
, __FUNCTION__, 3403, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3403 << "): " << "getType().getBasicType() == EbtUInt"
))
;
3404 value = operandArray[i].getUConst();
3405 }
3406 resultArray[i].setIConst(gl::FindMSB(value));
3407 break;
3408 }
3409
3410 default:
3411 return nullptr;
3412 }
3413 }
3414
3415 return resultArray;
3416}
3417
3418void TIntermConstantUnion::foldFloatTypeUnary(const TConstantUnion &parameter,
3419 FloatTypeUnaryFunc builtinFunc,
3420 TConstantUnion *result) const
3421{
3422 ASSERT(builtinFunc)(builtinFunc ? 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/IntermNode.cpp"
, __FUNCTION__, 3422, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3422 << "): " << "builtinFunc"
))
;
3423
3424 ASSERT(getType().getBasicType() == EbtFloat)(getType().getBasicType() == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 3424, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3424 << "): " << "getType().getBasicType() == EbtFloat"
))
;
3425 result->setFConst(builtinFunc(parameter.getFConst()));
3426}
3427
3428void TIntermConstantUnion::propagatePrecision(TPrecision precision)
3429{
3430 mType.setPrecision(precision);
3431}
3432
3433// static
3434TConstantUnion *TIntermConstantUnion::FoldAggregateBuiltIn(TIntermAggregate *aggregate,
3435 TDiagnostics *diagnostics)
3436{
3437 const TOperator op = aggregate->getOp();
3438 const TFunction *function = aggregate->getFunction();
3439 TIntermSequence *arguments = aggregate->getSequence();
3440 unsigned int argsCount = static_cast<unsigned int>(arguments->size());
3441 std::vector<const TConstantUnion *> unionArrays(argsCount);
3442 std::vector<size_t> objectSizes(argsCount);
3443 size_t maxObjectSize = 0;
3444 TBasicType basicType = EbtVoid;
3445 TSourceLoc loc;
3446 for (unsigned int i = 0; i < argsCount; i++)
3447 {
3448 TIntermConstantUnion *argConstant = (*arguments)[i]->getAsConstantUnion();
3449 ASSERT(argConstant != nullptr)(argConstant != nullptr ? 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/IntermNode.cpp"
, __FUNCTION__, 3449, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3449 << "): " << "argConstant != nullptr"
))
; // Should be checked already.
3450
3451 if (i == 0)
3452 {
3453 basicType = argConstant->getType().getBasicType();
3454 loc = argConstant->getLine();
3455 }
3456 unionArrays[i] = argConstant->getConstantValue();
3457 objectSizes[i] = argConstant->getType().getObjectSize();
3458 if (objectSizes[i] > maxObjectSize)
3459 maxObjectSize = objectSizes[i];
3460 }
3461
3462 if (!(*arguments)[0]->getAsTyped()->isMatrix() && aggregate->getOp() != EOpOuterProduct)
3463 {
3464 for (unsigned int i = 0; i < argsCount; i++)
3465 if (objectSizes[i] != maxObjectSize)
3466 unionArrays[i] = Vectorize(*unionArrays[i], maxObjectSize);
3467 }
3468
3469 TConstantUnion *resultArray = nullptr;
3470
3471 switch (op)
3472 {
3473 case EOpAtan:
3474 {
3475 ASSERT(basicType == EbtFloat)(basicType == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 3475, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3475 << "): " << "basicType == EbtFloat"
))
;
3476 resultArray = new TConstantUnion[maxObjectSize];
3477 for (size_t i = 0; i < maxObjectSize; i++)
3478 {
3479 float y = unionArrays[0][i].getFConst();
3480 float x = unionArrays[1][i].getFConst();
3481 // Results are undefined if x and y are both 0.
3482 if (x == 0.0f && y == 0.0f)
3483 UndefinedConstantFoldingError(loc, function, basicType, diagnostics,
3484 &resultArray[i]);
3485 else
3486 resultArray[i].setFConst(atan2f(y, x));
3487 }
3488 break;
3489 }
3490
3491 case EOpPow:
3492 {
3493 ASSERT(basicType == EbtFloat)(basicType == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 3493, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3493 << "): " << "basicType == EbtFloat"
))
;
3494 resultArray = new TConstantUnion[maxObjectSize];
3495 for (size_t i = 0; i < maxObjectSize; i++)
3496 {
3497 float x = unionArrays[0][i].getFConst();
3498 float y = unionArrays[1][i].getFConst();
3499 // Results are undefined if x < 0.
3500 // Results are undefined if x = 0 and y <= 0.
3501 if (x < 0.0f)
3502 UndefinedConstantFoldingError(loc, function, basicType, diagnostics,
3503 &resultArray[i]);
3504 else if (x == 0.0f && y <= 0.0f)
3505 UndefinedConstantFoldingError(loc, function, basicType, diagnostics,
3506 &resultArray[i]);
3507 else
3508 resultArray[i].setFConst(powf(x, y));
3509 }
3510 break;
3511 }
3512
3513 case EOpMod:
3514 {
3515 ASSERT(basicType == EbtFloat)(basicType == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 3515, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3515 << "): " << "basicType == EbtFloat"
))
;
3516 resultArray = new TConstantUnion[maxObjectSize];
3517 for (size_t i = 0; i < maxObjectSize; i++)
3518 {
3519 float x = unionArrays[0][i].getFConst();
3520 float y = unionArrays[1][i].getFConst();
3521 resultArray[i].setFConst(x - y * floorf(x / y));
3522 }
3523 break;
3524 }
3525
3526 case EOpMin:
3527 {
3528 resultArray = new TConstantUnion[maxObjectSize];
3529 for (size_t i = 0; i < maxObjectSize; i++)
3530 {
3531 switch (basicType)
3532 {
3533 case EbtFloat:
3534 resultArray[i].setFConst(
3535 std::min(unionArrays[0][i].getFConst(), unionArrays[1][i].getFConst()));
3536 break;
3537 case EbtInt:
3538 resultArray[i].setIConst(
3539 std::min(unionArrays[0][i].getIConst(), unionArrays[1][i].getIConst()));
3540 break;
3541 case EbtUInt:
3542 resultArray[i].setUConst(
3543 std::min(unionArrays[0][i].getUConst(), unionArrays[1][i].getUConst()));
3544 break;
3545 default:
3546 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/IntermNode.cpp"
, __FUNCTION__, 3546, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3546 << ")"; } while (0)
;
3547 break;
3548 }
3549 }
3550 break;
3551 }
3552
3553 case EOpMax:
3554 {
3555 resultArray = new TConstantUnion[maxObjectSize];
3556 for (size_t i = 0; i < maxObjectSize; i++)
3557 {
3558 switch (basicType)
3559 {
3560 case EbtFloat:
3561 resultArray[i].setFConst(
3562 std::max(unionArrays[0][i].getFConst(), unionArrays[1][i].getFConst()));
3563 break;
3564 case EbtInt:
3565 resultArray[i].setIConst(
3566 std::max(unionArrays[0][i].getIConst(), unionArrays[1][i].getIConst()));
3567 break;
3568 case EbtUInt:
3569 resultArray[i].setUConst(
3570 std::max(unionArrays[0][i].getUConst(), unionArrays[1][i].getUConst()));
3571 break;
3572 default:
3573 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/IntermNode.cpp"
, __FUNCTION__, 3573, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3573 << ")"; } while (0)
;
3574 break;
3575 }
3576 }
3577 break;
3578 }
3579
3580 case EOpStep:
3581 {
3582 ASSERT(basicType == EbtFloat)(basicType == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 3582, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3582 << "): " << "basicType == EbtFloat"
))
;
3583 resultArray = new TConstantUnion[maxObjectSize];
3584 for (size_t i = 0; i < maxObjectSize; i++)
3585 resultArray[i].setFConst(
3586 unionArrays[1][i].getFConst() < unionArrays[0][i].getFConst() ? 0.0f : 1.0f);
3587 break;
3588 }
3589
3590 case EOpLessThanComponentWise:
3591 {
3592 resultArray = new TConstantUnion[maxObjectSize];
3593 for (size_t i = 0; i < maxObjectSize; i++)
3594 {
3595 switch (basicType)
3596 {
3597 case EbtFloat:
3598 resultArray[i].setBConst(unionArrays[0][i].getFConst() <
3599 unionArrays[1][i].getFConst());
3600 break;
3601 case EbtInt:
3602 resultArray[i].setBConst(unionArrays[0][i].getIConst() <
3603 unionArrays[1][i].getIConst());
3604 break;
3605 case EbtUInt:
3606 resultArray[i].setBConst(unionArrays[0][i].getUConst() <
3607 unionArrays[1][i].getUConst());
3608 break;
3609 default:
3610 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/IntermNode.cpp"
, __FUNCTION__, 3610, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3610 << ")"; } while (0)
;
3611 break;
3612 }
3613 }
3614 break;
3615 }
3616
3617 case EOpLessThanEqualComponentWise:
3618 {
3619 resultArray = new TConstantUnion[maxObjectSize];
3620 for (size_t i = 0; i < maxObjectSize; i++)
3621 {
3622 switch (basicType)
3623 {
3624 case EbtFloat:
3625 resultArray[i].setBConst(unionArrays[0][i].getFConst() <=
3626 unionArrays[1][i].getFConst());
3627 break;
3628 case EbtInt:
3629 resultArray[i].setBConst(unionArrays[0][i].getIConst() <=
3630 unionArrays[1][i].getIConst());
3631 break;
3632 case EbtUInt:
3633 resultArray[i].setBConst(unionArrays[0][i].getUConst() <=
3634 unionArrays[1][i].getUConst());
3635 break;
3636 default:
3637 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/IntermNode.cpp"
, __FUNCTION__, 3637, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3637 << ")"; } while (0)
;
3638 break;
3639 }
3640 }
3641 break;
3642 }
3643
3644 case EOpGreaterThanComponentWise:
3645 {
3646 resultArray = new TConstantUnion[maxObjectSize];
3647 for (size_t i = 0; i < maxObjectSize; i++)
3648 {
3649 switch (basicType)
3650 {
3651 case EbtFloat:
3652 resultArray[i].setBConst(unionArrays[0][i].getFConst() >
3653 unionArrays[1][i].getFConst());
3654 break;
3655 case EbtInt:
3656 resultArray[i].setBConst(unionArrays[0][i].getIConst() >
3657 unionArrays[1][i].getIConst());
3658 break;
3659 case EbtUInt:
3660 resultArray[i].setBConst(unionArrays[0][i].getUConst() >
3661 unionArrays[1][i].getUConst());
3662 break;
3663 default:
3664 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/IntermNode.cpp"
, __FUNCTION__, 3664, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3664 << ")"; } while (0)
;
3665 break;
3666 }
3667 }
3668 break;
3669 }
3670 case EOpGreaterThanEqualComponentWise:
3671 {
3672 resultArray = new TConstantUnion[maxObjectSize];
3673 for (size_t i = 0; i < maxObjectSize; i++)
3674 {
3675 switch (basicType)
3676 {
3677 case EbtFloat:
3678 resultArray[i].setBConst(unionArrays[0][i].getFConst() >=
3679 unionArrays[1][i].getFConst());
3680 break;
3681 case EbtInt:
3682 resultArray[i].setBConst(unionArrays[0][i].getIConst() >=
3683 unionArrays[1][i].getIConst());
3684 break;
3685 case EbtUInt:
3686 resultArray[i].setBConst(unionArrays[0][i].getUConst() >=
3687 unionArrays[1][i].getUConst());
3688 break;
3689 default:
3690 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/IntermNode.cpp"
, __FUNCTION__, 3690, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3690 << ")"; } while (0)
;
3691 break;
3692 }
3693 }
3694 }
3695 break;
3696
3697 case EOpEqualComponentWise:
3698 {
3699 resultArray = new TConstantUnion[maxObjectSize];
3700 for (size_t i = 0; i < maxObjectSize; i++)
3701 {
3702 switch (basicType)
3703 {
3704 case EbtFloat:
3705 resultArray[i].setBConst(unionArrays[0][i].getFConst() ==
3706 unionArrays[1][i].getFConst());
3707 break;
3708 case EbtInt:
3709 resultArray[i].setBConst(unionArrays[0][i].getIConst() ==
3710 unionArrays[1][i].getIConst());
3711 break;
3712 case EbtUInt:
3713 resultArray[i].setBConst(unionArrays[0][i].getUConst() ==
3714 unionArrays[1][i].getUConst());
3715 break;
3716 case EbtBool:
3717 resultArray[i].setBConst(unionArrays[0][i].getBConst() ==
3718 unionArrays[1][i].getBConst());
3719 break;
3720 default:
3721 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/IntermNode.cpp"
, __FUNCTION__, 3721, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3721 << ")"; } while (0)
;
3722 break;
3723 }
3724 }
3725 break;
3726 }
3727
3728 case EOpNotEqualComponentWise:
3729 {
3730 resultArray = new TConstantUnion[maxObjectSize];
3731 for (size_t i = 0; i < maxObjectSize; i++)
3732 {
3733 switch (basicType)
3734 {
3735 case EbtFloat:
3736 resultArray[i].setBConst(unionArrays[0][i].getFConst() !=
3737 unionArrays[1][i].getFConst());
3738 break;
3739 case EbtInt:
3740 resultArray[i].setBConst(unionArrays[0][i].getIConst() !=
3741 unionArrays[1][i].getIConst());
3742 break;
3743 case EbtUInt:
3744 resultArray[i].setBConst(unionArrays[0][i].getUConst() !=
3745 unionArrays[1][i].getUConst());
3746 break;
3747 case EbtBool:
3748 resultArray[i].setBConst(unionArrays[0][i].getBConst() !=
3749 unionArrays[1][i].getBConst());
3750 break;
3751 default:
3752 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/IntermNode.cpp"
, __FUNCTION__, 3752, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3752 << ")"; } while (0)
;
3753 break;
3754 }
3755 }
3756 break;
3757 }
3758
3759 case EOpDistance:
3760 {
3761 ASSERT(basicType == EbtFloat)(basicType == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 3761, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3761 << "): " << "basicType == EbtFloat"
))
;
3762 TConstantUnion *distanceArray = new TConstantUnion[maxObjectSize];
3763 resultArray = new TConstantUnion();
3764 for (size_t i = 0; i < maxObjectSize; i++)
3765 {
3766 float x = unionArrays[0][i].getFConst();
3767 float y = unionArrays[1][i].getFConst();
3768 distanceArray[i].setFConst(x - y);
3769 }
3770 resultArray->setFConst(VectorLength(distanceArray, maxObjectSize));
3771 break;
3772 }
3773
3774 case EOpDot:
3775 ASSERT(basicType == EbtFloat)(basicType == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 3775, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3775 << "): " << "basicType == EbtFloat"
))
;
3776 resultArray = new TConstantUnion();
3777 resultArray->setFConst(VectorDotProduct(unionArrays[0], unionArrays[1], maxObjectSize));
3778 break;
3779
3780 case EOpCross:
3781 {
3782 ASSERT(basicType == EbtFloat && maxObjectSize == 3)(basicType == EbtFloat && maxObjectSize == 3 ? 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/IntermNode.cpp"
, __FUNCTION__, 3782, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3782 << "): " << "basicType == EbtFloat && maxObjectSize == 3"
))
;
3783 resultArray = new TConstantUnion[maxObjectSize];
3784 float x0 = unionArrays[0][0].getFConst();
3785 float x1 = unionArrays[0][1].getFConst();
3786 float x2 = unionArrays[0][2].getFConst();
3787 float y0 = unionArrays[1][0].getFConst();
3788 float y1 = unionArrays[1][1].getFConst();
3789 float y2 = unionArrays[1][2].getFConst();
3790 resultArray[0].setFConst(x1 * y2 - y1 * x2);
3791 resultArray[1].setFConst(x2 * y0 - y2 * x0);
3792 resultArray[2].setFConst(x0 * y1 - y0 * x1);
3793 break;
3794 }
3795
3796 case EOpReflect:
3797 {
3798 ASSERT(basicType == EbtFloat)(basicType == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 3798, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3798 << "): " << "basicType == EbtFloat"
))
;
3799 // genType reflect (genType I, genType N) :
3800 // For the incident vector I and surface orientation N, returns the reflection
3801 // direction:
3802 // I - 2 * dot(N, I) * N.
3803 resultArray = new TConstantUnion[maxObjectSize];
3804 float dotProduct = VectorDotProduct(unionArrays[1], unionArrays[0], maxObjectSize);
3805 for (size_t i = 0; i < maxObjectSize; i++)
3806 {
3807 float result = unionArrays[0][i].getFConst() -
3808 2.0f * dotProduct * unionArrays[1][i].getFConst();
3809 resultArray[i].setFConst(result);
3810 }
3811 break;
3812 }
3813
3814 case EOpMatrixCompMult:
3815 {
3816 ASSERT(basicType == EbtFloat && (*arguments)[0]->getAsTyped()->isMatrix() &&(basicType == EbtFloat && (*arguments)[0]->getAsTyped
()->isMatrix() && (*arguments)[1]->getAsTyped()
->isMatrix() ? 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/IntermNode.cpp"
, __FUNCTION__, 3817, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3817 << "): " << "basicType == EbtFloat && (*arguments)[0]->getAsTyped()->isMatrix() && (*arguments)[1]->getAsTyped()->isMatrix()"
))
3817 (*arguments)[1]->getAsTyped()->isMatrix())(basicType == EbtFloat && (*arguments)[0]->getAsTyped
()->isMatrix() && (*arguments)[1]->getAsTyped()
->isMatrix() ? 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/IntermNode.cpp"
, __FUNCTION__, 3817, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3817 << "): " << "basicType == EbtFloat && (*arguments)[0]->getAsTyped()->isMatrix() && (*arguments)[1]->getAsTyped()->isMatrix()"
))
;
3818 // Perform component-wise matrix multiplication.
3819 resultArray = new TConstantUnion[maxObjectSize];
3820 const uint8_t rows = (*arguments)[0]->getAsTyped()->getRows();
3821 const uint8_t cols = (*arguments)[0]->getAsTyped()->getCols();
3822 angle::Matrix<float> lhs = GetMatrix(unionArrays[0], rows, cols);
3823 angle::Matrix<float> rhs = GetMatrix(unionArrays[1], rows, cols);
3824 angle::Matrix<float> result = lhs.compMult(rhs);
3825 SetUnionArrayFromMatrix(result, resultArray);
3826 break;
3827 }
3828
3829 case EOpOuterProduct:
3830 {
3831 ASSERT(basicType == EbtFloat)(basicType == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 3831, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3831 << "): " << "basicType == EbtFloat"
))
;
3832 size_t numRows = (*arguments)[0]->getAsTyped()->getType().getObjectSize();
3833 size_t numCols = (*arguments)[1]->getAsTyped()->getType().getObjectSize();
3834 resultArray = new TConstantUnion[numRows * numCols];
3835 angle::Matrix<float> result =
3836 GetMatrix(unionArrays[0], static_cast<int>(numRows), 1)
3837 .outerProduct(GetMatrix(unionArrays[1], 1, static_cast<int>(numCols)));
3838 SetUnionArrayFromMatrix(result, resultArray);
3839 break;
3840 }
3841
3842 case EOpClamp:
3843 {
3844 resultArray = new TConstantUnion[maxObjectSize];
3845 for (size_t i = 0; i < maxObjectSize; i++)
3846 {
3847 switch (basicType)
3848 {
3849 case EbtFloat:
3850 {
3851 float x = unionArrays[0][i].getFConst();
3852 float min = unionArrays[1][i].getFConst();
3853 float max = unionArrays[2][i].getFConst();
3854 // Results are undefined if min > max.
3855 if (min > max)
3856 UndefinedConstantFoldingError(loc, function, basicType, diagnostics,
3857 &resultArray[i]);
3858 else
3859 resultArray[i].setFConst(gl::clamp(x, min, max));
3860 break;
3861 }
3862
3863 case EbtInt:
3864 {
3865 int x = unionArrays[0][i].getIConst();
3866 int min = unionArrays[1][i].getIConst();
3867 int max = unionArrays[2][i].getIConst();
3868 // Results are undefined if min > max.
3869 if (min > max)
3870 UndefinedConstantFoldingError(loc, function, basicType, diagnostics,
3871 &resultArray[i]);
3872 else
3873 resultArray[i].setIConst(gl::clamp(x, min, max));
3874 break;
3875 }
3876 case EbtUInt:
3877 {
3878 unsigned int x = unionArrays[0][i].getUConst();
3879 unsigned int min = unionArrays[1][i].getUConst();
3880 unsigned int max = unionArrays[2][i].getUConst();
3881 // Results are undefined if min > max.
3882 if (min > max)
3883 UndefinedConstantFoldingError(loc, function, basicType, diagnostics,
3884 &resultArray[i]);
3885 else
3886 resultArray[i].setUConst(gl::clamp(x, min, max));
3887 break;
3888 }
3889 default:
3890 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/IntermNode.cpp"
, __FUNCTION__, 3890, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3890 << ")"; } while (0)
;
3891 break;
3892 }
3893 }
3894 break;
3895 }
3896
3897 case EOpMix:
3898 {
3899 resultArray = new TConstantUnion[maxObjectSize];
3900 for (size_t i = 0; i < maxObjectSize; i++)
3901 {
3902 TBasicType type = (*arguments)[2]->getAsTyped()->getType().getBasicType();
3903 if (type == EbtFloat)
3904 {
3905 ASSERT(basicType == EbtFloat)(basicType == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 3905, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3905 << "): " << "basicType == EbtFloat"
))
;
3906 float x = unionArrays[0][i].getFConst();
3907 float y = unionArrays[1][i].getFConst();
3908
3909 // Returns the linear blend of x and y, i.e., x * (1 - a) + y * a.
3910 float a = unionArrays[2][i].getFConst();
3911 resultArray[i].setFConst(x * (1.0f - a) + y * a);
3912 }
3913 else // 3rd parameter is EbtBool
3914 {
3915 ASSERT(type == EbtBool)(type == EbtBool ? 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/IntermNode.cpp"
, __FUNCTION__, 3915, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3915 << "): " << "type == EbtBool"
))
;
3916 // Selects which vector each returned component comes from.
3917 // For a component of a that is false, the corresponding component of x is
3918 // returned.
3919 // For a component of a that is true, the corresponding component of y is
3920 // returned.
3921 bool a = unionArrays[2][i].getBConst();
3922 switch (basicType)
3923 {
3924 case EbtFloat:
3925 {
3926 float x = unionArrays[0][i].getFConst();
3927 float y = unionArrays[1][i].getFConst();
3928 resultArray[i].setFConst(a ? y : x);
3929 }
3930 break;
3931 case EbtInt:
3932 {
3933 int x = unionArrays[0][i].getIConst();
3934 int y = unionArrays[1][i].getIConst();
3935 resultArray[i].setIConst(a ? y : x);
3936 }
3937 break;
3938 case EbtUInt:
3939 {
3940 unsigned int x = unionArrays[0][i].getUConst();
3941 unsigned int y = unionArrays[1][i].getUConst();
3942 resultArray[i].setUConst(a ? y : x);
3943 }
3944 break;
3945 case EbtBool:
3946 {
3947 bool x = unionArrays[0][i].getBConst();
3948 bool y = unionArrays[1][i].getBConst();
3949 resultArray[i].setBConst(a ? y : x);
3950 }
3951 break;
3952 default:
3953 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/IntermNode.cpp"
, __FUNCTION__, 3953, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3953 << ")"; } while (0)
;
3954 break;
3955 }
3956 }
3957 }
3958 break;
3959 }
3960
3961 case EOpSmoothstep:
3962 {
3963 ASSERT(basicType == EbtFloat)(basicType == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 3963, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3963 << "): " << "basicType == EbtFloat"
))
;
3964 resultArray = new TConstantUnion[maxObjectSize];
3965 for (size_t i = 0; i < maxObjectSize; i++)
3966 {
3967 float edge0 = unionArrays[0][i].getFConst();
3968 float edge1 = unionArrays[1][i].getFConst();
3969 float x = unionArrays[2][i].getFConst();
3970 // Results are undefined if edge0 >= edge1.
3971 if (edge0 >= edge1)
3972 {
3973 UndefinedConstantFoldingError(loc, function, basicType, diagnostics,
3974 &resultArray[i]);
3975 }
3976 else
3977 {
3978 // Returns 0.0 if x <= edge0 and 1.0 if x >= edge1 and performs smooth
3979 // Hermite interpolation between 0 and 1 when edge0 < x < edge1.
3980 float t = gl::clamp((x - edge0) / (edge1 - edge0), 0.0f, 1.0f);
3981 resultArray[i].setFConst(t * t * (3.0f - 2.0f * t));
3982 }
3983 }
3984 break;
3985 }
3986
3987 case EOpFma:
3988 {
3989 ASSERT(basicType == EbtFloat)(basicType == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 3989, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 3989 << "): " << "basicType == EbtFloat"
))
;
3990 resultArray = new TConstantUnion[maxObjectSize];
3991 for (size_t i = 0; i < maxObjectSize; i++)
3992 {
3993 float a = unionArrays[0][i].getFConst();
3994 float b = unionArrays[1][i].getFConst();
3995 float c = unionArrays[2][i].getFConst();
3996
3997 // Returns a * b + c.
3998 resultArray[i].setFConst(a * b + c);
3999 }
4000 break;
4001 }
4002
4003 case EOpLdexp:
4004 {
4005 resultArray = new TConstantUnion[maxObjectSize];
4006 for (size_t i = 0; i < maxObjectSize; i++)
4007 {
4008 float x = unionArrays[0][i].getFConst();
4009 int exp = unionArrays[1][i].getIConst();
4010 if (exp > 128)
4011 {
4012 UndefinedConstantFoldingError(loc, function, basicType, diagnostics,
4013 &resultArray[i]);
4014 }
4015 else
4016 {
4017 resultArray[i].setFConst(gl::Ldexp(x, exp));
4018 }
4019 }
4020 break;
4021 }
4022
4023 case EOpFaceforward:
4024 {
4025 ASSERT(basicType == EbtFloat)(basicType == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 4025, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 4025 << "): " << "basicType == EbtFloat"
))
;
4026 // genType faceforward(genType N, genType I, genType Nref) :
4027 // If dot(Nref, I) < 0 return N, otherwise return -N.
4028 resultArray = new TConstantUnion[maxObjectSize];
4029 float dotProduct = VectorDotProduct(unionArrays[2], unionArrays[1], maxObjectSize);
4030 for (size_t i = 0; i < maxObjectSize; i++)
4031 {
4032 if (dotProduct < 0)
4033 resultArray[i].setFConst(unionArrays[0][i].getFConst());
4034 else
4035 resultArray[i].setFConst(-unionArrays[0][i].getFConst());
4036 }
4037 break;
4038 }
4039
4040 case EOpRefract:
4041 {
4042 ASSERT(basicType == EbtFloat)(basicType == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 4042, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 4042 << "): " << "basicType == EbtFloat"
))
;
4043 // genType refract(genType I, genType N, float eta) :
4044 // For the incident vector I and surface normal N, and the ratio of indices of
4045 // refraction eta,
4046 // return the refraction vector. The result is computed by
4047 // k = 1.0 - eta * eta * (1.0 - dot(N, I) * dot(N, I))
4048 // if (k < 0.0)
4049 // return genType(0.0)
4050 // else
4051 // return eta * I - (eta * dot(N, I) + sqrt(k)) * N
4052 resultArray = new TConstantUnion[maxObjectSize];
4053 float dotProduct = VectorDotProduct(unionArrays[1], unionArrays[0], maxObjectSize);
4054 for (size_t i = 0; i < maxObjectSize; i++)
4055 {
4056 float eta = unionArrays[2][i].getFConst();
4057 float k = 1.0f - eta * eta * (1.0f - dotProduct * dotProduct);
4058 if (k < 0.0f)
4059 resultArray[i].setFConst(0.0f);
4060 else
4061 resultArray[i].setFConst(eta * unionArrays[0][i].getFConst() -
4062 (eta * dotProduct + sqrtf(k)) *
4063 unionArrays[1][i].getFConst());
4064 }
4065 break;
4066 }
4067 case EOpBitfieldExtract:
4068 {
4069 resultArray = new TConstantUnion[maxObjectSize];
4070 for (size_t i = 0; i < maxObjectSize; ++i)
4071 {
4072 int offset = unionArrays[1][0].getIConst();
4073 int bits = unionArrays[2][0].getIConst();
4074 if (bits == 0)
4075 {
4076 if (aggregate->getBasicType() == EbtInt)
4077 {
4078 resultArray[i].setIConst(0);
4079 }
4080 else
4081 {
4082 ASSERT(aggregate->getBasicType() == EbtUInt)(aggregate->getBasicType() == EbtUInt ? 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/IntermNode.cpp"
, __FUNCTION__, 4082, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 4082 << "): " << "aggregate->getBasicType() == EbtUInt"
))
;
4083 resultArray[i].setUConst(0);
4084 }
4085 }
4086 else if (offset < 0 || bits < 0 || offset >= 32 || bits > 32 || offset + bits > 32)
4087 {
4088 UndefinedConstantFoldingError(loc, function, aggregate->getBasicType(),
4089 diagnostics, &resultArray[i]);
4090 }
4091 else
4092 {
4093 // bits can be 32 here, so we need to avoid bit shift overflow.
4094 uint32_t maskMsb = 1u << (bits - 1);
4095 uint32_t mask = ((maskMsb - 1u) | maskMsb) << offset;
4096 if (aggregate->getBasicType() == EbtInt)
4097 {
4098 uint32_t value = static_cast<uint32_t>(unionArrays[0][i].getIConst());
4099 uint32_t resultUnsigned = (value & mask) >> offset;
4100 if ((resultUnsigned & maskMsb) != 0)
4101 {
4102 // The most significant bits (from bits+1 to the most significant bit)
4103 // should be set to 1.
4104 uint32_t higherBitsMask = ((1u << (32 - bits)) - 1u) << bits;
4105 resultUnsigned |= higherBitsMask;
4106 }
4107 resultArray[i].setIConst(static_cast<int32_t>(resultUnsigned));
4108 }
4109 else
4110 {
4111 ASSERT(aggregate->getBasicType() == EbtUInt)(aggregate->getBasicType() == EbtUInt ? 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/IntermNode.cpp"
, __FUNCTION__, 4111, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 4111 << "): " << "aggregate->getBasicType() == EbtUInt"
))
;
4112 uint32_t value = unionArrays[0][i].getUConst();
4113 resultArray[i].setUConst((value & mask) >> offset);
4114 }
4115 }
4116 }
4117 break;
4118 }
4119 case EOpBitfieldInsert:
4120 {
4121 resultArray = new TConstantUnion[maxObjectSize];
4122 for (size_t i = 0; i < maxObjectSize; ++i)
4123 {
4124 int offset = unionArrays[2][0].getIConst();
4125 int bits = unionArrays[3][0].getIConst();
4126 if (bits == 0)
4127 {
4128 if (aggregate->getBasicType() == EbtInt)
4129 {
4130 int32_t base = unionArrays[0][i].getIConst();
4131 resultArray[i].setIConst(base);
4132 }
4133 else
4134 {
4135 ASSERT(aggregate->getBasicType() == EbtUInt)(aggregate->getBasicType() == EbtUInt ? 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/IntermNode.cpp"
, __FUNCTION__, 4135, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 4135 << "): " << "aggregate->getBasicType() == EbtUInt"
))
;
4136 uint32_t base = unionArrays[0][i].getUConst();
4137 resultArray[i].setUConst(base);
4138 }
4139 }
4140 else if (offset < 0 || bits < 0 || offset >= 32 || bits > 32 || offset + bits > 32)
4141 {
4142 UndefinedConstantFoldingError(loc, function, aggregate->getBasicType(),
4143 diagnostics, &resultArray[i]);
4144 }
4145 else
4146 {
4147 // bits can be 32 here, so we need to avoid bit shift overflow.
4148 uint32_t maskMsb = 1u << (bits - 1);
4149 uint32_t insertMask = ((maskMsb - 1u) | maskMsb) << offset;
4150 uint32_t baseMask = ~insertMask;
4151 if (aggregate->getBasicType() == EbtInt)
4152 {
4153 uint32_t base = static_cast<uint32_t>(unionArrays[0][i].getIConst());
4154 uint32_t insert = static_cast<uint32_t>(unionArrays[1][i].getIConst());
4155 uint32_t resultUnsigned =
4156 (base & baseMask) | ((insert << offset) & insertMask);
4157 resultArray[i].setIConst(static_cast<int32_t>(resultUnsigned));
4158 }
4159 else
4160 {
4161 ASSERT(aggregate->getBasicType() == EbtUInt)(aggregate->getBasicType() == EbtUInt ? 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/IntermNode.cpp"
, __FUNCTION__, 4161, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 4161 << "): " << "aggregate->getBasicType() == EbtUInt"
))
;
4162 uint32_t base = unionArrays[0][i].getUConst();
4163 uint32_t insert = unionArrays[1][i].getUConst();
4164 resultArray[i].setUConst((base & baseMask) |
4165 ((insert << offset) & insertMask));
4166 }
4167 }
4168 }
4169 break;
4170 }
4171 case EOpDFdx:
4172 case EOpDFdy:
4173 case EOpFwidth:
4174 ASSERT(basicType == EbtFloat)(basicType == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 4174, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 4174 << "): " << "basicType == EbtFloat"
))
;
4175 resultArray = new TConstantUnion[maxObjectSize];
4176 for (size_t i = 0; i < maxObjectSize; i++)
4177 {
4178 // Derivatives of constant arguments should be 0.
4179 resultArray[i].setFConst(0.0f);
4180 }
4181 break;
4182
4183 default:
4184 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/IntermNode.cpp"
, __FUNCTION__, 4184, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 4184 << ")"; } while (0)
;
4185 return nullptr;
4186 }
4187 return resultArray;
4188}
4189
4190bool TIntermConstantUnion::IsFloatDivision(TBasicType t1, TBasicType t2)
4191{
4192 ImplicitTypeConversion conversion = GetConversion(t1, t2);
4193 ASSERT(conversion != ImplicitTypeConversion::Invalid)(conversion != ImplicitTypeConversion::Invalid ? 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/IntermNode.cpp"
, __FUNCTION__, 4193, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 4193 << "): " << "conversion != ImplicitTypeConversion::Invalid"
))
;
4194 if (conversion == ImplicitTypeConversion::Same)
4195 {
4196 if (t1 == EbtFloat)
4197 return true;
4198 return false;
4199 }
4200 ASSERT(t1 == EbtFloat || t2 == EbtFloat)(t1 == EbtFloat || t2 == EbtFloat ? 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/IntermNode.cpp"
, __FUNCTION__, 4200, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 4200 << "): " << "t1 == EbtFloat || t2 == EbtFloat"
))
;
4201 return true;
4202}
4203
4204// TIntermPreprocessorDirective implementation.
4205TIntermPreprocessorDirective::TIntermPreprocessorDirective(PreprocessorDirective directive,
4206 ImmutableString command)
4207 : mDirective(directive), mCommand(std::move(command))
4208{}
4209
4210TIntermPreprocessorDirective::TIntermPreprocessorDirective(const TIntermPreprocessorDirective &node)
4211 : TIntermPreprocessorDirective(node.mDirective, node.mCommand)
4212{}
4213
4214TIntermPreprocessorDirective::~TIntermPreprocessorDirective() = default;
4215
4216size_t TIntermPreprocessorDirective::getChildCount() const
4217{
4218 return 0;
4219}
4220
4221TIntermNode *TIntermPreprocessorDirective::getChildNode(size_t index) const
4222{
4223 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/IntermNode.cpp"
, __FUNCTION__, 4223, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/IntermNode.cpp"
<< ":" << 4223 << ")"; } while (0)
;
4224 return nullptr;
4225}
4226} // namespace sh