blob: 059c5c76ab55a0905a1cc01e4ae9653a61734301 [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
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000024//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000025// Functions have buried pointers to delete.
26//
27TFunction::~TFunction()
28{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000029 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
30 delete (*i).type;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000031}
32
Dmitry Skiba58832202015-07-06 16:11:13 -070033const TString *TFunction::buildMangledName() const
34{
Cooper Partin149e6e62015-08-07 16:18:18 -070035 std::string newName = mangleName(getName()).c_str();
Dmitry Skiba58832202015-07-06 16:11:13 -070036
37 for (const auto &p : parameters)
38 {
Cooper Partin149e6e62015-08-07 16:18:18 -070039 newName += p.type->getMangledName().c_str();
Dmitry Skiba58832202015-07-06 16:11:13 -070040 }
41
Cooper Partin149e6e62015-08-07 16:18:18 -070042 return NewPoolTString(newName.c_str());
Dmitry Skiba58832202015-07-06 16:11:13 -070043}
44
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000045//
46// Symbol table levels are a map of pointers to symbols that have to be deleted.
47//
48TSymbolTableLevel::~TSymbolTableLevel()
49{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000050 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
51 delete (*it).second;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000052}
53
Nicolas Capensadfffe42014-06-17 02:13:36 -040054bool TSymbolTableLevel::insert(TSymbol *symbol)
Jamie Madillbfa91f42014-06-05 15:45:18 -040055{
Nicolas Capensadfffe42014-06-17 02:13:36 -040056 symbol->setUniqueId(TSymbolTable::nextUniqueId());
Jamie Madillbfa91f42014-06-05 15:45:18 -040057
58 // returning true means symbol was added to the table
Nicolas Capensadfffe42014-06-17 02:13:36 -040059 tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
Jamie Madillbfa91f42014-06-05 15:45:18 -040060
61 return result.second;
62}
63
Olli Etuahob2983c92015-03-18 14:02:46 +020064bool TSymbolTableLevel::insertUnmangled(TFunction *function)
65{
66 function->setUniqueId(TSymbolTable::nextUniqueId());
67
68 // returning true means symbol was added to the table
69 tInsertResult result = level.insert(tLevelPair(function->getName(), function));
70
71 return result.second;
72}
73
Jamie Madillbfa91f42014-06-05 15:45:18 -040074TSymbol *TSymbolTableLevel::find(const TString &name) const
75{
76 tLevel::const_iterator it = level.find(name);
77 if (it == level.end())
78 return 0;
79 else
80 return (*it).second;
81}
82
Zhenyao Moe740add2014-07-18 17:01:01 -070083TSymbol *TSymbolTable::find(const TString &name, int shaderVersion,
84 bool *builtIn, bool *sameScope) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000085{
86 int level = currentLevel();
87 TSymbol *symbol;
88
89 do
90 {
Martin Radeve93d24e2016-07-28 12:06:05 +030091 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
92 level--;
93 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -070094 level--;
95 if (level == ESSL1_BUILTINS && shaderVersion != 100)
96 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000097
98 symbol = table[level]->find(name);
99 }
100 while (symbol == 0 && --level >= 0);
101
102 if (builtIn)
103 *builtIn = (level <= LAST_BUILTIN_LEVEL);
104 if (sameScope)
105 *sameScope = (level == currentLevel());
106
107 return symbol;
108}
109
Zhenyao Moe740add2014-07-18 17:01:01 -0700110TSymbol *TSymbolTable::findBuiltIn(
111 const TString &name, int shaderVersion) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000112{
113 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
114 {
Martin Radeve93d24e2016-07-28 12:06:05 +0300115 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
116 level--;
117 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700118 level--;
119 if (level == ESSL1_BUILTINS && shaderVersion != 100)
120 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000121
122 TSymbol *symbol = table[level]->find(name);
123
124 if (symbol)
125 return symbol;
126 }
127
128 return 0;
129}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400130
131TSymbolTable::~TSymbolTable()
132{
133 while (table.size() > 0)
134 pop();
135}
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700136
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500137bool IsGenType(const TType *type)
138{
139 if (type)
140 {
141 TBasicType basicType = type->getBasicType();
142 return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType || basicType == EbtGenBType;
143 }
144
145 return false;
146}
147
148bool IsVecType(const TType *type)
149{
150 if (type)
151 {
152 TBasicType basicType = type->getBasicType();
153 return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec || basicType == EbtBVec;
154 }
155
156 return false;
157}
158
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700159const TType *SpecificType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500160{
161 ASSERT(size >= 1 && size <= 4);
162
163 if (!type)
164 {
165 return nullptr;
166 }
167
168 ASSERT(!IsVecType(type));
169
170 switch(type->getBasicType())
171 {
Dmitry Skiba01971112015-07-10 14:54:00 -0400172 case EbtGenType: return TCache::getType(EbtFloat, static_cast<unsigned char>(size));
173 case EbtGenIType: return TCache::getType(EbtInt, static_cast<unsigned char>(size));
174 case EbtGenUType: return TCache::getType(EbtUInt, static_cast<unsigned char>(size));
175 case EbtGenBType: return TCache::getType(EbtBool, static_cast<unsigned char>(size));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500176 default: return type;
177 }
178}
179
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700180const TType *VectorType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500181{
182 ASSERT(size >= 2 && size <= 4);
183
184 if (!type)
185 {
186 return nullptr;
187 }
188
189 ASSERT(!IsGenType(type));
190
191 switch(type->getBasicType())
192 {
Dmitry Skiba01971112015-07-10 14:54:00 -0400193 case EbtVec: return TCache::getType(EbtFloat, static_cast<unsigned char>(size));
194 case EbtIVec: return TCache::getType(EbtInt, static_cast<unsigned char>(size));
195 case EbtUVec: return TCache::getType(EbtUInt, static_cast<unsigned char>(size));
196 case EbtBVec: return TCache::getType(EbtBool, static_cast<unsigned char>(size));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500197 default: return type;
198 }
199}
200
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700201void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *ext, const TType *rvalue, const char *name,
202 const TType *ptype1, const TType *ptype2, const TType *ptype3, const TType *ptype4, const TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700203{
204 if (ptype1->getBasicType() == EbtGSampler2D)
205 {
Olli Etuahoc4a96d62015-07-23 17:37:39 +0530206 insertUnmangledBuiltIn(name);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700207 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Dmitry Skiba01971112015-07-10 14:54:00 -0400208 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
209 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
210 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700211 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500212 else if (ptype1->getBasicType() == EbtGSampler3D)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700213 {
Olli Etuahoc4a96d62015-07-23 17:37:39 +0530214 insertUnmangledBuiltIn(name);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700215 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Dmitry Skiba01971112015-07-10 14:54:00 -0400216 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name, TCache::getType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
217 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
218 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700219 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500220 else if (ptype1->getBasicType() == EbtGSamplerCube)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700221 {
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(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
225 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
226 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700227 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500228 else if (ptype1->getBasicType() == EbtGSampler2DArray)
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(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
233 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name, TCache::getType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
234 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name, TCache::getType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700235 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500236 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3))
237 {
238 ASSERT(!ptype4 && !ptype5);
Olli Etuahoc4a96d62015-07-23 17:37:39 +0530239 insertUnmangledBuiltIn(name);
Nicolas Capensc9d9b302015-02-20 23:02:15 -0500240 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1), SpecificType(ptype2, 1), SpecificType(ptype3, 1));
241 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2), SpecificType(ptype2, 2), SpecificType(ptype3, 2));
242 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3), SpecificType(ptype2, 3), SpecificType(ptype3, 3));
243 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4), SpecificType(ptype2, 4), SpecificType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500244 }
245 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
246 {
247 ASSERT(!ptype4 && !ptype5);
Olli Etuahoc4a96d62015-07-23 17:37:39 +0530248 insertUnmangledBuiltIn(name);
Nicolas Capensc9d9b302015-02-20 23:02:15 -0500249 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2), VectorType(ptype2, 2), VectorType(ptype3, 2));
250 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3), VectorType(ptype2, 3), VectorType(ptype3, 3));
251 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4), VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500252 }
253 else
254 {
Dmitry Skiba7f17a502015-06-22 15:08:39 -0700255 TFunction *function = new TFunction(NewPoolTString(name), rvalue, op, ext);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700256
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700257 function->addParameter(TConstParameter(ptype1));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700258
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500259 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700260 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700261 function->addParameter(TConstParameter(ptype2));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700262 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700263
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500264 if (ptype3)
265 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700266 function->addParameter(TConstParameter(ptype3));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500267 }
268
269 if (ptype4)
270 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700271 function->addParameter(TConstParameter(ptype4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500272 }
273
274 if (ptype5)
275 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700276 function->addParameter(TConstParameter(ptype5));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500277 }
278
Olli Etuahoc4a96d62015-07-23 17:37:39 +0530279 ASSERT(hasUnmangledBuiltIn(name));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500280 insert(level, function);
281 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700282}
283
Zhenyao Moe740add2014-07-18 17:01:01 -0700284TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700285{
286 if (!SupportsPrecision(type))
287 return EbpUndefined;
288
289 // unsigned integers use the same precision as signed
290 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
291
292 int level = static_cast<int>(precisionStack.size()) - 1;
293 assert(level >= 0); // Just to be safe. Should not happen.
Olli Etuaho183d7e22015-11-20 15:59:09 +0200294 // If we dont find anything we return this. Some types don't have predefined default precision.
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700295 TPrecision prec = EbpUndefined;
296 while (level >= 0)
297 {
298 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
299 if (it != precisionStack[level]->end())
300 {
301 prec = (*it).second;
302 break;
303 }
304 level--;
305 }
306 return prec;
307}