File: | root/firefox-clang/gfx/angle/checkout/src/compiler/translator/Types.cpp |
Warning: | line 626, column 5 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 | ||||
20 | namespace sh | |||
21 | { | |||
22 | ||||
23 | const 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. | |||
170 | TType::TType() : TType(EbtVoid, 0, 0) {} | |||
171 | ||||
172 | TType::TType(TBasicType t, uint8_t ps, uint8_t ss) : TType(t, EbpUndefined, EvqGlobal, ps, ss) {} | |||
173 | ||||
174 | TType::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 | ||||
178 | TType::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 | ||||
208 | TType::TType(const TStructure *userDef, bool isStructSpecifier) | |||
209 | : TType(EbtStruct, EbpUndefined, EvqTemporary, 1, 1) | |||
210 | { | |||
211 | mStructure = userDef; | |||
212 | mIsStructSpecifier = isStructSpecifier; | |||
213 | } | |||
214 | ||||
215 | TType::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 | ||||
224 | TType::TType(const TType &t) | |||
225 | { | |||
226 | *this = t; | |||
227 | } | |||
228 | ||||
229 | TType &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 | ||||
262 | bool 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 | ||||
277 | const 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 | ||||
393 | int TType::getDeepestStructNesting() const | |||
394 | { | |||
395 | return mStructure ? mStructure->deepestNesting() : 0; | |||
396 | } | |||
397 | ||||
398 | bool TType::isNamelessStruct() const | |||
399 | { | |||
400 | return mStructure && mStructure->symbolType() == SymbolType::Empty; | |||
401 | } | |||
402 | ||||
403 | bool TType::isStructureContainingArrays() const | |||
404 | { | |||
405 | return mStructure ? mStructure->containsArrays() : false; | |||
406 | } | |||
407 | ||||
408 | bool TType::isStructureContainingMatrices() const | |||
409 | { | |||
410 | return mStructure ? mStructure->containsMatrices() : false; | |||
411 | } | |||
412 | ||||
413 | bool TType::isStructureContainingType(TBasicType t) const | |||
414 | { | |||
415 | return mStructure ? mStructure->containsType(t) : false; | |||
416 | } | |||
417 | ||||
418 | bool TType::isStructureContainingSamplers() const | |||
419 | { | |||
420 | return mStructure ? mStructure->containsSamplers() : false; | |||
421 | } | |||
422 | ||||
423 | bool TType::isInterfaceBlockContainingType(TBasicType t) const | |||
424 | { | |||
425 | return isInterfaceBlock() ? mInterfaceBlock->containsType(t) : false; | |||
426 | } | |||
427 | ||||
428 | bool 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 | // | |||
452 | const 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 | ||||
502 | size_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 | ||||
525 | int 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 | ||||
554 | unsigned 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 | ||||
565 | bool 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 | ||||
577 | bool TType::sameNonArrayType(const TType &right) const | |||
578 | { | |||
579 | return (type == right.type && primarySize == right.primarySize && | |||
580 | secondarySize == right.secondarySize && mStructure == right.mStructure); | |||
581 | } | |||
582 | ||||
583 | bool 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 | ||||
603 | void 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 | ||||
623 | void 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" )); | |||
| ||||
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" )); | |||
| ||||
627 | (*mArraySizesStorage).back() = arraySize; | |||
628 | } | |||
629 | ||||
630 | void TType::setBasicType(TBasicType t) | |||
631 | { | |||
632 | if (type != t) | |||
633 | { | |||
634 | type = t; | |||
635 | invalidateMangledName(); | |||
636 | } | |||
637 | } | |||
638 | ||||
639 | void 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 | ||||
649 | void 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 | ||||
659 | void 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 | ||||
670 | void 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 | ||||
681 | void 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 | ||||
692 | void 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 | ||||
699 | void 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 | ||||
712 | void 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 | ||||
720 | void TType::toComponentType() | |||
721 | { | |||
722 | primarySize = 1; | |||
723 | secondarySize = 1; | |||
724 | invalidateMangledName(); | |||
725 | } | |||
726 | ||||
727 | void TType::setInterfaceBlock(const TInterfaceBlock *interfaceBlockIn) | |||
728 | { | |||
729 | if (mInterfaceBlock != interfaceBlockIn) | |||
730 | { | |||
731 | mInterfaceBlock = interfaceBlockIn; | |||
732 | invalidateMangledName(); | |||
733 | } | |||
734 | } | |||
735 | ||||
736 | void TType::setInterfaceBlockField(const TInterfaceBlock *interfaceBlockIn, size_t fieldIndex) | |||
737 | { | |||
738 | setInterfaceBlock(interfaceBlockIn); | |||
739 | mInterfaceBlockFieldIndex = fieldIndex; | |||
740 | } | |||
741 | ||||
742 | const char *TType::getMangledName() const | |||
743 | { | |||
744 | if (mMangledName == nullptr) | |||
745 | { | |||
746 | mMangledName = buildMangledName(); | |||
747 | } | |||
748 | ||||
749 | return mMangledName; | |||
750 | } | |||
751 | ||||
752 | void TType::realize() | |||
753 | { | |||
754 | getMangledName(); | |||
755 | } | |||
756 | ||||
757 | void 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 | ||||
798 | TFieldListCollection::TFieldListCollection(const TFieldList *fields) | |||
799 | : mFields(fields), mObjectSize(0), mDeepestNesting(0) | |||
800 | {} | |||
801 | ||||
802 | bool 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 | ||||
813 | bool 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 | ||||
824 | bool 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 | ||||
835 | bool 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 | ||||
846 | TString 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 | ||||
856 | size_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 | ||||
870 | size_t TFieldListCollection::objectSize() const | |||
871 | { | |||
872 | if (mObjectSize == 0) | |||
873 | mObjectSize = calculateObjectSize(); | |||
874 | return mObjectSize; | |||
875 | } | |||
876 | ||||
877 | int 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 | ||||
895 | int TFieldListCollection::deepestNesting() const | |||
896 | { | |||
897 | if (mDeepestNesting == 0) | |||
898 | mDeepestNesting = calculateDeepestNesting(); | |||
899 | return mDeepestNesting; | |||
900 | } | |||
901 | ||||
902 | const TString &TFieldListCollection::mangledFieldList() const | |||
903 | { | |||
904 | if (mMangledFieldList.empty()) | |||
905 | mMangledFieldList = buildMangledFieldList(); | |||
906 | return mMangledFieldList; | |||
907 | } | |||
908 | ||||
909 | int 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. | |||
918 | void 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 | ||||
930 | void 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 | ||||
944 | bool TPublicType::isStructureContainingArrays() const | |||
945 | { | |||
946 | if (!typeSpecifierNonArray.userDef) | |||
947 | { | |||
948 | return false; | |||
949 | } | |||
950 | ||||
951 | return typeSpecifierNonArray.userDef->containsArrays(); | |||
952 | } | |||
953 | ||||
954 | bool TPublicType::isStructureContainingType(TBasicType t) const | |||
955 | { | |||
956 | if (!typeSpecifierNonArray.userDef) | |||
957 | { | |||
958 | return false; | |||
959 | } | |||
960 | ||||
961 | return typeSpecifierNonArray.userDef->containsType(t); | |||
962 | } | |||
963 | ||||
964 | void TPublicType::setArraySizes(TVector<unsigned int> *sizes) | |||
965 | { | |||
966 | arraySizes = sizes; | |||
967 | } | |||
968 | ||||
969 | bool TPublicType::isArray() const | |||
970 | { | |||
971 | return arraySizes && !arraySizes->empty(); | |||
972 | } | |||
973 | ||||
974 | void TPublicType::clearArrayness() | |||
975 | { | |||
976 | arraySizes = nullptr; | |||
977 | } | |||
978 | ||||
979 | bool TPublicType::isAggregate() const | |||
980 | { | |||
981 | return isArray() || typeSpecifierNonArray.isMatrix() || typeSpecifierNonArray.isVector(); | |||
982 | } | |||
983 | ||||
984 | } // namespace sh |