1 //
2 // Copyright (c) 2002-2013 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 // Symbol table for parsing. The design principles and most of the functionality are documented in
7 // the header file.
8 //
9
10 #if defined(_MSC_VER)
11 #pragma warning(disable : 4718)
12 #endif
13
14 #include "compiler/translator/SymbolTable.h"
15
16 #include "compiler/translator/Cache.h"
17 #include "compiler/translator/IntermNode.h"
18
19 #include <stdio.h>
20 #include <algorithm>
21
22 namespace sh
23 {
24
25 namespace
26 {
27
28 static const char kFunctionMangledNameSeparator = '(';
29
30 } // anonymous namespace
31
TSymbol(TSymbolTable * symbolTable,const TString * n)32 TSymbol::TSymbol(TSymbolTable *symbolTable, const TString *n)
33 : uniqueId(symbolTable->nextUniqueId()), name(n), extension(TExtension::UNDEFINED)
34 {
35 }
36
37 //
38 // Functions have buried pointers to delete.
39 //
~TFunction()40 TFunction::~TFunction()
41 {
42 clearParameters();
43 }
44
clearParameters()45 void TFunction::clearParameters()
46 {
47 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
48 delete (*i).type;
49 parameters.clear();
50 mangledName = nullptr;
51 }
52
swapParameters(const TFunction & parametersSource)53 void TFunction::swapParameters(const TFunction ¶metersSource)
54 {
55 clearParameters();
56 for (auto parameter : parametersSource.parameters)
57 {
58 addParameter(parameter);
59 }
60 }
61
buildMangledName() const62 const TString *TFunction::buildMangledName() const
63 {
64 std::string newName = getName().c_str();
65 newName += kFunctionMangledNameSeparator;
66
67 for (const auto &p : parameters)
68 {
69 newName += p.type->getMangledName();
70 }
71 return NewPoolTString(newName.c_str());
72 }
73
GetMangledNameFromCall(const TString & functionName,const TIntermSequence & arguments)74 const TString &TFunction::GetMangledNameFromCall(const TString &functionName,
75 const TIntermSequence &arguments)
76 {
77 std::string newName = functionName.c_str();
78 newName += kFunctionMangledNameSeparator;
79
80 for (TIntermNode *argument : arguments)
81 {
82 newName += argument->getAsTyped()->getType().getMangledName();
83 }
84 return *NewPoolTString(newName.c_str());
85 }
86
87 //
88 // Symbol table levels are a map of pointers to symbols that have to be deleted.
89 //
~TSymbolTableLevel()90 TSymbolTableLevel::~TSymbolTableLevel()
91 {
92 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
93 delete (*it).second;
94 }
95
insert(TSymbol * symbol)96 bool TSymbolTableLevel::insert(TSymbol *symbol)
97 {
98 // returning true means symbol was added to the table
99 tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
100
101 return result.second;
102 }
103
insertUnmangled(TFunction * function)104 bool TSymbolTableLevel::insertUnmangled(TFunction *function)
105 {
106 // returning true means symbol was added to the table
107 tInsertResult result = level.insert(tLevelPair(function->getName(), function));
108
109 return result.second;
110 }
111
find(const TString & name) const112 TSymbol *TSymbolTableLevel::find(const TString &name) const
113 {
114 tLevel::const_iterator it = level.find(name);
115 if (it == level.end())
116 return 0;
117 else
118 return (*it).second;
119 }
120
find(const TString & name,int shaderVersion,bool * builtIn,bool * sameScope) const121 TSymbol *TSymbolTable::find(const TString &name,
122 int shaderVersion,
123 bool *builtIn,
124 bool *sameScope) const
125 {
126 int level = currentLevel();
127 TSymbol *symbol;
128
129 do
130 {
131 if (level == GLSL_BUILTINS)
132 level--;
133 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
134 level--;
135 if (level == ESSL3_BUILTINS && shaderVersion < 300)
136 level--;
137 if (level == ESSL1_BUILTINS && shaderVersion != 100)
138 level--;
139
140 symbol = table[level]->find(name);
141 } while (symbol == 0 && --level >= 0);
142
143 if (builtIn)
144 *builtIn = (level <= LAST_BUILTIN_LEVEL);
145 if (sameScope)
146 *sameScope = (level == currentLevel());
147
148 return symbol;
149 }
150
findGlobal(const TString & name) const151 TSymbol *TSymbolTable::findGlobal(const TString &name) const
152 {
153 ASSERT(table.size() > GLOBAL_LEVEL);
154 return table[GLOBAL_LEVEL]->find(name);
155 }
156
findBuiltIn(const TString & name,int shaderVersion) const157 TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
158 {
159 return findBuiltIn(name, shaderVersion, false);
160 }
161
findBuiltIn(const TString & name,int shaderVersion,bool includeGLSLBuiltins) const162 TSymbol *TSymbolTable::findBuiltIn(const TString &name,
163 int shaderVersion,
164 bool includeGLSLBuiltins) const
165 {
166 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
167 {
168 if (level == GLSL_BUILTINS && !includeGLSLBuiltins)
169 level--;
170 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
171 level--;
172 if (level == ESSL3_BUILTINS && shaderVersion < 300)
173 level--;
174 if (level == ESSL1_BUILTINS && shaderVersion != 100)
175 level--;
176
177 TSymbol *symbol = table[level]->find(name);
178
179 if (symbol)
180 return symbol;
181 }
182
183 return nullptr;
184 }
185
~TSymbolTable()186 TSymbolTable::~TSymbolTable()
187 {
188 while (table.size() > 0)
189 pop();
190 }
191
IsGenType(const TType * type)192 bool IsGenType(const TType *type)
193 {
194 if (type)
195 {
196 TBasicType basicType = type->getBasicType();
197 return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType ||
198 basicType == EbtGenBType;
199 }
200
201 return false;
202 }
203
IsVecType(const TType * type)204 bool IsVecType(const TType *type)
205 {
206 if (type)
207 {
208 TBasicType basicType = type->getBasicType();
209 return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec ||
210 basicType == EbtBVec;
211 }
212
213 return false;
214 }
215
SpecificType(const TType * type,int size)216 const TType *SpecificType(const TType *type, int size)
217 {
218 ASSERT(size >= 1 && size <= 4);
219
220 if (!type)
221 {
222 return nullptr;
223 }
224
225 ASSERT(!IsVecType(type));
226
227 switch (type->getBasicType())
228 {
229 case EbtGenType:
230 return TCache::getType(EbtFloat, type->getQualifier(),
231 static_cast<unsigned char>(size));
232 case EbtGenIType:
233 return TCache::getType(EbtInt, type->getQualifier(), static_cast<unsigned char>(size));
234 case EbtGenUType:
235 return TCache::getType(EbtUInt, type->getQualifier(), static_cast<unsigned char>(size));
236 case EbtGenBType:
237 return TCache::getType(EbtBool, type->getQualifier(), static_cast<unsigned char>(size));
238 default:
239 return type;
240 }
241 }
242
VectorType(const TType * type,int size)243 const TType *VectorType(const TType *type, int size)
244 {
245 ASSERT(size >= 2 && size <= 4);
246
247 if (!type)
248 {
249 return nullptr;
250 }
251
252 ASSERT(!IsGenType(type));
253
254 switch (type->getBasicType())
255 {
256 case EbtVec:
257 return TCache::getType(EbtFloat, static_cast<unsigned char>(size));
258 case EbtIVec:
259 return TCache::getType(EbtInt, static_cast<unsigned char>(size));
260 case EbtUVec:
261 return TCache::getType(EbtUInt, static_cast<unsigned char>(size));
262 case EbtBVec:
263 return TCache::getType(EbtBool, static_cast<unsigned char>(size));
264 default:
265 return type;
266 }
267 }
268
declareVariable(const TString * name,const TType & type)269 TVariable *TSymbolTable::declareVariable(const TString *name, const TType &type)
270 {
271 return insertVariable(currentLevel(), name, type);
272 }
273
declareStructType(TStructure * str)274 TVariable *TSymbolTable::declareStructType(TStructure *str)
275 {
276 return insertStructType(currentLevel(), str);
277 }
278
declareInterfaceBlockName(const TString * name)279 TInterfaceBlockName *TSymbolTable::declareInterfaceBlockName(const TString *name)
280 {
281 TInterfaceBlockName *blockNameSymbol = new TInterfaceBlockName(this, name);
282 if (insert(currentLevel(), blockNameSymbol))
283 {
284 return blockNameSymbol;
285 }
286 return nullptr;
287 }
288
insertInterfaceBlockNameExt(ESymbolLevel level,TExtension ext,const TString * name)289 TInterfaceBlockName *TSymbolTable::insertInterfaceBlockNameExt(ESymbolLevel level,
290 TExtension ext,
291 const TString *name)
292 {
293 TInterfaceBlockName *blockNameSymbol = new TInterfaceBlockName(this, name);
294 if (insert(level, ext, blockNameSymbol))
295 {
296 return blockNameSymbol;
297 }
298 return nullptr;
299 }
300
insertVariable(ESymbolLevel level,const char * name,const TType & type)301 TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType &type)
302 {
303 return insertVariable(level, NewPoolTString(name), type);
304 }
305
insertVariable(ESymbolLevel level,const TString * name,const TType & type)306 TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const TString *name, const TType &type)
307 {
308 TVariable *var = new TVariable(this, name, type);
309 if (insert(level, var))
310 {
311 // Do lazy initialization for struct types, so we allocate to the current scope.
312 if (var->getType().getBasicType() == EbtStruct)
313 {
314 var->getType().realize();
315 }
316 return var;
317 }
318 return nullptr;
319 }
320
insertVariableExt(ESymbolLevel level,TExtension ext,const char * name,const TType & type)321 TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
322 TExtension ext,
323 const char *name,
324 const TType &type)
325 {
326 TVariable *var = new TVariable(this, NewPoolTString(name), type);
327 if (insert(level, ext, var))
328 {
329 if (var->getType().getBasicType() == EbtStruct)
330 {
331 var->getType().realize();
332 }
333 return var;
334 }
335 return nullptr;
336 }
337
insertStructType(ESymbolLevel level,TStructure * str)338 TVariable *TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str)
339 {
340 TVariable *var = new TVariable(this, &str->name(), TType(str), true);
341 if (insert(level, var))
342 {
343 var->getType().realize();
344 return var;
345 }
346 return nullptr;
347 }
348
insertBuiltIn(ESymbolLevel level,TOperator op,TExtension ext,const TType * rvalue,const char * name,const TType * ptype1,const TType * ptype2,const TType * ptype3,const TType * ptype4,const TType * ptype5)349 void TSymbolTable::insertBuiltIn(ESymbolLevel level,
350 TOperator op,
351 TExtension ext,
352 const TType *rvalue,
353 const char *name,
354 const TType *ptype1,
355 const TType *ptype2,
356 const TType *ptype3,
357 const TType *ptype4,
358 const TType *ptype5)
359 {
360 if (ptype1->getBasicType() == EbtGSampler2D)
361 {
362 insertUnmangledBuiltInName(name, level);
363 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
364 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
365 TCache::getType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
366 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
367 TCache::getType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
368 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
369 TCache::getType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
370 }
371 else if (ptype1->getBasicType() == EbtGSampler3D)
372 {
373 insertUnmangledBuiltInName(name, level);
374 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
375 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
376 TCache::getType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
377 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
378 TCache::getType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
379 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
380 TCache::getType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
381 }
382 else if (ptype1->getBasicType() == EbtGSamplerCube)
383 {
384 insertUnmangledBuiltInName(name, level);
385 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
386 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
387 TCache::getType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
388 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
389 TCache::getType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
390 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
391 TCache::getType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
392 }
393 else if (ptype1->getBasicType() == EbtGSampler2DArray)
394 {
395 insertUnmangledBuiltInName(name, level);
396 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
397 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
398 TCache::getType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
399 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
400 TCache::getType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
401 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
402 TCache::getType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
403 }
404 else if (ptype1->getBasicType() == EbtGSampler2DMS)
405 {
406 insertUnmangledBuiltInName(name, level);
407 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
408 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
409 TCache::getType(EbtSampler2DMS), ptype2, ptype3, ptype4, ptype5);
410 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
411 TCache::getType(EbtISampler2DMS), ptype2, ptype3, ptype4, ptype5);
412 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
413 TCache::getType(EbtUSampler2DMS), ptype2, ptype3, ptype4, ptype5);
414 }
415 else if (IsGImage(ptype1->getBasicType()))
416 {
417 insertUnmangledBuiltInName(name, level);
418
419 const TType *floatType = TCache::getType(EbtFloat, 4);
420 const TType *intType = TCache::getType(EbtInt, 4);
421 const TType *unsignedType = TCache::getType(EbtUInt, 4);
422
423 const TType *floatImage =
424 TCache::getType(convertGImageToFloatImage(ptype1->getBasicType()));
425 const TType *intImage = TCache::getType(convertGImageToIntImage(ptype1->getBasicType()));
426 const TType *unsignedImage =
427 TCache::getType(convertGImageToUnsignedImage(ptype1->getBasicType()));
428
429 // GLSL ES 3.10, Revision 4, 8.12 Image Functions
430 if (rvalue->getBasicType() == EbtGVec4)
431 {
432 // imageLoad
433 insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
434 insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
435 insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
436 }
437 else if (rvalue->getBasicType() == EbtVoid)
438 {
439 // imageStore
440 insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
441 insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
442 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
443 }
444 else
445 {
446 // imageSize
447 insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
448 insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
449 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
450 }
451 }
452 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3) ||
453 IsGenType(ptype4))
454 {
455 ASSERT(!ptype5);
456 insertUnmangledBuiltInName(name, level);
457 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1),
458 SpecificType(ptype2, 1), SpecificType(ptype3, 1), SpecificType(ptype4, 1));
459 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2),
460 SpecificType(ptype2, 2), SpecificType(ptype3, 2), SpecificType(ptype4, 2));
461 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3),
462 SpecificType(ptype2, 3), SpecificType(ptype3, 3), SpecificType(ptype4, 3));
463 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4),
464 SpecificType(ptype2, 4), SpecificType(ptype3, 4), SpecificType(ptype4, 4));
465 }
466 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
467 {
468 ASSERT(!ptype4 && !ptype5);
469 insertUnmangledBuiltInName(name, level);
470 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2),
471 VectorType(ptype2, 2), VectorType(ptype3, 2));
472 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3),
473 VectorType(ptype2, 3), VectorType(ptype3, 3));
474 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4),
475 VectorType(ptype2, 4), VectorType(ptype3, 4));
476 }
477 else
478 {
479 TFunction *function = new TFunction(this, NewPoolTString(name), rvalue, op, ext);
480
481 function->addParameter(TConstParameter(ptype1));
482
483 if (ptype2)
484 {
485 function->addParameter(TConstParameter(ptype2));
486 }
487
488 if (ptype3)
489 {
490 function->addParameter(TConstParameter(ptype3));
491 }
492
493 if (ptype4)
494 {
495 function->addParameter(TConstParameter(ptype4));
496 }
497
498 if (ptype5)
499 {
500 function->addParameter(TConstParameter(ptype5));
501 }
502
503 ASSERT(hasUnmangledBuiltInAtLevel(name, level));
504 insert(level, function);
505 }
506 }
507
insertBuiltInOp(ESymbolLevel level,TOperator op,const TType * rvalue,const TType * ptype1,const TType * ptype2,const TType * ptype3,const TType * ptype4,const TType * ptype5)508 void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
509 TOperator op,
510 const TType *rvalue,
511 const TType *ptype1,
512 const TType *ptype2,
513 const TType *ptype3,
514 const TType *ptype4,
515 const TType *ptype5)
516 {
517 const char *name = GetOperatorString(op);
518 ASSERT(strlen(name) > 0);
519 insertUnmangledBuiltInName(name, level);
520 insertBuiltIn(level, op, TExtension::UNDEFINED, rvalue, name, ptype1, ptype2, ptype3, ptype4,
521 ptype5);
522 }
523
insertBuiltInOp(ESymbolLevel level,TOperator op,TExtension ext,const TType * rvalue,const TType * ptype1,const TType * ptype2,const TType * ptype3,const TType * ptype4,const TType * ptype5)524 void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
525 TOperator op,
526 TExtension ext,
527 const TType *rvalue,
528 const TType *ptype1,
529 const TType *ptype2,
530 const TType *ptype3,
531 const TType *ptype4,
532 const TType *ptype5)
533 {
534 const char *name = GetOperatorString(op);
535 insertUnmangledBuiltInName(name, level);
536 insertBuiltIn(level, op, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
537 }
538
insertBuiltInFunctionNoParameters(ESymbolLevel level,TOperator op,const TType * rvalue,const char * name)539 void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
540 TOperator op,
541 const TType *rvalue,
542 const char *name)
543 {
544 insertUnmangledBuiltInName(name, level);
545 insert(level, new TFunction(this, NewPoolTString(name), rvalue, op));
546 }
547
insertBuiltInFunctionNoParametersExt(ESymbolLevel level,TExtension ext,TOperator op,const TType * rvalue,const char * name)548 void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
549 TExtension ext,
550 TOperator op,
551 const TType *rvalue,
552 const char *name)
553 {
554 insertUnmangledBuiltInName(name, level);
555 insert(level, new TFunction(this, NewPoolTString(name), rvalue, op, ext));
556 }
557
getDefaultPrecision(TBasicType type) const558 TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
559 {
560 if (!SupportsPrecision(type))
561 return EbpUndefined;
562
563 // unsigned integers use the same precision as signed
564 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
565
566 int level = static_cast<int>(precisionStack.size()) - 1;
567 assert(level >= 0); // Just to be safe. Should not happen.
568 // If we dont find anything we return this. Some types don't have predefined default precision.
569 TPrecision prec = EbpUndefined;
570 while (level >= 0)
571 {
572 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
573 if (it != precisionStack[level]->end())
574 {
575 prec = (*it).second;
576 break;
577 }
578 level--;
579 }
580 return prec;
581 }
582
insertUnmangledBuiltInName(const char * name,ESymbolLevel level)583 void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
584 {
585 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
586 table[level]->insertUnmangledBuiltInName(std::string(name));
587 }
588
hasUnmangledBuiltInAtLevel(const char * name,ESymbolLevel level)589 bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level)
590 {
591 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
592 return table[level]->hasUnmangledBuiltIn(std::string(name));
593 }
594
hasUnmangledBuiltInForShaderVersion(const char * name,int shaderVersion)595 bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion)
596 {
597 ASSERT(static_cast<ESymbolLevel>(table.size()) > LAST_BUILTIN_LEVEL);
598
599 for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
600 {
601 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
602 {
603 --level;
604 }
605 if (level == ESSL3_BUILTINS && shaderVersion < 300)
606 {
607 --level;
608 }
609 if (level == ESSL1_BUILTINS && shaderVersion != 100)
610 {
611 --level;
612 }
613
614 if (table[level]->hasUnmangledBuiltIn(name))
615 {
616 return true;
617 }
618 }
619 return false;
620 }
621
622 } // namespace sh
623