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