blob: 34ef025a3ac5152df336d7d8e5a87ec4162f04fa [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 Madill45bcc782016-11-07 13:58:48 -050022namespace sh
23{
24
Jamie Madillbfa91f42014-06-05 15:45:18 -040025int TSymbolTable::uniqueIdCounter = 0;
Nicolas Capensbd10cf52013-06-20 09:51:51 -040026
Olli Etuaho476197f2016-10-11 13:59:08 +010027TSymbol::TSymbol(const TString *n) : uniqueId(TSymbolTable::nextUniqueId()), name(n)
28{
29}
30
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000031//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000032// Functions have buried pointers to delete.
33//
34TFunction::~TFunction()
35{
Olli Etuaho476197f2016-10-11 13:59:08 +010036 clearParameters();
37}
38
39void TFunction::clearParameters()
40{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000041 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
42 delete (*i).type;
Olli Etuaho476197f2016-10-11 13:59:08 +010043 parameters.clear();
44 mangledName = nullptr;
45}
46
47void TFunction::swapParameters(const TFunction &parametersSource)
48{
49 clearParameters();
50 for (auto parameter : parametersSource.parameters)
51 {
52 addParameter(parameter);
53 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000054}
55
Dmitry Skiba58832202015-07-06 16:11:13 -070056const TString *TFunction::buildMangledName() const
57{
Cooper Partin149e6e62015-08-07 16:18:18 -070058 std::string newName = mangleName(getName()).c_str();
Dmitry Skiba58832202015-07-06 16:11:13 -070059
60 for (const auto &p : parameters)
61 {
Cooper Partin149e6e62015-08-07 16:18:18 -070062 newName += p.type->getMangledName().c_str();
Dmitry Skiba58832202015-07-06 16:11:13 -070063 }
64
Cooper Partin149e6e62015-08-07 16:18:18 -070065 return NewPoolTString(newName.c_str());
Dmitry Skiba58832202015-07-06 16:11:13 -070066}
67
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000068//
69// Symbol table levels are a map of pointers to symbols that have to be deleted.
70//
71TSymbolTableLevel::~TSymbolTableLevel()
72{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000073 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
74 delete (*it).second;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000075}
76
Nicolas Capensadfffe42014-06-17 02:13:36 -040077bool TSymbolTableLevel::insert(TSymbol *symbol)
Jamie Madillbfa91f42014-06-05 15:45:18 -040078{
Jamie Madillbfa91f42014-06-05 15:45:18 -040079 // returning true means symbol was added to the table
Nicolas Capensadfffe42014-06-17 02:13:36 -040080 tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
Jamie Madillbfa91f42014-06-05 15:45:18 -040081
82 return result.second;
83}
84
Olli Etuahob2983c92015-03-18 14:02:46 +020085bool TSymbolTableLevel::insertUnmangled(TFunction *function)
86{
Olli Etuahob2983c92015-03-18 14:02:46 +020087 // returning true means symbol was added to the table
88 tInsertResult result = level.insert(tLevelPair(function->getName(), function));
89
90 return result.second;
91}
92
Jamie Madillbfa91f42014-06-05 15:45:18 -040093TSymbol *TSymbolTableLevel::find(const TString &name) const
94{
95 tLevel::const_iterator it = level.find(name);
96 if (it == level.end())
97 return 0;
98 else
99 return (*it).second;
100}
101
Zhenyao Moe740add2014-07-18 17:01:01 -0700102TSymbol *TSymbolTable::find(const TString &name, int shaderVersion,
103 bool *builtIn, bool *sameScope) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000104{
105 int level = currentLevel();
106 TSymbol *symbol;
107
108 do
109 {
Martin Radeve93d24e2016-07-28 12:06:05 +0300110 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
111 level--;
112 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700113 level--;
114 if (level == ESSL1_BUILTINS && shaderVersion != 100)
115 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000116
117 symbol = table[level]->find(name);
118 }
119 while (symbol == 0 && --level >= 0);
120
121 if (builtIn)
122 *builtIn = (level <= LAST_BUILTIN_LEVEL);
123 if (sameScope)
124 *sameScope = (level == currentLevel());
125
126 return symbol;
127}
128
Zhenyao Moe740add2014-07-18 17:01:01 -0700129TSymbol *TSymbolTable::findBuiltIn(
130 const TString &name, int shaderVersion) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000131{
132 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
133 {
Martin Radeve93d24e2016-07-28 12:06:05 +0300134 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
135 level--;
136 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700137 level--;
138 if (level == ESSL1_BUILTINS && shaderVersion != 100)
139 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000140
141 TSymbol *symbol = table[level]->find(name);
142
143 if (symbol)
144 return symbol;
145 }
146
147 return 0;
148}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400149
150TSymbolTable::~TSymbolTable()
151{
152 while (table.size() > 0)
153 pop();
154}
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700155
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500156bool IsGenType(const TType *type)
157{
158 if (type)
159 {
160 TBasicType basicType = type->getBasicType();
161 return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType || basicType == EbtGenBType;
162 }
163
164 return false;
165}
166
167bool IsVecType(const TType *type)
168{
169 if (type)
170 {
171 TBasicType basicType = type->getBasicType();
172 return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec || basicType == EbtBVec;
173 }
174
175 return false;
176}
177
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700178const TType *SpecificType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500179{
180 ASSERT(size >= 1 && size <= 4);
181
182 if (!type)
183 {
184 return nullptr;
185 }
186
187 ASSERT(!IsVecType(type));
188
189 switch(type->getBasicType())
190 {
Dmitry Skiba01971112015-07-10 14:54:00 -0400191 case EbtGenType: return TCache::getType(EbtFloat, static_cast<unsigned char>(size));
192 case EbtGenIType: return TCache::getType(EbtInt, static_cast<unsigned char>(size));
193 case EbtGenUType: return TCache::getType(EbtUInt, static_cast<unsigned char>(size));
194 case EbtGenBType: return TCache::getType(EbtBool, static_cast<unsigned char>(size));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500195 default: return type;
196 }
197}
198
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700199const TType *VectorType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500200{
201 ASSERT(size >= 2 && size <= 4);
202
203 if (!type)
204 {
205 return nullptr;
206 }
207
208 ASSERT(!IsGenType(type));
209
210 switch(type->getBasicType())
211 {
Dmitry Skiba01971112015-07-10 14:54:00 -0400212 case EbtVec: return TCache::getType(EbtFloat, static_cast<unsigned char>(size));
213 case EbtIVec: return TCache::getType(EbtInt, static_cast<unsigned char>(size));
214 case EbtUVec: return TCache::getType(EbtUInt, static_cast<unsigned char>(size));
215 case EbtBVec: return TCache::getType(EbtBool, static_cast<unsigned char>(size));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500216 default: return type;
217 }
218}
219
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700220void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *ext, const TType *rvalue, const char *name,
221 const TType *ptype1, const TType *ptype2, const TType *ptype3, const TType *ptype4, const TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700222{
223 if (ptype1->getBasicType() == EbtGSampler2D)
224 {
Olli Etuahoc4a96d62015-07-23 17:37:39 +0530225 insertUnmangledBuiltIn(name);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700226 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Dmitry Skiba01971112015-07-10 14:54:00 -0400227 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
228 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
229 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700230 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500231 else if (ptype1->getBasicType() == EbtGSampler3D)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700232 {
Olli Etuahoc4a96d62015-07-23 17:37:39 +0530233 insertUnmangledBuiltIn(name);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700234 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Dmitry Skiba01971112015-07-10 14:54:00 -0400235 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
236 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
237 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700238 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500239 else if (ptype1->getBasicType() == EbtGSamplerCube)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700240 {
Olli Etuahoc4a96d62015-07-23 17:37:39 +0530241 insertUnmangledBuiltIn(name);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700242 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Dmitry Skiba01971112015-07-10 14:54:00 -0400243 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
244 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
245 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700246 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500247 else if (ptype1->getBasicType() == EbtGSampler2DArray)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700248 {
Olli Etuahoc4a96d62015-07-23 17:37:39 +0530249 insertUnmangledBuiltIn(name);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700250 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Dmitry Skiba01971112015-07-10 14:54:00 -0400251 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
252 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
253 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700254 }
Martin Radev2cc85b32016-08-05 16:22:53 +0300255 else if (IsGImage(ptype1->getBasicType()))
256 {
257 insertUnmangledBuiltIn(name);
258
259 const TType *floatType = TCache::getType(EbtFloat, 4);
260 const TType *intType = TCache::getType(EbtInt, 4);
261 const TType *unsignedType = TCache::getType(EbtUInt, 4);
262
263 const TType *floatImage =
264 TCache::getType(convertGImageToFloatImage(ptype1->getBasicType()));
265 const TType *intImage = TCache::getType(convertGImageToIntImage(ptype1->getBasicType()));
266 const TType *unsignedImage =
267 TCache::getType(convertGImageToUnsignedImage(ptype1->getBasicType()));
268
269 // GLSL ES 3.10, Revision 4, 8.12 Image Functions
270 if (rvalue->getBasicType() == EbtGVec4)
271 {
272 // imageLoad
273 insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
274 insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
275 insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
276 }
277 else if (rvalue->getBasicType() == EbtVoid)
278 {
279 // imageStore
280 insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
281 insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
282 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
283 }
284 else
285 {
286 // imageSize
287 insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
288 insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
289 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
290 }
291 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500292 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3))
293 {
294 ASSERT(!ptype4 && !ptype5);
Olli Etuahoc4a96d62015-07-23 17:37:39 +0530295 insertUnmangledBuiltIn(name);
Nicolas Capensc9d9b302015-02-20 23:02:15 -0500296 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1), SpecificType(ptype2, 1), SpecificType(ptype3, 1));
297 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2), SpecificType(ptype2, 2), SpecificType(ptype3, 2));
298 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3), SpecificType(ptype2, 3), SpecificType(ptype3, 3));
299 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4), SpecificType(ptype2, 4), SpecificType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500300 }
301 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
302 {
303 ASSERT(!ptype4 && !ptype5);
Olli Etuahoc4a96d62015-07-23 17:37:39 +0530304 insertUnmangledBuiltIn(name);
Nicolas Capensc9d9b302015-02-20 23:02:15 -0500305 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2), VectorType(ptype2, 2), VectorType(ptype3, 2));
306 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3), VectorType(ptype2, 3), VectorType(ptype3, 3));
307 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4), VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500308 }
309 else
310 {
Dmitry Skiba7f17a502015-06-22 15:08:39 -0700311 TFunction *function = new TFunction(NewPoolTString(name), rvalue, op, ext);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700312
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700313 function->addParameter(TConstParameter(ptype1));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700314
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500315 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700316 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700317 function->addParameter(TConstParameter(ptype2));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700318 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700319
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500320 if (ptype3)
321 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700322 function->addParameter(TConstParameter(ptype3));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500323 }
324
325 if (ptype4)
326 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700327 function->addParameter(TConstParameter(ptype4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500328 }
329
330 if (ptype5)
331 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700332 function->addParameter(TConstParameter(ptype5));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500333 }
334
Olli Etuahoc4a96d62015-07-23 17:37:39 +0530335 ASSERT(hasUnmangledBuiltIn(name));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500336 insert(level, function);
337 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700338}
339
Zhenyao Moe740add2014-07-18 17:01:01 -0700340TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700341{
342 if (!SupportsPrecision(type))
343 return EbpUndefined;
344
345 // unsigned integers use the same precision as signed
346 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
347
348 int level = static_cast<int>(precisionStack.size()) - 1;
349 assert(level >= 0); // Just to be safe. Should not happen.
Olli Etuaho183d7e22015-11-20 15:59:09 +0200350 // If we dont find anything we return this. Some types don't have predefined default precision.
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700351 TPrecision prec = EbpUndefined;
352 while (level >= 0)
353 {
354 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
355 if (it != precisionStack[level]->end())
356 {
357 prec = (*it).second;
358 break;
359 }
360 level--;
361 }
362 return prec;
363}
Jamie Madill45bcc782016-11-07 13:58:48 -0500364
365} // namespace sh