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: return "void";
27 case EbtFloat: return "float";
28 case EbtInt: return "int";
29 case EbtUInt: return "uint";
30 case EbtBool: return "bool";
31 case EbtSampler2D: return "sampler2D";
32 case EbtSampler3D: return "sampler3D";
33 case EbtSamplerCube: return "samplerCube";
34 case EbtSamplerExternalOES: return "samplerExternalOES";
35 case EbtSampler2DRect: return "sampler2DRect";
36 case EbtSampler2DArray: return "sampler2DArray";
37 case EbtISampler2D: return "isampler2D";
38 case EbtISampler3D: return "isampler3D";
39 case EbtISamplerCube: return "isamplerCube";
40 case EbtISampler2DArray: return "isampler2DArray";
41 case EbtUSampler2D: return "usampler2D";
42 case EbtUSampler3D: return "usampler3D";
43 case EbtUSamplerCube: return "usamplerCube";
44 case EbtUSampler2DArray: return "usampler2DArray";
45 case EbtSampler2DShadow: return "sampler2DShadow";
46 case EbtSamplerCubeShadow: return "samplerCubeShadow";
47 case EbtSampler2DArrayShadow: return "sampler2DArrayShadow";
48 case EbtStruct: return "structure";
49 case EbtInterfaceBlock: return "interface block";
50 case EbtImage2D:
51 return "image2D";
52 case EbtIImage2D:
53 return "iimage2D";
54 case EbtUImage2D:
55 return "uimage2D";
56 case EbtImage3D:
57 return "image3D";
58 case EbtIImage3D:
59 return "iimage3D";
60 case EbtUImage3D:
61 return "uimage3D";
62 case EbtImage2DArray:
63 return "image2DArray";
64 case EbtIImage2DArray:
65 return "iimage2DArray";
66 case EbtUImage2DArray:
67 return "uimage2DArray";
68 case EbtImageCube:
69 return "imageCube";
70 case EbtIImageCube:
71 return "iimageCube";
72 case EbtUImageCube:
73 return "uimageCube";
74 default: UNREACHABLE(); return "unknown type";
75 }
76 }
77
TType(const TPublicType & p)78 TType::TType(const TPublicType &p)
79 : type(p.getBasicType()),
80 precision(p.precision),
81 qualifier(p.qualifier),
82 invariant(p.invariant),
83 memoryQualifier(p.memoryQualifier),
84 layoutQualifier(p.layoutQualifier),
85 primarySize(p.getPrimarySize()),
86 secondarySize(p.getSecondarySize()),
87 array(p.array),
88 arraySize(p.arraySize),
89 interfaceBlock(0),
90 structure(0)
91 {
92 if (p.getUserDef())
93 structure = p.getUserDef()->getStruct();
94 }
95
equals(const TStructure & other) const96 bool TStructure::equals(const TStructure &other) const
97 {
98 return (uniqueId() == other.uniqueId());
99 }
100
getBuiltInTypeNameString() const101 const char *TType::getBuiltInTypeNameString() const
102 {
103 if (isMatrix())
104 {
105 switch (getCols())
106 {
107 case 2:
108 switch (getRows())
109 {
110 case 2:
111 return "mat2";
112 case 3:
113 return "mat2x3";
114 case 4:
115 return "mat2x4";
116 default:
117 UNREACHABLE();
118 return nullptr;
119 }
120 case 3:
121 switch (getRows())
122 {
123 case 2:
124 return "mat3x2";
125 case 3:
126 return "mat3";
127 case 4:
128 return "mat3x4";
129 default:
130 UNREACHABLE();
131 return nullptr;
132 }
133 case 4:
134 switch (getRows())
135 {
136 case 2:
137 return "mat4x2";
138 case 3:
139 return "mat4x3";
140 case 4:
141 return "mat4";
142 default:
143 UNREACHABLE();
144 return nullptr;
145 }
146 default:
147 UNREACHABLE();
148 return nullptr;
149 }
150 }
151 if (isVector())
152 {
153 switch (getBasicType())
154 {
155 case EbtFloat:
156 switch (getNominalSize())
157 {
158 case 2:
159 return "vec2";
160 case 3:
161 return "vec3";
162 case 4:
163 return "vec4";
164 default:
165 UNREACHABLE();
166 return nullptr;
167 }
168 case EbtInt:
169 switch (getNominalSize())
170 {
171 case 2:
172 return "ivec2";
173 case 3:
174 return "ivec3";
175 case 4:
176 return "ivec4";
177 default:
178 UNREACHABLE();
179 return nullptr;
180 }
181 case EbtBool:
182 switch (getNominalSize())
183 {
184 case 2:
185 return "bvec2";
186 case 3:
187 return "bvec3";
188 case 4:
189 return "bvec4";
190 default:
191 UNREACHABLE();
192 return nullptr;
193 }
194 case EbtUInt:
195 switch (getNominalSize())
196 {
197 case 2:
198 return "uvec2";
199 case 3:
200 return "uvec3";
201 case 4:
202 return "uvec4";
203 default:
204 UNREACHABLE();
205 return nullptr;
206 }
207 default:
208 UNREACHABLE();
209 return nullptr;
210 }
211 }
212 ASSERT(getBasicType() != EbtStruct);
213 ASSERT(getBasicType() != EbtInterfaceBlock);
214 return getBasicString();
215 }
216
getCompleteString() const217 TString TType::getCompleteString() const
218 {
219 TStringStream stream;
220
221 if (invariant)
222 stream << "invariant ";
223 if (qualifier != EvqTemporary && qualifier != EvqGlobal)
224 stream << getQualifierString() << " ";
225 if (precision != EbpUndefined)
226 stream << getPrecisionString() << " ";
227 if (array)
228 stream << "array[" << getArraySize() << "] of ";
229 if (isMatrix())
230 stream << getCols() << "X" << getRows() << " matrix of ";
231 else if (isVector())
232 stream << getNominalSize() << "-component vector of ";
233
234 stream << getBasicString();
235 return stream.str();
236 }
237
238 //
239 // Recursively generate mangled names.
240 //
buildMangledName() const241 TString TType::buildMangledName() const
242 {
243 TString mangledName;
244 if (isMatrix())
245 mangledName += 'm';
246 else if (isVector())
247 mangledName += 'v';
248
249 switch (type)
250 {
251 case EbtFloat:
252 mangledName += 'f';
253 break;
254 case EbtInt:
255 mangledName += 'i';
256 break;
257 case EbtUInt:
258 mangledName += 'u';
259 break;
260 case EbtBool:
261 mangledName += 'b';
262 break;
263 case EbtSampler2D:
264 mangledName += "s2";
265 break;
266 case EbtSampler3D:
267 mangledName += "s3";
268 break;
269 case EbtSamplerCube:
270 mangledName += "sC";
271 break;
272 case EbtSampler2DArray:
273 mangledName += "s2a";
274 break;
275 case EbtSamplerExternalOES:
276 mangledName += "sext";
277 break;
278 case EbtSampler2DRect:
279 mangledName += "s2r";
280 break;
281 case EbtISampler2D:
282 mangledName += "is2";
283 break;
284 case EbtISampler3D:
285 mangledName += "is3";
286 break;
287 case EbtISamplerCube:
288 mangledName += "isC";
289 break;
290 case EbtISampler2DArray:
291 mangledName += "is2a";
292 break;
293 case EbtUSampler2D:
294 mangledName += "us2";
295 break;
296 case EbtUSampler3D:
297 mangledName += "us3";
298 break;
299 case EbtUSamplerCube:
300 mangledName += "usC";
301 break;
302 case EbtUSampler2DArray:
303 mangledName += "us2a";
304 break;
305 case EbtSampler2DShadow:
306 mangledName += "s2s";
307 break;
308 case EbtSamplerCubeShadow:
309 mangledName += "sCs";
310 break;
311 case EbtSampler2DArrayShadow:
312 mangledName += "s2as";
313 break;
314 case EbtImage2D:
315 mangledName += "im2";
316 break;
317 case EbtIImage2D:
318 mangledName += "iim2";
319 break;
320 case EbtUImage2D:
321 mangledName += "uim2";
322 break;
323 case EbtImage3D:
324 mangledName += "im3";
325 break;
326 case EbtIImage3D:
327 mangledName += "iim3";
328 break;
329 case EbtUImage3D:
330 mangledName += "uim3";
331 break;
332 case EbtImage2DArray:
333 mangledName += "im2a";
334 break;
335 case EbtIImage2DArray:
336 mangledName += "iim2a";
337 break;
338 case EbtUImage2DArray:
339 mangledName += "uim2a";
340 break;
341 case EbtImageCube:
342 mangledName += "imc";
343 break;
344 case EbtIImageCube:
345 mangledName += "iimc";
346 break;
347 case EbtUImageCube:
348 mangledName += "uimc";
349 break;
350 case EbtStruct:
351 mangledName += structure->mangledName();
352 break;
353 case EbtInterfaceBlock:
354 mangledName += interfaceBlock->mangledName();
355 break;
356 default:
357 // EbtVoid, EbtAddress and non types
358 break;
359 }
360
361 if (isMatrix())
362 {
363 mangledName += static_cast<char>('0' + getCols());
364 mangledName += static_cast<char>('x');
365 mangledName += static_cast<char>('0' + getRows());
366 }
367 else
368 {
369 mangledName += static_cast<char>('0' + getNominalSize());
370 }
371
372 if (isArray())
373 {
374 char buf[20];
375 snprintf(buf, sizeof(buf), "%d", arraySize);
376 mangledName += '[';
377 mangledName += buf;
378 mangledName += ']';
379 }
380 return mangledName;
381 }
382
getObjectSize() const383 size_t TType::getObjectSize() const
384 {
385 size_t totalSize;
386
387 if (getBasicType() == EbtStruct)
388 totalSize = structure->objectSize();
389 else
390 totalSize = primarySize * secondarySize;
391
392 if (isArray())
393 {
394 if (totalSize == 0)
395 return 0;
396
397 size_t currentArraySize = getArraySize();
398 if (currentArraySize > INT_MAX / totalSize)
399 totalSize = INT_MAX;
400 else
401 totalSize *= currentArraySize;
402 }
403
404 return totalSize;
405 }
406
TStructure(const TString * name,TFieldList * fields)407 TStructure::TStructure(const TString *name, TFieldList *fields)
408 : TFieldListCollection(name, fields),
409 mDeepestNesting(0),
410 mUniqueId(TSymbolTable::nextUniqueId()),
411 mAtGlobalScope(false)
412 {
413 }
414
containsArrays() const415 bool TStructure::containsArrays() const
416 {
417 for (size_t i = 0; i < mFields->size(); ++i)
418 {
419 const TType *fieldType = (*mFields)[i]->type();
420 if (fieldType->isArray() || fieldType->isStructureContainingArrays())
421 return true;
422 }
423 return false;
424 }
425
containsType(TBasicType type) const426 bool TStructure::containsType(TBasicType type) const
427 {
428 for (size_t i = 0; i < mFields->size(); ++i)
429 {
430 const TType *fieldType = (*mFields)[i]->type();
431 if (fieldType->getBasicType() == type || fieldType->isStructureContainingType(type))
432 return true;
433 }
434 return false;
435 }
436
containsSamplers() const437 bool TStructure::containsSamplers() const
438 {
439 for (size_t i = 0; i < mFields->size(); ++i)
440 {
441 const TType *fieldType = (*mFields)[i]->type();
442 if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
443 return true;
444 }
445 return false;
446 }
447
containsImages() const448 bool TStructure::containsImages() const
449 {
450 for (size_t i = 0; i < mFields->size(); ++i)
451 {
452 const TType *fieldType = (*mFields)[i]->type();
453 if (IsImage(fieldType->getBasicType()) || fieldType->isStructureContainingImages())
454 return true;
455 }
456 return false;
457 }
458
createSamplerSymbols(const TString & structName,const TString & structAPIName,const unsigned int arrayOfStructsSize,TVector<TIntermSymbol * > * outputSymbols,TMap<TIntermSymbol *,TString> * outputSymbolsToAPINames) const459 void TStructure::createSamplerSymbols(const TString &structName,
460 const TString &structAPIName,
461 const unsigned int arrayOfStructsSize,
462 TVector<TIntermSymbol *> *outputSymbols,
463 TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames) const
464 {
465 for (auto &field : *mFields)
466 {
467 const TType *fieldType = field->type();
468 if (IsSampler(fieldType->getBasicType()))
469 {
470 if (arrayOfStructsSize > 0u)
471 {
472 for (unsigned int arrayIndex = 0u; arrayIndex < arrayOfStructsSize; ++arrayIndex)
473 {
474 TStringStream name;
475 name << structName << "_" << arrayIndex << "_" << field->name();
476 TIntermSymbol *symbol = new TIntermSymbol(0, name.str(), *fieldType);
477 outputSymbols->push_back(symbol);
478
479 if (outputSymbolsToAPINames)
480 {
481 TStringStream apiName;
482 apiName << structAPIName << "[" << arrayIndex << "]." << field->name();
483 (*outputSymbolsToAPINames)[symbol] = apiName.str();
484 }
485 }
486 }
487 else
488 {
489 TString symbolName = structName + "_" + field->name();
490 TIntermSymbol *symbol = new TIntermSymbol(0, symbolName, *fieldType);
491 outputSymbols->push_back(symbol);
492
493 if (outputSymbolsToAPINames)
494 {
495 TString apiName = structAPIName + "." + field->name();
496 (*outputSymbolsToAPINames)[symbol] = apiName;
497 }
498 }
499 }
500 else if (fieldType->isStructureContainingSamplers())
501 {
502 unsigned int nestedArrayOfStructsSize =
503 fieldType->isArray() ? fieldType->getArraySize() : 0u;
504 if (arrayOfStructsSize > 0)
505 {
506 for (unsigned int arrayIndex = 0u; arrayIndex < arrayOfStructsSize; ++arrayIndex)
507 {
508 TStringStream fieldName;
509 fieldName << structName << "_" << arrayIndex << "_" << field->name();
510 TStringStream fieldAPIName;
511 if (outputSymbolsToAPINames)
512 {
513 fieldAPIName << structAPIName << "[" << arrayIndex << "]." << field->name();
514 }
515 fieldType->createSamplerSymbols(fieldName.str(), fieldAPIName.str(),
516 nestedArrayOfStructsSize, outputSymbols,
517 outputSymbolsToAPINames);
518 }
519 }
520 else
521 {
522 fieldType->createSamplerSymbols(
523 structName + "_" + field->name(), structAPIName + "." + field->name(),
524 nestedArrayOfStructsSize, outputSymbols, outputSymbolsToAPINames);
525 }
526 }
527 }
528 }
529
buildMangledName(const TString & mangledNamePrefix) const530 TString TFieldListCollection::buildMangledName(const TString &mangledNamePrefix) const
531 {
532 TString mangledName(mangledNamePrefix);
533 mangledName += *mName;
534 for (size_t i = 0; i < mFields->size(); ++i)
535 {
536 mangledName += '-';
537 mangledName += (*mFields)[i]->type()->getMangledName();
538 }
539 return mangledName;
540 }
541
calculateObjectSize() const542 size_t TFieldListCollection::calculateObjectSize() const
543 {
544 size_t size = 0;
545 for (size_t i = 0; i < mFields->size(); ++i)
546 {
547 size_t fieldSize = (*mFields)[i]->type()->getObjectSize();
548 if (fieldSize > INT_MAX - size)
549 size = INT_MAX;
550 else
551 size += fieldSize;
552 }
553 return size;
554 }
555
calculateDeepestNesting() const556 int TStructure::calculateDeepestNesting() const
557 {
558 int maxNesting = 0;
559 for (size_t i = 0; i < mFields->size(); ++i)
560 maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
561 return 1 + maxNesting;
562 }
563
564 } // namespace sh
565