blob: 91404faa6911e396e9ae7037f58f59cb0c3033ef [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//
Olli Etuaho0f684632017-07-13 12:42:15 +03006// Symbol table for parsing. The design principles and most of the functionality are documented in
7// the header file.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00008//
9
apatrick@chromium.orge057c5d2012-01-26 19:18:24 +000010#if defined(_MSC_VER)
Jamie Madilld7b1ab52016-12-12 14:42:19 -050011#pragma warning(disable : 4718)
apatrick@chromium.orge057c5d2012-01-26 19:18:24 +000012#endif
13
Geoff Lang17732822013-08-29 13:46:49 -040014#include "compiler/translator/SymbolTable.h"
Olli Etuaho01d0ad02017-01-22 14:51:23 -080015
Dmitry Skiba01971112015-07-10 14:54:00 -040016#include "compiler/translator/Cache.h"
Olli Etuaho01d0ad02017-01-22 14:51:23 -080017#include "compiler/translator/IntermNode.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
Olli Etuahof2209f72017-04-01 12:45:55 +030025namespace
26{
27
28static const char kFunctionMangledNameSeparator = '(';
29
30} // anonymous namespace
31
Jamie Madillbfa91f42014-06-05 15:45:18 -040032int TSymbolTable::uniqueIdCounter = 0;
Nicolas Capensbd10cf52013-06-20 09:51:51 -040033
Olli Etuahofe486322017-03-21 09:30:54 +000034TSymbolUniqueId::TSymbolUniqueId() : mId(TSymbolTable::nextUniqueId())
35{
36}
37
38TSymbolUniqueId::TSymbolUniqueId(const TSymbol &symbol) : mId(symbol.getUniqueId())
39{
40}
41
42int TSymbolUniqueId::get() const
43{
44 return mId;
45}
46
Olli Etuaho476197f2016-10-11 13:59:08 +010047TSymbol::TSymbol(const TString *n) : uniqueId(TSymbolTable::nextUniqueId()), name(n)
48{
49}
50
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000051//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000052// Functions have buried pointers to delete.
53//
54TFunction::~TFunction()
55{
Olli Etuaho476197f2016-10-11 13:59:08 +010056 clearParameters();
57}
58
59void TFunction::clearParameters()
60{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000061 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
62 delete (*i).type;
Olli Etuaho476197f2016-10-11 13:59:08 +010063 parameters.clear();
64 mangledName = nullptr;
65}
66
67void TFunction::swapParameters(const TFunction &parametersSource)
68{
69 clearParameters();
70 for (auto parameter : parametersSource.parameters)
71 {
72 addParameter(parameter);
73 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000074}
75
Dmitry Skiba58832202015-07-06 16:11:13 -070076const TString *TFunction::buildMangledName() const
77{
Olli Etuahof2209f72017-04-01 12:45:55 +030078 std::string newName = getName().c_str();
79 newName += kFunctionMangledNameSeparator;
Dmitry Skiba58832202015-07-06 16:11:13 -070080
81 for (const auto &p : parameters)
82 {
Cooper Partin149e6e62015-08-07 16:18:18 -070083 newName += p.type->getMangledName().c_str();
Dmitry Skiba58832202015-07-06 16:11:13 -070084 }
Cooper Partin149e6e62015-08-07 16:18:18 -070085 return NewPoolTString(newName.c_str());
Dmitry Skiba58832202015-07-06 16:11:13 -070086}
87
Olli Etuahof2209f72017-04-01 12:45:55 +030088const TString &TFunction::GetMangledNameFromCall(const TString &functionName,
89 const TIntermSequence &arguments)
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -080090{
Olli Etuahof2209f72017-04-01 12:45:55 +030091 std::string newName = functionName.c_str();
92 newName += kFunctionMangledNameSeparator;
93
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -080094 for (TIntermNode *argument : arguments)
95 {
96 newName += argument->getAsTyped()->getType().getMangledName().c_str();
97 }
98 return *NewPoolTString(newName.c_str());
99}
100
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000101//
102// Symbol table levels are a map of pointers to symbols that have to be deleted.
103//
104TSymbolTableLevel::~TSymbolTableLevel()
105{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000106 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
107 delete (*it).second;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000108}
109
Nicolas Capensadfffe42014-06-17 02:13:36 -0400110bool TSymbolTableLevel::insert(TSymbol *symbol)
Jamie Madillbfa91f42014-06-05 15:45:18 -0400111{
Jamie Madillbfa91f42014-06-05 15:45:18 -0400112 // returning true means symbol was added to the table
Nicolas Capensadfffe42014-06-17 02:13:36 -0400113 tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
Jamie Madillbfa91f42014-06-05 15:45:18 -0400114
115 return result.second;
116}
117
Olli Etuahob2983c92015-03-18 14:02:46 +0200118bool TSymbolTableLevel::insertUnmangled(TFunction *function)
119{
Olli Etuahob2983c92015-03-18 14:02:46 +0200120 // returning true means symbol was added to the table
121 tInsertResult result = level.insert(tLevelPair(function->getName(), function));
122
123 return result.second;
124}
125
Jamie Madillbfa91f42014-06-05 15:45:18 -0400126TSymbol *TSymbolTableLevel::find(const TString &name) const
127{
128 tLevel::const_iterator it = level.find(name);
129 if (it == level.end())
130 return 0;
131 else
132 return (*it).second;
133}
134
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500135TSymbol *TSymbolTable::find(const TString &name,
136 int shaderVersion,
137 bool *builtIn,
138 bool *sameScope) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000139{
140 int level = currentLevel();
141 TSymbol *symbol;
142
143 do
144 {
Martin Radeve93d24e2016-07-28 12:06:05 +0300145 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
146 level--;
147 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700148 level--;
149 if (level == ESSL1_BUILTINS && shaderVersion != 100)
150 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000151
152 symbol = table[level]->find(name);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500153 } while (symbol == 0 && --level >= 0);
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000154
155 if (builtIn)
156 *builtIn = (level <= LAST_BUILTIN_LEVEL);
157 if (sameScope)
158 *sameScope = (level == currentLevel());
159
160 return symbol;
161}
162
Zhenyao Mod7490962016-11-09 15:49:51 -0800163TSymbol *TSymbolTable::findGlobal(const TString &name) const
164{
165 ASSERT(table.size() > GLOBAL_LEVEL);
166 return table[GLOBAL_LEVEL]->find(name);
167}
168
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500169TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000170{
171 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
172 {
Martin Radeve93d24e2016-07-28 12:06:05 +0300173 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
174 level--;
175 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700176 level--;
177 if (level == ESSL1_BUILTINS && shaderVersion != 100)
178 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000179
180 TSymbol *symbol = table[level]->find(name);
181
182 if (symbol)
183 return symbol;
184 }
185
186 return 0;
187}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400188
189TSymbolTable::~TSymbolTable()
190{
191 while (table.size() > 0)
192 pop();
193}
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700194
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500195bool IsGenType(const TType *type)
196{
197 if (type)
198 {
199 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500200 return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType ||
201 basicType == EbtGenBType;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500202 }
203
204 return false;
205}
206
207bool IsVecType(const TType *type)
208{
209 if (type)
210 {
211 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500212 return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec ||
213 basicType == EbtBVec;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500214 }
215
216 return false;
217}
218
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700219const TType *SpecificType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500220{
221 ASSERT(size >= 1 && size <= 4);
222
223 if (!type)
224 {
225 return nullptr;
226 }
227
228 ASSERT(!IsVecType(type));
229
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500230 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500231 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500232 case EbtGenType:
Olli Etuaho9250cb22017-01-21 10:51:27 +0000233 return TCache::getType(EbtFloat, type->getQualifier(),
234 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500235 case EbtGenIType:
Olli Etuaho9250cb22017-01-21 10:51:27 +0000236 return TCache::getType(EbtInt, type->getQualifier(), static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500237 case EbtGenUType:
Olli Etuaho9250cb22017-01-21 10:51:27 +0000238 return TCache::getType(EbtUInt, type->getQualifier(), static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500239 case EbtGenBType:
Olli Etuaho9250cb22017-01-21 10:51:27 +0000240 return TCache::getType(EbtBool, type->getQualifier(), static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500241 default:
242 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500243 }
244}
245
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700246const TType *VectorType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500247{
248 ASSERT(size >= 2 && size <= 4);
249
250 if (!type)
251 {
252 return nullptr;
253 }
254
255 ASSERT(!IsGenType(type));
256
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500257 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500258 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500259 case EbtVec:
260 return TCache::getType(EbtFloat, static_cast<unsigned char>(size));
261 case EbtIVec:
262 return TCache::getType(EbtInt, static_cast<unsigned char>(size));
263 case EbtUVec:
264 return TCache::getType(EbtUInt, static_cast<unsigned char>(size));
265 case EbtBVec:
266 return TCache::getType(EbtBool, static_cast<unsigned char>(size));
267 default:
268 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500269 }
270}
271
Olli Etuaho0f684632017-07-13 12:42:15 +0300272TVariable *TSymbolTable::declareVariable(const TString *name, const TType &type)
273{
274 return insertVariable(currentLevel(), name, type);
275}
276
277TVariable *TSymbolTable::declareStructType(TStructure *str)
278{
279 return insertStructType(currentLevel(), str);
280}
281
282TInterfaceBlockName *TSymbolTable::declareInterfaceBlockName(const TString *name)
283{
284 TInterfaceBlockName *blockNameSymbol = new TInterfaceBlockName(name);
285 if (insert(currentLevel(), blockNameSymbol))
286 {
287 return blockNameSymbol;
288 }
289 return nullptr;
290}
291
292TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType &type)
293{
294 return insertVariable(level, NewPoolTString(name), type);
295}
296
297TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const TString *name, const TType &type)
298{
299 TVariable *var = new TVariable(name, type);
300 if (insert(level, var))
301 {
302 // Do lazy initialization for struct types, so we allocate to the current scope.
303 if (var->getType().getBasicType() == EbtStruct)
304 {
305 var->getType().realize();
306 }
307 return var;
308 }
309 return nullptr;
310}
311
312TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
313 const char *ext,
314 const char *name,
315 const TType &type)
316{
317 TVariable *var = new TVariable(NewPoolTString(name), type);
318 if (insert(level, ext, var))
319 {
320 if (var->getType().getBasicType() == EbtStruct)
321 {
322 var->getType().realize();
323 }
324 return var;
325 }
326 return nullptr;
327}
328
329TVariable *TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str)
330{
331 TVariable *var = new TVariable(&str->name(), TType(str), true);
332 if (insert(level, var))
333 {
334 var->getType().realize();
335 return var;
336 }
337 return nullptr;
338}
339
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500340void TSymbolTable::insertBuiltIn(ESymbolLevel level,
341 TOperator op,
342 const char *ext,
343 const TType *rvalue,
344 const char *name,
345 const TType *ptype1,
346 const TType *ptype2,
347 const TType *ptype3,
348 const TType *ptype4,
349 const TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700350{
351 if (ptype1->getBasicType() == EbtGSampler2D)
352 {
Martin Radevda6254b2016-12-14 17:00:36 +0200353 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700354 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500355 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
356 TCache::getType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
357 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
358 TCache::getType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
359 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
360 TCache::getType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700361 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500362 else if (ptype1->getBasicType() == EbtGSampler3D)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700363 {
Martin Radevda6254b2016-12-14 17:00:36 +0200364 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700365 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500366 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
367 TCache::getType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
368 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
369 TCache::getType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
370 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
371 TCache::getType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700372 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500373 else if (ptype1->getBasicType() == EbtGSamplerCube)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700374 {
Martin Radevda6254b2016-12-14 17:00:36 +0200375 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700376 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500377 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
378 TCache::getType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
379 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
380 TCache::getType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
381 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
382 TCache::getType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700383 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500384 else if (ptype1->getBasicType() == EbtGSampler2DArray)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700385 {
Martin Radevda6254b2016-12-14 17:00:36 +0200386 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700387 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500388 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
389 TCache::getType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
390 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
391 TCache::getType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
392 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
393 TCache::getType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700394 }
JiangYizhou40219322016-12-09 09:50:51 +0800395 else if (ptype1->getBasicType() == EbtGSampler2DMS)
396 {
397 insertUnmangledBuiltInName(name, level);
398 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
399 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
400 TCache::getType(EbtSampler2DMS), ptype2, ptype3, ptype4, ptype5);
401 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
402 TCache::getType(EbtISampler2DMS), ptype2, ptype3, ptype4, ptype5);
403 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
404 TCache::getType(EbtUSampler2DMS), ptype2, ptype3, ptype4, ptype5);
405 }
Martin Radev2cc85b32016-08-05 16:22:53 +0300406 else if (IsGImage(ptype1->getBasicType()))
407 {
Martin Radevda6254b2016-12-14 17:00:36 +0200408 insertUnmangledBuiltInName(name, level);
Martin Radev2cc85b32016-08-05 16:22:53 +0300409
410 const TType *floatType = TCache::getType(EbtFloat, 4);
411 const TType *intType = TCache::getType(EbtInt, 4);
412 const TType *unsignedType = TCache::getType(EbtUInt, 4);
413
414 const TType *floatImage =
415 TCache::getType(convertGImageToFloatImage(ptype1->getBasicType()));
416 const TType *intImage = TCache::getType(convertGImageToIntImage(ptype1->getBasicType()));
417 const TType *unsignedImage =
418 TCache::getType(convertGImageToUnsignedImage(ptype1->getBasicType()));
419
420 // GLSL ES 3.10, Revision 4, 8.12 Image Functions
421 if (rvalue->getBasicType() == EbtGVec4)
422 {
423 // imageLoad
424 insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
425 insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
426 insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
427 }
428 else if (rvalue->getBasicType() == EbtVoid)
429 {
430 // imageStore
431 insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
432 insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
433 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
434 }
435 else
436 {
437 // imageSize
438 insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
439 insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
440 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
441 }
442 }
Olli Etuaho9250cb22017-01-21 10:51:27 +0000443 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3) ||
444 IsGenType(ptype4))
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500445 {
Olli Etuaho9250cb22017-01-21 10:51:27 +0000446 ASSERT(!ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200447 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500448 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000449 SpecificType(ptype2, 1), SpecificType(ptype3, 1), SpecificType(ptype4, 1));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500450 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000451 SpecificType(ptype2, 2), SpecificType(ptype3, 2), SpecificType(ptype4, 2));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500452 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000453 SpecificType(ptype2, 3), SpecificType(ptype3, 3), SpecificType(ptype4, 3));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500454 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000455 SpecificType(ptype2, 4), SpecificType(ptype3, 4), SpecificType(ptype4, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500456 }
457 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
458 {
459 ASSERT(!ptype4 && !ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200460 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500461 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2),
462 VectorType(ptype2, 2), VectorType(ptype3, 2));
463 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3),
464 VectorType(ptype2, 3), VectorType(ptype3, 3));
465 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4),
466 VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500467 }
468 else
469 {
Dmitry Skiba7f17a502015-06-22 15:08:39 -0700470 TFunction *function = new TFunction(NewPoolTString(name), rvalue, op, ext);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700471
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700472 function->addParameter(TConstParameter(ptype1));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700473
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500474 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700475 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700476 function->addParameter(TConstParameter(ptype2));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700477 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700478
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500479 if (ptype3)
480 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700481 function->addParameter(TConstParameter(ptype3));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500482 }
483
484 if (ptype4)
485 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700486 function->addParameter(TConstParameter(ptype4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500487 }
488
489 if (ptype5)
490 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700491 function->addParameter(TConstParameter(ptype5));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500492 }
493
Martin Radevda6254b2016-12-14 17:00:36 +0200494 ASSERT(hasUnmangledBuiltInAtLevel(name, level));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500495 insert(level, function);
496 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700497}
498
Olli Etuaho492cfab2017-01-20 21:18:29 +0000499void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
500 TOperator op,
501 const TType *rvalue,
502 const TType *ptype1,
503 const TType *ptype2,
504 const TType *ptype3,
505 const TType *ptype4,
506 const TType *ptype5)
507{
508 const char *name = GetOperatorString(op);
509 ASSERT(strlen(name) > 0);
510 insertUnmangledBuiltInName(name, level);
511 insertBuiltIn(level, op, "", rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
512}
513
514void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
515 TOperator op,
516 const char *ext,
517 const TType *rvalue,
518 const TType *ptype1,
519 const TType *ptype2,
520 const TType *ptype3,
521 const TType *ptype4,
522 const TType *ptype5)
523{
524 const char *name = GetOperatorString(op);
525 insertUnmangledBuiltInName(name, level);
526 insertBuiltIn(level, op, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
527}
528
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300529void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
530 TOperator op,
531 const TType *rvalue,
532 const char *name)
533{
534 insertUnmangledBuiltInName(name, level);
535 insert(level, new TFunction(NewPoolTString(name), rvalue, op));
536}
537
Zhenyao Moe740add2014-07-18 17:01:01 -0700538TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700539{
540 if (!SupportsPrecision(type))
541 return EbpUndefined;
542
543 // unsigned integers use the same precision as signed
544 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
545
546 int level = static_cast<int>(precisionStack.size()) - 1;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500547 assert(level >= 0); // Just to be safe. Should not happen.
Olli Etuaho183d7e22015-11-20 15:59:09 +0200548 // If we dont find anything we return this. Some types don't have predefined default precision.
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700549 TPrecision prec = EbpUndefined;
550 while (level >= 0)
551 {
552 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
553 if (it != precisionStack[level]->end())
554 {
555 prec = (*it).second;
556 break;
557 }
558 level--;
559 }
560 return prec;
561}
Jamie Madill45bcc782016-11-07 13:58:48 -0500562
Martin Radevda6254b2016-12-14 17:00:36 +0200563void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
564{
565 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
566 table[level]->insertUnmangledBuiltInName(std::string(name));
567}
568
569bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level)
570{
571 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
572 return table[level]->hasUnmangledBuiltIn(std::string(name));
573}
574
575bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion)
576{
577 ASSERT(static_cast<ESymbolLevel>(table.size()) > LAST_BUILTIN_LEVEL);
578
579 for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
580 {
581 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
582 {
583 --level;
584 }
585 if (level == ESSL3_BUILTINS && shaderVersion < 300)
586 {
587 --level;
588 }
589 if (level == ESSL1_BUILTINS && shaderVersion != 100)
590 {
591 --level;
592 }
593
594 if (table[level]->hasUnmangledBuiltIn(name))
595 {
596 return true;
597 }
598 }
599 return false;
600}
601
Jamie Madill45bcc782016-11-07 13:58:48 -0500602} // namespace sh