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