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