blob: 92121e8f4ebaa25caf6e157964d3e23c99bb474f [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +00002// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003// 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
apatrick@chromium.orge057c5d2012-01-26 19:18:24 +000012#if defined(_MSC_VER)
13#pragma warning(disable: 4718)
14#endif
15
Geoff Lang17732822013-08-29 13:46:49 -040016#include "compiler/translator/SymbolTable.h"
Dmitry Skiba01971112015-07-10 14:54:00 -040017#include "compiler/translator/Cache.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000018
apatrick@chromium.org8187fa82010-06-15 22:09:28 +000019#include <stdio.h>
kbr@chromium.org476541f2011-10-27 21:14:51 +000020#include <algorithm>
21
Jamie Madillbfa91f42014-06-05 15:45:18 -040022int TSymbolTable::uniqueIdCounter = 0;
Nicolas Capensbd10cf52013-06-20 09:51:51 -040023
Olli Etuaho476197f2016-10-11 13:59:08 +010024TSymbol::TSymbol(const TString *n) : uniqueId(TSymbolTable::nextUniqueId()), name(n)
25{
26}
27
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000028//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000029// Functions have buried pointers to delete.
30//
31TFunction::~TFunction()
32{
Olli Etuaho476197f2016-10-11 13:59:08 +010033 clearParameters();
34}
35
36void TFunction::clearParameters()
37{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000038 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
39 delete (*i).type;
Olli Etuaho476197f2016-10-11 13:59:08 +010040 parameters.clear();
41 mangledName = nullptr;
42}
43
44void TFunction::swapParameters(const TFunction &parametersSource)
45{
46 clearParameters();
47 for (auto parameter : parametersSource.parameters)
48 {
49 addParameter(parameter);
50 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000051}
52
Dmitry Skiba58832202015-07-06 16:11:13 -070053const TString *TFunction::buildMangledName() const
54{
Cooper Partin149e6e62015-08-07 16:18:18 -070055 std::string newName = mangleName(getName()).c_str();
Dmitry Skiba58832202015-07-06 16:11:13 -070056
57 for (const auto &p : parameters)
58 {
Cooper Partin149e6e62015-08-07 16:18:18 -070059 newName += p.type->getMangledName().c_str();
Dmitry Skiba58832202015-07-06 16:11:13 -070060 }
61
Cooper Partin149e6e62015-08-07 16:18:18 -070062 return NewPoolTString(newName.c_str());
Dmitry Skiba58832202015-07-06 16:11:13 -070063}
64
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000065//
66// Symbol table levels are a map of pointers to symbols that have to be deleted.
67//
68TSymbolTableLevel::~TSymbolTableLevel()
69{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000070 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
71 delete (*it).second;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000072}
73
Nicolas Capensadfffe42014-06-17 02:13:36 -040074bool TSymbolTableLevel::insert(TSymbol *symbol)
Jamie Madillbfa91f42014-06-05 15:45:18 -040075{
Jamie Madillbfa91f42014-06-05 15:45:18 -040076 // returning true means symbol was added to the table
Nicolas Capensadfffe42014-06-17 02:13:36 -040077 tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
Jamie Madillbfa91f42014-06-05 15:45:18 -040078
79 return result.second;
80}
81
Olli Etuahob2983c92015-03-18 14:02:46 +020082bool TSymbolTableLevel::insertUnmangled(TFunction *function)
83{
Olli Etuahob2983c92015-03-18 14:02:46 +020084 // returning true means symbol was added to the table
85 tInsertResult result = level.insert(tLevelPair(function->getName(), function));
86
87 return result.second;
88}
89
Jamie Madillbfa91f42014-06-05 15:45:18 -040090TSymbol *TSymbolTableLevel::find(const TString &name) const
91{
92 tLevel::const_iterator it = level.find(name);
93 if (it == level.end())
94 return 0;
95 else
96 return (*it).second;
97}
98
Zhenyao Moe740add2014-07-18 17:01:01 -070099TSymbol *TSymbolTable::find(const TString &name, int shaderVersion,
100 bool *builtIn, bool *sameScope) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000101{
102 int level = currentLevel();
103 TSymbol *symbol;
104
105 do
106 {
Martin Radeve93d24e2016-07-28 12:06:05 +0300107 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
108 level--;
109 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700110 level--;
111 if (level == ESSL1_BUILTINS && shaderVersion != 100)
112 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000113
114 symbol = table[level]->find(name);
115 }
116 while (symbol == 0 && --level >= 0);
117
118 if (builtIn)
119 *builtIn = (level <= LAST_BUILTIN_LEVEL);
120 if (sameScope)
121 *sameScope = (level == currentLevel());
122
123 return symbol;
124}
125
Zhenyao Moe740add2014-07-18 17:01:01 -0700126TSymbol *TSymbolTable::findBuiltIn(
127 const TString &name, int shaderVersion) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000128{
129 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
130 {
Martin Radeve93d24e2016-07-28 12:06:05 +0300131 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
132 level--;
133 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700134 level--;
135 if (level == ESSL1_BUILTINS && shaderVersion != 100)
136 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000137
138 TSymbol *symbol = table[level]->find(name);
139
140 if (symbol)
141 return symbol;
142 }
143
144 return 0;
145}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400146
147TSymbolTable::~TSymbolTable()
148{
149 while (table.size() > 0)
150 pop();
151}
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700152
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500153bool IsGenType(const TType *type)
154{
155 if (type)
156 {
157 TBasicType basicType = type->getBasicType();
158 return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType || basicType == EbtGenBType;
159 }
160
161 return false;
162}
163
164bool IsVecType(const TType *type)
165{
166 if (type)
167 {
168 TBasicType basicType = type->getBasicType();
169 return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec || basicType == EbtBVec;
170 }
171
172 return false;
173}
174
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700175const TType *SpecificType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500176{
177 ASSERT(size >= 1 && size <= 4);
178
179 if (!type)
180 {
181 return nullptr;
182 }
183
184 ASSERT(!IsVecType(type));
185
186 switch(type->getBasicType())
187 {
Dmitry Skiba01971112015-07-10 14:54:00 -0400188 case EbtGenType: return TCache::getType(EbtFloat, static_cast<unsigned char>(size));
189 case EbtGenIType: return TCache::getType(EbtInt, static_cast<unsigned char>(size));
190 case EbtGenUType: return TCache::getType(EbtUInt, static_cast<unsigned char>(size));
191 case EbtGenBType: return TCache::getType(EbtBool, static_cast<unsigned char>(size));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500192 default: return type;
193 }
194}
195
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700196const TType *VectorType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500197{
198 ASSERT(size >= 2 && size <= 4);
199
200 if (!type)
201 {
202 return nullptr;
203 }
204
205 ASSERT(!IsGenType(type));
206
207 switch(type->getBasicType())
208 {
Dmitry Skiba01971112015-07-10 14:54:00 -0400209 case EbtVec: return TCache::getType(EbtFloat, static_cast<unsigned char>(size));
210 case EbtIVec: return TCache::getType(EbtInt, static_cast<unsigned char>(size));
211 case EbtUVec: return TCache::getType(EbtUInt, static_cast<unsigned char>(size));
212 case EbtBVec: return TCache::getType(EbtBool, static_cast<unsigned char>(size));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500213 default: return type;
214 }
215}
216
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700217void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *ext, const TType *rvalue, const char *name,
218 const TType *ptype1, const TType *ptype2, const TType *ptype3, const TType *ptype4, const TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700219{
220 if (ptype1->getBasicType() == EbtGSampler2D)
221 {
Olli Etuahoc4a96d62015-07-23 17:37:39 +0530222 insertUnmangledBuiltIn(name);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700223 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Dmitry Skiba01971112015-07-10 14:54:00 -0400224 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
225 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
226 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700227 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500228 else if (ptype1->getBasicType() == EbtGSampler3D)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700229 {
Olli Etuahoc4a96d62015-07-23 17:37:39 +0530230 insertUnmangledBuiltIn(name);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700231 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Dmitry Skiba01971112015-07-10 14:54:00 -0400232 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
233 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
234 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700235 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500236 else if (ptype1->getBasicType() == EbtGSamplerCube)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700237 {
Olli Etuahoc4a96d62015-07-23 17:37:39 +0530238 insertUnmangledBuiltIn(name);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700239 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Dmitry Skiba01971112015-07-10 14:54:00 -0400240 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
241 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
242 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700243 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500244 else if (ptype1->getBasicType() == EbtGSampler2DArray)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700245 {
Olli Etuahoc4a96d62015-07-23 17:37:39 +0530246 insertUnmangledBuiltIn(name);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700247 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Dmitry Skiba01971112015-07-10 14:54:00 -0400248 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
249 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
250 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700251 }
Martin Radev2cc85b32016-08-05 16:22:53 +0300252 else if (IsGImage(ptype1->getBasicType()))
253 {
254 insertUnmangledBuiltIn(name);
255
256 const TType *floatType = TCache::getType(EbtFloat, 4);
257 const TType *intType = TCache::getType(EbtInt, 4);
258 const TType *unsignedType = TCache::getType(EbtUInt, 4);
259
260 const TType *floatImage =
261 TCache::getType(convertGImageToFloatImage(ptype1->getBasicType()));
262 const TType *intImage = TCache::getType(convertGImageToIntImage(ptype1->getBasicType()));
263 const TType *unsignedImage =
264 TCache::getType(convertGImageToUnsignedImage(ptype1->getBasicType()));
265
266 // GLSL ES 3.10, Revision 4, 8.12 Image Functions
267 if (rvalue->getBasicType() == EbtGVec4)
268 {
269 // imageLoad
270 insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
271 insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
272 insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
273 }
274 else if (rvalue->getBasicType() == EbtVoid)
275 {
276 // imageStore
277 insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
278 insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
279 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
280 }
281 else
282 {
283 // imageSize
284 insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
285 insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
286 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
287 }
288 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500289 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3))
290 {
291 ASSERT(!ptype4 && !ptype5);
Olli Etuahoc4a96d62015-07-23 17:37:39 +0530292 insertUnmangledBuiltIn(name);
Nicolas Capensc9d9b302015-02-20 23:02:15 -0500293 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1), SpecificType(ptype2, 1), SpecificType(ptype3, 1));
294 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2), SpecificType(ptype2, 2), SpecificType(ptype3, 2));
295 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3), SpecificType(ptype2, 3), SpecificType(ptype3, 3));
296 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4), SpecificType(ptype2, 4), SpecificType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500297 }
298 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
299 {
300 ASSERT(!ptype4 && !ptype5);
Olli Etuahoc4a96d62015-07-23 17:37:39 +0530301 insertUnmangledBuiltIn(name);
Nicolas Capensc9d9b302015-02-20 23:02:15 -0500302 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2), VectorType(ptype2, 2), VectorType(ptype3, 2));
303 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3), VectorType(ptype2, 3), VectorType(ptype3, 3));
304 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4), VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500305 }
306 else
307 {
Dmitry Skiba7f17a502015-06-22 15:08:39 -0700308 TFunction *function = new TFunction(NewPoolTString(name), rvalue, op, ext);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700309
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700310 function->addParameter(TConstParameter(ptype1));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700311
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500312 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700313 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700314 function->addParameter(TConstParameter(ptype2));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700315 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700316
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500317 if (ptype3)
318 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700319 function->addParameter(TConstParameter(ptype3));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500320 }
321
322 if (ptype4)
323 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700324 function->addParameter(TConstParameter(ptype4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500325 }
326
327 if (ptype5)
328 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700329 function->addParameter(TConstParameter(ptype5));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500330 }
331
Olli Etuahoc4a96d62015-07-23 17:37:39 +0530332 ASSERT(hasUnmangledBuiltIn(name));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500333 insert(level, function);
334 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700335}
336
Zhenyao Moe740add2014-07-18 17:01:01 -0700337TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700338{
339 if (!SupportsPrecision(type))
340 return EbpUndefined;
341
342 // unsigned integers use the same precision as signed
343 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
344
345 int level = static_cast<int>(precisionStack.size()) - 1;
346 assert(level >= 0); // Just to be safe. Should not happen.
Olli Etuaho183d7e22015-11-20 15:59:09 +0200347 // If we dont find anything we return this. Some types don't have predefined default precision.
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700348 TPrecision prec = EbpUndefined;
349 while (level >= 0)
350 {
351 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
352 if (it != precisionStack[level]->end())
353 {
354 prec = (*it).second;
355 break;
356 }
357 level--;
358 }
359 return prec;
360}