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