blob: 9525040f5c42c46ffe5002105a9b8e62fbc81989 [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
Olli Etuahob2983c92015-03-18 14:02:46 +020051bool TSymbolTableLevel::insertUnmangled(TFunction *function)
52{
53 function->setUniqueId(TSymbolTable::nextUniqueId());
54
55 // returning true means symbol was added to the table
56 tInsertResult result = level.insert(tLevelPair(function->getName(), function));
57
58 return result.second;
59}
60
Jamie Madillbfa91f42014-06-05 15:45:18 -040061TSymbol *TSymbolTableLevel::find(const TString &name) const
62{
63 tLevel::const_iterator it = level.find(name);
64 if (it == level.end())
65 return 0;
66 else
67 return (*it).second;
68}
69
Zhenyao Moe740add2014-07-18 17:01:01 -070070TSymbol *TSymbolTable::find(const TString &name, int shaderVersion,
71 bool *builtIn, bool *sameScope) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000072{
73 int level = currentLevel();
74 TSymbol *symbol;
75
76 do
77 {
Zhenyao Mo9eedea02014-05-12 16:02:35 -070078 if (level == ESSL3_BUILTINS && shaderVersion != 300)
79 level--;
80 if (level == ESSL1_BUILTINS && shaderVersion != 100)
81 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000082
83 symbol = table[level]->find(name);
84 }
85 while (symbol == 0 && --level >= 0);
86
87 if (builtIn)
88 *builtIn = (level <= LAST_BUILTIN_LEVEL);
89 if (sameScope)
90 *sameScope = (level == currentLevel());
91
92 return symbol;
93}
94
Zhenyao Moe740add2014-07-18 17:01:01 -070095TSymbol *TSymbolTable::findBuiltIn(
96 const TString &name, int shaderVersion) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000097{
98 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
99 {
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700100 if (level == ESSL3_BUILTINS && shaderVersion != 300)
101 level--;
102 if (level == ESSL1_BUILTINS && shaderVersion != 100)
103 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000104
105 TSymbol *symbol = table[level]->find(name);
106
107 if (symbol)
108 return symbol;
109 }
110
111 return 0;
112}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400113
114TSymbolTable::~TSymbolTable()
115{
116 while (table.size() > 0)
117 pop();
118}
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700119
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500120bool IsGenType(const TType *type)
121{
122 if (type)
123 {
124 TBasicType basicType = type->getBasicType();
125 return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType || basicType == EbtGenBType;
126 }
127
128 return false;
129}
130
131bool IsVecType(const TType *type)
132{
133 if (type)
134 {
135 TBasicType basicType = type->getBasicType();
136 return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec || basicType == EbtBVec;
137 }
138
139 return false;
140}
141
142TType *SpecificType(TType *type, int size)
143{
144 ASSERT(size >= 1 && size <= 4);
145
146 if (!type)
147 {
148 return nullptr;
149 }
150
151 ASSERT(!IsVecType(type));
152
153 switch(type->getBasicType())
154 {
Minmin Gong3b26e232015-04-07 18:31:54 -0700155 case EbtGenType: return new TType(EbtFloat, static_cast<unsigned char>(size));
156 case EbtGenIType: return new TType(EbtInt, static_cast<unsigned char>(size));
157 case EbtGenUType: return new TType(EbtUInt, static_cast<unsigned char>(size));
158 case EbtGenBType: return new TType(EbtBool, static_cast<unsigned char>(size));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500159 default: return type;
160 }
161}
162
163TType *VectorType(TType *type, int size)
164{
165 ASSERT(size >= 2 && size <= 4);
166
167 if (!type)
168 {
169 return nullptr;
170 }
171
172 ASSERT(!IsGenType(type));
173
174 switch(type->getBasicType())
175 {
Minmin Gong3b26e232015-04-07 18:31:54 -0700176 case EbtVec: return new TType(EbtFloat, static_cast<unsigned char>(size));
177 case EbtIVec: return new TType(EbtInt, static_cast<unsigned char>(size));
178 case EbtUVec: return new TType(EbtUInt, static_cast<unsigned char>(size));
179 case EbtBVec: return new TType(EbtBool, static_cast<unsigned char>(size));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500180 default: return type;
181 }
182}
183
Nicolas Capensc9d9b302015-02-20 23:02:15 -0500184void TSymbolTable::insertBuiltIn(ESymbolLevel level, TOperator op, const char *ext, TType *rvalue, const char *name,
185 TType *ptype1, TType *ptype2, TType *ptype3, TType *ptype4, TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700186{
187 if (ptype1->getBasicType() == EbtGSampler2D)
188 {
189 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500190 insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
191 insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
192 insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700193 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500194 else if (ptype1->getBasicType() == EbtGSampler3D)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700195 {
196 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500197 insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
198 insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
199 insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700200 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500201 else if (ptype1->getBasicType() == EbtGSamplerCube)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700202 {
203 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500204 insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
205 insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
206 insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700207 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500208 else if (ptype1->getBasicType() == EbtGSampler2DArray)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700209 {
210 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500211 insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, new TType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
212 insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, new TType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
213 insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, new TType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700214 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500215 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3))
216 {
217 ASSERT(!ptype4 && !ptype5);
Nicolas Capensc9d9b302015-02-20 23:02:15 -0500218 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1), SpecificType(ptype2, 1), SpecificType(ptype3, 1));
219 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2), SpecificType(ptype2, 2), SpecificType(ptype3, 2));
220 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3), SpecificType(ptype2, 3), SpecificType(ptype3, 3));
221 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4), SpecificType(ptype2, 4), SpecificType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500222 }
223 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
224 {
225 ASSERT(!ptype4 && !ptype5);
Nicolas Capensc9d9b302015-02-20 23:02:15 -0500226 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2), VectorType(ptype2, 2), VectorType(ptype3, 2));
227 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3), VectorType(ptype2, 3), VectorType(ptype3, 3));
228 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4), VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500229 }
230 else
231 {
Nicolas Capensc9d9b302015-02-20 23:02:15 -0500232 TFunction *function = new TFunction(NewPoolTString(name), *rvalue, op, ext);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700233
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500234 TParameter param1 = {0, ptype1};
235 function->addParameter(param1);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700236
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500237 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700238 {
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500239 TParameter param2 = {0, ptype2};
240 function->addParameter(param2);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700241 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700242
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500243 if (ptype3)
244 {
245 TParameter param3 = {0, ptype3};
246 function->addParameter(param3);
247 }
248
249 if (ptype4)
250 {
251 TParameter param4 = {0, ptype4};
252 function->addParameter(param4);
253 }
254
255 if (ptype5)
256 {
257 TParameter param5 = {0, ptype5};
258 function->addParameter(param5);
259 }
260
261 insert(level, function);
262 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700263}
264
Zhenyao Moe740add2014-07-18 17:01:01 -0700265TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700266{
267 if (!SupportsPrecision(type))
268 return EbpUndefined;
269
270 // unsigned integers use the same precision as signed
271 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
272
273 int level = static_cast<int>(precisionStack.size()) - 1;
274 assert(level >= 0); // Just to be safe. Should not happen.
275 // If we dont find anything we return this. Should we error check this?
276 TPrecision prec = EbpUndefined;
277 while (level >= 0)
278 {
279 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
280 if (it != precisionStack[level]->end())
281 {
282 prec = (*it).second;
283 break;
284 }
285 level--;
286 }
287 return prec;
288}