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