1 //
2 // Copyright (c) 2002-2014 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/InfoSink.h"
13 #include "compiler/translator/IntermNode.h"
14 #include "compiler/translator/SymbolTable.h"
15 
16 #include <algorithm>
17 #include <climits>
18 
19 namespace sh
20 {
21 
getBasicString(TBasicType t)22 const char *getBasicString(TBasicType t)
23 {
24     switch (t)
25     {
26         case EbtVoid:
27             return "void";
28         case EbtFloat:
29             return "float";
30         case EbtInt:
31             return "int";
32         case EbtUInt:
33             return "uint";
34         case EbtBool:
35             return "bool";
36         case EbtYuvCscStandardEXT:
37             return "yuvCscStandardEXT";
38         case EbtSampler2D:
39             return "sampler2D";
40         case EbtSampler3D:
41             return "sampler3D";
42         case EbtSamplerCube:
43             return "samplerCube";
44         case EbtSamplerExternalOES:
45             return "samplerExternalOES";
46         case EbtSamplerExternal2DY2YEXT:
47             return "__samplerExternal2DY2YEXT";
48         case EbtSampler2DRect:
49             return "sampler2DRect";
50         case EbtSampler2DArray:
51             return "sampler2DArray";
52         case EbtSampler2DMS:
53             return "sampler2DMS";
54         case EbtISampler2D:
55             return "isampler2D";
56         case EbtISampler3D:
57             return "isampler3D";
58         case EbtISamplerCube:
59             return "isamplerCube";
60         case EbtISampler2DArray:
61             return "isampler2DArray";
62         case EbtISampler2DMS:
63             return "isampler2DMS";
64         case EbtUSampler2D:
65             return "usampler2D";
66         case EbtUSampler3D:
67             return "usampler3D";
68         case EbtUSamplerCube:
69             return "usamplerCube";
70         case EbtUSampler2DArray:
71             return "usampler2DArray";
72         case EbtUSampler2DMS:
73             return "usampler2DMS";
74         case EbtSampler2DShadow:
75             return "sampler2DShadow";
76         case EbtSamplerCubeShadow:
77             return "samplerCubeShadow";
78         case EbtSampler2DArrayShadow:
79             return "sampler2DArrayShadow";
80         case EbtStruct:
81             return "structure";
82         case EbtInterfaceBlock:
83             return "interface block";
84         case EbtImage2D:
85             return "image2D";
86         case EbtIImage2D:
87             return "iimage2D";
88         case EbtUImage2D:
89             return "uimage2D";
90         case EbtImage3D:
91             return "image3D";
92         case EbtIImage3D:
93             return "iimage3D";
94         case EbtUImage3D:
95             return "uimage3D";
96         case EbtImage2DArray:
97             return "image2DArray";
98         case EbtIImage2DArray:
99             return "iimage2DArray";
100         case EbtUImage2DArray:
101             return "uimage2DArray";
102         case EbtImageCube:
103             return "imageCube";
104         case EbtIImageCube:
105             return "iimageCube";
106         case EbtUImageCube:
107             return "uimageCube";
108         case EbtAtomicCounter:
109             return "atomic_uint";
110         default:
111             UNREACHABLE();
112             return "unknown type";
113     }
114 }
115 
116 // TType implementation.
TType()117 TType::TType()
118     : type(EbtVoid),
119       precision(EbpUndefined),
120       qualifier(EvqGlobal),
121       invariant(false),
122       memoryQualifier(TMemoryQualifier::Create()),
123       layoutQualifier(TLayoutQualifier::Create()),
124       primarySize(0),
125       secondarySize(0),
126       mArraySizes(nullptr),
127       mInterfaceBlock(nullptr),
128       mStructure(nullptr),
129       mIsStructSpecifier(false),
130       mMangledName(nullptr)
131 {
132 }
133 
TType(TBasicType t,unsigned char ps,unsigned char ss)134 TType::TType(TBasicType t, unsigned char ps, unsigned char ss)
135     : type(t),
136       precision(EbpUndefined),
137       qualifier(EvqGlobal),
138       invariant(false),
139       memoryQualifier(TMemoryQualifier::Create()),
140       layoutQualifier(TLayoutQualifier::Create()),
141       primarySize(ps),
142       secondarySize(ss),
143       mArraySizes(nullptr),
144       mInterfaceBlock(nullptr),
145       mStructure(nullptr),
146       mIsStructSpecifier(false),
147       mMangledName(nullptr)
148 {
149 }
150 
TType(TBasicType t,TPrecision p,TQualifier q,unsigned char ps,unsigned char ss)151 TType::TType(TBasicType t, TPrecision p, TQualifier q, unsigned char ps, unsigned char ss)
152     : type(t),
153       precision(p),
154       qualifier(q),
155       invariant(false),
156       memoryQualifier(TMemoryQualifier::Create()),
157       layoutQualifier(TLayoutQualifier::Create()),
158       primarySize(ps),
159       secondarySize(ss),
160       mArraySizes(nullptr),
161       mInterfaceBlock(nullptr),
162       mStructure(nullptr),
163       mIsStructSpecifier(false),
164       mMangledName(nullptr)
165 {
166 }
167 
TType(const TPublicType & p)168 TType::TType(const TPublicType &p)
169     : type(p.getBasicType()),
170       precision(p.precision),
171       qualifier(p.qualifier),
172       invariant(p.invariant),
173       memoryQualifier(p.memoryQualifier),
174       layoutQualifier(p.layoutQualifier),
175       primarySize(p.getPrimarySize()),
176       secondarySize(p.getSecondarySize()),
177       mArraySizes(nullptr),
178       mInterfaceBlock(nullptr),
179       mStructure(nullptr),
180       mIsStructSpecifier(false),
181       mMangledName(nullptr)
182 {
183     ASSERT(primarySize <= 4);
184     ASSERT(secondarySize <= 4);
185     if (p.isArray())
186     {
187         mArraySizes = new TVector<unsigned int>(*p.arraySizes);
188     }
189     if (p.getUserDef())
190     {
191         mStructure         = p.getUserDef();
192         mIsStructSpecifier = p.isStructSpecifier();
193     }
194 }
195 
TType(TStructure * userDef)196 TType::TType(TStructure *userDef)
197     : type(EbtStruct),
198       precision(EbpUndefined),
199       qualifier(EvqTemporary),
200       invariant(false),
201       memoryQualifier(TMemoryQualifier::Create()),
202       layoutQualifier(TLayoutQualifier::Create()),
203       primarySize(1),
204       secondarySize(1),
205       mArraySizes(nullptr),
206       mInterfaceBlock(nullptr),
207       mStructure(userDef),
208       mIsStructSpecifier(false),
209       mMangledName(nullptr)
210 {
211 }
212 
TType(TInterfaceBlock * interfaceBlockIn,TQualifier qualifierIn,TLayoutQualifier layoutQualifierIn)213 TType::TType(TInterfaceBlock *interfaceBlockIn,
214              TQualifier qualifierIn,
215              TLayoutQualifier layoutQualifierIn)
216     : type(EbtInterfaceBlock),
217       precision(EbpUndefined),
218       qualifier(qualifierIn),
219       invariant(false),
220       memoryQualifier(TMemoryQualifier::Create()),
221       layoutQualifier(layoutQualifierIn),
222       primarySize(1),
223       secondarySize(1),
224       mArraySizes(nullptr),
225       mInterfaceBlock(interfaceBlockIn),
226       mStructure(0),
227       mIsStructSpecifier(false),
228       mMangledName(nullptr)
229 {
230 }
231 
TType(const TType & t)232 TType::TType(const TType &t)
233     : type(t.type),
234       precision(t.precision),
235       qualifier(t.qualifier),
236       invariant(t.invariant),
237       memoryQualifier(t.memoryQualifier),
238       layoutQualifier(t.layoutQualifier),
239       primarySize(t.primarySize),
240       secondarySize(t.secondarySize),
241       mArraySizes(t.mArraySizes ? new TVector<unsigned int>(*t.mArraySizes) : nullptr),
242       mInterfaceBlock(t.mInterfaceBlock),
243       mStructure(t.mStructure),
244       mIsStructSpecifier(t.mIsStructSpecifier),
245       mMangledName(t.mMangledName)
246 {
247 }
248 
operator =(const TType & t)249 TType &TType::operator=(const TType &t)
250 {
251     type               = t.type;
252     precision          = t.precision;
253     qualifier          = t.qualifier;
254     invariant          = t.invariant;
255     memoryQualifier    = t.memoryQualifier;
256     layoutQualifier    = t.layoutQualifier;
257     primarySize        = t.primarySize;
258     secondarySize      = t.secondarySize;
259     mArraySizes        = t.mArraySizes ? new TVector<unsigned int>(*t.mArraySizes) : nullptr;
260     mInterfaceBlock    = t.mInterfaceBlock;
261     mStructure         = t.mStructure;
262     mIsStructSpecifier = t.mIsStructSpecifier;
263     mMangledName       = t.mMangledName;
264     return *this;
265 }
266 
canBeConstructed() const267 bool TType::canBeConstructed() const
268 {
269     switch (type)
270     {
271         case EbtFloat:
272         case EbtInt:
273         case EbtUInt:
274         case EbtBool:
275         case EbtStruct:
276             return true;
277         default:
278             return false;
279     }
280 }
281 
getBuiltInTypeNameString() const282 const char *TType::getBuiltInTypeNameString() const
283 {
284     if (isMatrix())
285     {
286         switch (getCols())
287         {
288             case 2:
289                 switch (getRows())
290                 {
291                     case 2:
292                         return "mat2";
293                     case 3:
294                         return "mat2x3";
295                     case 4:
296                         return "mat2x4";
297                     default:
298                         UNREACHABLE();
299                         return nullptr;
300                 }
301             case 3:
302                 switch (getRows())
303                 {
304                     case 2:
305                         return "mat3x2";
306                     case 3:
307                         return "mat3";
308                     case 4:
309                         return "mat3x4";
310                     default:
311                         UNREACHABLE();
312                         return nullptr;
313                 }
314             case 4:
315                 switch (getRows())
316                 {
317                     case 2:
318                         return "mat4x2";
319                     case 3:
320                         return "mat4x3";
321                     case 4:
322                         return "mat4";
323                     default:
324                         UNREACHABLE();
325                         return nullptr;
326                 }
327             default:
328                 UNREACHABLE();
329                 return nullptr;
330         }
331     }
332     if (isVector())
333     {
334         switch (getBasicType())
335         {
336             case EbtFloat:
337                 switch (getNominalSize())
338                 {
339                     case 2:
340                         return "vec2";
341                     case 3:
342                         return "vec3";
343                     case 4:
344                         return "vec4";
345                     default:
346                         UNREACHABLE();
347                         return nullptr;
348                 }
349             case EbtInt:
350                 switch (getNominalSize())
351                 {
352                     case 2:
353                         return "ivec2";
354                     case 3:
355                         return "ivec3";
356                     case 4:
357                         return "ivec4";
358                     default:
359                         UNREACHABLE();
360                         return nullptr;
361                 }
362             case EbtBool:
363                 switch (getNominalSize())
364                 {
365                     case 2:
366                         return "bvec2";
367                     case 3:
368                         return "bvec3";
369                     case 4:
370                         return "bvec4";
371                     default:
372                         UNREACHABLE();
373                         return nullptr;
374                 }
375             case EbtUInt:
376                 switch (getNominalSize())
377                 {
378                     case 2:
379                         return "uvec2";
380                     case 3:
381                         return "uvec3";
382                     case 4:
383                         return "uvec4";
384                     default:
385                         UNREACHABLE();
386                         return nullptr;
387                 }
388             default:
389                 UNREACHABLE();
390                 return nullptr;
391         }
392     }
393     ASSERT(getBasicType() != EbtStruct);
394     ASSERT(getBasicType() != EbtInterfaceBlock);
395     return getBasicString();
396 }
397 
getCompleteString() const398 TString TType::getCompleteString() const
399 {
400     TStringStream stream;
401 
402     if (invariant)
403         stream << "invariant ";
404     if (qualifier != EvqTemporary && qualifier != EvqGlobal)
405         stream << getQualifierString() << " ";
406     if (precision != EbpUndefined)
407         stream << getPrecisionString() << " ";
408     if (mArraySizes)
409     {
410         for (auto arraySizeIter = mArraySizes->rbegin(); arraySizeIter != mArraySizes->rend();
411              ++arraySizeIter)
412         {
413             stream << "array[" << (*arraySizeIter) << "] of ";
414         }
415     }
416     if (isMatrix())
417         stream << getCols() << "X" << getRows() << " matrix of ";
418     else if (isVector())
419         stream << getNominalSize() << "-component vector of ";
420 
421     stream << getBasicString();
422     return stream.str();
423 }
424 
425 //
426 // Recursively generate mangled names.
427 //
buildMangledName() const428 const char *TType::buildMangledName() const
429 {
430     TString mangledName;
431     if (isMatrix())
432         mangledName += 'm';
433     else if (isVector())
434         mangledName += 'v';
435 
436     switch (type)
437     {
438         case EbtFloat:
439             mangledName += 'f';
440             break;
441         case EbtInt:
442             mangledName += 'i';
443             break;
444         case EbtUInt:
445             mangledName += 'u';
446             break;
447         case EbtBool:
448             mangledName += 'b';
449             break;
450         case EbtYuvCscStandardEXT:
451             mangledName += "ycs";
452             break;
453         case EbtSampler2D:
454             mangledName += "s2";
455             break;
456         case EbtSampler3D:
457             mangledName += "s3";
458             break;
459         case EbtSamplerCube:
460             mangledName += "sC";
461             break;
462         case EbtSampler2DArray:
463             mangledName += "s2a";
464             break;
465         case EbtSamplerExternalOES:
466             mangledName += "sext";
467             break;
468         case EbtSamplerExternal2DY2YEXT:
469             mangledName += "sext2y2y";
470             break;
471         case EbtSampler2DRect:
472             mangledName += "s2r";
473             break;
474         case EbtSampler2DMS:
475             mangledName += "s2ms";
476             break;
477         case EbtISampler2D:
478             mangledName += "is2";
479             break;
480         case EbtISampler3D:
481             mangledName += "is3";
482             break;
483         case EbtISamplerCube:
484             mangledName += "isC";
485             break;
486         case EbtISampler2DArray:
487             mangledName += "is2a";
488             break;
489         case EbtISampler2DMS:
490             mangledName += "is2ms";
491             break;
492         case EbtUSampler2D:
493             mangledName += "us2";
494             break;
495         case EbtUSampler3D:
496             mangledName += "us3";
497             break;
498         case EbtUSamplerCube:
499             mangledName += "usC";
500             break;
501         case EbtUSampler2DArray:
502             mangledName += "us2a";
503             break;
504         case EbtUSampler2DMS:
505             mangledName += "us2ms";
506             break;
507         case EbtSampler2DShadow:
508             mangledName += "s2s";
509             break;
510         case EbtSamplerCubeShadow:
511             mangledName += "sCs";
512             break;
513         case EbtSampler2DArrayShadow:
514             mangledName += "s2as";
515             break;
516         case EbtImage2D:
517             mangledName += "im2";
518             break;
519         case EbtIImage2D:
520             mangledName += "iim2";
521             break;
522         case EbtUImage2D:
523             mangledName += "uim2";
524             break;
525         case EbtImage3D:
526             mangledName += "im3";
527             break;
528         case EbtIImage3D:
529             mangledName += "iim3";
530             break;
531         case EbtUImage3D:
532             mangledName += "uim3";
533             break;
534         case EbtImage2DArray:
535             mangledName += "im2a";
536             break;
537         case EbtIImage2DArray:
538             mangledName += "iim2a";
539             break;
540         case EbtUImage2DArray:
541             mangledName += "uim2a";
542             break;
543         case EbtImageCube:
544             mangledName += "imc";
545             break;
546         case EbtIImageCube:
547             mangledName += "iimc";
548             break;
549         case EbtUImageCube:
550             mangledName += "uimc";
551             break;
552         case EbtAtomicCounter:
553             mangledName += "ac";
554             break;
555         case EbtStruct:
556             mangledName += mStructure->mangledName();
557             break;
558         case EbtInterfaceBlock:
559             mangledName += mInterfaceBlock->mangledName();
560             break;
561         default:
562             // EbtVoid, EbtAddress and non types
563             break;
564     }
565 
566     if (isMatrix())
567     {
568         mangledName += static_cast<char>('0' + getCols());
569         mangledName += static_cast<char>('x');
570         mangledName += static_cast<char>('0' + getRows());
571     }
572     else
573     {
574         mangledName += static_cast<char>('0' + getNominalSize());
575     }
576 
577     if (mArraySizes)
578     {
579         for (unsigned int arraySize : *mArraySizes)
580         {
581             char buf[20];
582             snprintf(buf, sizeof(buf), "%d", arraySize);
583             mangledName += '[';
584             mangledName += buf;
585             mangledName += ']';
586         }
587     }
588 
589     mangledName += ';';
590 
591     // Copy string contents into a pool-allocated buffer, so we never need to call delete.
592     size_t requiredSize = mangledName.size() + 1;
593     char *buffer = reinterpret_cast<char *>(GetGlobalPoolAllocator()->allocate(requiredSize));
594     memcpy(buffer, mangledName.c_str(), requiredSize);
595     return buffer;
596 }
597 
getObjectSize() const598 size_t TType::getObjectSize() const
599 {
600     size_t totalSize;
601 
602     if (getBasicType() == EbtStruct)
603         totalSize = mStructure->objectSize();
604     else
605         totalSize = primarySize * secondarySize;
606 
607     if (totalSize == 0)
608         return 0;
609 
610     if (mArraySizes)
611     {
612         for (size_t arraySize : *mArraySizes)
613         {
614             if (arraySize > INT_MAX / totalSize)
615                 totalSize = INT_MAX;
616             else
617                 totalSize *= arraySize;
618         }
619     }
620 
621     return totalSize;
622 }
623 
getLocationCount() const624 int TType::getLocationCount() const
625 {
626     int count = 1;
627 
628     if (getBasicType() == EbtStruct)
629     {
630         count = mStructure->getLocationCount();
631     }
632 
633     if (count == 0)
634     {
635         return 0;
636     }
637 
638     if (mArraySizes)
639     {
640         for (unsigned int arraySize : *mArraySizes)
641         {
642             if (arraySize > static_cast<unsigned int>(std::numeric_limits<int>::max() / count))
643             {
644                 count = std::numeric_limits<int>::max();
645             }
646             else
647             {
648                 count *= static_cast<int>(arraySize);
649             }
650         }
651     }
652 
653     return count;
654 }
655 
getArraySizeProduct() const656 unsigned int TType::getArraySizeProduct() const
657 {
658     if (!mArraySizes)
659         return 1u;
660 
661     unsigned int product = 1u;
662 
663     for (unsigned int arraySize : *mArraySizes)
664     {
665         product *= arraySize;
666     }
667     return product;
668 }
669 
isUnsizedArray() const670 bool TType::isUnsizedArray() const
671 {
672     if (!mArraySizes)
673         return false;
674 
675     for (unsigned int arraySize : *mArraySizes)
676     {
677         if (arraySize == 0u)
678         {
679             return true;
680         }
681     }
682     return false;
683 }
684 
sameNonArrayType(const TType & right) const685 bool TType::sameNonArrayType(const TType &right) const
686 {
687     return (type == right.type && primarySize == right.primarySize &&
688             secondarySize == right.secondarySize && mStructure == right.mStructure);
689 }
690 
isElementTypeOf(const TType & arrayType) const691 bool TType::isElementTypeOf(const TType &arrayType) const
692 {
693     if (!sameNonArrayType(arrayType))
694     {
695         return false;
696     }
697     if (arrayType.getNumArraySizes() != getNumArraySizes() + 1u)
698     {
699         return false;
700     }
701     if (isArray())
702     {
703         for (size_t i = 0; i < mArraySizes->size(); ++i)
704         {
705             if ((*mArraySizes)[i] != (*arrayType.mArraySizes)[i])
706             {
707                 return false;
708             }
709         }
710     }
711     return true;
712 }
713 
sizeUnsizedArrays(const TVector<unsigned int> * newArraySizes)714 void TType::sizeUnsizedArrays(const TVector<unsigned int> *newArraySizes)
715 {
716     size_t newArraySizesSize = newArraySizes ? newArraySizes->size() : 0;
717     for (size_t i = 0u; i < getNumArraySizes(); ++i)
718     {
719         if ((*mArraySizes)[i] == 0)
720         {
721             if (i < newArraySizesSize)
722             {
723                 ASSERT(newArraySizes != nullptr);
724                 (*mArraySizes)[i] = (*newArraySizes)[i];
725             }
726             else
727             {
728                 (*mArraySizes)[i] = 1u;
729             }
730         }
731     }
732     invalidateMangledName();
733 }
734 
sizeOutermostUnsizedArray(unsigned int arraySize)735 void TType::sizeOutermostUnsizedArray(unsigned int arraySize)
736 {
737     ASSERT(isArray());
738     ASSERT(mArraySizes->back() == 0u);
739     mArraySizes->back() = arraySize;
740 }
741 
setBasicType(TBasicType t)742 void TType::setBasicType(TBasicType t)
743 {
744     if (type != t)
745     {
746         type = t;
747         invalidateMangledName();
748     }
749 }
750 
setPrimarySize(unsigned char ps)751 void TType::setPrimarySize(unsigned char ps)
752 {
753     if (primarySize != ps)
754     {
755         ASSERT(ps <= 4);
756         primarySize = ps;
757         invalidateMangledName();
758     }
759 }
760 
setSecondarySize(unsigned char ss)761 void TType::setSecondarySize(unsigned char ss)
762 {
763     if (secondarySize != ss)
764     {
765         ASSERT(ss <= 4);
766         secondarySize = ss;
767         invalidateMangledName();
768     }
769 }
770 
makeArray(unsigned int s)771 void TType::makeArray(unsigned int s)
772 {
773     if (!mArraySizes)
774         mArraySizes = new TVector<unsigned int>();
775 
776     mArraySizes->push_back(s);
777     invalidateMangledName();
778 }
779 
makeArrays(const TVector<unsigned int> & sizes)780 void TType::makeArrays(const TVector<unsigned int> &sizes)
781 {
782     if (!mArraySizes)
783         mArraySizes = new TVector<unsigned int>();
784 
785     mArraySizes->insert(mArraySizes->end(), sizes.begin(), sizes.end());
786     invalidateMangledName();
787 }
788 
setArraySize(size_t arrayDimension,unsigned int s)789 void TType::setArraySize(size_t arrayDimension, unsigned int s)
790 {
791     ASSERT(mArraySizes != nullptr);
792     ASSERT(arrayDimension < mArraySizes->size());
793     if (mArraySizes->at(arrayDimension) != s)
794     {
795         (*mArraySizes)[arrayDimension] = s;
796         invalidateMangledName();
797     }
798 }
799 
toArrayElementType()800 void TType::toArrayElementType()
801 {
802     ASSERT(mArraySizes != nullptr);
803     if (mArraySizes->size() > 0)
804     {
805         mArraySizes->pop_back();
806         invalidateMangledName();
807     }
808 }
809 
setInterfaceBlock(TInterfaceBlock * interfaceBlockIn)810 void TType::setInterfaceBlock(TInterfaceBlock *interfaceBlockIn)
811 {
812     if (mInterfaceBlock != interfaceBlockIn)
813     {
814         mInterfaceBlock = interfaceBlockIn;
815         invalidateMangledName();
816     }
817 }
818 
setStruct(TStructure * s)819 void TType::setStruct(TStructure *s)
820 {
821     if (mStructure != s)
822     {
823         mStructure = s;
824         invalidateMangledName();
825     }
826 }
827 
getMangledName() const828 const char *TType::getMangledName() const
829 {
830     if (mMangledName == nullptr)
831     {
832         mMangledName = buildMangledName();
833     }
834 
835     return mMangledName;
836 }
837 
realize()838 void TType::realize()
839 {
840     getMangledName();
841 }
842 
invalidateMangledName()843 void TType::invalidateMangledName()
844 {
845     mMangledName = nullptr;
846 }
847 
848 // TStructure implementation.
TStructure(TSymbolTable * symbolTable,const TString * name,TFieldList * fields)849 TStructure::TStructure(TSymbolTable *symbolTable, const TString *name, TFieldList *fields)
850     : TFieldListCollection(name, fields),
851       mDeepestNesting(0),
852       mUniqueId(symbolTable->nextUniqueId()),
853       mAtGlobalScope(false)
854 {
855 }
856 
equals(const TStructure & other) const857 bool TStructure::equals(const TStructure &other) const
858 {
859     return (uniqueId() == other.uniqueId());
860 }
861 
containsArrays() const862 bool TStructure::containsArrays() const
863 {
864     for (size_t i = 0; i < mFields->size(); ++i)
865     {
866         const TType *fieldType = (*mFields)[i]->type();
867         if (fieldType->isArray() || fieldType->isStructureContainingArrays())
868             return true;
869     }
870     return false;
871 }
872 
containsType(TBasicType type) const873 bool TStructure::containsType(TBasicType type) const
874 {
875     for (size_t i = 0; i < mFields->size(); ++i)
876     {
877         const TType *fieldType = (*mFields)[i]->type();
878         if (fieldType->getBasicType() == type || fieldType->isStructureContainingType(type))
879             return true;
880     }
881     return false;
882 }
883 
containsSamplers() const884 bool TStructure::containsSamplers() const
885 {
886     for (size_t i = 0; i < mFields->size(); ++i)
887     {
888         const TType *fieldType = (*mFields)[i]->type();
889         if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
890             return true;
891     }
892     return false;
893 }
894 
createSamplerSymbols(const TString & namePrefix,const TString & apiNamePrefix,TVector<TIntermSymbol * > * outputSymbols,TMap<TIntermSymbol *,TString> * outputSymbolsToAPINames,TSymbolTable * symbolTable) const895 void TType::createSamplerSymbols(const TString &namePrefix,
896                                  const TString &apiNamePrefix,
897                                  TVector<TIntermSymbol *> *outputSymbols,
898                                  TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames,
899                                  TSymbolTable *symbolTable) const
900 {
901     if (isStructureContainingSamplers())
902     {
903         if (isArray())
904         {
905             TType elementType(*this);
906             elementType.toArrayElementType();
907             for (unsigned int arrayIndex = 0u; arrayIndex < getOutermostArraySize(); ++arrayIndex)
908             {
909                 TStringStream elementName;
910                 elementName << namePrefix << "_" << arrayIndex;
911                 TStringStream elementApiName;
912                 elementApiName << apiNamePrefix << "[" << arrayIndex << "]";
913                 elementType.createSamplerSymbols(elementName.str(), elementApiName.str(),
914                                                  outputSymbols, outputSymbolsToAPINames,
915                                                  symbolTable);
916             }
917         }
918         else
919         {
920             mStructure->createSamplerSymbols(namePrefix, apiNamePrefix, outputSymbols,
921                                              outputSymbolsToAPINames, symbolTable);
922         }
923         return;
924     }
925 
926     ASSERT(IsSampler(type));
927     TIntermSymbol *symbol = new TIntermSymbol(symbolTable->nextUniqueId(), namePrefix, *this);
928     outputSymbols->push_back(symbol);
929     if (outputSymbolsToAPINames)
930     {
931         (*outputSymbolsToAPINames)[symbol] = apiNamePrefix;
932     }
933 }
934 
createSamplerSymbols(const TString & namePrefix,const TString & apiNamePrefix,TVector<TIntermSymbol * > * outputSymbols,TMap<TIntermSymbol *,TString> * outputSymbolsToAPINames,TSymbolTable * symbolTable) const935 void TStructure::createSamplerSymbols(const TString &namePrefix,
936                                       const TString &apiNamePrefix,
937                                       TVector<TIntermSymbol *> *outputSymbols,
938                                       TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames,
939                                       TSymbolTable *symbolTable) const
940 {
941     ASSERT(containsSamplers());
942     for (auto &field : *mFields)
943     {
944         const TType *fieldType = field->type();
945         if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
946         {
947             TString fieldName    = namePrefix + "_" + field->name();
948             TString fieldApiName = apiNamePrefix + "." + field->name();
949             fieldType->createSamplerSymbols(fieldName, fieldApiName, outputSymbols,
950                                             outputSymbolsToAPINames, symbolTable);
951         }
952     }
953 }
954 
buildMangledName(const TString & mangledNamePrefix) const955 TString TFieldListCollection::buildMangledName(const TString &mangledNamePrefix) const
956 {
957     TString mangledName(mangledNamePrefix);
958     mangledName += *mName;
959     for (size_t i = 0; i < mFields->size(); ++i)
960     {
961         mangledName += '-';
962         mangledName += (*mFields)[i]->type()->getMangledName();
963     }
964     return mangledName;
965 }
966 
calculateObjectSize() const967 size_t TFieldListCollection::calculateObjectSize() const
968 {
969     size_t size = 0;
970     for (const TField *field : *mFields)
971     {
972         size_t fieldSize = field->type()->getObjectSize();
973         if (fieldSize > INT_MAX - size)
974             size = INT_MAX;
975         else
976             size += fieldSize;
977     }
978     return size;
979 }
980 
getLocationCount() const981 int TFieldListCollection::getLocationCount() const
982 {
983     int count = 0;
984     for (const TField *field : *mFields)
985     {
986         int fieldCount = field->type()->getLocationCount();
987         if (fieldCount > std::numeric_limits<int>::max() - count)
988         {
989             count = std::numeric_limits<int>::max();
990         }
991         else
992         {
993             count += fieldCount;
994         }
995     }
996     return count;
997 }
998 
calculateDeepestNesting() const999 int TStructure::calculateDeepestNesting() const
1000 {
1001     int maxNesting = 0;
1002     for (size_t i = 0; i < mFields->size(); ++i)
1003         maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
1004     return 1 + maxNesting;
1005 }
1006 
1007 // TPublicType implementation.
initialize(const TTypeSpecifierNonArray & typeSpecifier,TQualifier q)1008 void TPublicType::initialize(const TTypeSpecifierNonArray &typeSpecifier, TQualifier q)
1009 {
1010     typeSpecifierNonArray = typeSpecifier;
1011     layoutQualifier       = TLayoutQualifier::Create();
1012     memoryQualifier       = TMemoryQualifier::Create();
1013     qualifier             = q;
1014     invariant             = false;
1015     precision             = EbpUndefined;
1016     arraySizes            = nullptr;
1017 }
1018 
initializeBasicType(TBasicType basicType)1019 void TPublicType::initializeBasicType(TBasicType basicType)
1020 {
1021     typeSpecifierNonArray.type          = basicType;
1022     typeSpecifierNonArray.primarySize   = 1;
1023     typeSpecifierNonArray.secondarySize = 1;
1024     layoutQualifier                     = TLayoutQualifier::Create();
1025     memoryQualifier                     = TMemoryQualifier::Create();
1026     qualifier                           = EvqTemporary;
1027     invariant                           = false;
1028     precision                           = EbpUndefined;
1029     arraySizes                          = nullptr;
1030 }
1031 
isStructureContainingArrays() const1032 bool TPublicType::isStructureContainingArrays() const
1033 {
1034     if (!typeSpecifierNonArray.userDef)
1035     {
1036         return false;
1037     }
1038 
1039     return typeSpecifierNonArray.userDef->containsArrays();
1040 }
1041 
isStructureContainingType(TBasicType t) const1042 bool TPublicType::isStructureContainingType(TBasicType t) const
1043 {
1044     if (!typeSpecifierNonArray.userDef)
1045     {
1046         return false;
1047     }
1048 
1049     return typeSpecifierNonArray.userDef->containsType(t);
1050 }
1051 
setArraySizes(TVector<unsigned int> * sizes)1052 void TPublicType::setArraySizes(TVector<unsigned int> *sizes)
1053 {
1054     arraySizes = sizes;
1055 }
1056 
isArray() const1057 bool TPublicType::isArray() const
1058 {
1059     return arraySizes && !arraySizes->empty();
1060 }
1061 
clearArrayness()1062 void TPublicType::clearArrayness()
1063 {
1064     arraySizes = nullptr;
1065 }
1066 
isAggregate() const1067 bool TPublicType::isAggregate() const
1068 {
1069     return isArray() || typeSpecifierNonArray.isMatrix() || typeSpecifierNonArray.isVector();
1070 }
1071 
1072 }  // namespace sh
1073