• 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 EbtISampler2D:
58             return "isampler2D";
59         case EbtISampler3D:
60             return "isampler3D";
61         case EbtISamplerCube:
62             return "isamplerCube";
63         case EbtISampler2DArray:
64             return "isampler2DArray";
65         case EbtISampler2DMS:
66             return "isampler2DMS";
67         case EbtISampler2DMSArray:
68             return "isampler2DMSArray";
69         case EbtUSampler2D:
70             return "usampler2D";
71         case EbtUSampler3D:
72             return "usampler3D";
73         case EbtUSamplerCube:
74             return "usamplerCube";
75         case EbtUSampler2DArray:
76             return "usampler2DArray";
77         case EbtUSampler2DMS:
78             return "usampler2DMS";
79         case EbtUSampler2DMSArray:
80             return "usampler2DMSArray";
81         case EbtSampler2DShadow:
82             return "sampler2DShadow";
83         case EbtSamplerCubeShadow:
84             return "samplerCubeShadow";
85         case EbtSampler2DArrayShadow:
86             return "sampler2DArrayShadow";
87         case EbtStruct:
88             return "structure";
89         case EbtInterfaceBlock:
90             return "interface block";
91         case EbtImage2D:
92             return "image2D";
93         case EbtIImage2D:
94             return "iimage2D";
95         case EbtUImage2D:
96             return "uimage2D";
97         case EbtImage3D:
98             return "image3D";
99         case EbtIImage3D:
100             return "iimage3D";
101         case EbtUImage3D:
102             return "uimage3D";
103         case EbtImage2DArray:
104             return "image2DArray";
105         case EbtIImage2DArray:
106             return "iimage2DArray";
107         case EbtUImage2DArray:
108             return "uimage2DArray";
109         case EbtImageCube:
110             return "imageCube";
111         case EbtIImageCube:
112             return "iimageCube";
113         case EbtUImageCube:
114             return "uimageCube";
115         case EbtAtomicCounter:
116             return "atomic_uint";
117         default:
118             UNREACHABLE();
119             return "unknown type";
120     }
121 }
122 
123 // TType implementation.
TType()124 TType::TType()
125     : type(EbtVoid),
126       precision(EbpUndefined),
127       qualifier(EvqGlobal),
128       invariant(false),
129       memoryQualifier(TMemoryQualifier::Create()),
130       layoutQualifier(TLayoutQualifier::Create()),
131       primarySize(0),
132       secondarySize(0),
133       mArraySizes(nullptr),
134       mInterfaceBlock(nullptr),
135       mStructure(nullptr),
136       mIsStructSpecifier(false),
137       mMangledName(nullptr)
138 {}
139 
TType(TBasicType t,unsigned char ps,unsigned char ss)140 TType::TType(TBasicType t, unsigned char ps, unsigned char ss)
141     : type(t),
142       precision(EbpUndefined),
143       qualifier(EvqGlobal),
144       invariant(false),
145       memoryQualifier(TMemoryQualifier::Create()),
146       layoutQualifier(TLayoutQualifier::Create()),
147       primarySize(ps),
148       secondarySize(ss),
149       mArraySizes(nullptr),
150       mInterfaceBlock(nullptr),
151       mStructure(nullptr),
152       mIsStructSpecifier(false),
153       mMangledName(nullptr)
154 {}
155 
TType(TBasicType t,TPrecision p,TQualifier q,unsigned char ps,unsigned char ss)156 TType::TType(TBasicType t, TPrecision p, TQualifier q, unsigned char ps, unsigned char ss)
157     : type(t),
158       precision(p),
159       qualifier(q),
160       invariant(false),
161       memoryQualifier(TMemoryQualifier::Create()),
162       layoutQualifier(TLayoutQualifier::Create()),
163       primarySize(ps),
164       secondarySize(ss),
165       mArraySizes(nullptr),
166       mInterfaceBlock(nullptr),
167       mStructure(nullptr),
168       mIsStructSpecifier(false),
169       mMangledName(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       memoryQualifier(p.memoryQualifier),
178       layoutQualifier(p.layoutQualifier),
179       primarySize(p.getPrimarySize()),
180       secondarySize(p.getSecondarySize()),
181       mArraySizes(nullptr),
182       mInterfaceBlock(nullptr),
183       mStructure(nullptr),
184       mIsStructSpecifier(false),
185       mMangledName(nullptr)
186 {
187     ASSERT(primarySize <= 4);
188     ASSERT(secondarySize <= 4);
189     if (p.isArray())
190     {
191         mArraySizes = new TVector<unsigned int>(*p.arraySizes);
192     }
193     if (p.getUserDef())
194     {
195         mStructure         = p.getUserDef();
196         mIsStructSpecifier = p.isStructSpecifier();
197     }
198 }
199 
TType(const TStructure * userDef,bool isStructSpecifier)200 TType::TType(const TStructure *userDef, bool isStructSpecifier)
201     : type(EbtStruct),
202       precision(EbpUndefined),
203       qualifier(EvqTemporary),
204       invariant(false),
205       memoryQualifier(TMemoryQualifier::Create()),
206       layoutQualifier(TLayoutQualifier::Create()),
207       primarySize(1),
208       secondarySize(1),
209       mArraySizes(nullptr),
210       mInterfaceBlock(nullptr),
211       mStructure(userDef),
212       mIsStructSpecifier(isStructSpecifier),
213       mMangledName(nullptr)
214 {}
215 
TType(const TInterfaceBlock * interfaceBlockIn,TQualifier qualifierIn,TLayoutQualifier layoutQualifierIn)216 TType::TType(const TInterfaceBlock *interfaceBlockIn,
217              TQualifier qualifierIn,
218              TLayoutQualifier layoutQualifierIn)
219     : type(EbtInterfaceBlock),
220       precision(EbpUndefined),
221       qualifier(qualifierIn),
222       invariant(false),
223       memoryQualifier(TMemoryQualifier::Create()),
224       layoutQualifier(layoutQualifierIn),
225       primarySize(1),
226       secondarySize(1),
227       mArraySizes(nullptr),
228       mInterfaceBlock(interfaceBlockIn),
229       mStructure(0),
230       mIsStructSpecifier(false),
231       mMangledName(nullptr)
232 {}
233 
TType(const TType & t)234 TType::TType(const TType &t)
235     : type(t.type),
236       precision(t.precision),
237       qualifier(t.qualifier),
238       invariant(t.invariant),
239       memoryQualifier(t.memoryQualifier),
240       layoutQualifier(t.layoutQualifier),
241       primarySize(t.primarySize),
242       secondarySize(t.secondarySize),
243       mArraySizes(t.mArraySizes ? new TVector<unsigned int>(*t.mArraySizes) : nullptr),
244       mInterfaceBlock(t.mInterfaceBlock),
245       mStructure(t.mStructure),
246       mIsStructSpecifier(t.mIsStructSpecifier),
247       mMangledName(t.mMangledName)
248 {}
249 
operator =(const TType & t)250 TType &TType::operator=(const TType &t)
251 {
252     type               = t.type;
253     precision          = t.precision;
254     qualifier          = t.qualifier;
255     invariant          = t.invariant;
256     memoryQualifier    = t.memoryQualifier;
257     layoutQualifier    = t.layoutQualifier;
258     primarySize        = t.primarySize;
259     secondarySize      = t.secondarySize;
260     mArraySizes        = t.mArraySizes ? new TVector<unsigned int>(*t.mArraySizes) : nullptr;
261     mInterfaceBlock    = t.mInterfaceBlock;
262     mStructure         = t.mStructure;
263     mIsStructSpecifier = t.mIsStructSpecifier;
264     mMangledName       = t.mMangledName;
265     return *this;
266 }
267 
canBeConstructed() const268 bool TType::canBeConstructed() const
269 {
270     switch (type)
271     {
272         case EbtFloat:
273         case EbtInt:
274         case EbtUInt:
275         case EbtBool:
276         case EbtStruct:
277             return true;
278         default:
279             return false;
280     }
281 }
282 
getBuiltInTypeNameString() const283 const char *TType::getBuiltInTypeNameString() const
284 {
285     if (isMatrix())
286     {
287         switch (getCols())
288         {
289             case 2:
290                 switch (getRows())
291                 {
292                     case 2:
293                         return "mat2";
294                     case 3:
295                         return "mat2x3";
296                     case 4:
297                         return "mat2x4";
298                     default:
299                         UNREACHABLE();
300                         return nullptr;
301                 }
302             case 3:
303                 switch (getRows())
304                 {
305                     case 2:
306                         return "mat3x2";
307                     case 3:
308                         return "mat3";
309                     case 4:
310                         return "mat3x4";
311                     default:
312                         UNREACHABLE();
313                         return nullptr;
314                 }
315             case 4:
316                 switch (getRows())
317                 {
318                     case 2:
319                         return "mat4x2";
320                     case 3:
321                         return "mat4x3";
322                     case 4:
323                         return "mat4";
324                     default:
325                         UNREACHABLE();
326                         return nullptr;
327                 }
328             default:
329                 UNREACHABLE();
330                 return nullptr;
331         }
332     }
333     if (isVector())
334     {
335         switch (getBasicType())
336         {
337             case EbtFloat:
338                 switch (getNominalSize())
339                 {
340                     case 2:
341                         return "vec2";
342                     case 3:
343                         return "vec3";
344                     case 4:
345                         return "vec4";
346                     default:
347                         UNREACHABLE();
348                         return nullptr;
349                 }
350             case EbtInt:
351                 switch (getNominalSize())
352                 {
353                     case 2:
354                         return "ivec2";
355                     case 3:
356                         return "ivec3";
357                     case 4:
358                         return "ivec4";
359                     default:
360                         UNREACHABLE();
361                         return nullptr;
362                 }
363             case EbtBool:
364                 switch (getNominalSize())
365                 {
366                     case 2:
367                         return "bvec2";
368                     case 3:
369                         return "bvec3";
370                     case 4:
371                         return "bvec4";
372                     default:
373                         UNREACHABLE();
374                         return nullptr;
375                 }
376             case EbtUInt:
377                 switch (getNominalSize())
378                 {
379                     case 2:
380                         return "uvec2";
381                     case 3:
382                         return "uvec3";
383                     case 4:
384                         return "uvec4";
385                     default:
386                         UNREACHABLE();
387                         return nullptr;
388                 }
389             default:
390                 UNREACHABLE();
391                 return nullptr;
392         }
393     }
394     ASSERT(getBasicType() != EbtStruct);
395     ASSERT(getBasicType() != EbtInterfaceBlock);
396     return getBasicString();
397 }
398 
getDeepestStructNesting() const399 int TType::getDeepestStructNesting() const
400 {
401     return mStructure ? mStructure->deepestNesting() : 0;
402 }
403 
isNamelessStruct() const404 bool TType::isNamelessStruct() const
405 {
406     return mStructure && mStructure->symbolType() == SymbolType::Empty;
407 }
408 
isStructureContainingArrays() const409 bool TType::isStructureContainingArrays() const
410 {
411     return mStructure ? mStructure->containsArrays() : false;
412 }
413 
isStructureContainingMatrices() const414 bool TType::isStructureContainingMatrices() const
415 {
416     return mStructure ? mStructure->containsMatrices() : false;
417 }
418 
isStructureContainingType(TBasicType t) const419 bool TType::isStructureContainingType(TBasicType t) const
420 {
421     return mStructure ? mStructure->containsType(t) : false;
422 }
423 
isStructureContainingSamplers() const424 bool TType::isStructureContainingSamplers() const
425 {
426     return mStructure ? mStructure->containsSamplers() : false;
427 }
428 
canReplaceWithConstantUnion() const429 bool TType::canReplaceWithConstantUnion() const
430 {
431     if (isArray())
432     {
433         return false;
434     }
435     if (!mStructure)
436     {
437         return true;
438     }
439     if (isStructureContainingArrays())
440     {
441         return false;
442     }
443     if (getObjectSize() > 16)
444     {
445         return false;
446     }
447     return true;
448 }
449 
450 //
451 // Recursively generate mangled names.
452 //
buildMangledName() const453 const char *TType::buildMangledName() const
454 {
455     TString mangledName(1, GetSizeMangledName(primarySize, secondarySize));
456 
457     TBasicMangledName typeName(type);
458     char *basicMangledName = typeName.getName();
459     static_assert(TBasicMangledName::mangledNameSize == 2, "Mangled name size is not 2");
460     if (basicMangledName[0] != '{')
461     {
462         mangledName += basicMangledName[0];
463         mangledName += basicMangledName[1];
464     }
465     else
466     {
467         ASSERT(type == EbtStruct || type == EbtInterfaceBlock);
468         switch (type)
469         {
470             case EbtStruct:
471                 mangledName += "{s";
472                 if (mStructure->symbolType() != SymbolType::Empty)
473                 {
474                     mangledName += mStructure->name().data();
475                 }
476                 mangledName += mStructure->mangledFieldList();
477                 mangledName += '}';
478                 break;
479             case EbtInterfaceBlock:
480                 mangledName += "{i";
481                 mangledName += mInterfaceBlock->name().data();
482                 mangledName += mInterfaceBlock->mangledFieldList();
483                 mangledName += '}';
484                 break;
485             default:
486                 UNREACHABLE();
487                 break;
488         }
489     }
490 
491     if (mArraySizes)
492     {
493         for (unsigned int arraySize : *mArraySizes)
494         {
495             char buf[20];
496             snprintf(buf, sizeof(buf), "%d", arraySize);
497             mangledName += '[';
498             mangledName += buf;
499             mangledName += ']';
500         }
501     }
502 
503     // Copy string contents into a pool-allocated buffer, so we never need to call delete.
504     return AllocatePoolCharArray(mangledName.c_str(), mangledName.size());
505 }
506 
getObjectSize() const507 size_t TType::getObjectSize() const
508 {
509     size_t totalSize;
510 
511     if (getBasicType() == EbtStruct)
512         totalSize = mStructure->objectSize();
513     else
514         totalSize = primarySize * secondarySize;
515 
516     if (totalSize == 0)
517         return 0;
518 
519     if (mArraySizes)
520     {
521         for (size_t arraySize : *mArraySizes)
522         {
523             if (arraySize > INT_MAX / totalSize)
524                 totalSize = INT_MAX;
525             else
526                 totalSize *= arraySize;
527         }
528     }
529 
530     return totalSize;
531 }
532 
getLocationCount() const533 int TType::getLocationCount() const
534 {
535     int count = 1;
536 
537     if (getBasicType() == EbtStruct)
538     {
539         count = mStructure->getLocationCount();
540     }
541 
542     if (count == 0)
543     {
544         return 0;
545     }
546 
547     if (mArraySizes)
548     {
549         for (unsigned int arraySize : *mArraySizes)
550         {
551             if (arraySize > static_cast<unsigned int>(std::numeric_limits<int>::max() / count))
552             {
553                 count = std::numeric_limits<int>::max();
554             }
555             else
556             {
557                 count *= static_cast<int>(arraySize);
558             }
559         }
560     }
561 
562     return count;
563 }
564 
getArraySizeProduct() const565 unsigned int TType::getArraySizeProduct() const
566 {
567     if (!mArraySizes)
568         return 1u;
569 
570     unsigned int product = 1u;
571 
572     for (unsigned int arraySize : *mArraySizes)
573     {
574         product *= arraySize;
575     }
576     return product;
577 }
578 
isUnsizedArray() const579 bool TType::isUnsizedArray() const
580 {
581     if (!mArraySizes)
582         return false;
583 
584     for (unsigned int arraySize : *mArraySizes)
585     {
586         if (arraySize == 0u)
587         {
588             return true;
589         }
590     }
591     return false;
592 }
593 
sameNonArrayType(const TType & right) const594 bool TType::sameNonArrayType(const TType &right) const
595 {
596     return (type == right.type && primarySize == right.primarySize &&
597             secondarySize == right.secondarySize && mStructure == right.mStructure);
598 }
599 
isElementTypeOf(const TType & arrayType) const600 bool TType::isElementTypeOf(const TType &arrayType) const
601 {
602     if (!sameNonArrayType(arrayType))
603     {
604         return false;
605     }
606     if (arrayType.getNumArraySizes() != getNumArraySizes() + 1u)
607     {
608         return false;
609     }
610     if (isArray())
611     {
612         for (size_t i = 0; i < mArraySizes->size(); ++i)
613         {
614             if ((*mArraySizes)[i] != (*arrayType.mArraySizes)[i])
615             {
616                 return false;
617             }
618         }
619     }
620     return true;
621 }
622 
sizeUnsizedArrays(const TVector<unsigned int> * newArraySizes)623 void TType::sizeUnsizedArrays(const TVector<unsigned int> *newArraySizes)
624 {
625     size_t newArraySizesSize = newArraySizes ? newArraySizes->size() : 0;
626     for (size_t i = 0u; i < getNumArraySizes(); ++i)
627     {
628         if ((*mArraySizes)[i] == 0)
629         {
630             if (i < newArraySizesSize)
631             {
632                 ASSERT(newArraySizes != nullptr);
633                 (*mArraySizes)[i] = (*newArraySizes)[i];
634             }
635             else
636             {
637                 (*mArraySizes)[i] = 1u;
638             }
639         }
640     }
641     invalidateMangledName();
642 }
643 
sizeOutermostUnsizedArray(unsigned int arraySize)644 void TType::sizeOutermostUnsizedArray(unsigned int arraySize)
645 {
646     ASSERT(isArray());
647     ASSERT(mArraySizes->back() == 0u);
648     mArraySizes->back() = arraySize;
649 }
650 
setBasicType(TBasicType t)651 void TType::setBasicType(TBasicType t)
652 {
653     if (type != t)
654     {
655         type = t;
656         invalidateMangledName();
657     }
658 }
659 
setPrimarySize(unsigned char ps)660 void TType::setPrimarySize(unsigned char ps)
661 {
662     if (primarySize != ps)
663     {
664         ASSERT(ps <= 4);
665         primarySize = ps;
666         invalidateMangledName();
667     }
668 }
669 
setSecondarySize(unsigned char ss)670 void TType::setSecondarySize(unsigned char ss)
671 {
672     if (secondarySize != ss)
673     {
674         ASSERT(ss <= 4);
675         secondarySize = ss;
676         invalidateMangledName();
677     }
678 }
679 
makeArray(unsigned int s)680 void TType::makeArray(unsigned int s)
681 {
682     if (!mArraySizes)
683         mArraySizes = new TVector<unsigned int>();
684 
685     mArraySizes->push_back(s);
686     invalidateMangledName();
687 }
688 
makeArrays(const TVector<unsigned int> & sizes)689 void TType::makeArrays(const TVector<unsigned int> &sizes)
690 {
691     if (!mArraySizes)
692         mArraySizes = new TVector<unsigned int>();
693 
694     mArraySizes->insert(mArraySizes->end(), sizes.begin(), sizes.end());
695     invalidateMangledName();
696 }
697 
setArraySize(size_t arrayDimension,unsigned int s)698 void TType::setArraySize(size_t arrayDimension, unsigned int s)
699 {
700     ASSERT(mArraySizes != nullptr);
701     ASSERT(arrayDimension < mArraySizes->size());
702     if (mArraySizes->at(arrayDimension) != s)
703     {
704         (*mArraySizes)[arrayDimension] = s;
705         invalidateMangledName();
706     }
707 }
708 
toArrayElementType()709 void TType::toArrayElementType()
710 {
711     ASSERT(mArraySizes != nullptr);
712     if (mArraySizes->size() > 0)
713     {
714         mArraySizes->pop_back();
715         invalidateMangledName();
716     }
717 }
718 
setInterfaceBlock(const TInterfaceBlock * interfaceBlockIn)719 void TType::setInterfaceBlock(const TInterfaceBlock *interfaceBlockIn)
720 {
721     if (mInterfaceBlock != interfaceBlockIn)
722     {
723         mInterfaceBlock = interfaceBlockIn;
724         invalidateMangledName();
725     }
726 }
727 
getMangledName() const728 const char *TType::getMangledName() const
729 {
730     if (mMangledName == nullptr)
731     {
732         mMangledName = buildMangledName();
733     }
734 
735     return mMangledName;
736 }
737 
realize()738 void TType::realize()
739 {
740     getMangledName();
741 }
742 
invalidateMangledName()743 void TType::invalidateMangledName()
744 {
745     mMangledName = nullptr;
746 }
747 
createSamplerSymbols(const ImmutableString & namePrefix,const TString & apiNamePrefix,TVector<const TVariable * > * outputSymbols,TMap<const TVariable *,TString> * outputSymbolsToAPINames,TSymbolTable * symbolTable) const748 void TType::createSamplerSymbols(const ImmutableString &namePrefix,
749                                  const TString &apiNamePrefix,
750                                  TVector<const TVariable *> *outputSymbols,
751                                  TMap<const TVariable *, TString> *outputSymbolsToAPINames,
752                                  TSymbolTable *symbolTable) const
753 {
754     if (isStructureContainingSamplers())
755     {
756         if (isArray())
757         {
758             TType elementType(*this);
759             elementType.toArrayElementType();
760             for (unsigned int arrayIndex = 0u; arrayIndex < getOutermostArraySize(); ++arrayIndex)
761             {
762                 std::stringstream elementName = sh::InitializeStream<std::stringstream>();
763                 elementName << namePrefix << "_" << arrayIndex;
764                 TStringStream elementApiName;
765                 elementApiName << apiNamePrefix << "[" << arrayIndex << "]";
766                 elementType.createSamplerSymbols(ImmutableString(elementName.str()),
767                                                  elementApiName.str(), outputSymbols,
768                                                  outputSymbolsToAPINames, symbolTable);
769             }
770         }
771         else
772         {
773             mStructure->createSamplerSymbols(namePrefix.data(), apiNamePrefix, outputSymbols,
774                                              outputSymbolsToAPINames, symbolTable);
775         }
776         return;
777     }
778 
779     ASSERT(IsSampler(type));
780     TVariable *variable =
781         new TVariable(symbolTable, namePrefix, new TType(*this), SymbolType::AngleInternal);
782     outputSymbols->push_back(variable);
783     if (outputSymbolsToAPINames)
784     {
785         (*outputSymbolsToAPINames)[variable] = apiNamePrefix;
786     }
787 }
788 
TFieldListCollection(const TFieldList * fields)789 TFieldListCollection::TFieldListCollection(const TFieldList *fields)
790     : mFields(fields), mObjectSize(0), mDeepestNesting(0)
791 {}
792 
containsArrays() const793 bool TFieldListCollection::containsArrays() const
794 {
795     for (const auto *field : *mFields)
796     {
797         const TType *fieldType = field->type();
798         if (fieldType->isArray() || fieldType->isStructureContainingArrays())
799             return true;
800     }
801     return false;
802 }
803 
containsMatrices() const804 bool TFieldListCollection::containsMatrices() const
805 {
806     for (const auto *field : *mFields)
807     {
808         const TType *fieldType = field->type();
809         if (fieldType->isMatrix() || fieldType->isStructureContainingMatrices())
810             return true;
811     }
812     return false;
813 }
814 
containsType(TBasicType type) const815 bool TFieldListCollection::containsType(TBasicType type) const
816 {
817     for (const auto *field : *mFields)
818     {
819         const TType *fieldType = field->type();
820         if (fieldType->getBasicType() == type || fieldType->isStructureContainingType(type))
821             return true;
822     }
823     return false;
824 }
825 
containsSamplers() const826 bool TFieldListCollection::containsSamplers() const
827 {
828     for (const auto *field : *mFields)
829     {
830         const TType *fieldType = field->type();
831         if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
832             return true;
833     }
834     return false;
835 }
836 
buildMangledFieldList() const837 TString TFieldListCollection::buildMangledFieldList() const
838 {
839     TString mangledName;
840     for (const auto *field : *mFields)
841     {
842         mangledName += field->type()->getMangledName();
843     }
844     return mangledName;
845 }
846 
calculateObjectSize() const847 size_t TFieldListCollection::calculateObjectSize() const
848 {
849     size_t size = 0;
850     for (const TField *field : *mFields)
851     {
852         size_t fieldSize = field->type()->getObjectSize();
853         if (fieldSize > INT_MAX - size)
854             size = INT_MAX;
855         else
856             size += fieldSize;
857     }
858     return size;
859 }
860 
objectSize() const861 size_t TFieldListCollection::objectSize() const
862 {
863     if (mObjectSize == 0)
864         mObjectSize = calculateObjectSize();
865     return mObjectSize;
866 }
867 
getLocationCount() const868 int TFieldListCollection::getLocationCount() const
869 {
870     int count = 0;
871     for (const TField *field : *mFields)
872     {
873         int fieldCount = field->type()->getLocationCount();
874         if (fieldCount > std::numeric_limits<int>::max() - count)
875         {
876             count = std::numeric_limits<int>::max();
877         }
878         else
879         {
880             count += fieldCount;
881         }
882     }
883     return count;
884 }
885 
deepestNesting() const886 int TFieldListCollection::deepestNesting() const
887 {
888     if (mDeepestNesting == 0)
889         mDeepestNesting = calculateDeepestNesting();
890     return mDeepestNesting;
891 }
892 
mangledFieldList() const893 const TString &TFieldListCollection::mangledFieldList() const
894 {
895     if (mMangledFieldList.empty())
896         mMangledFieldList = buildMangledFieldList();
897     return mMangledFieldList;
898 }
899 
calculateDeepestNesting() const900 int TFieldListCollection::calculateDeepestNesting() const
901 {
902     int maxNesting = 0;
903     for (size_t i = 0; i < mFields->size(); ++i)
904         maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
905     return 1 + maxNesting;
906 }
907 
908 // TPublicType implementation.
initialize(const TTypeSpecifierNonArray & typeSpecifier,TQualifier q)909 void TPublicType::initialize(const TTypeSpecifierNonArray &typeSpecifier, TQualifier q)
910 {
911     typeSpecifierNonArray = typeSpecifier;
912     layoutQualifier       = TLayoutQualifier::Create();
913     memoryQualifier       = TMemoryQualifier::Create();
914     qualifier             = q;
915     invariant             = false;
916     precision             = EbpUndefined;
917     arraySizes            = nullptr;
918 }
919 
initializeBasicType(TBasicType basicType)920 void TPublicType::initializeBasicType(TBasicType basicType)
921 {
922     typeSpecifierNonArray.type          = basicType;
923     typeSpecifierNonArray.primarySize   = 1;
924     typeSpecifierNonArray.secondarySize = 1;
925     layoutQualifier                     = TLayoutQualifier::Create();
926     memoryQualifier                     = TMemoryQualifier::Create();
927     qualifier                           = EvqTemporary;
928     invariant                           = false;
929     precision                           = EbpUndefined;
930     arraySizes                          = nullptr;
931 }
932 
isStructureContainingArrays() const933 bool TPublicType::isStructureContainingArrays() const
934 {
935     if (!typeSpecifierNonArray.userDef)
936     {
937         return false;
938     }
939 
940     return typeSpecifierNonArray.userDef->containsArrays();
941 }
942 
isStructureContainingType(TBasicType t) const943 bool TPublicType::isStructureContainingType(TBasicType t) const
944 {
945     if (!typeSpecifierNonArray.userDef)
946     {
947         return false;
948     }
949 
950     return typeSpecifierNonArray.userDef->containsType(t);
951 }
952 
setArraySizes(TVector<unsigned int> * sizes)953 void TPublicType::setArraySizes(TVector<unsigned int> *sizes)
954 {
955     arraySizes = sizes;
956 }
957 
isArray() const958 bool TPublicType::isArray() const
959 {
960     return arraySizes && !arraySizes->empty();
961 }
962 
clearArrayness()963 void TPublicType::clearArrayness()
964 {
965     arraySizes = nullptr;
966 }
967 
isAggregate() const968 bool TPublicType::isAggregate() const
969 {
970     return isArray() || typeSpecifierNonArray.isMatrix() || typeSpecifierNonArray.isVector();
971 }
972 
973 }  // namespace sh
974