xref: /aosp_15_r20/external/angle/src/compiler/translator/Types.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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