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