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
getBasicString(TBasicType t)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();
165 return "unknown type";
166 }
167 }
168
169 // TType implementation.
TType()170 TType::TType() : TType(EbtVoid, 0, 0) {}
171
TType(TBasicType t,uint8_t ps,uint8_t ss)172 TType::TType(TBasicType t, uint8_t ps, uint8_t ss) : TType(t, EbpUndefined, EvqGlobal, ps, ss) {}
173
TType(TBasicType t,TPrecision p,TQualifier q,uint8_t ps,uint8_t ss)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
TType(const TPublicType & p)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 interpolant(false),
185 memoryQualifier(p.memoryQualifier),
186 layoutQualifier(p.layoutQualifier),
187 primarySize(p.getPrimarySize()),
188 secondarySize(p.getSecondarySize()),
189 mArraySizesStorage(nullptr),
190 mInterfaceBlock(nullptr),
191 mStructure(nullptr),
192 mIsStructSpecifier(false),
193 mInterfaceBlockFieldIndex(0),
194 mMangledName(nullptr)
195 {
196 ASSERT(primarySize <= 4);
197 ASSERT(secondarySize <= 4);
198 if (p.isArray())
199 {
200 makeArrays(*p.arraySizes);
201 }
202 if (p.getUserDef())
203 {
204 mStructure = p.getUserDef();
205 mIsStructSpecifier = p.isStructSpecifier();
206 }
207 }
208
TType(const TStructure * userDef,bool isStructSpecifier)209 TType::TType(const TStructure *userDef, bool isStructSpecifier)
210 : TType(EbtStruct, EbpUndefined, EvqTemporary, 1, 1)
211 {
212 mStructure = userDef;
213 mIsStructSpecifier = isStructSpecifier;
214 }
215
TType(const TInterfaceBlock * interfaceBlockIn,TQualifier qualifierIn,TLayoutQualifier layoutQualifierIn)216 TType::TType(const TInterfaceBlock *interfaceBlockIn,
217 TQualifier qualifierIn,
218 TLayoutQualifier layoutQualifierIn)
219 : TType(EbtInterfaceBlock, EbpUndefined, qualifierIn, 1, 1)
220 {
221 layoutQualifier = layoutQualifierIn;
222 mInterfaceBlock = interfaceBlockIn;
223 }
224
TType(const TType & t)225 TType::TType(const TType &t)
226 {
227 *this = t;
228 }
229
operator =(const TType & t)230 TType &TType::operator=(const TType &t)
231 {
232 type = t.type;
233 precision = t.precision;
234 qualifier = t.qualifier;
235 invariant = t.invariant;
236 precise = t.precise;
237 interpolant = t.interpolant;
238 memoryQualifier = t.memoryQualifier;
239 layoutQualifier = t.layoutQualifier;
240 primarySize = t.primarySize;
241 secondarySize = t.secondarySize;
242 mArraySizesStorage = nullptr;
243 mInterfaceBlock = t.mInterfaceBlock;
244 mStructure = t.mStructure;
245 mIsStructSpecifier = t.mIsStructSpecifier;
246 mInterfaceBlockFieldIndex = t.mInterfaceBlockFieldIndex;
247 mMangledName = t.mMangledName;
248
249 if (t.mArraySizesStorage)
250 {
251 // If other type has storage, duplicate the storage and set the view to our own storage.
252 mArraySizesStorage = new TVector<unsigned int>(*t.mArraySizesStorage);
253 mArraySizes = *mArraySizesStorage;
254 }
255 else
256 {
257 // Otherwise reference the same (constexpr) array sizes as the other type.
258 mArraySizes = t.mArraySizes;
259 }
260
261 return *this;
262 }
263
canBeConstructed() const264 bool TType::canBeConstructed() const
265 {
266 switch (type)
267 {
268 case EbtFloat:
269 case EbtInt:
270 case EbtUInt:
271 case EbtBool:
272 case EbtStruct:
273 return true;
274 default:
275 return false;
276 }
277 }
278
getBuiltInTypeNameString() const279 const char *TType::getBuiltInTypeNameString() const
280 {
281 if (isMatrix())
282 {
283 switch (getCols())
284 {
285 case 2:
286 switch (getRows())
287 {
288 case 2:
289 return "mat2";
290 case 3:
291 return "mat2x3";
292 case 4:
293 return "mat2x4";
294 default:
295 UNREACHABLE();
296 return nullptr;
297 }
298 case 3:
299 switch (getRows())
300 {
301 case 2:
302 return "mat3x2";
303 case 3:
304 return "mat3";
305 case 4:
306 return "mat3x4";
307 default:
308 UNREACHABLE();
309 return nullptr;
310 }
311 case 4:
312 switch (getRows())
313 {
314 case 2:
315 return "mat4x2";
316 case 3:
317 return "mat4x3";
318 case 4:
319 return "mat4";
320 default:
321 UNREACHABLE();
322 return nullptr;
323 }
324 default:
325 UNREACHABLE();
326 return nullptr;
327 }
328 }
329 if (isVector())
330 {
331 switch (getBasicType())
332 {
333 case EbtFloat:
334 switch (getNominalSize())
335 {
336 case 2:
337 return "vec2";
338 case 3:
339 return "vec3";
340 case 4:
341 return "vec4";
342 default:
343 UNREACHABLE();
344 return nullptr;
345 }
346 case EbtInt:
347 switch (getNominalSize())
348 {
349 case 2:
350 return "ivec2";
351 case 3:
352 return "ivec3";
353 case 4:
354 return "ivec4";
355 default:
356 UNREACHABLE();
357 return nullptr;
358 }
359 case EbtBool:
360 switch (getNominalSize())
361 {
362 case 2:
363 return "bvec2";
364 case 3:
365 return "bvec3";
366 case 4:
367 return "bvec4";
368 default:
369 UNREACHABLE();
370 return nullptr;
371 }
372 case EbtUInt:
373 switch (getNominalSize())
374 {
375 case 2:
376 return "uvec2";
377 case 3:
378 return "uvec3";
379 case 4:
380 return "uvec4";
381 default:
382 UNREACHABLE();
383 return nullptr;
384 }
385 default:
386 UNREACHABLE();
387 return nullptr;
388 }
389 }
390 ASSERT(getBasicType() != EbtStruct);
391 ASSERT(getBasicType() != EbtInterfaceBlock);
392 return getBasicString();
393 }
394
getDeepestStructNesting() const395 int TType::getDeepestStructNesting() const
396 {
397 return mStructure ? mStructure->deepestNesting() : 0;
398 }
399
isNamelessStruct() const400 bool TType::isNamelessStruct() const
401 {
402 return mStructure && mStructure->symbolType() == SymbolType::Empty;
403 }
404
isStructureContainingArrays() const405 bool TType::isStructureContainingArrays() const
406 {
407 return mStructure ? mStructure->containsArrays() : false;
408 }
409
isStructureContainingMatrices() const410 bool TType::isStructureContainingMatrices() const
411 {
412 return mStructure ? mStructure->containsMatrices() : false;
413 }
414
isStructureContainingType(TBasicType t) const415 bool TType::isStructureContainingType(TBasicType t) const
416 {
417 return mStructure ? mStructure->containsType(t) : false;
418 }
419
isStructureContainingSamplers() const420 bool TType::isStructureContainingSamplers() const
421 {
422 return mStructure ? mStructure->containsSamplers() : false;
423 }
424
isInterfaceBlockContainingType(TBasicType t) const425 bool TType::isInterfaceBlockContainingType(TBasicType t) const
426 {
427 return isInterfaceBlock() ? mInterfaceBlock->containsType(t) : false;
428 }
429
canReplaceWithConstantUnion() const430 bool TType::canReplaceWithConstantUnion() const
431 {
432 if (isArray())
433 {
434 return false;
435 }
436 if (!mStructure)
437 {
438 return true;
439 }
440 if (isStructureContainingArrays())
441 {
442 return false;
443 }
444 if (getObjectSize() > 16)
445 {
446 return false;
447 }
448 return true;
449 }
450
451 //
452 // Recursively generate mangled names.
453 //
buildMangledName() const454 const char *TType::buildMangledName() const
455 {
456 TString mangledName(1, GetSizeMangledName(primarySize, secondarySize));
457
458 TBasicMangledName typeName(type);
459 char *basicMangledName = typeName.getName();
460 static_assert(TBasicMangledName::mangledNameSize == 2, "Mangled name size is not 2");
461 if (basicMangledName[0] != '{')
462 {
463 mangledName += basicMangledName[0];
464 mangledName += basicMangledName[1];
465 }
466 else
467 {
468 ASSERT(type == EbtStruct || type == EbtInterfaceBlock);
469 switch (type)
470 {
471 case EbtStruct:
472 mangledName += "{s";
473 if (mStructure->symbolType() != SymbolType::Empty)
474 {
475 mangledName += mStructure->name().data();
476 }
477 mangledName += mStructure->mangledFieldList();
478 mangledName += '}';
479 break;
480 case EbtInterfaceBlock:
481 mangledName += "{i";
482 mangledName += mInterfaceBlock->name().data();
483 mangledName += mInterfaceBlock->mangledFieldList();
484 mangledName += '}';
485 break;
486 default:
487 UNREACHABLE();
488 break;
489 }
490 }
491
492 for (unsigned int arraySize : mArraySizes)
493 {
494 char buf[20];
495 snprintf(buf, sizeof(buf), "%d", arraySize);
496 mangledName += 'x';
497 mangledName += buf;
498 }
499
500 // Copy string contents into a pool-allocated buffer, so we never need to call delete.
501 return AllocatePoolCharArray(mangledName.c_str(), mangledName.size());
502 }
503
getObjectSize() const504 size_t TType::getObjectSize() const
505 {
506 size_t totalSize;
507
508 if (getBasicType() == EbtStruct)
509 totalSize = mStructure->objectSize();
510 else
511 totalSize = primarySize * secondarySize;
512
513 if (totalSize == 0)
514 return 0;
515
516 for (size_t arraySize : mArraySizes)
517 {
518 if (arraySize > INT_MAX / totalSize)
519 totalSize = INT_MAX;
520 else
521 totalSize *= arraySize;
522 }
523
524 return totalSize;
525 }
526
getLocationCount() const527 int TType::getLocationCount() const
528 {
529 int count = 1;
530
531 if (getBasicType() == EbtStruct)
532 {
533 count = mStructure->getLocationCount();
534 }
535
536 if (count == 0)
537 {
538 return 0;
539 }
540
541 for (unsigned int arraySize : mArraySizes)
542 {
543 if (arraySize > static_cast<unsigned int>(std::numeric_limits<int>::max() / count))
544 {
545 count = std::numeric_limits<int>::max();
546 }
547 else
548 {
549 count *= static_cast<int>(arraySize);
550 }
551 }
552
553 return count;
554 }
555
getArraySizeProduct() const556 unsigned int TType::getArraySizeProduct() const
557 {
558 unsigned int product = 1u;
559
560 for (unsigned int arraySize : mArraySizes)
561 {
562 product *= arraySize;
563 }
564 return product;
565 }
566
isUnsizedArray() const567 bool TType::isUnsizedArray() const
568 {
569 for (unsigned int arraySize : mArraySizes)
570 {
571 if (arraySize == 0u)
572 {
573 return true;
574 }
575 }
576 return false;
577 }
578
sameNonArrayType(const TType & right) const579 bool TType::sameNonArrayType(const TType &right) const
580 {
581 return (type == right.type && primarySize == right.primarySize &&
582 secondarySize == right.secondarySize && mStructure == right.mStructure);
583 }
584
isElementTypeOf(const TType & arrayType) const585 bool TType::isElementTypeOf(const TType &arrayType) const
586 {
587 if (!sameNonArrayType(arrayType))
588 {
589 return false;
590 }
591 if (arrayType.getNumArraySizes() != getNumArraySizes() + 1u)
592 {
593 return false;
594 }
595 for (size_t i = 0; i < mArraySizes.size(); ++i)
596 {
597 if (mArraySizes[i] != arrayType.mArraySizes[i])
598 {
599 return false;
600 }
601 }
602 return true;
603 }
604
sizeUnsizedArrays(const TSpan<const unsigned int> & newArraySizes)605 void TType::sizeUnsizedArrays(const TSpan<const unsigned int> &newArraySizes)
606 {
607 ASSERT(!isArray() || mArraySizesStorage != nullptr);
608 for (size_t i = 0u; i < getNumArraySizes(); ++i)
609 {
610 if (mArraySizes[i] == 0)
611 {
612 if (i < newArraySizes.size())
613 {
614 (*mArraySizesStorage)[i] = newArraySizes[i];
615 }
616 else
617 {
618 (*mArraySizesStorage)[i] = 1u;
619 }
620 }
621 }
622 invalidateMangledName();
623 }
624
sizeOutermostUnsizedArray(unsigned int arraySize)625 void TType::sizeOutermostUnsizedArray(unsigned int arraySize)
626 {
627 ASSERT(isArray() && mArraySizesStorage != nullptr);
628 ASSERT((*mArraySizesStorage).back() == 0u);
629 (*mArraySizesStorage).back() = arraySize;
630 }
631
setBasicType(TBasicType t)632 void TType::setBasicType(TBasicType t)
633 {
634 if (type != t)
635 {
636 type = t;
637 invalidateMangledName();
638 }
639 }
640
setPrimarySize(uint8_t ps)641 void TType::setPrimarySize(uint8_t ps)
642 {
643 if (primarySize != ps)
644 {
645 ASSERT(ps <= 4);
646 primarySize = ps;
647 invalidateMangledName();
648 }
649 }
650
setSecondarySize(uint8_t ss)651 void TType::setSecondarySize(uint8_t ss)
652 {
653 if (secondarySize != ss)
654 {
655 ASSERT(ss <= 4);
656 secondarySize = ss;
657 invalidateMangledName();
658 }
659 }
660
makeArray(unsigned int s)661 void TType::makeArray(unsigned int s)
662 {
663 if (mArraySizesStorage == nullptr)
664 {
665 mArraySizesStorage = new TVector<unsigned int>();
666 }
667 // Add a dimension to the current ones.
668 mArraySizesStorage->push_back(s);
669 onArrayDimensionsChange(*mArraySizesStorage);
670 }
671
makeArrays(const TSpan<const unsigned int> & sizes)672 void TType::makeArrays(const TSpan<const unsigned int> &sizes)
673 {
674 if (mArraySizesStorage == nullptr)
675 {
676 mArraySizesStorage = new TVector<unsigned int>();
677 }
678 // Add dimensions to the current ones.
679 mArraySizesStorage->insert(mArraySizesStorage->end(), sizes.begin(), sizes.end());
680 onArrayDimensionsChange(*mArraySizesStorage);
681 }
682
setArraySize(size_t arrayDimension,unsigned int s)683 void TType::setArraySize(size_t arrayDimension, unsigned int s)
684 {
685 ASSERT(isArray() && mArraySizesStorage != nullptr);
686 ASSERT(arrayDimension < mArraySizesStorage->size());
687 if (mArraySizes[arrayDimension] != s)
688 {
689 (*mArraySizesStorage)[arrayDimension] = s;
690 invalidateMangledName();
691 }
692 }
693
toArrayElementType()694 void TType::toArrayElementType()
695 {
696 ASSERT(isArray() && mArraySizesStorage != nullptr);
697 mArraySizesStorage->pop_back();
698 onArrayDimensionsChange(*mArraySizesStorage);
699 }
700
toArrayBaseType()701 void TType::toArrayBaseType()
702 {
703 if (!isArray())
704 {
705 return;
706 }
707 if (mArraySizesStorage)
708 {
709 mArraySizesStorage->clear();
710 }
711 onArrayDimensionsChange(TSpan<const unsigned int>());
712 }
713
toMatrixColumnType()714 void TType::toMatrixColumnType()
715 {
716 ASSERT(isMatrix());
717 primarySize = secondarySize;
718 secondarySize = 1;
719 invalidateMangledName();
720 }
721
toComponentType()722 void TType::toComponentType()
723 {
724 primarySize = 1;
725 secondarySize = 1;
726 invalidateMangledName();
727 }
728
setInterfaceBlock(const TInterfaceBlock * interfaceBlockIn)729 void TType::setInterfaceBlock(const TInterfaceBlock *interfaceBlockIn)
730 {
731 if (mInterfaceBlock != interfaceBlockIn)
732 {
733 mInterfaceBlock = interfaceBlockIn;
734 invalidateMangledName();
735 }
736 }
737
setInterfaceBlockField(const TInterfaceBlock * interfaceBlockIn,size_t fieldIndex)738 void TType::setInterfaceBlockField(const TInterfaceBlock *interfaceBlockIn, size_t fieldIndex)
739 {
740 setInterfaceBlock(interfaceBlockIn);
741 mInterfaceBlockFieldIndex = fieldIndex;
742 }
743
getMangledName() const744 const char *TType::getMangledName() const
745 {
746 if (mMangledName == nullptr)
747 {
748 mMangledName = buildMangledName();
749 }
750
751 return mMangledName;
752 }
753
realize()754 void TType::realize()
755 {
756 getMangledName();
757 }
758
createSamplerSymbols(const ImmutableString & namePrefix,const TString & apiNamePrefix,TVector<const TVariable * > * outputSymbols,TMap<const TVariable *,TString> * outputSymbolsToAPINames,TSymbolTable * symbolTable) const759 void TType::createSamplerSymbols(const ImmutableString &namePrefix,
760 const TString &apiNamePrefix,
761 TVector<const TVariable *> *outputSymbols,
762 TMap<const TVariable *, TString> *outputSymbolsToAPINames,
763 TSymbolTable *symbolTable) const
764 {
765 if (isStructureContainingSamplers())
766 {
767 if (isArray())
768 {
769 TType elementType(*this);
770 elementType.toArrayElementType();
771 for (unsigned int arrayIndex = 0u; arrayIndex < getOutermostArraySize(); ++arrayIndex)
772 {
773 std::stringstream elementName = sh::InitializeStream<std::stringstream>();
774 elementName << namePrefix << "_" << arrayIndex;
775 TStringStream elementApiName;
776 elementApiName << apiNamePrefix << "[" << arrayIndex << "]";
777 elementType.createSamplerSymbols(ImmutableString(elementName.str()),
778 elementApiName.str(), outputSymbols,
779 outputSymbolsToAPINames, symbolTable);
780 }
781 }
782 else
783 {
784 mStructure->createSamplerSymbols(namePrefix.data(), apiNamePrefix, outputSymbols,
785 outputSymbolsToAPINames, symbolTable);
786 }
787 return;
788 }
789
790 ASSERT(IsSampler(type));
791 TVariable *variable =
792 new TVariable(symbolTable, namePrefix, new TType(*this), SymbolType::AngleInternal);
793 outputSymbols->push_back(variable);
794 if (outputSymbolsToAPINames)
795 {
796 (*outputSymbolsToAPINames)[variable] = apiNamePrefix;
797 }
798 }
799
TFieldListCollection(const TFieldList * fields)800 TFieldListCollection::TFieldListCollection(const TFieldList *fields)
801 : mFields(fields), mObjectSize(0), mDeepestNesting(0)
802 {}
803
containsArrays() const804 bool TFieldListCollection::containsArrays() const
805 {
806 for (const auto *field : *mFields)
807 {
808 const TType *fieldType = field->type();
809 if (fieldType->isArray() || fieldType->isStructureContainingArrays())
810 return true;
811 }
812 return false;
813 }
814
containsMatrices() const815 bool TFieldListCollection::containsMatrices() const
816 {
817 for (const auto *field : *mFields)
818 {
819 const TType *fieldType = field->type();
820 if (fieldType->isMatrix() || fieldType->isStructureContainingMatrices())
821 return true;
822 }
823 return false;
824 }
825
containsType(TBasicType type) const826 bool TFieldListCollection::containsType(TBasicType type) const
827 {
828 for (const auto *field : *mFields)
829 {
830 const TType *fieldType = field->type();
831 if (fieldType->getBasicType() == type || fieldType->isStructureContainingType(type))
832 return true;
833 }
834 return false;
835 }
836
containsSamplers() const837 bool TFieldListCollection::containsSamplers() const
838 {
839 for (const auto *field : *mFields)
840 {
841 const TType *fieldType = field->type();
842 if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
843 return true;
844 }
845 return false;
846 }
847
buildMangledFieldList() const848 TString TFieldListCollection::buildMangledFieldList() const
849 {
850 TString mangledName;
851 for (const auto *field : *mFields)
852 {
853 mangledName += field->type()->getMangledName();
854 }
855 return mangledName;
856 }
857
calculateObjectSize() const858 size_t TFieldListCollection::calculateObjectSize() const
859 {
860 size_t size = 0;
861 for (const TField *field : *mFields)
862 {
863 size_t fieldSize = field->type()->getObjectSize();
864 if (fieldSize > INT_MAX - size)
865 size = INT_MAX;
866 else
867 size += fieldSize;
868 }
869 return size;
870 }
871
objectSize() const872 size_t TFieldListCollection::objectSize() const
873 {
874 if (mObjectSize == 0)
875 mObjectSize = calculateObjectSize();
876 return mObjectSize;
877 }
878
getLocationCount() const879 int TFieldListCollection::getLocationCount() const
880 {
881 int count = 0;
882 for (const TField *field : *mFields)
883 {
884 int fieldCount = field->type()->getLocationCount();
885 if (fieldCount > std::numeric_limits<int>::max() - count)
886 {
887 count = std::numeric_limits<int>::max();
888 }
889 else
890 {
891 count += fieldCount;
892 }
893 }
894 return count;
895 }
896
deepestNesting() const897 int TFieldListCollection::deepestNesting() const
898 {
899 if (mDeepestNesting == 0)
900 mDeepestNesting = calculateDeepestNesting();
901 return mDeepestNesting;
902 }
903
mangledFieldList() const904 const TString &TFieldListCollection::mangledFieldList() const
905 {
906 if (mMangledFieldList.empty())
907 mMangledFieldList = buildMangledFieldList();
908 return mMangledFieldList;
909 }
910
calculateDeepestNesting() const911 int TFieldListCollection::calculateDeepestNesting() const
912 {
913 int maxNesting = 0;
914 for (size_t i = 0; i < mFields->size(); ++i)
915 maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
916 return 1 + maxNesting;
917 }
918
919 // TPublicType implementation.
initialize(const TTypeSpecifierNonArray & typeSpecifier,TQualifier q)920 void TPublicType::initialize(const TTypeSpecifierNonArray &typeSpecifier, TQualifier q)
921 {
922 typeSpecifierNonArray = typeSpecifier;
923 layoutQualifier = TLayoutQualifier::Create();
924 memoryQualifier = TMemoryQualifier::Create();
925 qualifier = q;
926 invariant = false;
927 precise = false;
928 precision = EbpUndefined;
929 arraySizes = nullptr;
930 }
931
initializeBasicType(TBasicType basicType)932 void TPublicType::initializeBasicType(TBasicType basicType)
933 {
934 typeSpecifierNonArray.type = basicType;
935 typeSpecifierNonArray.primarySize = 1;
936 typeSpecifierNonArray.secondarySize = 1;
937 layoutQualifier = TLayoutQualifier::Create();
938 memoryQualifier = TMemoryQualifier::Create();
939 qualifier = EvqTemporary;
940 invariant = false;
941 precise = false;
942 precision = EbpUndefined;
943 arraySizes = nullptr;
944 }
945
isStructureContainingArrays() const946 bool TPublicType::isStructureContainingArrays() const
947 {
948 if (!typeSpecifierNonArray.userDef)
949 {
950 return false;
951 }
952
953 return typeSpecifierNonArray.userDef->containsArrays();
954 }
955
isStructureContainingType(TBasicType t) const956 bool TPublicType::isStructureContainingType(TBasicType t) const
957 {
958 if (!typeSpecifierNonArray.userDef)
959 {
960 return false;
961 }
962
963 return typeSpecifierNonArray.userDef->containsType(t);
964 }
965
setArraySizes(TVector<unsigned int> * sizes)966 void TPublicType::setArraySizes(TVector<unsigned int> *sizes)
967 {
968 arraySizes = sizes;
969 }
970
isArray() const971 bool TPublicType::isArray() const
972 {
973 return arraySizes && !arraySizes->empty();
974 }
975
clearArrayness()976 void TPublicType::clearArrayness()
977 {
978 arraySizes = nullptr;
979 }
980
isAggregate() const981 bool TPublicType::isAggregate() const
982 {
983 return isArray() || typeSpecifierNonArray.isMatrix() || typeSpecifierNonArray.isVector();
984 }
985
986 } // namespace sh
987