1 //
2 // Copyright 2002 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6
7 #if defined(_MSC_VER)
8 # pragma warning(disable : 4718)
9 #endif
10
11 #include "compiler/translator/Types.h"
12 #include "compiler/translator/ImmutableString.h"
13 #include "compiler/translator/InfoSink.h"
14 #include "compiler/translator/IntermNode.h"
15 #include "compiler/translator/SymbolTable.h"
16
17 #include <algorithm>
18 #include <climits>
19
20 namespace sh
21 {
22
getBasicString(TBasicType t)23 const char *getBasicString(TBasicType t)
24 {
25 switch (t)
26 {
27 case EbtVoid:
28 return "void";
29 case EbtFloat:
30 return "float";
31 case EbtInt:
32 return "int";
33 case EbtUInt:
34 return "uint";
35 case EbtBool:
36 return "bool";
37 case EbtYuvCscStandardEXT:
38 return "yuvCscStandardEXT";
39 case EbtSampler2D:
40 return "sampler2D";
41 case EbtSampler3D:
42 return "sampler3D";
43 case EbtSamplerCube:
44 return "samplerCube";
45 case EbtSamplerExternalOES:
46 return "samplerExternalOES";
47 case EbtSamplerExternal2DY2YEXT:
48 return "__samplerExternal2DY2YEXT";
49 case EbtSampler2DRect:
50 return "sampler2DRect";
51 case EbtSampler2DArray:
52 return "sampler2DArray";
53 case EbtSampler2DMS:
54 return "sampler2DMS";
55 case EbtSampler2DMSArray:
56 return "sampler2DMSArray";
57 case EbtSamplerCubeArray:
58 return "samplerCubeArray";
59 case EbtISampler2D:
60 return "isampler2D";
61 case EbtISampler3D:
62 return "isampler3D";
63 case EbtISamplerCube:
64 return "isamplerCube";
65 case EbtISampler2DArray:
66 return "isampler2DArray";
67 case EbtISampler2DMS:
68 return "isampler2DMS";
69 case EbtISampler2DMSArray:
70 return "isampler2DMSArray";
71 case EbtISamplerCubeArray:
72 return "isamplerCubeArray";
73 case EbtUSampler2D:
74 return "usampler2D";
75 case EbtUSampler3D:
76 return "usampler3D";
77 case EbtUSamplerCube:
78 return "usamplerCube";
79 case EbtUSampler2DArray:
80 return "usampler2DArray";
81 case EbtUSampler2DMS:
82 return "usampler2DMS";
83 case EbtUSampler2DMSArray:
84 return "usampler2DMSArray";
85 case EbtUSamplerCubeArray:
86 return "usamplerCubeArray";
87 case EbtSampler2DShadow:
88 return "sampler2DShadow";
89 case EbtSamplerCubeShadow:
90 return "samplerCubeShadow";
91 case EbtSampler2DArrayShadow:
92 return "sampler2DArrayShadow";
93 case EbtSamplerCubeArrayShadow:
94 return "samplerCubeArrayShadow";
95 case EbtStruct:
96 return "structure";
97 case EbtInterfaceBlock:
98 return "interface block";
99 case EbtImage2D:
100 return "image2D";
101 case EbtIImage2D:
102 return "iimage2D";
103 case EbtUImage2D:
104 return "uimage2D";
105 case EbtImage3D:
106 return "image3D";
107 case EbtIImage3D:
108 return "iimage3D";
109 case EbtUImage3D:
110 return "uimage3D";
111 case EbtImage2DArray:
112 return "image2DArray";
113 case EbtIImage2DArray:
114 return "iimage2DArray";
115 case EbtUImage2DArray:
116 return "uimage2DArray";
117 case EbtImageCube:
118 return "imageCube";
119 case EbtIImageCube:
120 return "iimageCube";
121 case EbtUImageCube:
122 return "uimageCube";
123 case EbtImageCubeArray:
124 return "imageCubeArray";
125 case EbtIImageCubeArray:
126 return "iimageCubeArray";
127 case EbtUImageCubeArray:
128 return "uimageCubeArray";
129 case EbtAtomicCounter:
130 return "atomic_uint";
131 case EbtSamplerVideoWEBGL:
132 return "samplerVideoWEBGL";
133 default:
134 UNREACHABLE();
135 return "unknown type";
136 }
137 }
138
139 // TType implementation.
TType()140 TType::TType() : TType(EbtVoid, 0, 0) {}
141
TType(TBasicType t,unsigned char ps,unsigned char ss)142 TType::TType(TBasicType t, unsigned char ps, unsigned char ss)
143 : TType(t, EbpUndefined, EvqGlobal, ps, ss)
144 {}
145
TType(TBasicType t,TPrecision p,TQualifier q,unsigned char ps,unsigned char ss)146 TType::TType(TBasicType t, TPrecision p, TQualifier q, unsigned char ps, unsigned char ss)
147 : TType(t, p, q, ps, ss, TSpan<const unsigned int>(), nullptr)
148 {}
149
TType(const TPublicType & p)150 TType::TType(const TPublicType &p)
151 : type(p.getBasicType()),
152 precision(p.precision),
153 qualifier(p.qualifier),
154 invariant(p.invariant),
155 precise(p.precise),
156 memoryQualifier(p.memoryQualifier),
157 layoutQualifier(p.layoutQualifier),
158 primarySize(p.getPrimarySize()),
159 secondarySize(p.getSecondarySize()),
160 mArraySizesStorage(nullptr),
161 mInterfaceBlock(nullptr),
162 mStructure(nullptr),
163 mIsStructSpecifier(false),
164 mMangledName(nullptr)
165 {
166 ASSERT(primarySize <= 4);
167 ASSERT(secondarySize <= 4);
168 if (p.isArray())
169 {
170 makeArrays(*p.arraySizes);
171 }
172 if (p.getUserDef())
173 {
174 mStructure = p.getUserDef();
175 mIsStructSpecifier = p.isStructSpecifier();
176 }
177 }
178
TType(const TStructure * userDef,bool isStructSpecifier)179 TType::TType(const TStructure *userDef, bool isStructSpecifier)
180 : TType(EbtStruct, EbpUndefined, EvqTemporary, 1, 1)
181 {
182 mStructure = userDef;
183 mIsStructSpecifier = isStructSpecifier;
184 }
185
TType(const TInterfaceBlock * interfaceBlockIn,TQualifier qualifierIn,TLayoutQualifier layoutQualifierIn)186 TType::TType(const TInterfaceBlock *interfaceBlockIn,
187 TQualifier qualifierIn,
188 TLayoutQualifier layoutQualifierIn)
189 : TType(EbtInterfaceBlock, EbpUndefined, qualifierIn, 1, 1)
190 {
191 layoutQualifier = layoutQualifierIn;
192 mInterfaceBlock = interfaceBlockIn;
193 }
194
TType(const TType & t)195 TType::TType(const TType &t)
196 {
197 *this = t;
198 }
199
operator =(const TType & t)200 TType &TType::operator=(const TType &t)
201 {
202 type = t.type;
203 precision = t.precision;
204 qualifier = t.qualifier;
205 invariant = t.invariant;
206 precise = t.precise;
207 memoryQualifier = t.memoryQualifier;
208 layoutQualifier = t.layoutQualifier;
209 primarySize = t.primarySize;
210 secondarySize = t.secondarySize;
211 mArraySizesStorage = nullptr;
212 mInterfaceBlock = t.mInterfaceBlock;
213 mStructure = t.mStructure;
214 mIsStructSpecifier = t.mIsStructSpecifier;
215 mMangledName = t.mMangledName;
216
217 if (t.mArraySizesStorage)
218 {
219 // If other type has storage, duplicate the storage and set the view to our own storage.
220 mArraySizesStorage = new TVector<unsigned int>(*t.mArraySizesStorage);
221 mArraySizes = *mArraySizesStorage;
222 }
223 else
224 {
225 // Otherwise reference the same (constexpr) array sizes as the other type.
226 mArraySizes = t.mArraySizes;
227 }
228
229 return *this;
230 }
231
canBeConstructed() const232 bool TType::canBeConstructed() const
233 {
234 switch (type)
235 {
236 case EbtFloat:
237 case EbtInt:
238 case EbtUInt:
239 case EbtBool:
240 case EbtStruct:
241 return true;
242 default:
243 return false;
244 }
245 }
246
getBuiltInTypeNameString() const247 const char *TType::getBuiltInTypeNameString() const
248 {
249 if (isMatrix())
250 {
251 switch (getCols())
252 {
253 case 2:
254 switch (getRows())
255 {
256 case 2:
257 return "mat2";
258 case 3:
259 return "mat2x3";
260 case 4:
261 return "mat2x4";
262 default:
263 UNREACHABLE();
264 return nullptr;
265 }
266 case 3:
267 switch (getRows())
268 {
269 case 2:
270 return "mat3x2";
271 case 3:
272 return "mat3";
273 case 4:
274 return "mat3x4";
275 default:
276 UNREACHABLE();
277 return nullptr;
278 }
279 case 4:
280 switch (getRows())
281 {
282 case 2:
283 return "mat4x2";
284 case 3:
285 return "mat4x3";
286 case 4:
287 return "mat4";
288 default:
289 UNREACHABLE();
290 return nullptr;
291 }
292 default:
293 UNREACHABLE();
294 return nullptr;
295 }
296 }
297 if (isVector())
298 {
299 switch (getBasicType())
300 {
301 case EbtFloat:
302 switch (getNominalSize())
303 {
304 case 2:
305 return "vec2";
306 case 3:
307 return "vec3";
308 case 4:
309 return "vec4";
310 default:
311 UNREACHABLE();
312 return nullptr;
313 }
314 case EbtInt:
315 switch (getNominalSize())
316 {
317 case 2:
318 return "ivec2";
319 case 3:
320 return "ivec3";
321 case 4:
322 return "ivec4";
323 default:
324 UNREACHABLE();
325 return nullptr;
326 }
327 case EbtBool:
328 switch (getNominalSize())
329 {
330 case 2:
331 return "bvec2";
332 case 3:
333 return "bvec3";
334 case 4:
335 return "bvec4";
336 default:
337 UNREACHABLE();
338 return nullptr;
339 }
340 case EbtUInt:
341 switch (getNominalSize())
342 {
343 case 2:
344 return "uvec2";
345 case 3:
346 return "uvec3";
347 case 4:
348 return "uvec4";
349 default:
350 UNREACHABLE();
351 return nullptr;
352 }
353 default:
354 UNREACHABLE();
355 return nullptr;
356 }
357 }
358 ASSERT(getBasicType() != EbtStruct);
359 ASSERT(getBasicType() != EbtInterfaceBlock);
360 return getBasicString();
361 }
362
getDeepestStructNesting() const363 int TType::getDeepestStructNesting() const
364 {
365 return mStructure ? mStructure->deepestNesting() : 0;
366 }
367
isNamelessStruct() const368 bool TType::isNamelessStruct() const
369 {
370 return mStructure && mStructure->symbolType() == SymbolType::Empty;
371 }
372
isStructureContainingArrays() const373 bool TType::isStructureContainingArrays() const
374 {
375 return mStructure ? mStructure->containsArrays() : false;
376 }
377
isStructureContainingMatrices() const378 bool TType::isStructureContainingMatrices() const
379 {
380 return mStructure ? mStructure->containsMatrices() : false;
381 }
382
isStructureContainingType(TBasicType t) const383 bool TType::isStructureContainingType(TBasicType t) const
384 {
385 return mStructure ? mStructure->containsType(t) : false;
386 }
387
isStructureContainingSamplers() const388 bool TType::isStructureContainingSamplers() const
389 {
390 return mStructure ? mStructure->containsSamplers() : false;
391 }
392
canReplaceWithConstantUnion() const393 bool TType::canReplaceWithConstantUnion() const
394 {
395 if (isArray())
396 {
397 return false;
398 }
399 if (!mStructure)
400 {
401 return true;
402 }
403 if (isStructureContainingArrays())
404 {
405 return false;
406 }
407 if (getObjectSize() > 16)
408 {
409 return false;
410 }
411 return true;
412 }
413
414 //
415 // Recursively generate mangled names.
416 //
buildMangledName() const417 const char *TType::buildMangledName() const
418 {
419 TString mangledName(1, GetSizeMangledName(primarySize, secondarySize));
420
421 TBasicMangledName typeName(type);
422 char *basicMangledName = typeName.getName();
423 static_assert(TBasicMangledName::mangledNameSize == 2, "Mangled name size is not 2");
424 if (basicMangledName[0] != '{')
425 {
426 mangledName += basicMangledName[0];
427 mangledName += basicMangledName[1];
428 }
429 else
430 {
431 ASSERT(type == EbtStruct || type == EbtInterfaceBlock);
432 switch (type)
433 {
434 case EbtStruct:
435 mangledName += "{s";
436 if (mStructure->symbolType() != SymbolType::Empty)
437 {
438 mangledName += mStructure->name().data();
439 }
440 mangledName += mStructure->mangledFieldList();
441 mangledName += '}';
442 break;
443 case EbtInterfaceBlock:
444 mangledName += "{i";
445 mangledName += mInterfaceBlock->name().data();
446 mangledName += mInterfaceBlock->mangledFieldList();
447 mangledName += '}';
448 break;
449 default:
450 UNREACHABLE();
451 break;
452 }
453 }
454
455 for (unsigned int arraySize : mArraySizes)
456 {
457 char buf[20];
458 snprintf(buf, sizeof(buf), "%d", arraySize);
459 mangledName += 'x';
460 mangledName += buf;
461 }
462
463 // Copy string contents into a pool-allocated buffer, so we never need to call delete.
464 return AllocatePoolCharArray(mangledName.c_str(), mangledName.size());
465 }
466
getObjectSize() const467 size_t TType::getObjectSize() const
468 {
469 size_t totalSize;
470
471 if (getBasicType() == EbtStruct)
472 totalSize = mStructure->objectSize();
473 else
474 totalSize = primarySize * secondarySize;
475
476 if (totalSize == 0)
477 return 0;
478
479 for (size_t arraySize : mArraySizes)
480 {
481 if (arraySize > INT_MAX / totalSize)
482 totalSize = INT_MAX;
483 else
484 totalSize *= arraySize;
485 }
486
487 return totalSize;
488 }
489
getLocationCount() const490 int TType::getLocationCount() const
491 {
492 int count = 1;
493
494 if (getBasicType() == EbtStruct)
495 {
496 count = mStructure->getLocationCount();
497 }
498
499 if (count == 0)
500 {
501 return 0;
502 }
503
504 for (unsigned int arraySize : mArraySizes)
505 {
506 if (arraySize > static_cast<unsigned int>(std::numeric_limits<int>::max() / count))
507 {
508 count = std::numeric_limits<int>::max();
509 }
510 else
511 {
512 count *= static_cast<int>(arraySize);
513 }
514 }
515
516 return count;
517 }
518
getArraySizeProduct() const519 unsigned int TType::getArraySizeProduct() const
520 {
521 unsigned int product = 1u;
522
523 for (unsigned int arraySize : mArraySizes)
524 {
525 product *= arraySize;
526 }
527 return product;
528 }
529
isUnsizedArray() const530 bool TType::isUnsizedArray() const
531 {
532 for (unsigned int arraySize : mArraySizes)
533 {
534 if (arraySize == 0u)
535 {
536 return true;
537 }
538 }
539 return false;
540 }
541
sameNonArrayType(const TType & right) const542 bool TType::sameNonArrayType(const TType &right) const
543 {
544 return (type == right.type && primarySize == right.primarySize &&
545 secondarySize == right.secondarySize && mStructure == right.mStructure);
546 }
547
isElementTypeOf(const TType & arrayType) const548 bool TType::isElementTypeOf(const TType &arrayType) const
549 {
550 if (!sameNonArrayType(arrayType))
551 {
552 return false;
553 }
554 if (arrayType.getNumArraySizes() != getNumArraySizes() + 1u)
555 {
556 return false;
557 }
558 for (size_t i = 0; i < mArraySizes.size(); ++i)
559 {
560 if (mArraySizes[i] != arrayType.mArraySizes[i])
561 {
562 return false;
563 }
564 }
565 return true;
566 }
567
sizeUnsizedArrays(const TSpan<const unsigned int> & newArraySizes)568 void TType::sizeUnsizedArrays(const TSpan<const unsigned int> &newArraySizes)
569 {
570 ASSERT(!isArray() || mArraySizesStorage != nullptr);
571 for (size_t i = 0u; i < getNumArraySizes(); ++i)
572 {
573 if (mArraySizes[i] == 0)
574 {
575 if (i < newArraySizes.size())
576 {
577 (*mArraySizesStorage)[i] = newArraySizes[i];
578 }
579 else
580 {
581 (*mArraySizesStorage)[i] = 1u;
582 }
583 }
584 }
585 invalidateMangledName();
586 }
587
sizeOutermostUnsizedArray(unsigned int arraySize)588 void TType::sizeOutermostUnsizedArray(unsigned int arraySize)
589 {
590 ASSERT(isArray() && mArraySizesStorage != nullptr);
591 ASSERT((*mArraySizesStorage).back() == 0u);
592 (*mArraySizesStorage).back() = arraySize;
593 }
594
setBasicType(TBasicType t)595 void TType::setBasicType(TBasicType t)
596 {
597 if (type != t)
598 {
599 type = t;
600 invalidateMangledName();
601 }
602 }
603
setPrimarySize(unsigned char ps)604 void TType::setPrimarySize(unsigned char ps)
605 {
606 if (primarySize != ps)
607 {
608 ASSERT(ps <= 4);
609 primarySize = ps;
610 invalidateMangledName();
611 }
612 }
613
setSecondarySize(unsigned char ss)614 void TType::setSecondarySize(unsigned char ss)
615 {
616 if (secondarySize != ss)
617 {
618 ASSERT(ss <= 4);
619 secondarySize = ss;
620 invalidateMangledName();
621 }
622 }
623
makeArray(unsigned int s)624 void TType::makeArray(unsigned int s)
625 {
626 if (mArraySizesStorage == nullptr)
627 {
628 mArraySizesStorage = new TVector<unsigned int>();
629 }
630 // Add a dimension to the current ones.
631 mArraySizesStorage->push_back(s);
632 onArrayDimensionsChange(*mArraySizesStorage);
633 }
634
makeArrays(const TSpan<const unsigned int> & sizes)635 void TType::makeArrays(const TSpan<const unsigned int> &sizes)
636 {
637 if (mArraySizesStorage == nullptr)
638 {
639 mArraySizesStorage = new TVector<unsigned int>();
640 }
641 // Add dimensions to the current ones.
642 mArraySizesStorage->insert(mArraySizesStorage->end(), sizes.begin(), sizes.end());
643 onArrayDimensionsChange(*mArraySizesStorage);
644 }
645
setArraySize(size_t arrayDimension,unsigned int s)646 void TType::setArraySize(size_t arrayDimension, unsigned int s)
647 {
648 ASSERT(isArray() && mArraySizesStorage != nullptr);
649 ASSERT(arrayDimension < mArraySizesStorage->size());
650 if (mArraySizes[arrayDimension] != s)
651 {
652 (*mArraySizesStorage)[arrayDimension] = s;
653 invalidateMangledName();
654 }
655 }
656
toArrayElementType()657 void TType::toArrayElementType()
658 {
659 ASSERT(isArray() && mArraySizesStorage != nullptr);
660 mArraySizesStorage->pop_back();
661 onArrayDimensionsChange(*mArraySizesStorage);
662 }
663
toArrayBaseType()664 void TType::toArrayBaseType()
665 {
666 if (!isArray())
667 {
668 return;
669 }
670 if (mArraySizesStorage)
671 {
672 mArraySizesStorage->clear();
673 }
674 onArrayDimensionsChange(TSpan<const unsigned int>());
675 }
676
setInterfaceBlock(const TInterfaceBlock * interfaceBlockIn)677 void TType::setInterfaceBlock(const TInterfaceBlock *interfaceBlockIn)
678 {
679 if (mInterfaceBlock != interfaceBlockIn)
680 {
681 mInterfaceBlock = interfaceBlockIn;
682 invalidateMangledName();
683 }
684 }
685
getMangledName() const686 const char *TType::getMangledName() const
687 {
688 if (mMangledName == nullptr)
689 {
690 mMangledName = buildMangledName();
691 }
692
693 return mMangledName;
694 }
695
realize()696 void TType::realize()
697 {
698 getMangledName();
699 }
700
createSamplerSymbols(const ImmutableString & namePrefix,const TString & apiNamePrefix,TVector<const TVariable * > * outputSymbols,TMap<const TVariable *,TString> * outputSymbolsToAPINames,TSymbolTable * symbolTable) const701 void TType::createSamplerSymbols(const ImmutableString &namePrefix,
702 const TString &apiNamePrefix,
703 TVector<const TVariable *> *outputSymbols,
704 TMap<const TVariable *, TString> *outputSymbolsToAPINames,
705 TSymbolTable *symbolTable) const
706 {
707 if (isStructureContainingSamplers())
708 {
709 if (isArray())
710 {
711 TType elementType(*this);
712 elementType.toArrayElementType();
713 for (unsigned int arrayIndex = 0u; arrayIndex < getOutermostArraySize(); ++arrayIndex)
714 {
715 std::stringstream elementName = sh::InitializeStream<std::stringstream>();
716 elementName << namePrefix << "_" << arrayIndex;
717 TStringStream elementApiName;
718 elementApiName << apiNamePrefix << "[" << arrayIndex << "]";
719 elementType.createSamplerSymbols(ImmutableString(elementName.str()),
720 elementApiName.str(), outputSymbols,
721 outputSymbolsToAPINames, symbolTable);
722 }
723 }
724 else
725 {
726 mStructure->createSamplerSymbols(namePrefix.data(), apiNamePrefix, outputSymbols,
727 outputSymbolsToAPINames, symbolTable);
728 }
729 return;
730 }
731
732 ASSERT(IsSampler(type));
733 TVariable *variable =
734 new TVariable(symbolTable, namePrefix, new TType(*this), SymbolType::AngleInternal);
735 outputSymbols->push_back(variable);
736 if (outputSymbolsToAPINames)
737 {
738 (*outputSymbolsToAPINames)[variable] = apiNamePrefix;
739 }
740 }
741
TFieldListCollection(const TFieldList * fields)742 TFieldListCollection::TFieldListCollection(const TFieldList *fields)
743 : mFields(fields), mObjectSize(0), mDeepestNesting(0)
744 {}
745
containsArrays() const746 bool TFieldListCollection::containsArrays() const
747 {
748 for (const auto *field : *mFields)
749 {
750 const TType *fieldType = field->type();
751 if (fieldType->isArray() || fieldType->isStructureContainingArrays())
752 return true;
753 }
754 return false;
755 }
756
containsMatrices() const757 bool TFieldListCollection::containsMatrices() const
758 {
759 for (const auto *field : *mFields)
760 {
761 const TType *fieldType = field->type();
762 if (fieldType->isMatrix() || fieldType->isStructureContainingMatrices())
763 return true;
764 }
765 return false;
766 }
767
containsType(TBasicType type) const768 bool TFieldListCollection::containsType(TBasicType type) const
769 {
770 for (const auto *field : *mFields)
771 {
772 const TType *fieldType = field->type();
773 if (fieldType->getBasicType() == type || fieldType->isStructureContainingType(type))
774 return true;
775 }
776 return false;
777 }
778
containsSamplers() const779 bool TFieldListCollection::containsSamplers() const
780 {
781 for (const auto *field : *mFields)
782 {
783 const TType *fieldType = field->type();
784 if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
785 return true;
786 }
787 return false;
788 }
789
buildMangledFieldList() const790 TString TFieldListCollection::buildMangledFieldList() const
791 {
792 TString mangledName;
793 for (const auto *field : *mFields)
794 {
795 mangledName += field->type()->getMangledName();
796 }
797 return mangledName;
798 }
799
calculateObjectSize() const800 size_t TFieldListCollection::calculateObjectSize() const
801 {
802 size_t size = 0;
803 for (const TField *field : *mFields)
804 {
805 size_t fieldSize = field->type()->getObjectSize();
806 if (fieldSize > INT_MAX - size)
807 size = INT_MAX;
808 else
809 size += fieldSize;
810 }
811 return size;
812 }
813
objectSize() const814 size_t TFieldListCollection::objectSize() const
815 {
816 if (mObjectSize == 0)
817 mObjectSize = calculateObjectSize();
818 return mObjectSize;
819 }
820
getLocationCount() const821 int TFieldListCollection::getLocationCount() const
822 {
823 int count = 0;
824 for (const TField *field : *mFields)
825 {
826 int fieldCount = field->type()->getLocationCount();
827 if (fieldCount > std::numeric_limits<int>::max() - count)
828 {
829 count = std::numeric_limits<int>::max();
830 }
831 else
832 {
833 count += fieldCount;
834 }
835 }
836 return count;
837 }
838
deepestNesting() const839 int TFieldListCollection::deepestNesting() const
840 {
841 if (mDeepestNesting == 0)
842 mDeepestNesting = calculateDeepestNesting();
843 return mDeepestNesting;
844 }
845
mangledFieldList() const846 const TString &TFieldListCollection::mangledFieldList() const
847 {
848 if (mMangledFieldList.empty())
849 mMangledFieldList = buildMangledFieldList();
850 return mMangledFieldList;
851 }
852
calculateDeepestNesting() const853 int TFieldListCollection::calculateDeepestNesting() const
854 {
855 int maxNesting = 0;
856 for (size_t i = 0; i < mFields->size(); ++i)
857 maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
858 return 1 + maxNesting;
859 }
860
861 // TPublicType implementation.
initialize(const TTypeSpecifierNonArray & typeSpecifier,TQualifier q)862 void TPublicType::initialize(const TTypeSpecifierNonArray &typeSpecifier, TQualifier q)
863 {
864 typeSpecifierNonArray = typeSpecifier;
865 layoutQualifier = TLayoutQualifier::Create();
866 memoryQualifier = TMemoryQualifier::Create();
867 qualifier = q;
868 invariant = false;
869 precise = false;
870 precision = EbpUndefined;
871 arraySizes = nullptr;
872 }
873
initializeBasicType(TBasicType basicType)874 void TPublicType::initializeBasicType(TBasicType basicType)
875 {
876 typeSpecifierNonArray.type = basicType;
877 typeSpecifierNonArray.primarySize = 1;
878 typeSpecifierNonArray.secondarySize = 1;
879 layoutQualifier = TLayoutQualifier::Create();
880 memoryQualifier = TMemoryQualifier::Create();
881 qualifier = EvqTemporary;
882 invariant = false;
883 precise = false;
884 precision = EbpUndefined;
885 arraySizes = nullptr;
886 }
887
isStructureContainingArrays() const888 bool TPublicType::isStructureContainingArrays() const
889 {
890 if (!typeSpecifierNonArray.userDef)
891 {
892 return false;
893 }
894
895 return typeSpecifierNonArray.userDef->containsArrays();
896 }
897
isStructureContainingType(TBasicType t) const898 bool TPublicType::isStructureContainingType(TBasicType t) const
899 {
900 if (!typeSpecifierNonArray.userDef)
901 {
902 return false;
903 }
904
905 return typeSpecifierNonArray.userDef->containsType(t);
906 }
907
setArraySizes(TVector<unsigned int> * sizes)908 void TPublicType::setArraySizes(TVector<unsigned int> *sizes)
909 {
910 arraySizes = sizes;
911 }
912
isArray() const913 bool TPublicType::isArray() const
914 {
915 return arraySizes && !arraySizes->empty();
916 }
917
clearArrayness()918 void TPublicType::clearArrayness()
919 {
920 arraySizes = nullptr;
921 }
922
isAggregate() const923 bool TPublicType::isAggregate() const
924 {
925 return isArray() || typeSpecifierNonArray.isMatrix() || typeSpecifierNonArray.isVector();
926 }
927
928 } // namespace sh
929