• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
7 //
8 // Symbol table for parsing.  Most functionaliy and main ideas
9 // are documented in the header file.
10 //
11 
12 #if defined(_MSC_VER)
13 #pragma warning(disable: 4718)
14 #endif
15 
16 #include "compiler/translator/SymbolTable.h"
17 
18 #include <stdio.h>
19 #include <algorithm>
20 
21 int TSymbolTable::uniqueIdCounter = 0;
22 
23 //
24 // Functions have buried pointers to delete.
25 //
~TFunction()26 TFunction::~TFunction()
27 {
28     for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
29         delete (*i).type;
30 }
31 
32 //
33 // Symbol table levels are a map of pointers to symbols that have to be deleted.
34 //
~TSymbolTableLevel()35 TSymbolTableLevel::~TSymbolTableLevel()
36 {
37     for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
38         delete (*it).second;
39 }
40 
insert(const TString & name,TSymbol & symbol)41 bool TSymbolTableLevel::insert(const TString &name, TSymbol &symbol)
42 {
43     symbol.setUniqueId(TSymbolTable::nextUniqueId());
44 
45     // returning true means symbol was added to the table
46     tInsertResult result = level.insert(tLevelPair(name, &symbol));
47 
48     return result.second;
49 }
50 
insert(TSymbol & symbol)51 bool TSymbolTableLevel::insert(TSymbol &symbol)
52 {
53     return insert(symbol.getMangledName(), symbol);
54 }
55 
find(const TString & name) const56 TSymbol *TSymbolTableLevel::find(const TString &name) const
57 {
58     tLevel::const_iterator it = level.find(name);
59     if (it == level.end())
60         return 0;
61     else
62         return (*it).second;
63 }
64 
65 //
66 // Change all function entries in the table with the non-mangled name
67 // to be related to the provided built-in operation.  This is a low
68 // performance operation, and only intended for symbol tables that
69 // live across a large number of compiles.
70 //
relateToOperator(const char * name,TOperator op)71 void TSymbolTableLevel::relateToOperator(const char *name, TOperator op)
72 {
73     for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
74     {
75         if ((*it).second->isFunction())
76         {
77             TFunction *function = static_cast<TFunction*>((*it).second);
78             if (function->getName() == name)
79                 function->relateToOperator(op);
80         }
81     }
82 }
83 
84 //
85 // Change all function entries in the table with the non-mangled name
86 // to be related to the provided built-in extension. This is a low
87 // performance operation, and only intended for symbol tables that
88 // live across a large number of compiles.
89 //
relateToExtension(const char * name,const TString & ext)90 void TSymbolTableLevel::relateToExtension(const char *name, const TString &ext)
91 {
92     for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
93     {
94         TSymbol *symbol = it->second;
95         if (symbol->getName() == name)
96             symbol->relateToExtension(ext);
97     }
98 }
99 
TSymbol(const TSymbol & copyOf)100 TSymbol::TSymbol(const TSymbol &copyOf)
101 {
102     name = NewPoolTString(copyOf.name->c_str());
103     uniqueId = copyOf.uniqueId;
104 }
105 
find(const TString & name,int shaderVersion,bool * builtIn,bool * sameScope)106 TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, bool *builtIn, bool *sameScope)
107 {
108     int level = currentLevel();
109     TSymbol *symbol;
110 
111     do
112     {
113         if (level == ESSL3_BUILTINS && shaderVersion != 300)
114             level--;
115         if (level == ESSL1_BUILTINS && shaderVersion != 100)
116             level--;
117 
118         symbol = table[level]->find(name);
119     }
120     while (symbol == 0 && --level >= 0);
121 
122     if (builtIn)
123         *builtIn = (level <= LAST_BUILTIN_LEVEL);
124     if (sameScope)
125         *sameScope = (level == currentLevel());
126 
127     return symbol;
128 }
129 
findBuiltIn(const TString & name,int shaderVersion)130 TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion)
131 {
132     for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
133     {
134         if (level == ESSL3_BUILTINS && shaderVersion != 300)
135             level--;
136         if (level == ESSL1_BUILTINS && shaderVersion != 100)
137             level--;
138 
139         TSymbol *symbol = table[level]->find(name);
140 
141         if (symbol)
142             return symbol;
143     }
144 
145     return 0;
146 }
147 
~TSymbolTable()148 TSymbolTable::~TSymbolTable()
149 {
150     while (table.size() > 0)
151         pop();
152 }
153 
insertBuiltIn(ESymbolLevel level,TType * rvalue,const char * name,TType * ptype1,TType * ptype2,TType * ptype3,TType * ptype4,TType * ptype5)154 void TSymbolTable::insertBuiltIn(
155     ESymbolLevel level, TType *rvalue, const char *name,
156     TType *ptype1, TType *ptype2, TType *ptype3, TType *ptype4, TType *ptype5)
157 {
158     if (ptype1->getBasicType() == EbtGSampler2D)
159     {
160         bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
161         insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name,
162                       new TType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
163         insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name,
164                       new TType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
165         insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name,
166                       new TType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
167         return;
168     }
169     if (ptype1->getBasicType() == EbtGSampler3D)
170     {
171         bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
172         insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name,
173                       new TType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
174         insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name,
175                       new TType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
176         insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name,
177                       new TType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
178         return;
179     }
180     if (ptype1->getBasicType() == EbtGSamplerCube)
181     {
182         bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
183         insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name,
184                       new TType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
185         insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name,
186                       new TType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
187         insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name,
188                       new TType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
189         return;
190     }
191     if (ptype1->getBasicType() == EbtGSampler2DArray)
192     {
193         bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
194         insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name,
195                       new TType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
196         insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name,
197                       new TType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
198         insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name,
199                       new TType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
200         return;
201     }
202 
203     TFunction *function = new TFunction(NewPoolTString(name), *rvalue);
204 
205     TType *types[] = {ptype1, ptype2, ptype3, ptype4, ptype5};
206     for (size_t ii = 0; ii < sizeof(types) / sizeof(types[0]); ++ii)
207     {
208         if (types[ii])
209         {
210             TParameter param = {NULL, types[ii]};
211             function->addParameter(param);
212         }
213     }
214 
215     insert(level, *function);
216 }
217 
getDefaultPrecision(TBasicType type)218 TPrecision TSymbolTable::getDefaultPrecision(TBasicType type)
219 {
220     if (!SupportsPrecision(type))
221         return EbpUndefined;
222 
223     // unsigned integers use the same precision as signed
224     TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
225 
226     int level = static_cast<int>(precisionStack.size()) - 1;
227     assert(level >= 0); // Just to be safe. Should not happen.
228     // If we dont find anything we return this. Should we error check this?
229     TPrecision prec = EbpUndefined;
230     while (level >= 0)
231     {
232         PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
233         if (it != precisionStack[level]->end())
234         {
235             prec = (*it).second;
236             break;
237         }
238         level--;
239     }
240     return prec;
241 }
242