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
toComponentType()716 void TType::toComponentType()
717 {
718 primarySize = 1;
719 secondarySize = 1;
720 invalidateMangledName();
721 }
722
setInterfaceBlock(const TInterfaceBlock * interfaceBlockIn)723 void TType::setInterfaceBlock(const TInterfaceBlock *interfaceBlockIn)
724 {
725 if (mInterfaceBlock != interfaceBlockIn)
726 {
727 mInterfaceBlock = interfaceBlockIn;
728 invalidateMangledName();
729 }
730 }
731
setInterfaceBlockField(const TInterfaceBlock * interfaceBlockIn,size_t fieldIndex)732 void TType::setInterfaceBlockField(const TInterfaceBlock *interfaceBlockIn, size_t fieldIndex)
733 {
734 setInterfaceBlock(interfaceBlockIn);
735 mInterfaceBlockFieldIndex = fieldIndex;
736 }
737
getMangledName() const738 const char *TType::getMangledName() const
739 {
740 if (mMangledName == nullptr)
741 {
742 mMangledName = buildMangledName();
743 }
744
745 return mMangledName;
746 }
747
realize()748 void TType::realize()
749 {
750 getMangledName();
751 }
752
createSamplerSymbols(const ImmutableString & namePrefix,const TString & apiNamePrefix,TVector<const TVariable * > * outputSymbols,TMap<const TVariable *,TString> * outputSymbolsToAPINames,TSymbolTable * symbolTable) const753 void TType::createSamplerSymbols(const ImmutableString &namePrefix,
754 const TString &apiNamePrefix,
755 TVector<const TVariable *> *outputSymbols,
756 TMap<const TVariable *, TString> *outputSymbolsToAPINames,
757 TSymbolTable *symbolTable) const
758 {
759 if (isStructureContainingSamplers())
760 {
761 if (isArray())
762 {
763 TType elementType(*this);
764 elementType.toArrayElementType();
765 for (unsigned int arrayIndex = 0u; arrayIndex < getOutermostArraySize(); ++arrayIndex)
766 {
767 std::stringstream elementName = sh::InitializeStream<std::stringstream>();
768 elementName << namePrefix << "_" << arrayIndex;
769 TStringStream elementApiName;
770 elementApiName << apiNamePrefix << "[" << arrayIndex << "]";
771 elementType.createSamplerSymbols(ImmutableString(elementName.str()),
772 elementApiName.str(), outputSymbols,
773 outputSymbolsToAPINames, symbolTable);
774 }
775 }
776 else
777 {
778 mStructure->createSamplerSymbols(namePrefix.data(), apiNamePrefix, outputSymbols,
779 outputSymbolsToAPINames, symbolTable);
780 }
781 return;
782 }
783
784 ASSERT(IsSampler(type));
785 TVariable *variable =
786 new TVariable(symbolTable, namePrefix, new TType(*this), SymbolType::AngleInternal);
787 outputSymbols->push_back(variable);
788 if (outputSymbolsToAPINames)
789 {
790 (*outputSymbolsToAPINames)[variable] = apiNamePrefix;
791 }
792 }
793
TFieldListCollection(const TFieldList * fields)794 TFieldListCollection::TFieldListCollection(const TFieldList *fields)
795 : mFields(fields), mObjectSize(0), mDeepestNesting(0)
796 {}
797
containsArrays() const798 bool TFieldListCollection::containsArrays() const
799 {
800 for (const auto *field : *mFields)
801 {
802 const TType *fieldType = field->type();
803 if (fieldType->isArray() || fieldType->isStructureContainingArrays())
804 return true;
805 }
806 return false;
807 }
808
containsMatrices() const809 bool TFieldListCollection::containsMatrices() const
810 {
811 for (const auto *field : *mFields)
812 {
813 const TType *fieldType = field->type();
814 if (fieldType->isMatrix() || fieldType->isStructureContainingMatrices())
815 return true;
816 }
817 return false;
818 }
819
containsType(TBasicType type) const820 bool TFieldListCollection::containsType(TBasicType type) const
821 {
822 for (const auto *field : *mFields)
823 {
824 const TType *fieldType = field->type();
825 if (fieldType->getBasicType() == type || fieldType->isStructureContainingType(type))
826 return true;
827 }
828 return false;
829 }
830
containsSamplers() const831 bool TFieldListCollection::containsSamplers() const
832 {
833 for (const auto *field : *mFields)
834 {
835 const TType *fieldType = field->type();
836 if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
837 return true;
838 }
839 return false;
840 }
841
buildMangledFieldList() const842 TString TFieldListCollection::buildMangledFieldList() const
843 {
844 TString mangledName;
845 for (const auto *field : *mFields)
846 {
847 mangledName += field->type()->getMangledName();
848 }
849 return mangledName;
850 }
851
calculateObjectSize() const852 size_t TFieldListCollection::calculateObjectSize() const
853 {
854 size_t size = 0;
855 for (const TField *field : *mFields)
856 {
857 size_t fieldSize = field->type()->getObjectSize();
858 if (fieldSize > INT_MAX - size)
859 size = INT_MAX;
860 else
861 size += fieldSize;
862 }
863 return size;
864 }
865
objectSize() const866 size_t TFieldListCollection::objectSize() const
867 {
868 if (mObjectSize == 0)
869 mObjectSize = calculateObjectSize();
870 return mObjectSize;
871 }
872
getLocationCount() const873 int TFieldListCollection::getLocationCount() const
874 {
875 int count = 0;
876 for (const TField *field : *mFields)
877 {
878 int fieldCount = field->type()->getLocationCount();
879 if (fieldCount > std::numeric_limits<int>::max() - count)
880 {
881 count = std::numeric_limits<int>::max();
882 }
883 else
884 {
885 count += fieldCount;
886 }
887 }
888 return count;
889 }
890
deepestNesting() const891 int TFieldListCollection::deepestNesting() const
892 {
893 if (mDeepestNesting == 0)
894 mDeepestNesting = calculateDeepestNesting();
895 return mDeepestNesting;
896 }
897
mangledFieldList() const898 const TString &TFieldListCollection::mangledFieldList() const
899 {
900 if (mMangledFieldList.empty())
901 mMangledFieldList = buildMangledFieldList();
902 return mMangledFieldList;
903 }
904
calculateDeepestNesting() const905 int TFieldListCollection::calculateDeepestNesting() const
906 {
907 int maxNesting = 0;
908 for (size_t i = 0; i < mFields->size(); ++i)
909 maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
910 return 1 + maxNesting;
911 }
912
913 // TPublicType implementation.
initialize(const TTypeSpecifierNonArray & typeSpecifier,TQualifier q)914 void TPublicType::initialize(const TTypeSpecifierNonArray &typeSpecifier, TQualifier q)
915 {
916 typeSpecifierNonArray = typeSpecifier;
917 layoutQualifier = TLayoutQualifier::Create();
918 memoryQualifier = TMemoryQualifier::Create();
919 qualifier = q;
920 invariant = false;
921 precise = false;
922 precision = EbpUndefined;
923 arraySizes = nullptr;
924 }
925
initializeBasicType(TBasicType basicType)926 void TPublicType::initializeBasicType(TBasicType basicType)
927 {
928 typeSpecifierNonArray.type = basicType;
929 typeSpecifierNonArray.primarySize = 1;
930 typeSpecifierNonArray.secondarySize = 1;
931 layoutQualifier = TLayoutQualifier::Create();
932 memoryQualifier = TMemoryQualifier::Create();
933 qualifier = EvqTemporary;
934 invariant = false;
935 precise = false;
936 precision = EbpUndefined;
937 arraySizes = nullptr;
938 }
939
isStructureContainingArrays() const940 bool TPublicType::isStructureContainingArrays() const
941 {
942 if (!typeSpecifierNonArray.userDef)
943 {
944 return false;
945 }
946
947 return typeSpecifierNonArray.userDef->containsArrays();
948 }
949
isStructureContainingType(TBasicType t) const950 bool TPublicType::isStructureContainingType(TBasicType t) const
951 {
952 if (!typeSpecifierNonArray.userDef)
953 {
954 return false;
955 }
956
957 return typeSpecifierNonArray.userDef->containsType(t);
958 }
959
setArraySizes(TVector<unsigned int> * sizes)960 void TPublicType::setArraySizes(TVector<unsigned int> *sizes)
961 {
962 arraySizes = sizes;
963 }
964
isArray() const965 bool TPublicType::isArray() const
966 {
967 return arraySizes && !arraySizes->empty();
968 }
969
clearArrayness()970 void TPublicType::clearArrayness()
971 {
972 arraySizes = nullptr;
973 }
974
isAggregate() const975 bool TPublicType::isAggregate() const
976 {
977 return isArray() || typeSpecifierNonArray.isMatrix() || typeSpecifierNonArray.isVector();
978 }
979
980 } // namespace sh
981