blob: a230ef42bffb470bd1e8a6f14136a0b86685a080 [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"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000017
apatrick@chromium.org8187fa82010-06-15 22:09:28 +000018#include <stdio.h>
kbr@chromium.org476541f2011-10-27 21:14:51 +000019#include <algorithm>
20
Jamie Madillbfa91f42014-06-05 15:45:18 -040021int TSymbolTable::uniqueIdCounter = 0;
Nicolas Capensbd10cf52013-06-20 09:51:51 -040022
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000023//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000024// Functions have buried pointers to delete.
25//
26TFunction::~TFunction()
27{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000028 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
29 delete (*i).type;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000030}
31
32//
33// Symbol table levels are a map of pointers to symbols that have to be deleted.
34//
35TSymbolTableLevel::~TSymbolTableLevel()
36{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000037 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
38 delete (*it).second;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000039}
40
Nicolas Capensadfffe42014-06-17 02:13:36 -040041bool TSymbolTableLevel::insert(TSymbol *symbol)
Jamie Madillbfa91f42014-06-05 15:45:18 -040042{
Nicolas Capensadfffe42014-06-17 02:13:36 -040043 symbol->setUniqueId(TSymbolTable::nextUniqueId());
Jamie Madillbfa91f42014-06-05 15:45:18 -040044
45 // returning true means symbol was added to the table
Nicolas Capensadfffe42014-06-17 02:13:36 -040046 tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
Jamie Madillbfa91f42014-06-05 15:45:18 -040047
48 return result.second;
49}
50
Jamie Madillbfa91f42014-06-05 15:45:18 -040051TSymbol *TSymbolTableLevel::find(const TString &name) const
52{
53 tLevel::const_iterator it = level.find(name);
54 if (it == level.end())
55 return 0;
56 else
57 return (*it).second;
58}
59
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000060//
61// Change all function entries in the table with the non-mangled name
alokp@chromium.org8815d7f2010-09-09 17:30:03 +000062// to be related to the provided built-in extension. This is a low
63// performance operation, and only intended for symbol tables that
64// live across a large number of compiles.
65//
Zhenyao Mo9eedea02014-05-12 16:02:35 -070066void TSymbolTableLevel::relateToExtension(const char *name, const TString &ext)
alokp@chromium.org8815d7f2010-09-09 17:30:03 +000067{
Zhenyao Mo9eedea02014-05-12 16:02:35 -070068 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
69 {
70 TSymbol *symbol = it->second;
71 if (symbol->getName() == name)
Jamie Madill2aeb26a2013-07-08 14:02:55 -040072 symbol->relateToExtension(ext);
alokp@chromium.org8815d7f2010-09-09 17:30:03 +000073 }
74}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000075
Zhenyao Moe740add2014-07-18 17:01:01 -070076TSymbol *TSymbolTable::find(const TString &name, int shaderVersion,
77 bool *builtIn, bool *sameScope) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000078{
79 int level = currentLevel();
80 TSymbol *symbol;
81
82 do
83 {
Zhenyao Mo9eedea02014-05-12 16:02:35 -070084 if (level == ESSL3_BUILTINS && shaderVersion != 300)
85 level--;
86 if (level == ESSL1_BUILTINS && shaderVersion != 100)
87 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000088
89 symbol = table[level]->find(name);
90 }
91 while (symbol == 0 && --level >= 0);
92
93 if (builtIn)
94 *builtIn = (level <= LAST_BUILTIN_LEVEL);
95 if (sameScope)
96 *sameScope = (level == currentLevel());
97
98 return symbol;
99}
100
Zhenyao Moe740add2014-07-18 17:01:01 -0700101TSymbol *TSymbolTable::findBuiltIn(
102 const TString &name, int shaderVersion) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000103{
104 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
105 {
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700106 if (level == ESSL3_BUILTINS && shaderVersion != 300)
107 level--;
108 if (level == ESSL1_BUILTINS && shaderVersion != 100)
109 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000110
111 TSymbol *symbol = table[level]->find(name);
112
113 if (symbol)
114 return symbol;
115 }
116
117 return 0;
118}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400119
120TSymbolTable::~TSymbolTable()
121{
122 while (table.size() > 0)
123 pop();
124}
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700125
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500126bool IsGenType(const TType *type)
127{
128 if (type)
129 {
130 TBasicType basicType = type->getBasicType();
131 return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType || basicType == EbtGenBType;
132 }
133
134 return false;
135}
136
137bool IsVecType(const TType *type)
138{
139 if (type)
140 {
141 TBasicType basicType = type->getBasicType();
142 return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec || basicType == EbtBVec;
143 }
144
145 return false;
146}
147
148TType *SpecificType(TType *type, int size)
149{
150 ASSERT(size >= 1 && size <= 4);
151
152 if (!type)
153 {
154 return nullptr;
155 }
156
157 ASSERT(!IsVecType(type));
158
159 switch(type->getBasicType())
160 {
161 case EbtGenType: return new TType(EbtFloat, size);
162 case EbtGenIType: return new TType(EbtInt, size);
163 case EbtGenUType: return new TType(EbtUInt, size);
164 case EbtGenBType: return new TType(EbtBool, size);
165 default: return type;
166 }
167}
168
169TType *VectorType(TType *type, int size)
170{
171 ASSERT(size >= 2 && size <= 4);
172
173 if (!type)
174 {
175 return nullptr;
176 }
177
178 ASSERT(!IsGenType(type));
179
180 switch(type->getBasicType())
181 {
182 case EbtVec: return new TType(EbtFloat, size);
183 case EbtIVec: return new TType(EbtInt, size);
184 case EbtUVec: return new TType(EbtUInt, size);
185 case EbtBVec: return new TType(EbtBool, size);
186 default: return type;
187 }
188}
189
Nicolas Capens482907e2015-02-23 16:56:33 -0500190void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, TType *rvalue, const char *name, TType *ptype1, TType *ptype2, TType *ptype3, TType *ptype4, TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700191{
192 if (ptype1->getBasicType() == EbtGSampler2D)
193 {
194 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500195 insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
196 insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
197 insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700198 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500199 else if (ptype1->getBasicType() == EbtGSampler3D)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700200 {
201 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500202 insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
203 insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
204 insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700205 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500206 else if (ptype1->getBasicType() == EbtGSamplerCube)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700207 {
208 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500209 insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
210 insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
211 insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700212 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500213 else if (ptype1->getBasicType() == EbtGSampler2DArray)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700214 {
215 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500216 insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
217 insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
218 insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700219 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500220 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3))
221 {
222 ASSERT(!ptype4 && !ptype5);
Nicolas Capens482907e2015-02-23 16:56:33 -0500223 insertBuiltIn(level, op, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1), SpecificType(ptype2, 1), SpecificType(ptype3, 1));
224 insertBuiltIn(level, op, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2), SpecificType(ptype2, 2), SpecificType(ptype3, 2));
225 insertBuiltIn(level, op, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3), SpecificType(ptype2, 3), SpecificType(ptype3, 3));
226 insertBuiltIn(level, op, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4), SpecificType(ptype2, 4), SpecificType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500227 }
228 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
229 {
230 ASSERT(!ptype4 && !ptype5);
Nicolas Capens482907e2015-02-23 16:56:33 -0500231 insertBuiltIn(level, op, VectorType(rvalue, 2), name, VectorType(ptype1, 2), VectorType(ptype2, 2), VectorType(ptype3, 2));
232 insertBuiltIn(level, op, VectorType(rvalue, 3), name, VectorType(ptype1, 3), VectorType(ptype2, 3), VectorType(ptype3, 3));
233 insertBuiltIn(level, op, VectorType(rvalue, 4), name, VectorType(ptype1, 4), VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500234 }
235 else
236 {
Nicolas Capens482907e2015-02-23 16:56:33 -0500237 TFunction *function = new TFunction(NewPoolTString(name), *rvalue, op);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700238
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500239 TParameter param1 = {0, ptype1};
240 function->addParameter(param1);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700241
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500242 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700243 {
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500244 TParameter param2 = {0, ptype2};
245 function->addParameter(param2);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700246 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700247
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500248 if (ptype3)
249 {
250 TParameter param3 = {0, ptype3};
251 function->addParameter(param3);
252 }
253
254 if (ptype4)
255 {
256 TParameter param4 = {0, ptype4};
257 function->addParameter(param4);
258 }
259
260 if (ptype5)
261 {
262 TParameter param5 = {0, ptype5};
263 function->addParameter(param5);
264 }
265
266 insert(level, function);
267 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700268}
269
Zhenyao Moe740add2014-07-18 17:01:01 -0700270TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700271{
272 if (!SupportsPrecision(type))
273 return EbpUndefined;
274
275 // unsigned integers use the same precision as signed
276 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
277
278 int level = static_cast<int>(precisionStack.size()) - 1;
279 assert(level >= 0); // Just to be safe. Should not happen.
280 // If we dont find anything we return this. Should we error check this?
281 TPrecision prec = EbpUndefined;
282 while (level >= 0)
283 {
284 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
285 if (it != precisionStack[level]->end())
286 {
287 prec = (*it).second;
288 break;
289 }
290 level--;
291 }
292 return prec;
293}