Line data Source code
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 : #include "compiler/translator/Cache.h"
18 :
19 : #include <stdio.h>
20 : #include <algorithm>
21 :
22 : namespace sh
23 : {
24 :
25 : int TSymbolTable::uniqueIdCounter = 0;
26 :
27 0 : TSymbol::TSymbol(const TString *n) : uniqueId(TSymbolTable::nextUniqueId()), name(n)
28 : {
29 0 : }
30 :
31 : //
32 : // Functions have buried pointers to delete.
33 : //
34 0 : TFunction::~TFunction()
35 : {
36 0 : clearParameters();
37 0 : }
38 :
39 0 : void TFunction::clearParameters()
40 : {
41 0 : for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
42 0 : delete (*i).type;
43 0 : parameters.clear();
44 0 : mangledName = nullptr;
45 0 : }
46 :
47 0 : void TFunction::swapParameters(const TFunction ¶metersSource)
48 : {
49 0 : clearParameters();
50 0 : for (auto parameter : parametersSource.parameters)
51 : {
52 0 : addParameter(parameter);
53 : }
54 0 : }
55 :
56 0 : const TString *TFunction::buildMangledName() const
57 : {
58 0 : std::string newName = mangleName(getName()).c_str();
59 :
60 0 : for (const auto &p : parameters)
61 : {
62 0 : newName += p.type->getMangledName().c_str();
63 : }
64 :
65 0 : return NewPoolTString(newName.c_str());
66 : }
67 :
68 : //
69 : // Symbol table levels are a map of pointers to symbols that have to be deleted.
70 : //
71 0 : TSymbolTableLevel::~TSymbolTableLevel()
72 : {
73 0 : for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
74 0 : delete (*it).second;
75 0 : }
76 :
77 0 : bool TSymbolTableLevel::insert(TSymbol *symbol)
78 : {
79 : // returning true means symbol was added to the table
80 0 : tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
81 :
82 0 : return result.second;
83 : }
84 :
85 0 : bool TSymbolTableLevel::insertUnmangled(TFunction *function)
86 : {
87 : // returning true means symbol was added to the table
88 0 : tInsertResult result = level.insert(tLevelPair(function->getName(), function));
89 :
90 0 : return result.second;
91 : }
92 :
93 0 : TSymbol *TSymbolTableLevel::find(const TString &name) const
94 : {
95 0 : tLevel::const_iterator it = level.find(name);
96 0 : if (it == level.end())
97 0 : return 0;
98 : else
99 0 : return (*it).second;
100 : }
101 :
102 0 : TSymbol *TSymbolTable::find(const TString &name, int shaderVersion,
103 : bool *builtIn, bool *sameScope) const
104 : {
105 0 : int level = currentLevel();
106 : TSymbol *symbol;
107 :
108 0 : do
109 : {
110 0 : if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
111 0 : level--;
112 0 : if (level == ESSL3_BUILTINS && shaderVersion < 300)
113 0 : level--;
114 0 : if (level == ESSL1_BUILTINS && shaderVersion != 100)
115 0 : level--;
116 :
117 0 : symbol = table[level]->find(name);
118 : }
119 0 : while (symbol == 0 && --level >= 0);
120 :
121 0 : if (builtIn)
122 0 : *builtIn = (level <= LAST_BUILTIN_LEVEL);
123 0 : if (sameScope)
124 0 : *sameScope = (level == currentLevel());
125 :
126 0 : return symbol;
127 : }
128 :
129 0 : TSymbol *TSymbolTable::findGlobal(const TString &name) const
130 : {
131 0 : ASSERT(table.size() > GLOBAL_LEVEL);
132 0 : return table[GLOBAL_LEVEL]->find(name);
133 : }
134 :
135 0 : TSymbol *TSymbolTable::findBuiltIn(
136 : const TString &name, int shaderVersion) const
137 : {
138 0 : for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
139 : {
140 0 : if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
141 0 : level--;
142 0 : if (level == ESSL3_BUILTINS && shaderVersion < 300)
143 0 : level--;
144 0 : if (level == ESSL1_BUILTINS && shaderVersion != 100)
145 0 : level--;
146 :
147 0 : TSymbol *symbol = table[level]->find(name);
148 :
149 0 : if (symbol)
150 0 : return symbol;
151 : }
152 :
153 0 : return 0;
154 : }
155 :
156 0 : TSymbolTable::~TSymbolTable()
157 : {
158 0 : while (table.size() > 0)
159 0 : pop();
160 0 : }
161 :
162 0 : bool IsGenType(const TType *type)
163 : {
164 0 : if (type)
165 : {
166 0 : TBasicType basicType = type->getBasicType();
167 0 : return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType || basicType == EbtGenBType;
168 : }
169 :
170 0 : return false;
171 : }
172 :
173 0 : bool IsVecType(const TType *type)
174 : {
175 0 : if (type)
176 : {
177 0 : TBasicType basicType = type->getBasicType();
178 0 : return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec || basicType == EbtBVec;
179 : }
180 :
181 0 : return false;
182 : }
183 :
184 0 : const TType *SpecificType(const TType *type, int size)
185 : {
186 0 : ASSERT(size >= 1 && size <= 4);
187 :
188 0 : if (!type)
189 : {
190 0 : return nullptr;
191 : }
192 :
193 0 : ASSERT(!IsVecType(type));
194 :
195 0 : switch(type->getBasicType())
196 : {
197 0 : case EbtGenType: return TCache::getType(EbtFloat, static_cast<unsigned char>(size));
198 0 : case EbtGenIType: return TCache::getType(EbtInt, static_cast<unsigned char>(size));
199 0 : case EbtGenUType: return TCache::getType(EbtUInt, static_cast<unsigned char>(size));
200 0 : case EbtGenBType: return TCache::getType(EbtBool, static_cast<unsigned char>(size));
201 0 : default: return type;
202 : }
203 : }
204 :
205 0 : const TType *VectorType(const TType *type, int size)
206 : {
207 0 : ASSERT(size >= 2 && size <= 4);
208 :
209 0 : if (!type)
210 : {
211 0 : return nullptr;
212 : }
213 :
214 0 : ASSERT(!IsGenType(type));
215 :
216 0 : switch(type->getBasicType())
217 : {
218 0 : case EbtVec: return TCache::getType(EbtFloat, static_cast<unsigned char>(size));
219 0 : case EbtIVec: return TCache::getType(EbtInt, static_cast<unsigned char>(size));
220 0 : case EbtUVec: return TCache::getType(EbtUInt, static_cast<unsigned char>(size));
221 0 : case EbtBVec: return TCache::getType(EbtBool, static_cast<unsigned char>(size));
222 0 : default: return type;
223 : }
224 : }
225 :
226 0 : void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *ext, const TType *rvalue, const char *name,
227 : const TType *ptype1, const TType *ptype2, const TType *ptype3, const TType *ptype4, const TType *ptype5)
228 : {
229 0 : if (ptype1->getBasicType() == EbtGSampler2D)
230 : {
231 0 : insertUnmangledBuiltIn(name);
232 0 : bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
233 0 : insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
234 0 : insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
235 0 : insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
236 : }
237 0 : else if (ptype1->getBasicType() == EbtGSampler3D)
238 : {
239 0 : insertUnmangledBuiltIn(name);
240 0 : bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
241 0 : insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
242 0 : insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
243 0 : insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
244 : }
245 0 : else if (ptype1->getBasicType() == EbtGSamplerCube)
246 : {
247 0 : insertUnmangledBuiltIn(name);
248 0 : bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
249 0 : insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
250 0 : insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
251 0 : insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
252 : }
253 0 : else if (ptype1->getBasicType() == EbtGSampler2DArray)
254 : {
255 0 : insertUnmangledBuiltIn(name);
256 0 : bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
257 0 : insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
258 0 : insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
259 0 : insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
260 : }
261 0 : else if (IsGImage(ptype1->getBasicType()))
262 : {
263 0 : insertUnmangledBuiltIn(name);
264 :
265 0 : const TType *floatType = TCache::getType(EbtFloat, 4);
266 0 : const TType *intType = TCache::getType(EbtInt, 4);
267 0 : const TType *unsignedType = TCache::getType(EbtUInt, 4);
268 :
269 : const TType *floatImage =
270 0 : TCache::getType(convertGImageToFloatImage(ptype1->getBasicType()));
271 0 : const TType *intImage = TCache::getType(convertGImageToIntImage(ptype1->getBasicType()));
272 : const TType *unsignedImage =
273 0 : TCache::getType(convertGImageToUnsignedImage(ptype1->getBasicType()));
274 :
275 : // GLSL ES 3.10, Revision 4, 8.12 Image Functions
276 0 : if (rvalue->getBasicType() == EbtGVec4)
277 : {
278 : // imageLoad
279 0 : insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
280 0 : insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
281 0 : insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
282 : }
283 0 : else if (rvalue->getBasicType() == EbtVoid)
284 : {
285 : // imageStore
286 0 : insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
287 0 : insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
288 0 : insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
289 : }
290 : else
291 : {
292 : // imageSize
293 0 : insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
294 0 : insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
295 0 : insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
296 : }
297 : }
298 0 : else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3))
299 : {
300 0 : ASSERT(!ptype4 && !ptype5);
301 0 : insertUnmangledBuiltIn(name);
302 0 : insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1), SpecificType(ptype2, 1), SpecificType(ptype3, 1));
303 0 : insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2), SpecificType(ptype2, 2), SpecificType(ptype3, 2));
304 0 : insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3), SpecificType(ptype2, 3), SpecificType(ptype3, 3));
305 0 : insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4), SpecificType(ptype2, 4), SpecificType(ptype3, 4));
306 : }
307 0 : else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
308 : {
309 0 : ASSERT(!ptype4 && !ptype5);
310 0 : insertUnmangledBuiltIn(name);
311 0 : insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2), VectorType(ptype2, 2), VectorType(ptype3, 2));
312 0 : insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3), VectorType(ptype2, 3), VectorType(ptype3, 3));
313 0 : insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4), VectorType(ptype2, 4), VectorType(ptype3, 4));
314 : }
315 : else
316 : {
317 0 : TFunction *function = new TFunction(NewPoolTString(name), rvalue, op, ext);
318 :
319 0 : function->addParameter(TConstParameter(ptype1));
320 :
321 0 : if (ptype2)
322 : {
323 0 : function->addParameter(TConstParameter(ptype2));
324 : }
325 :
326 0 : if (ptype3)
327 : {
328 0 : function->addParameter(TConstParameter(ptype3));
329 : }
330 :
331 0 : if (ptype4)
332 : {
333 0 : function->addParameter(TConstParameter(ptype4));
334 : }
335 :
336 0 : if (ptype5)
337 : {
338 0 : function->addParameter(TConstParameter(ptype5));
339 : }
340 :
341 0 : ASSERT(hasUnmangledBuiltIn(name));
342 0 : insert(level, function);
343 : }
344 0 : }
345 :
346 0 : TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
347 : {
348 0 : if (!SupportsPrecision(type))
349 0 : return EbpUndefined;
350 :
351 : // unsigned integers use the same precision as signed
352 0 : TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
353 :
354 0 : int level = static_cast<int>(precisionStack.size()) - 1;
355 0 : assert(level >= 0); // Just to be safe. Should not happen.
356 : // If we dont find anything we return this. Some types don't have predefined default precision.
357 0 : TPrecision prec = EbpUndefined;
358 0 : while (level >= 0)
359 : {
360 0 : PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
361 0 : if (it != precisionStack[level]->end())
362 : {
363 0 : prec = (*it).second;
364 0 : break;
365 : }
366 0 : level--;
367 : }
368 0 : return prec;
369 : }
370 :
371 : } // namespace sh
|