blob: 27f55799ca0118198699a852669ddc91882a08b0 [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
Dmitry Skiba58832202015-07-06 16:11:13 -070032const TString *TFunction::buildMangledName() const
33{
34 std::string mangledName = mangleName(getName()).c_str();
35
36 for (const auto &p : parameters)
37 {
38 mangledName += p.type->getMangledName().c_str();
39 }
40
41 return NewPoolTString(mangledName.c_str());
42}
43
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000044//
45// Symbol table levels are a map of pointers to symbols that have to be deleted.
46//
47TSymbolTableLevel::~TSymbolTableLevel()
48{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000049 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
50 delete (*it).second;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000051}
52
Nicolas Capensadfffe42014-06-17 02:13:36 -040053bool TSymbolTableLevel::insert(TSymbol *symbol)
Jamie Madillbfa91f42014-06-05 15:45:18 -040054{
Nicolas Capensadfffe42014-06-17 02:13:36 -040055 symbol->setUniqueId(TSymbolTable::nextUniqueId());
Jamie Madillbfa91f42014-06-05 15:45:18 -040056
57 // returning true means symbol was added to the table
Nicolas Capensadfffe42014-06-17 02:13:36 -040058 tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
Jamie Madillbfa91f42014-06-05 15:45:18 -040059
60 return result.second;
61}
62
Olli Etuahob2983c92015-03-18 14:02:46 +020063bool TSymbolTableLevel::insertUnmangled(TFunction *function)
64{
65 function->setUniqueId(TSymbolTable::nextUniqueId());
66
67 // returning true means symbol was added to the table
68 tInsertResult result = level.insert(tLevelPair(function->getName(), function));
69
70 return result.second;
71}
72
Jamie Madillbfa91f42014-06-05 15:45:18 -040073TSymbol *TSymbolTableLevel::find(const TString &name) const
74{
75 tLevel::const_iterator it = level.find(name);
76 if (it == level.end())
77 return 0;
78 else
79 return (*it).second;
80}
81
Zhenyao Moe740add2014-07-18 17:01:01 -070082TSymbol *TSymbolTable::find(const TString &name, int shaderVersion,
83 bool *builtIn, bool *sameScope) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000084{
85 int level = currentLevel();
86 TSymbol *symbol;
87
88 do
89 {
Zhenyao Mo9eedea02014-05-12 16:02:35 -070090 if (level == ESSL3_BUILTINS && shaderVersion != 300)
91 level--;
92 if (level == ESSL1_BUILTINS && shaderVersion != 100)
93 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000094
95 symbol = table[level]->find(name);
96 }
97 while (symbol == 0 && --level >= 0);
98
99 if (builtIn)
100 *builtIn = (level <= LAST_BUILTIN_LEVEL);
101 if (sameScope)
102 *sameScope = (level == currentLevel());
103
104 return symbol;
105}
106
Zhenyao Moe740add2014-07-18 17:01:01 -0700107TSymbol *TSymbolTable::findBuiltIn(
108 const TString &name, int shaderVersion) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000109{
110 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
111 {
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700112 if (level == ESSL3_BUILTINS && shaderVersion != 300)
113 level--;
114 if (level == ESSL1_BUILTINS && shaderVersion != 100)
115 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000116
117 TSymbol *symbol = table[level]->find(name);
118
119 if (symbol)
120 return symbol;
121 }
122
123 return 0;
124}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400125
126TSymbolTable::~TSymbolTable()
127{
128 while (table.size() > 0)
129 pop();
130}
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700131
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500132bool IsGenType(const TType *type)
133{
134 if (type)
135 {
136 TBasicType basicType = type->getBasicType();
137 return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType || basicType == EbtGenBType;
138 }
139
140 return false;
141}
142
143bool IsVecType(const TType *type)
144{
145 if (type)
146 {
147 TBasicType basicType = type->getBasicType();
148 return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec || basicType == EbtBVec;
149 }
150
151 return false;
152}
153
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700154const TType *SpecificType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500155{
156 ASSERT(size >= 1 && size <= 4);
157
158 if (!type)
159 {
160 return nullptr;
161 }
162
163 ASSERT(!IsVecType(type));
164
165 switch(type->getBasicType())
166 {
Jamie Madill2f232372015-07-07 21:57:55 +0000167 case EbtGenType: return new TType(EbtFloat, static_cast<unsigned char>(size));
168 case EbtGenIType: return new TType(EbtInt, static_cast<unsigned char>(size));
169 case EbtGenUType: return new TType(EbtUInt, static_cast<unsigned char>(size));
170 case EbtGenBType: return new TType(EbtBool, static_cast<unsigned char>(size));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500171 default: return type;
172 }
173}
174
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700175const TType *VectorType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500176{
177 ASSERT(size >= 2 && size <= 4);
178
179 if (!type)
180 {
181 return nullptr;
182 }
183
184 ASSERT(!IsGenType(type));
185
186 switch(type->getBasicType())
187 {
Jamie Madill2f232372015-07-07 21:57:55 +0000188 case EbtVec: return new TType(EbtFloat, static_cast<unsigned char>(size));
189 case EbtIVec: return new TType(EbtInt, static_cast<unsigned char>(size));
190 case EbtUVec: return new TType(EbtUInt, static_cast<unsigned char>(size));
191 case EbtBVec: return new TType(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 -0700196void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *ext, const TType *rvalue, const char *name,
197 const TType *ptype1, const TType *ptype2, const TType *ptype3, const TType *ptype4, const TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700198{
199 if (ptype1->getBasicType() == EbtGSampler2D)
200 {
201 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madill2f232372015-07-07 21:57:55 +0000202 insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
203 insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
204 insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700205 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500206 else if (ptype1->getBasicType() == EbtGSampler3D)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700207 {
208 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madill2f232372015-07-07 21:57:55 +0000209 insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
210 insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
211 insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700212 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500213 else if (ptype1->getBasicType() == EbtGSamplerCube)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700214 {
215 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madill2f232372015-07-07 21:57:55 +0000216 insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
217 insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
218 insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700219 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500220 else if (ptype1->getBasicType() == EbtGSampler2DArray)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700221 {
222 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madill2f232372015-07-07 21:57:55 +0000223 insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
224 insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
225 insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700226 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500227 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3))
228 {
229 ASSERT(!ptype4 && !ptype5);
Nicolas Capensc9d9b302015-02-20 23:02:15 -0500230 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1), SpecificType(ptype2, 1), SpecificType(ptype3, 1));
231 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2), SpecificType(ptype2, 2), SpecificType(ptype3, 2));
232 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3), SpecificType(ptype2, 3), SpecificType(ptype3, 3));
233 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4), SpecificType(ptype2, 4), SpecificType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500234 }
235 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
236 {
237 ASSERT(!ptype4 && !ptype5);
Nicolas Capensc9d9b302015-02-20 23:02:15 -0500238 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2), VectorType(ptype2, 2), VectorType(ptype3, 2));
239 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3), VectorType(ptype2, 3), VectorType(ptype3, 3));
240 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4), VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500241 }
242 else
243 {
Dmitry Skiba7f17a502015-06-22 15:08:39 -0700244 TFunction *function = new TFunction(NewPoolTString(name), rvalue, op, ext);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700245
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700246 function->addParameter(TConstParameter(ptype1));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700247
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500248 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700249 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700250 function->addParameter(TConstParameter(ptype2));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700251 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700252
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500253 if (ptype3)
254 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700255 function->addParameter(TConstParameter(ptype3));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500256 }
257
258 if (ptype4)
259 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700260 function->addParameter(TConstParameter(ptype4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500261 }
262
263 if (ptype5)
264 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700265 function->addParameter(TConstParameter(ptype5));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500266 }
267
268 insert(level, function);
269 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700270}
271
Zhenyao Moe740add2014-07-18 17:01:01 -0700272TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700273{
274 if (!SupportsPrecision(type))
275 return EbpUndefined;
276
277 // unsigned integers use the same precision as signed
278 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
279
280 int level = static_cast<int>(precisionStack.size()) - 1;
281 assert(level >= 0); // Just to be safe. Should not happen.
282 // If we dont find anything we return this. Should we error check this?
283 TPrecision prec = EbpUndefined;
284 while (level >= 0)
285 {
286 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
287 if (it != precisionStack[level]->end())
288 {
289 prec = (*it).second;
290 break;
291 }
292 level--;
293 }
294 return prec;
295}