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 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 interpolant(false),
179 memoryQualifier(p.memoryQualifier),
180 layoutQualifier(p.layoutQualifier),
181 primarySize(p.getPrimarySize()),
182 secondarySize(p.getSecondarySize()),
183 mArraySizesStorage(nullptr),
184 mInterfaceBlock(nullptr),
185 mStructure(nullptr),
186 mIsStructSpecifier(false),
187 mInterfaceBlockFieldIndex(0),
188 mMangledName(nullptr)
189 {
190 ASSERT(primarySize <= 4);
191 ASSERT(secondarySize <= 4);
192 if (p.isArray())
193 {
194 makeArrays(*p.arraySizes);
195 }
196 if (p.getUserDef())
197 {
198 mStructure = p.getUserDef();
199 mIsStructSpecifier = p.isStructSpecifier();
200 }
201 }
202
TType(const TStructure * userDef,bool isStructSpecifier)203 TType::TType(const TStructure *userDef, bool isStructSpecifier)
204 : TType(EbtStruct, EbpUndefined, EvqTemporary, 1, 1)
205 {
206 mStructure = userDef;
207 mIsStructSpecifier = isStructSpecifier;
208 }
209
TType(const TInterfaceBlock * interfaceBlockIn,TQualifier qualifierIn,TLayoutQualifier layoutQualifierIn)210 TType::TType(const TInterfaceBlock *interfaceBlockIn,
211 TQualifier qualifierIn,
212 TLayoutQualifier layoutQualifierIn)
213 : TType(EbtInterfaceBlock, EbpUndefined, qualifierIn, 1, 1)
214 {
215 layoutQualifier = layoutQualifierIn;
216 mInterfaceBlock = interfaceBlockIn;
217 }
218
TType(const TType & t)219 TType::TType(const TType &t)
220 {
221 *this = t;
222 }
223
operator =(const TType & t)224 TType &TType::operator=(const TType &t)
225 {
226 type = t.type;
227 precision = t.precision;
228 qualifier = t.qualifier;
229 invariant = t.invariant;
230 precise = t.precise;
231 interpolant = t.interpolant;
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(uint8_t ps)635 void TType::setPrimarySize(uint8_t ps)
636 {
637 if (primarySize != ps)
638 {
639 ASSERT(ps <= 4);
640 primarySize = ps;
641 invalidateMangledName();
642 }
643 }
644
setSecondarySize(uint8_t ss)645 void TType::setSecondarySize(uint8_t 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
isUnsizedArray() const980 bool TPublicType::isUnsizedArray() const
981 {
982 if (!arraySizes)
983 {
984 return false;
985 }
986 for (unsigned int arraySize : *arraySizes)
987 {
988 if (arraySize == 0u)
989 {
990 return true;
991 }
992 }
993 return false;
994 }
995
sizeUnsizedArrays()996 void TPublicType::sizeUnsizedArrays()
997 {
998 auto *sizes = new TVector<unsigned int>(arraySizes->size(), 1);
999 for (size_t i = 0; i < arraySizes->size(); ++i)
1000 {
1001 auto value = (*arraySizes)[i];
1002 if (value != 0)
1003 {
1004 (*sizes)[i] = value;
1005 }
1006 }
1007 arraySizes = sizes;
1008 }
1009
makeArrays(TVector<unsigned int> * sizes)1010 void TPublicType::makeArrays(TVector<unsigned int> *sizes)
1011 {
1012 if (arraySizes == nullptr)
1013 {
1014 arraySizes = sizes;
1015 return;
1016 }
1017 auto *newSizes = new TVector<unsigned int>(arraySizes->size() + sizes->size());
1018 size_t i = 0;
1019 for (; i < arraySizes->size(); ++i)
1020 {
1021 (*newSizes)[i] = (*arraySizes)[i];
1022 }
1023 for (size_t j = 0; j < sizes->size(); ++j, ++i)
1024 {
1025 (*newSizes)[i] = (*sizes)[j];
1026 }
1027 arraySizes = newSizes;
1028 }
1029
1030 } // namespace sh
1031