Bug Summary

File:root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp
Warning:line 626, 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 Types.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/Types.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#if defined(_MSC_VER)
8# pragma warning(disable : 4718)
9#endif
10
11#include "compiler/translator/Types.h"
12#include "compiler/translator/ImmutableString.h"
13#include "compiler/translator/InfoSink.h"
14#include "compiler/translator/IntermNode.h"
15#include "compiler/translator/SymbolTable.h"
16
17#include <algorithm>
18#include <climits>
19
20namespace sh
21{
22
23const char *getBasicString(TBasicType t)
24{
25 switch (t)
26 {
27 case EbtVoid:
28 return "void";
29 case EbtFloat:
30 return "float";
31 case EbtInt:
32 return "int";
33 case EbtUInt:
34 return "uint";
35 case EbtBool:
36 return "bool";
37 case EbtYuvCscStandardEXT:
38 return "yuvCscStandardEXT";
39 case EbtSampler2D:
40 return "sampler2D";
41 case EbtSampler3D:
42 return "sampler3D";
43 case EbtSamplerCube:
44 return "samplerCube";
45 case EbtSamplerExternalOES:
46 return "samplerExternalOES";
47 case EbtSamplerExternal2DY2YEXT:
48 return "__samplerExternal2DY2YEXT";
49 case EbtSampler2DRect:
50 return "sampler2DRect";
51 case EbtSampler2DArray:
52 return "sampler2DArray";
53 case EbtSampler2DMS:
54 return "sampler2DMS";
55 case EbtSampler2DMSArray:
56 return "sampler2DMSArray";
57 case EbtSamplerCubeArray:
58 return "samplerCubeArray";
59 case EbtSamplerBuffer:
60 return "samplerBuffer";
61 case EbtISampler2D:
62 return "isampler2D";
63 case EbtISampler3D:
64 return "isampler3D";
65 case EbtISamplerCube:
66 return "isamplerCube";
67 case EbtISampler2DArray:
68 return "isampler2DArray";
69 case EbtISampler2DMS:
70 return "isampler2DMS";
71 case EbtISampler2DMSArray:
72 return "isampler2DMSArray";
73 case EbtISamplerCubeArray:
74 return "isamplerCubeArray";
75 case EbtISamplerBuffer:
76 return "isamplerBuffer";
77 case EbtUSampler2D:
78 return "usampler2D";
79 case EbtUSampler3D:
80 return "usampler3D";
81 case EbtUSamplerCube:
82 return "usamplerCube";
83 case EbtUSampler2DArray:
84 return "usampler2DArray";
85 case EbtUSampler2DMS:
86 return "usampler2DMS";
87 case EbtUSampler2DMSArray:
88 return "usampler2DMSArray";
89 case EbtUSamplerCubeArray:
90 return "usamplerCubeArray";
91 case EbtUSamplerBuffer:
92 return "usamplerBuffer";
93 case EbtSampler2DShadow:
94 return "sampler2DShadow";
95 case EbtSamplerCubeShadow:
96 return "samplerCubeShadow";
97 case EbtSampler2DArrayShadow:
98 return "sampler2DArrayShadow";
99 case EbtSamplerCubeArrayShadow:
100 return "samplerCubeArrayShadow";
101 case EbtStruct:
102 return "structure";
103 case EbtInterfaceBlock:
104 return "interface block";
105 case EbtImage2D:
106 return "image2D";
107 case EbtIImage2D:
108 return "iimage2D";
109 case EbtUImage2D:
110 return "uimage2D";
111 case EbtImage3D:
112 return "image3D";
113 case EbtIImage3D:
114 return "iimage3D";
115 case EbtUImage3D:
116 return "uimage3D";
117 case EbtImage2DArray:
118 return "image2DArray";
119 case EbtIImage2DArray:
120 return "iimage2DArray";
121 case EbtUImage2DArray:
122 return "uimage2DArray";
123 case EbtImageCube:
124 return "imageCube";
125 case EbtIImageCube:
126 return "iimageCube";
127 case EbtUImageCube:
128 return "uimageCube";
129 case EbtImageCubeArray:
130 return "imageCubeArray";
131 case EbtIImageCubeArray:
132 return "iimageCubeArray";
133 case EbtUImageCubeArray:
134 return "uimageCubeArray";
135 case EbtImageBuffer:
136 return "imageBuffer";
137 case EbtIImageBuffer:
138 return "iimageBuffer";
139 case EbtUImageBuffer:
140 return "uimageBuffer";
141 case EbtAtomicCounter:
142 return "atomic_uint";
143 case EbtSamplerVideoWEBGL:
144 return "samplerVideoWEBGL";
145 case EbtPixelLocalANGLE:
146 return "pixelLocalANGLE";
147 case EbtIPixelLocalANGLE:
148 return "ipixelLocalANGLE";
149 case EbtUPixelLocalANGLE:
150 return "upixelLocalANGLE";
151 case EbtSubpassInput:
152 return "subpassInput";
153 case EbtISubpassInput:
154 return "isubpassInput";
155 case EbtUSubpassInput:
156 return "usubpassInput";
157 case EbtSubpassInputMS:
158 return "subpassInputMS";
159 case EbtISubpassInputMS:
160 return "isubpassInputMS";
161 case EbtUSubpassInputMS:
162 return "usubpassInputMS";
163 default:
164 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/Types.cpp"
, __FUNCTION__, 164, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 164 << ")"; } while (0)
;
165 return "unknown type";
166 }
167}
168
169// TType implementation.
170TType::TType() : TType(EbtVoid, 0, 0) {}
171
172TType::TType(TBasicType t, uint8_t ps, uint8_t ss) : TType(t, EbpUndefined, EvqGlobal, ps, ss) {}
173
174TType::TType(TBasicType t, TPrecision p, TQualifier q, uint8_t ps, uint8_t ss)
175 : TType(t, p, q, ps, ss, TSpan<const unsigned int>(), nullptr)
176{}
177
178TType::TType(const TPublicType &p)
179 : type(p.getBasicType()),
180 precision(p.precision),
181 qualifier(p.qualifier),
182 invariant(p.invariant),
183 precise(p.precise),
184 memoryQualifier(p.memoryQualifier),
185 layoutQualifier(p.layoutQualifier),
186 primarySize(p.getPrimarySize()),
187 secondarySize(p.getSecondarySize()),
188 mArraySizesStorage(nullptr),
189 mInterfaceBlock(nullptr),
190 mStructure(nullptr),
191 mIsStructSpecifier(false),
192 mInterfaceBlockFieldIndex(0),
193 mMangledName(nullptr)
194{
195 ASSERT(primarySize <= 4)(primarySize <= 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/Types.cpp"
, __FUNCTION__, 195, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 195 << "): " << "primarySize <= 4"
))
;
196 ASSERT(secondarySize <= 4)(secondarySize <= 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/Types.cpp"
, __FUNCTION__, 196, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 196 << "): " << "secondarySize <= 4"
))
;
197 if (p.isArray())
198 {
199 makeArrays(*p.arraySizes);
200 }
201 if (p.getUserDef())
202 {
203 mStructure = p.getUserDef();
204 mIsStructSpecifier = p.isStructSpecifier();
205 }
206}
207
208TType::TType(const TStructure *userDef, bool isStructSpecifier)
209 : TType(EbtStruct, EbpUndefined, EvqTemporary, 1, 1)
210{
211 mStructure = userDef;
212 mIsStructSpecifier = isStructSpecifier;
213}
214
215TType::TType(const TInterfaceBlock *interfaceBlockIn,
216 TQualifier qualifierIn,
217 TLayoutQualifier layoutQualifierIn)
218 : TType(EbtInterfaceBlock, EbpUndefined, qualifierIn, 1, 1)
219{
220 layoutQualifier = layoutQualifierIn;
221 mInterfaceBlock = interfaceBlockIn;
222}
223
224TType::TType(const TType &t)
225{
226 *this = t;
227}
228
229TType &TType::operator=(const TType &t)
230{
231 type = t.type;
232 precision = t.precision;
233 qualifier = t.qualifier;
234 invariant = t.invariant;
235 precise = t.precise;
236 memoryQualifier = t.memoryQualifier;
237 layoutQualifier = t.layoutQualifier;
238 primarySize = t.primarySize;
239 secondarySize = t.secondarySize;
240 mArraySizesStorage = nullptr;
241 mInterfaceBlock = t.mInterfaceBlock;
242 mStructure = t.mStructure;
243 mIsStructSpecifier = t.mIsStructSpecifier;
244 mInterfaceBlockFieldIndex = t.mInterfaceBlockFieldIndex;
245 mMangledName = t.mMangledName;
246
247 if (t.mArraySizesStorage)
248 {
249 // If other type has storage, duplicate the storage and set the view to our own storage.
250 mArraySizesStorage = new TVector<unsigned int>(*t.mArraySizesStorage);
251 mArraySizes = *mArraySizesStorage;
252 }
253 else
254 {
255 // Otherwise reference the same (constexpr) array sizes as the other type.
256 mArraySizes = t.mArraySizes;
257 }
258
259 return *this;
260}
261
262bool TType::canBeConstructed() const
263{
264 switch (type)
265 {
266 case EbtFloat:
267 case EbtInt:
268 case EbtUInt:
269 case EbtBool:
270 case EbtStruct:
271 return true;
272 default:
273 return false;
274 }
275}
276
277const char *TType::getBuiltInTypeNameString() const
278{
279 if (isMatrix())
280 {
281 switch (getCols())
282 {
283 case 2:
284 switch (getRows())
285 {
286 case 2:
287 return "mat2";
288 case 3:
289 return "mat2x3";
290 case 4:
291 return "mat2x4";
292 default:
293 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/Types.cpp"
, __FUNCTION__, 293, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 293 << ")"; } while (0)
;
294 return nullptr;
295 }
296 case 3:
297 switch (getRows())
298 {
299 case 2:
300 return "mat3x2";
301 case 3:
302 return "mat3";
303 case 4:
304 return "mat3x4";
305 default:
306 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/Types.cpp"
, __FUNCTION__, 306, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 306 << ")"; } while (0)
;
307 return nullptr;
308 }
309 case 4:
310 switch (getRows())
311 {
312 case 2:
313 return "mat4x2";
314 case 3:
315 return "mat4x3";
316 case 4:
317 return "mat4";
318 default:
319 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/Types.cpp"
, __FUNCTION__, 319, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 319 << ")"; } while (0)
;
320 return nullptr;
321 }
322 default:
323 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/Types.cpp"
, __FUNCTION__, 323, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 323 << ")"; } while (0)
;
324 return nullptr;
325 }
326 }
327 if (isVector())
328 {
329 switch (getBasicType())
330 {
331 case EbtFloat:
332 switch (getNominalSize())
333 {
334 case 2:
335 return "vec2";
336 case 3:
337 return "vec3";
338 case 4:
339 return "vec4";
340 default:
341 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/Types.cpp"
, __FUNCTION__, 341, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 341 << ")"; } while (0)
;
342 return nullptr;
343 }
344 case EbtInt:
345 switch (getNominalSize())
346 {
347 case 2:
348 return "ivec2";
349 case 3:
350 return "ivec3";
351 case 4:
352 return "ivec4";
353 default:
354 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/Types.cpp"
, __FUNCTION__, 354, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 354 << ")"; } while (0)
;
355 return nullptr;
356 }
357 case EbtBool:
358 switch (getNominalSize())
359 {
360 case 2:
361 return "bvec2";
362 case 3:
363 return "bvec3";
364 case 4:
365 return "bvec4";
366 default:
367 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/Types.cpp"
, __FUNCTION__, 367, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 367 << ")"; } while (0)
;
368 return nullptr;
369 }
370 case EbtUInt:
371 switch (getNominalSize())
372 {
373 case 2:
374 return "uvec2";
375 case 3:
376 return "uvec3";
377 case 4:
378 return "uvec4";
379 default:
380 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/Types.cpp"
, __FUNCTION__, 380, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 380 << ")"; } while (0)
;
381 return nullptr;
382 }
383 default:
384 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/Types.cpp"
, __FUNCTION__, 384, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 384 << ")"; } while (0)
;
385 return nullptr;
386 }
387 }
388 ASSERT(getBasicType() != EbtStruct)(getBasicType() != EbtStruct ? 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/Types.cpp"
, __FUNCTION__, 388, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 388 << "): " << "getBasicType() != EbtStruct"
))
;
389 ASSERT(getBasicType() != EbtInterfaceBlock)(getBasicType() != EbtInterfaceBlock ? 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/Types.cpp"
, __FUNCTION__, 389, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 389 << "): " << "getBasicType() != EbtInterfaceBlock"
))
;
390 return getBasicString();
391}
392
393int TType::getDeepestStructNesting() const
394{
395 return mStructure ? mStructure->deepestNesting() : 0;
396}
397
398bool TType::isNamelessStruct() const
399{
400 return mStructure && mStructure->symbolType() == SymbolType::Empty;
401}
402
403bool TType::isStructureContainingArrays() const
404{
405 return mStructure ? mStructure->containsArrays() : false;
406}
407
408bool TType::isStructureContainingMatrices() const
409{
410 return mStructure ? mStructure->containsMatrices() : false;
411}
412
413bool TType::isStructureContainingType(TBasicType t) const
414{
415 return mStructure ? mStructure->containsType(t) : false;
416}
417
418bool TType::isStructureContainingSamplers() const
419{
420 return mStructure ? mStructure->containsSamplers() : false;
421}
422
423bool TType::isInterfaceBlockContainingType(TBasicType t) const
424{
425 return isInterfaceBlock() ? mInterfaceBlock->containsType(t) : false;
426}
427
428bool TType::canReplaceWithConstantUnion() const
429{
430 if (isArray())
431 {
432 return false;
433 }
434 if (!mStructure)
435 {
436 return true;
437 }
438 if (isStructureContainingArrays())
439 {
440 return false;
441 }
442 if (getObjectSize() > 16)
443 {
444 return false;
445 }
446 return true;
447}
448
449//
450// Recursively generate mangled names.
451//
452const char *TType::buildMangledName() const
453{
454 TString mangledName(1, GetSizeMangledName(primarySize, secondarySize));
455
456 TBasicMangledName typeName(type);
457 char *basicMangledName = typeName.getName();
458 static_assert(TBasicMangledName::mangledNameSize == 2, "Mangled name size is not 2");
459 if (basicMangledName[0] != '{')
460 {
461 mangledName += basicMangledName[0];
462 mangledName += basicMangledName[1];
463 }
464 else
465 {
466 ASSERT(type == EbtStruct || type == EbtInterfaceBlock)(type == EbtStruct || type == EbtInterfaceBlock ? 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/Types.cpp"
, __FUNCTION__, 466, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 466 << "): " << "type == EbtStruct || type == EbtInterfaceBlock"
))
;
467 switch (type)
468 {
469 case EbtStruct:
470 mangledName += "{s";
471 if (mStructure->symbolType() != SymbolType::Empty)
472 {
473 mangledName += mStructure->name().data();
474 }
475 mangledName += mStructure->mangledFieldList();
476 mangledName += '}';
477 break;
478 case EbtInterfaceBlock:
479 mangledName += "{i";
480 mangledName += mInterfaceBlock->name().data();
481 mangledName += mInterfaceBlock->mangledFieldList();
482 mangledName += '}';
483 break;
484 default:
485 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/Types.cpp"
, __FUNCTION__, 485, ::gl::LOG_FATAL).stream()) << "\t! Unreachable reached: "
<< __FUNCTION__ << "(" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 485 << ")"; } while (0)
;
486 break;
487 }
488 }
489
490 for (unsigned int arraySize : mArraySizes)
491 {
492 char buf[20];
493 snprintf(buf, sizeof(buf), "%d", arraySize);
494 mangledName += 'x';
495 mangledName += buf;
496 }
497
498 // Copy string contents into a pool-allocated buffer, so we never need to call delete.
499 return AllocatePoolCharArray(mangledName.c_str(), mangledName.size());
500}
501
502size_t TType::getObjectSize() const
503{
504 size_t totalSize;
505
506 if (getBasicType() == EbtStruct)
507 totalSize = mStructure->objectSize();
508 else
509 totalSize = primarySize * secondarySize;
510
511 if (totalSize == 0)
512 return 0;
513
514 for (size_t arraySize : mArraySizes)
515 {
516 if (arraySize > INT_MAX2147483647 / totalSize)
517 totalSize = INT_MAX2147483647;
518 else
519 totalSize *= arraySize;
520 }
521
522 return totalSize;
523}
524
525int TType::getLocationCount() const
526{
527 int count = 1;
528
529 if (getBasicType() == EbtStruct)
530 {
531 count = mStructure->getLocationCount();
532 }
533
534 if (count == 0)
535 {
536 return 0;
537 }
538
539 for (unsigned int arraySize : mArraySizes)
540 {
541 if (arraySize > static_cast<unsigned int>(std::numeric_limits<int>::max() / count))
542 {
543 count = std::numeric_limits<int>::max();
544 }
545 else
546 {
547 count *= static_cast<int>(arraySize);
548 }
549 }
550
551 return count;
552}
553
554unsigned int TType::getArraySizeProduct() const
555{
556 unsigned int product = 1u;
557
558 for (unsigned int arraySize : mArraySizes)
559 {
560 product *= arraySize;
561 }
562 return product;
563}
564
565bool TType::isUnsizedArray() const
566{
567 for (unsigned int arraySize : mArraySizes)
568 {
569 if (arraySize == 0u)
570 {
571 return true;
572 }
573 }
574 return false;
575}
576
577bool TType::sameNonArrayType(const TType &right) const
578{
579 return (type == right.type && primarySize == right.primarySize &&
580 secondarySize == right.secondarySize && mStructure == right.mStructure);
581}
582
583bool TType::isElementTypeOf(const TType &arrayType) const
584{
585 if (!sameNonArrayType(arrayType))
586 {
587 return false;
588 }
589 if (arrayType.getNumArraySizes() != getNumArraySizes() + 1u)
590 {
591 return false;
592 }
593 for (size_t i = 0; i < mArraySizes.size(); ++i)
594 {
595 if (mArraySizes[i] != arrayType.mArraySizes[i])
596 {
597 return false;
598 }
599 }
600 return true;
601}
602
603void TType::sizeUnsizedArrays(const TSpan<const unsigned int> &newArraySizes)
604{
605 ASSERT(!isArray() || mArraySizesStorage != nullptr)(!isArray() || mArraySizesStorage != 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/Types.cpp"
, __FUNCTION__, 605, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 605 << "): " << "!isArray() || mArraySizesStorage != nullptr"
))
;
606 for (size_t i = 0u; i < getNumArraySizes(); ++i)
607 {
608 if (mArraySizes[i] == 0)
609 {
610 if (i < newArraySizes.size())
611 {
612 (*mArraySizesStorage)[i] = newArraySizes[i];
613 }
614 else
615 {
616 (*mArraySizesStorage)[i] = 1u;
617 }
618 }
619 }
620 invalidateMangledName();
621}
622
623void TType::sizeOutermostUnsizedArray(unsigned int arraySize)
624{
625 ASSERT(isArray() && mArraySizesStorage != nullptr)(isArray() && mArraySizesStorage != 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/Types.cpp"
, __FUNCTION__, 625, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 625 << "): " << "isArray() && mArraySizesStorage != nullptr"
))
;
1
Assuming pointer value is null
2
'?' condition is false
3
Assuming the condition is true
4
'?' condition is true
626 ASSERT((*mArraySizesStorage).back() == 0u)((*mArraySizesStorage).back() == 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/Types.cpp"
, __FUNCTION__, 626, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 626 << "): " << "(*mArraySizesStorage).back() == 0u"
))
;
5
Called C++ object pointer is null
627 (*mArraySizesStorage).back() = arraySize;
628}
629
630void TType::setBasicType(TBasicType t)
631{
632 if (type != t)
633 {
634 type = t;
635 invalidateMangledName();
636 }
637}
638
639void TType::setPrimarySize(uint8_t ps)
640{
641 if (primarySize != ps)
642 {
643 ASSERT(ps <= 4)(ps <= 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/Types.cpp"
, __FUNCTION__, 643, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 643 << "): " << "ps <= 4"
))
;
644 primarySize = ps;
645 invalidateMangledName();
646 }
647}
648
649void TType::setSecondarySize(uint8_t ss)
650{
651 if (secondarySize != ss)
652 {
653 ASSERT(ss <= 4)(ss <= 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/Types.cpp"
, __FUNCTION__, 653, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 653 << "): " << "ss <= 4"
))
;
654 secondarySize = ss;
655 invalidateMangledName();
656 }
657}
658
659void TType::makeArray(unsigned int s)
660{
661 if (mArraySizesStorage == nullptr)
662 {
663 mArraySizesStorage = new TVector<unsigned int>();
664 }
665 // Add a dimension to the current ones.
666 mArraySizesStorage->push_back(s);
667 onArrayDimensionsChange(*mArraySizesStorage);
668}
669
670void TType::makeArrays(const TSpan<const unsigned int> &sizes)
671{
672 if (mArraySizesStorage == nullptr)
673 {
674 mArraySizesStorage = new TVector<unsigned int>();
675 }
676 // Add dimensions to the current ones.
677 mArraySizesStorage->insert(mArraySizesStorage->end(), sizes.begin(), sizes.end());
678 onArrayDimensionsChange(*mArraySizesStorage);
679}
680
681void TType::setArraySize(size_t arrayDimension, unsigned int s)
682{
683 ASSERT(isArray() && mArraySizesStorage != nullptr)(isArray() && mArraySizesStorage != 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/Types.cpp"
, __FUNCTION__, 683, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 683 << "): " << "isArray() && mArraySizesStorage != nullptr"
))
;
684 ASSERT(arrayDimension < mArraySizesStorage->size())(arrayDimension < mArraySizesStorage->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/Types.cpp"
, __FUNCTION__, 684, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 684 << "): " << "arrayDimension < mArraySizesStorage->size()"
))
;
685 if (mArraySizes[arrayDimension] != s)
686 {
687 (*mArraySizesStorage)[arrayDimension] = s;
688 invalidateMangledName();
689 }
690}
691
692void TType::toArrayElementType()
693{
694 ASSERT(isArray() && mArraySizesStorage != nullptr)(isArray() && mArraySizesStorage != 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/Types.cpp"
, __FUNCTION__, 694, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 694 << "): " << "isArray() && mArraySizesStorage != nullptr"
))
;
695 mArraySizesStorage->pop_back();
696 onArrayDimensionsChange(*mArraySizesStorage);
697}
698
699void TType::toArrayBaseType()
700{
701 if (!isArray())
702 {
703 return;
704 }
705 if (mArraySizesStorage)
706 {
707 mArraySizesStorage->clear();
708 }
709 onArrayDimensionsChange(TSpan<const unsigned int>());
710}
711
712void TType::toMatrixColumnType()
713{
714 ASSERT(isMatrix())(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/Types.cpp"
, __FUNCTION__, 714, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 714 << "): " << "isMatrix()"
))
;
715 primarySize = secondarySize;
716 secondarySize = 1;
717 invalidateMangledName();
718}
719
720void TType::toComponentType()
721{
722 primarySize = 1;
723 secondarySize = 1;
724 invalidateMangledName();
725}
726
727void TType::setInterfaceBlock(const TInterfaceBlock *interfaceBlockIn)
728{
729 if (mInterfaceBlock != interfaceBlockIn)
730 {
731 mInterfaceBlock = interfaceBlockIn;
732 invalidateMangledName();
733 }
734}
735
736void TType::setInterfaceBlockField(const TInterfaceBlock *interfaceBlockIn, size_t fieldIndex)
737{
738 setInterfaceBlock(interfaceBlockIn);
739 mInterfaceBlockFieldIndex = fieldIndex;
740}
741
742const char *TType::getMangledName() const
743{
744 if (mMangledName == nullptr)
745 {
746 mMangledName = buildMangledName();
747 }
748
749 return mMangledName;
750}
751
752void TType::realize()
753{
754 getMangledName();
755}
756
757void TType::createSamplerSymbols(const ImmutableString &namePrefix,
758 const TString &apiNamePrefix,
759 TVector<const TVariable *> *outputSymbols,
760 TMap<const TVariable *, TString> *outputSymbolsToAPINames,
761 TSymbolTable *symbolTable) const
762{
763 if (isStructureContainingSamplers())
764 {
765 if (isArray())
766 {
767 TType elementType(*this);
768 elementType.toArrayElementType();
769 for (unsigned int arrayIndex = 0u; arrayIndex < getOutermostArraySize(); ++arrayIndex)
770 {
771 std::stringstream elementName = sh::InitializeStream<std::stringstream>();
772 elementName << namePrefix << "_" << arrayIndex;
773 TStringStream elementApiName;
774 elementApiName << apiNamePrefix << "[" << arrayIndex << "]";
775 elementType.createSamplerSymbols(ImmutableString(elementName.str()),
776 elementApiName.str(), outputSymbols,
777 outputSymbolsToAPINames, symbolTable);
778 }
779 }
780 else
781 {
782 mStructure->createSamplerSymbols(namePrefix.data(), apiNamePrefix, outputSymbols,
783 outputSymbolsToAPINames, symbolTable);
784 }
785 return;
786 }
787
788 ASSERT(IsSampler(type))(IsSampler(type) ? 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/Types.cpp"
, __FUNCTION__, 788, ::gl::LOG_FATAL).stream()) << "\t! Assert failed in "
<< __FUNCTION__ << " (" << "/root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp"
<< ":" << 788 << "): " << "IsSampler(type)"
))
;
789 TVariable *variable =
790 new TVariable(symbolTable, namePrefix, new TType(*this), SymbolType::AngleInternal);
791 outputSymbols->push_back(variable);
792 if (outputSymbolsToAPINames)
793 {
794 (*outputSymbolsToAPINames)[variable] = apiNamePrefix;
795 }
796}
797
798TFieldListCollection::TFieldListCollection(const TFieldList *fields)
799 : mFields(fields), mObjectSize(0), mDeepestNesting(0)
800{}
801
802bool TFieldListCollection::containsArrays() const
803{
804 for (const auto *field : *mFields)
805 {
806 const TType *fieldType = field->type();
807 if (fieldType->isArray() || fieldType->isStructureContainingArrays())
808 return true;
809 }
810 return false;
811}
812
813bool TFieldListCollection::containsMatrices() const
814{
815 for (const auto *field : *mFields)
816 {
817 const TType *fieldType = field->type();
818 if (fieldType->isMatrix() || fieldType->isStructureContainingMatrices())
819 return true;
820 }
821 return false;
822}
823
824bool TFieldListCollection::containsType(TBasicType type) const
825{
826 for (const auto *field : *mFields)
827 {
828 const TType *fieldType = field->type();
829 if (fieldType->getBasicType() == type || fieldType->isStructureContainingType(type))
830 return true;
831 }
832 return false;
833}
834
835bool TFieldListCollection::containsSamplers() const
836{
837 for (const auto *field : *mFields)
838 {
839 const TType *fieldType = field->type();
840 if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
841 return true;
842 }
843 return false;
844}
845
846TString TFieldListCollection::buildMangledFieldList() const
847{
848 TString mangledName;
849 for (const auto *field : *mFields)
850 {
851 mangledName += field->type()->getMangledName();
852 }
853 return mangledName;
854}
855
856size_t TFieldListCollection::calculateObjectSize() const
857{
858 size_t size = 0;
859 for (const TField *field : *mFields)
860 {
861 size_t fieldSize = field->type()->getObjectSize();
862 if (fieldSize > INT_MAX2147483647 - size)
863 size = INT_MAX2147483647;
864 else
865 size += fieldSize;
866 }
867 return size;
868}
869
870size_t TFieldListCollection::objectSize() const
871{
872 if (mObjectSize == 0)
873 mObjectSize = calculateObjectSize();
874 return mObjectSize;
875}
876
877int TFieldListCollection::getLocationCount() const
878{
879 int count = 0;
880 for (const TField *field : *mFields)
881 {
882 int fieldCount = field->type()->getLocationCount();
883 if (fieldCount > std::numeric_limits<int>::max() - count)
884 {
885 count = std::numeric_limits<int>::max();
886 }
887 else
888 {
889 count += fieldCount;
890 }
891 }
892 return count;
893}
894
895int TFieldListCollection::deepestNesting() const
896{
897 if (mDeepestNesting == 0)
898 mDeepestNesting = calculateDeepestNesting();
899 return mDeepestNesting;
900}
901
902const TString &TFieldListCollection::mangledFieldList() const
903{
904 if (mMangledFieldList.empty())
905 mMangledFieldList = buildMangledFieldList();
906 return mMangledFieldList;
907}
908
909int TFieldListCollection::calculateDeepestNesting() const
910{
911 int maxNesting = 0;
912 for (size_t i = 0; i < mFields->size(); ++i)
913 maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
914 return 1 + maxNesting;
915}
916
917// TPublicType implementation.
918void TPublicType::initialize(const TTypeSpecifierNonArray &typeSpecifier, TQualifier q)
919{
920 typeSpecifierNonArray = typeSpecifier;
921 layoutQualifier = TLayoutQualifier::Create();
922 memoryQualifier = TMemoryQualifier::Create();
923 qualifier = q;
924 invariant = false;
925 precise = false;
926 precision = EbpUndefined;
927 arraySizes = nullptr;
928}
929
930void TPublicType::initializeBasicType(TBasicType basicType)
931{
932 typeSpecifierNonArray.type = basicType;
933 typeSpecifierNonArray.primarySize = 1;
934 typeSpecifierNonArray.secondarySize = 1;
935 layoutQualifier = TLayoutQualifier::Create();
936 memoryQualifier = TMemoryQualifier::Create();
937 qualifier = EvqTemporary;
938 invariant = false;
939 precise = false;
940 precision = EbpUndefined;
941 arraySizes = nullptr;
942}
943
944bool TPublicType::isStructureContainingArrays() const
945{
946 if (!typeSpecifierNonArray.userDef)
947 {
948 return false;
949 }
950
951 return typeSpecifierNonArray.userDef->containsArrays();
952}
953
954bool TPublicType::isStructureContainingType(TBasicType t) const
955{
956 if (!typeSpecifierNonArray.userDef)
957 {
958 return false;
959 }
960
961 return typeSpecifierNonArray.userDef->containsType(t);
962}
963
964void TPublicType::setArraySizes(TVector<unsigned int> *sizes)
965{
966 arraySizes = sizes;
967}
968
969bool TPublicType::isArray() const
970{
971 return arraySizes && !arraySizes->empty();
972}
973
974void TPublicType::clearArrayness()
975{
976 arraySizes = nullptr;
977}
978
979bool TPublicType::isAggregate() const
980{
981 return isArray() || typeSpecifierNonArray.isMatrix() || typeSpecifierNonArray.isVector();
982}
983
984} // namespace sh