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 case EbtSamplerVideoWEBGL:
118 return "samplerVideoWEBGL";
119 default:
120 UNREACHABLE();
121 return "unknown type";
122 }
123 }
124
125 // TType implementation.
TType()126 TType::TType() : TType(EbtVoid, 0, 0) {}
127
TType(TBasicType t,unsigned char ps,unsigned char ss)128 TType::TType(TBasicType t, unsigned char ps, unsigned char ss)
129 : TType(t, EbpUndefined, EvqGlobal, ps, ss)
130 {}
131
TType(TBasicType t,TPrecision p,TQualifier q,unsigned char ps,unsigned char ss)132 TType::TType(TBasicType t, TPrecision p, TQualifier q, unsigned char ps, unsigned char ss)
133 : TType(t, p, q, ps, ss, TSpan<const unsigned int>(), nullptr)
134 {}
135
TType(const TPublicType & p)136 TType::TType(const TPublicType &p)
137 : type(p.getBasicType()),
138 precision(p.precision),
139 qualifier(p.qualifier),
140 invariant(p.invariant),
141 precise(p.precise),
142 memoryQualifier(p.memoryQualifier),
143 layoutQualifier(p.layoutQualifier),
144 primarySize(p.getPrimarySize()),
145 secondarySize(p.getSecondarySize()),
146 mArraySizesStorage(nullptr),
147 mInterfaceBlock(nullptr),
148 mStructure(nullptr),
149 mIsStructSpecifier(false),
150 mMangledName(nullptr)
151 {
152 ASSERT(primarySize <= 4);
153 ASSERT(secondarySize <= 4);
154 if (p.isArray())
155 {
156 makeArrays(*p.arraySizes);
157 }
158 if (p.getUserDef())
159 {
160 mStructure = p.getUserDef();
161 mIsStructSpecifier = p.isStructSpecifier();
162 }
163 }
164
TType(const TStructure * userDef,bool isStructSpecifier)165 TType::TType(const TStructure *userDef, bool isStructSpecifier)
166 : TType(EbtStruct, EbpUndefined, EvqTemporary, 1, 1)
167 {
168 mStructure = userDef;
169 mIsStructSpecifier = isStructSpecifier;
170 }
171
TType(const TInterfaceBlock * interfaceBlockIn,TQualifier qualifierIn,TLayoutQualifier layoutQualifierIn)172 TType::TType(const TInterfaceBlock *interfaceBlockIn,
173 TQualifier qualifierIn,
174 TLayoutQualifier layoutQualifierIn)
175 : TType(EbtInterfaceBlock, EbpUndefined, qualifierIn, 1, 1)
176 {
177 layoutQualifier = layoutQualifierIn;
178 mInterfaceBlock = interfaceBlockIn;
179 }
180
TType(const TType & t)181 TType::TType(const TType &t)
182 {
183 *this = t;
184 }
185
operator =(const TType & t)186 TType &TType::operator=(const TType &t)
187 {
188 type = t.type;
189 precision = t.precision;
190 qualifier = t.qualifier;
191 invariant = t.invariant;
192 precise = t.precise;
193 memoryQualifier = t.memoryQualifier;
194 layoutQualifier = t.layoutQualifier;
195 primarySize = t.primarySize;
196 secondarySize = t.secondarySize;
197 mArraySizesStorage = nullptr;
198 mInterfaceBlock = t.mInterfaceBlock;
199 mStructure = t.mStructure;
200 mIsStructSpecifier = t.mIsStructSpecifier;
201 mMangledName = t.mMangledName;
202
203 if (t.mArraySizesStorage)
204 {
205 // If other type has storage, duplicate the storage and set the view to our own storage.
206 mArraySizesStorage = new TVector<unsigned int>(*t.mArraySizesStorage);
207 mArraySizes = *mArraySizesStorage;
208 }
209 else
210 {
211 // Otherwise reference the same (constexpr) array sizes as the other type.
212 mArraySizes = t.mArraySizes;
213 }
214
215 return *this;
216 }
217
canBeConstructed() const218 bool TType::canBeConstructed() const
219 {
220 switch (type)
221 {
222 case EbtFloat:
223 case EbtInt:
224 case EbtUInt:
225 case EbtBool:
226 case EbtStruct:
227 return true;
228 default:
229 return false;
230 }
231 }
232
getBuiltInTypeNameString() const233 const char *TType::getBuiltInTypeNameString() const
234 {
235 if (isMatrix())
236 {
237 switch (getCols())
238 {
239 case 2:
240 switch (getRows())
241 {
242 case 2:
243 return "mat2";
244 case 3:
245 return "mat2x3";
246 case 4:
247 return "mat2x4";
248 default:
249 UNREACHABLE();
250 return nullptr;
251 }
252 case 3:
253 switch (getRows())
254 {
255 case 2:
256 return "mat3x2";
257 case 3:
258 return "mat3";
259 case 4:
260 return "mat3x4";
261 default:
262 UNREACHABLE();
263 return nullptr;
264 }
265 case 4:
266 switch (getRows())
267 {
268 case 2:
269 return "mat4x2";
270 case 3:
271 return "mat4x3";
272 case 4:
273 return "mat4";
274 default:
275 UNREACHABLE();
276 return nullptr;
277 }
278 default:
279 UNREACHABLE();
280 return nullptr;
281 }
282 }
283 if (isVector())
284 {
285 switch (getBasicType())
286 {
287 case EbtFloat:
288 switch (getNominalSize())
289 {
290 case 2:
291 return "vec2";
292 case 3:
293 return "vec3";
294 case 4:
295 return "vec4";
296 default:
297 UNREACHABLE();
298 return nullptr;
299 }
300 case EbtInt:
301 switch (getNominalSize())
302 {
303 case 2:
304 return "ivec2";
305 case 3:
306 return "ivec3";
307 case 4:
308 return "ivec4";
309 default:
310 UNREACHABLE();
311 return nullptr;
312 }
313 case EbtBool:
314 switch (getNominalSize())
315 {
316 case 2:
317 return "bvec2";
318 case 3:
319 return "bvec3";
320 case 4:
321 return "bvec4";
322 default:
323 UNREACHABLE();
324 return nullptr;
325 }
326 case EbtUInt:
327 switch (getNominalSize())
328 {
329 case 2:
330 return "uvec2";
331 case 3:
332 return "uvec3";
333 case 4:
334 return "uvec4";
335 default:
336 UNREACHABLE();
337 return nullptr;
338 }
339 default:
340 UNREACHABLE();
341 return nullptr;
342 }
343 }
344 ASSERT(getBasicType() != EbtStruct);
345 ASSERT(getBasicType() != EbtInterfaceBlock);
346 return getBasicString();
347 }
348
getDeepestStructNesting() const349 int TType::getDeepestStructNesting() const
350 {
351 return mStructure ? mStructure->deepestNesting() : 0;
352 }
353
isNamelessStruct() const354 bool TType::isNamelessStruct() const
355 {
356 return mStructure && mStructure->symbolType() == SymbolType::Empty;
357 }
358
isStructureContainingArrays() const359 bool TType::isStructureContainingArrays() const
360 {
361 return mStructure ? mStructure->containsArrays() : false;
362 }
363
isStructureContainingMatrices() const364 bool TType::isStructureContainingMatrices() const
365 {
366 return mStructure ? mStructure->containsMatrices() : false;
367 }
368
isStructureContainingType(TBasicType t) const369 bool TType::isStructureContainingType(TBasicType t) const
370 {
371 return mStructure ? mStructure->containsType(t) : false;
372 }
373
isStructureContainingSamplers() const374 bool TType::isStructureContainingSamplers() const
375 {
376 return mStructure ? mStructure->containsSamplers() : false;
377 }
378
canReplaceWithConstantUnion() const379 bool TType::canReplaceWithConstantUnion() const
380 {
381 if (isArray())
382 {
383 return false;
384 }
385 if (!mStructure)
386 {
387 return true;
388 }
389 if (isStructureContainingArrays())
390 {
391 return false;
392 }
393 if (getObjectSize() > 16)
394 {
395 return false;
396 }
397 return true;
398 }
399
400 //
401 // Recursively generate mangled names.
402 //
buildMangledName() const403 const char *TType::buildMangledName() const
404 {
405 TString mangledName(1, GetSizeMangledName(primarySize, secondarySize));
406
407 TBasicMangledName typeName(type);
408 char *basicMangledName = typeName.getName();
409 static_assert(TBasicMangledName::mangledNameSize == 2, "Mangled name size is not 2");
410 if (basicMangledName[0] != '{')
411 {
412 mangledName += basicMangledName[0];
413 mangledName += basicMangledName[1];
414 }
415 else
416 {
417 ASSERT(type == EbtStruct || type == EbtInterfaceBlock);
418 switch (type)
419 {
420 case EbtStruct:
421 mangledName += "{s";
422 if (mStructure->symbolType() != SymbolType::Empty)
423 {
424 mangledName += mStructure->name().data();
425 }
426 mangledName += mStructure->mangledFieldList();
427 mangledName += '}';
428 break;
429 case EbtInterfaceBlock:
430 mangledName += "{i";
431 mangledName += mInterfaceBlock->name().data();
432 mangledName += mInterfaceBlock->mangledFieldList();
433 mangledName += '}';
434 break;
435 default:
436 UNREACHABLE();
437 break;
438 }
439 }
440
441 for (unsigned int arraySize : mArraySizes)
442 {
443 char buf[20];
444 snprintf(buf, sizeof(buf), "%d", arraySize);
445 mangledName += 'x';
446 mangledName += buf;
447 }
448
449 // Copy string contents into a pool-allocated buffer, so we never need to call delete.
450 return AllocatePoolCharArray(mangledName.c_str(), mangledName.size());
451 }
452
getObjectSize() const453 size_t TType::getObjectSize() const
454 {
455 size_t totalSize;
456
457 if (getBasicType() == EbtStruct)
458 totalSize = mStructure->objectSize();
459 else
460 totalSize = primarySize * secondarySize;
461
462 if (totalSize == 0)
463 return 0;
464
465 for (size_t arraySize : mArraySizes)
466 {
467 if (arraySize > INT_MAX / totalSize)
468 totalSize = INT_MAX;
469 else
470 totalSize *= arraySize;
471 }
472
473 return totalSize;
474 }
475
getLocationCount() const476 int TType::getLocationCount() const
477 {
478 int count = 1;
479
480 if (getBasicType() == EbtStruct)
481 {
482 count = mStructure->getLocationCount();
483 }
484
485 if (count == 0)
486 {
487 return 0;
488 }
489
490 for (unsigned int arraySize : mArraySizes)
491 {
492 if (arraySize > static_cast<unsigned int>(std::numeric_limits<int>::max() / count))
493 {
494 count = std::numeric_limits<int>::max();
495 }
496 else
497 {
498 count *= static_cast<int>(arraySize);
499 }
500 }
501
502 return count;
503 }
504
getArraySizeProduct() const505 unsigned int TType::getArraySizeProduct() const
506 {
507 unsigned int product = 1u;
508
509 for (unsigned int arraySize : mArraySizes)
510 {
511 product *= arraySize;
512 }
513 return product;
514 }
515
isUnsizedArray() const516 bool TType::isUnsizedArray() const
517 {
518 for (unsigned int arraySize : mArraySizes)
519 {
520 if (arraySize == 0u)
521 {
522 return true;
523 }
524 }
525 return false;
526 }
527
sameNonArrayType(const TType & right) const528 bool TType::sameNonArrayType(const TType &right) const
529 {
530 return (type == right.type && primarySize == right.primarySize &&
531 secondarySize == right.secondarySize && mStructure == right.mStructure);
532 }
533
isElementTypeOf(const TType & arrayType) const534 bool TType::isElementTypeOf(const TType &arrayType) const
535 {
536 if (!sameNonArrayType(arrayType))
537 {
538 return false;
539 }
540 if (arrayType.getNumArraySizes() != getNumArraySizes() + 1u)
541 {
542 return false;
543 }
544 for (size_t i = 0; i < mArraySizes.size(); ++i)
545 {
546 if (mArraySizes[i] != arrayType.mArraySizes[i])
547 {
548 return false;
549 }
550 }
551 return true;
552 }
553
sizeUnsizedArrays(const TSpan<const unsigned int> & newArraySizes)554 void TType::sizeUnsizedArrays(const TSpan<const unsigned int> &newArraySizes)
555 {
556 ASSERT(!isArray() || mArraySizesStorage != nullptr);
557 for (size_t i = 0u; i < getNumArraySizes(); ++i)
558 {
559 if (mArraySizes[i] == 0)
560 {
561 if (i < newArraySizes.size())
562 {
563 (*mArraySizesStorage)[i] = newArraySizes[i];
564 }
565 else
566 {
567 (*mArraySizesStorage)[i] = 1u;
568 }
569 }
570 }
571 invalidateMangledName();
572 }
573
sizeOutermostUnsizedArray(unsigned int arraySize)574 void TType::sizeOutermostUnsizedArray(unsigned int arraySize)
575 {
576 ASSERT(isArray() && mArraySizesStorage != nullptr);
577 ASSERT((*mArraySizesStorage).back() == 0u);
578 (*mArraySizesStorage).back() = arraySize;
579 }
580
setBasicType(TBasicType t)581 void TType::setBasicType(TBasicType t)
582 {
583 if (type != t)
584 {
585 type = t;
586 invalidateMangledName();
587 }
588 }
589
setPrimarySize(unsigned char ps)590 void TType::setPrimarySize(unsigned char ps)
591 {
592 if (primarySize != ps)
593 {
594 ASSERT(ps <= 4);
595 primarySize = ps;
596 invalidateMangledName();
597 }
598 }
599
setSecondarySize(unsigned char ss)600 void TType::setSecondarySize(unsigned char ss)
601 {
602 if (secondarySize != ss)
603 {
604 ASSERT(ss <= 4);
605 secondarySize = ss;
606 invalidateMangledName();
607 }
608 }
609
makeArray(unsigned int s)610 void TType::makeArray(unsigned int s)
611 {
612 if (mArraySizesStorage == nullptr)
613 {
614 mArraySizesStorage = new TVector<unsigned int>();
615 }
616 // Add a dimension to the current ones.
617 mArraySizesStorage->push_back(s);
618 onArrayDimensionsChange(*mArraySizesStorage);
619 }
620
makeArrays(const TSpan<const unsigned int> & sizes)621 void TType::makeArrays(const TSpan<const unsigned int> &sizes)
622 {
623 if (mArraySizesStorage == nullptr)
624 {
625 mArraySizesStorage = new TVector<unsigned int>();
626 }
627 // Add dimensions to the current ones.
628 mArraySizesStorage->insert(mArraySizesStorage->end(), sizes.begin(), sizes.end());
629 onArrayDimensionsChange(*mArraySizesStorage);
630 }
631
setArraySize(size_t arrayDimension,unsigned int s)632 void TType::setArraySize(size_t arrayDimension, unsigned int s)
633 {
634 ASSERT(isArray() && mArraySizesStorage != nullptr);
635 ASSERT(arrayDimension < mArraySizesStorage->size());
636 if (mArraySizes[arrayDimension] != s)
637 {
638 (*mArraySizesStorage)[arrayDimension] = s;
639 invalidateMangledName();
640 }
641 }
642
toArrayElementType()643 void TType::toArrayElementType()
644 {
645 ASSERT(isArray() && mArraySizesStorage != nullptr);
646 mArraySizesStorage->pop_back();
647 onArrayDimensionsChange(*mArraySizesStorage);
648 }
649
toArrayBaseType()650 void TType::toArrayBaseType()
651 {
652 if (!isArray())
653 {
654 return;
655 }
656 if (mArraySizesStorage)
657 {
658 mArraySizesStorage->clear();
659 }
660 onArrayDimensionsChange(TSpan<const unsigned int>());
661 }
662
setInterfaceBlock(const TInterfaceBlock * interfaceBlockIn)663 void TType::setInterfaceBlock(const TInterfaceBlock *interfaceBlockIn)
664 {
665 if (mInterfaceBlock != interfaceBlockIn)
666 {
667 mInterfaceBlock = interfaceBlockIn;
668 invalidateMangledName();
669 }
670 }
671
getMangledName() const672 const char *TType::getMangledName() const
673 {
674 if (mMangledName == nullptr)
675 {
676 mMangledName = buildMangledName();
677 }
678
679 return mMangledName;
680 }
681
realize()682 void TType::realize()
683 {
684 getMangledName();
685 }
686
createSamplerSymbols(const ImmutableString & namePrefix,const TString & apiNamePrefix,TVector<const TVariable * > * outputSymbols,TMap<const TVariable *,TString> * outputSymbolsToAPINames,TSymbolTable * symbolTable) const687 void TType::createSamplerSymbols(const ImmutableString &namePrefix,
688 const TString &apiNamePrefix,
689 TVector<const TVariable *> *outputSymbols,
690 TMap<const TVariable *, TString> *outputSymbolsToAPINames,
691 TSymbolTable *symbolTable) const
692 {
693 if (isStructureContainingSamplers())
694 {
695 if (isArray())
696 {
697 TType elementType(*this);
698 elementType.toArrayElementType();
699 for (unsigned int arrayIndex = 0u; arrayIndex < getOutermostArraySize(); ++arrayIndex)
700 {
701 std::stringstream elementName = sh::InitializeStream<std::stringstream>();
702 elementName << namePrefix << "_" << arrayIndex;
703 TStringStream elementApiName;
704 elementApiName << apiNamePrefix << "[" << arrayIndex << "]";
705 elementType.createSamplerSymbols(ImmutableString(elementName.str()),
706 elementApiName.str(), outputSymbols,
707 outputSymbolsToAPINames, symbolTable);
708 }
709 }
710 else
711 {
712 mStructure->createSamplerSymbols(namePrefix.data(), apiNamePrefix, outputSymbols,
713 outputSymbolsToAPINames, symbolTable);
714 }
715 return;
716 }
717
718 ASSERT(IsSampler(type));
719 TVariable *variable =
720 new TVariable(symbolTable, namePrefix, new TType(*this), SymbolType::AngleInternal);
721 outputSymbols->push_back(variable);
722 if (outputSymbolsToAPINames)
723 {
724 (*outputSymbolsToAPINames)[variable] = apiNamePrefix;
725 }
726 }
727
TFieldListCollection(const TFieldList * fields)728 TFieldListCollection::TFieldListCollection(const TFieldList *fields)
729 : mFields(fields), mObjectSize(0), mDeepestNesting(0)
730 {}
731
containsArrays() const732 bool TFieldListCollection::containsArrays() const
733 {
734 for (const auto *field : *mFields)
735 {
736 const TType *fieldType = field->type();
737 if (fieldType->isArray() || fieldType->isStructureContainingArrays())
738 return true;
739 }
740 return false;
741 }
742
containsMatrices() const743 bool TFieldListCollection::containsMatrices() const
744 {
745 for (const auto *field : *mFields)
746 {
747 const TType *fieldType = field->type();
748 if (fieldType->isMatrix() || fieldType->isStructureContainingMatrices())
749 return true;
750 }
751 return false;
752 }
753
containsType(TBasicType type) const754 bool TFieldListCollection::containsType(TBasicType type) const
755 {
756 for (const auto *field : *mFields)
757 {
758 const TType *fieldType = field->type();
759 if (fieldType->getBasicType() == type || fieldType->isStructureContainingType(type))
760 return true;
761 }
762 return false;
763 }
764
containsSamplers() const765 bool TFieldListCollection::containsSamplers() const
766 {
767 for (const auto *field : *mFields)
768 {
769 const TType *fieldType = field->type();
770 if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
771 return true;
772 }
773 return false;
774 }
775
buildMangledFieldList() const776 TString TFieldListCollection::buildMangledFieldList() const
777 {
778 TString mangledName;
779 for (const auto *field : *mFields)
780 {
781 mangledName += field->type()->getMangledName();
782 }
783 return mangledName;
784 }
785
calculateObjectSize() const786 size_t TFieldListCollection::calculateObjectSize() const
787 {
788 size_t size = 0;
789 for (const TField *field : *mFields)
790 {
791 size_t fieldSize = field->type()->getObjectSize();
792 if (fieldSize > INT_MAX - size)
793 size = INT_MAX;
794 else
795 size += fieldSize;
796 }
797 return size;
798 }
799
objectSize() const800 size_t TFieldListCollection::objectSize() const
801 {
802 if (mObjectSize == 0)
803 mObjectSize = calculateObjectSize();
804 return mObjectSize;
805 }
806
getLocationCount() const807 int TFieldListCollection::getLocationCount() const
808 {
809 int count = 0;
810 for (const TField *field : *mFields)
811 {
812 int fieldCount = field->type()->getLocationCount();
813 if (fieldCount > std::numeric_limits<int>::max() - count)
814 {
815 count = std::numeric_limits<int>::max();
816 }
817 else
818 {
819 count += fieldCount;
820 }
821 }
822 return count;
823 }
824
deepestNesting() const825 int TFieldListCollection::deepestNesting() const
826 {
827 if (mDeepestNesting == 0)
828 mDeepestNesting = calculateDeepestNesting();
829 return mDeepestNesting;
830 }
831
mangledFieldList() const832 const TString &TFieldListCollection::mangledFieldList() const
833 {
834 if (mMangledFieldList.empty())
835 mMangledFieldList = buildMangledFieldList();
836 return mMangledFieldList;
837 }
838
calculateDeepestNesting() const839 int TFieldListCollection::calculateDeepestNesting() const
840 {
841 int maxNesting = 0;
842 for (size_t i = 0; i < mFields->size(); ++i)
843 maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
844 return 1 + maxNesting;
845 }
846
847 // TPublicType implementation.
initialize(const TTypeSpecifierNonArray & typeSpecifier,TQualifier q)848 void TPublicType::initialize(const TTypeSpecifierNonArray &typeSpecifier, TQualifier q)
849 {
850 typeSpecifierNonArray = typeSpecifier;
851 layoutQualifier = TLayoutQualifier::Create();
852 memoryQualifier = TMemoryQualifier::Create();
853 qualifier = q;
854 invariant = false;
855 precise = false;
856 precision = EbpUndefined;
857 arraySizes = nullptr;
858 }
859
initializeBasicType(TBasicType basicType)860 void TPublicType::initializeBasicType(TBasicType basicType)
861 {
862 typeSpecifierNonArray.type = basicType;
863 typeSpecifierNonArray.primarySize = 1;
864 typeSpecifierNonArray.secondarySize = 1;
865 layoutQualifier = TLayoutQualifier::Create();
866 memoryQualifier = TMemoryQualifier::Create();
867 qualifier = EvqTemporary;
868 invariant = false;
869 precise = false;
870 precision = EbpUndefined;
871 arraySizes = nullptr;
872 }
873
isStructureContainingArrays() const874 bool TPublicType::isStructureContainingArrays() const
875 {
876 if (!typeSpecifierNonArray.userDef)
877 {
878 return false;
879 }
880
881 return typeSpecifierNonArray.userDef->containsArrays();
882 }
883
isStructureContainingType(TBasicType t) const884 bool TPublicType::isStructureContainingType(TBasicType t) const
885 {
886 if (!typeSpecifierNonArray.userDef)
887 {
888 return false;
889 }
890
891 return typeSpecifierNonArray.userDef->containsType(t);
892 }
893
setArraySizes(TVector<unsigned int> * sizes)894 void TPublicType::setArraySizes(TVector<unsigned int> *sizes)
895 {
896 arraySizes = sizes;
897 }
898
isArray() const899 bool TPublicType::isArray() const
900 {
901 return arraySizes && !arraySizes->empty();
902 }
903
clearArrayness()904 void TPublicType::clearArrayness()
905 {
906 arraySizes = nullptr;
907 }
908
isAggregate() const909 bool TPublicType::isAggregate() const
910 {
911 return isArray() || typeSpecifierNonArray.isMatrix() || typeSpecifierNonArray.isVector();
912 }
913
914 } // namespace sh
915