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 &parametersSource)
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