blob: 7885df7f23049bc46370b09ec758be14645c75ad [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
Olli Etuahoa5e693a2017-07-13 16:07:26 +030032TSymbolUniqueId::TSymbolUniqueId(TSymbolTable *symbolTable) : mId(symbolTable->nextUniqueId())
Olli Etuahofe486322017-03-21 09:30:54 +000033{
34}
35
36TSymbolUniqueId::TSymbolUniqueId(const TSymbol &symbol) : mId(symbol.getUniqueId())
37{
38}
39
40int TSymbolUniqueId::get() const
41{
42 return mId;
43}
44
Olli Etuahoa5e693a2017-07-13 16:07:26 +030045TSymbol::TSymbol(TSymbolTable *symbolTable, const TString *n)
Olli Etuaho2a1e8f92017-07-14 11:49:36 +030046 : uniqueId(symbolTable->nextUniqueId()), name(n), extension(TExtension::UNDEFINED)
Olli Etuaho476197f2016-10-11 13:59:08 +010047{
48}
49
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000050//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000051// Functions have buried pointers to delete.
52//
53TFunction::~TFunction()
54{
Olli Etuaho476197f2016-10-11 13:59:08 +010055 clearParameters();
56}
57
58void TFunction::clearParameters()
59{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000060 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
61 delete (*i).type;
Olli Etuaho476197f2016-10-11 13:59:08 +010062 parameters.clear();
63 mangledName = nullptr;
64}
65
66void TFunction::swapParameters(const TFunction &parametersSource)
67{
68 clearParameters();
69 for (auto parameter : parametersSource.parameters)
70 {
71 addParameter(parameter);
72 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000073}
74
Dmitry Skiba58832202015-07-06 16:11:13 -070075const TString *TFunction::buildMangledName() const
76{
Olli Etuahof2209f72017-04-01 12:45:55 +030077 std::string newName = getName().c_str();
78 newName += kFunctionMangledNameSeparator;
Dmitry Skiba58832202015-07-06 16:11:13 -070079
80 for (const auto &p : parameters)
81 {
Cooper Partin149e6e62015-08-07 16:18:18 -070082 newName += p.type->getMangledName().c_str();
Dmitry Skiba58832202015-07-06 16:11:13 -070083 }
Cooper Partin149e6e62015-08-07 16:18:18 -070084 return NewPoolTString(newName.c_str());
Dmitry Skiba58832202015-07-06 16:11:13 -070085}
86
Olli Etuahof2209f72017-04-01 12:45:55 +030087const TString &TFunction::GetMangledNameFromCall(const TString &functionName,
88 const TIntermSequence &arguments)
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -080089{
Olli Etuahof2209f72017-04-01 12:45:55 +030090 std::string newName = functionName.c_str();
91 newName += kFunctionMangledNameSeparator;
92
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -080093 for (TIntermNode *argument : arguments)
94 {
95 newName += argument->getAsTyped()->getType().getMangledName().c_str();
96 }
97 return *NewPoolTString(newName.c_str());
98}
99
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000100//
101// Symbol table levels are a map of pointers to symbols that have to be deleted.
102//
103TSymbolTableLevel::~TSymbolTableLevel()
104{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000105 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
106 delete (*it).second;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000107}
108
Nicolas Capensadfffe42014-06-17 02:13:36 -0400109bool TSymbolTableLevel::insert(TSymbol *symbol)
Jamie Madillbfa91f42014-06-05 15:45:18 -0400110{
Jamie Madillbfa91f42014-06-05 15:45:18 -0400111 // returning true means symbol was added to the table
Nicolas Capensadfffe42014-06-17 02:13:36 -0400112 tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
Jamie Madillbfa91f42014-06-05 15:45:18 -0400113
114 return result.second;
115}
116
Olli Etuahob2983c92015-03-18 14:02:46 +0200117bool TSymbolTableLevel::insertUnmangled(TFunction *function)
118{
Olli Etuahob2983c92015-03-18 14:02:46 +0200119 // returning true means symbol was added to the table
120 tInsertResult result = level.insert(tLevelPair(function->getName(), function));
121
122 return result.second;
123}
124
Jamie Madillbfa91f42014-06-05 15:45:18 -0400125TSymbol *TSymbolTableLevel::find(const TString &name) const
126{
127 tLevel::const_iterator it = level.find(name);
128 if (it == level.end())
129 return 0;
130 else
131 return (*it).second;
132}
133
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500134TSymbol *TSymbolTable::find(const TString &name,
135 int shaderVersion,
136 bool *builtIn,
137 bool *sameScope) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000138{
139 int level = currentLevel();
140 TSymbol *symbol;
141
142 do
143 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300144 if (level == GLSL_BUILTINS)
145 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +0300146 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
147 level--;
148 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700149 level--;
150 if (level == ESSL1_BUILTINS && shaderVersion != 100)
151 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000152
153 symbol = table[level]->find(name);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500154 } while (symbol == 0 && --level >= 0);
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000155
156 if (builtIn)
157 *builtIn = (level <= LAST_BUILTIN_LEVEL);
158 if (sameScope)
159 *sameScope = (level == currentLevel());
160
161 return symbol;
162}
163
Zhenyao Mod7490962016-11-09 15:49:51 -0800164TSymbol *TSymbolTable::findGlobal(const TString &name) const
165{
166 ASSERT(table.size() > GLOBAL_LEVEL);
167 return table[GLOBAL_LEVEL]->find(name);
168}
169
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500170TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000171{
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300172 return findBuiltIn(name, shaderVersion, false);
173}
174
175TSymbol *TSymbolTable::findBuiltIn(const TString &name,
176 int shaderVersion,
177 bool includeGLSLBuiltins) const
178{
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000179 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
180 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300181 if (level == GLSL_BUILTINS && !includeGLSLBuiltins)
182 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +0300183 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
184 level--;
185 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700186 level--;
187 if (level == ESSL1_BUILTINS && shaderVersion != 100)
188 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000189
190 TSymbol *symbol = table[level]->find(name);
191
192 if (symbol)
193 return symbol;
194 }
195
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300196 return nullptr;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000197}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400198
199TSymbolTable::~TSymbolTable()
200{
201 while (table.size() > 0)
202 pop();
203}
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700204
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500205bool IsGenType(const TType *type)
206{
207 if (type)
208 {
209 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500210 return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType ||
211 basicType == EbtGenBType;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500212 }
213
214 return false;
215}
216
217bool IsVecType(const TType *type)
218{
219 if (type)
220 {
221 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500222 return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec ||
223 basicType == EbtBVec;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500224 }
225
226 return false;
227}
228
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700229const TType *SpecificType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500230{
231 ASSERT(size >= 1 && size <= 4);
232
233 if (!type)
234 {
235 return nullptr;
236 }
237
238 ASSERT(!IsVecType(type));
239
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500240 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500241 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500242 case EbtGenType:
Olli Etuaho9250cb22017-01-21 10:51:27 +0000243 return TCache::getType(EbtFloat, type->getQualifier(),
244 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500245 case EbtGenIType:
Olli Etuaho9250cb22017-01-21 10:51:27 +0000246 return TCache::getType(EbtInt, type->getQualifier(), static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500247 case EbtGenUType:
Olli Etuaho9250cb22017-01-21 10:51:27 +0000248 return TCache::getType(EbtUInt, type->getQualifier(), static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500249 case EbtGenBType:
Olli Etuaho9250cb22017-01-21 10:51:27 +0000250 return TCache::getType(EbtBool, type->getQualifier(), static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500251 default:
252 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500253 }
254}
255
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700256const TType *VectorType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500257{
258 ASSERT(size >= 2 && size <= 4);
259
260 if (!type)
261 {
262 return nullptr;
263 }
264
265 ASSERT(!IsGenType(type));
266
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500267 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500268 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500269 case EbtVec:
270 return TCache::getType(EbtFloat, static_cast<unsigned char>(size));
271 case EbtIVec:
272 return TCache::getType(EbtInt, static_cast<unsigned char>(size));
273 case EbtUVec:
274 return TCache::getType(EbtUInt, static_cast<unsigned char>(size));
275 case EbtBVec:
276 return TCache::getType(EbtBool, static_cast<unsigned char>(size));
277 default:
278 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500279 }
280}
281
Olli Etuaho0f684632017-07-13 12:42:15 +0300282TVariable *TSymbolTable::declareVariable(const TString *name, const TType &type)
283{
284 return insertVariable(currentLevel(), name, type);
285}
286
287TVariable *TSymbolTable::declareStructType(TStructure *str)
288{
289 return insertStructType(currentLevel(), str);
290}
291
292TInterfaceBlockName *TSymbolTable::declareInterfaceBlockName(const TString *name)
293{
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300294 TInterfaceBlockName *blockNameSymbol = new TInterfaceBlockName(this, name);
Olli Etuaho0f684632017-07-13 12:42:15 +0300295 if (insert(currentLevel(), blockNameSymbol))
296 {
297 return blockNameSymbol;
298 }
299 return nullptr;
300}
301
Jiawei Shaod8105a02017-08-08 09:54:36 +0800302TInterfaceBlockName *TSymbolTable::insertInterfaceBlockNameExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300303 TExtension ext,
Jiawei Shaod8105a02017-08-08 09:54:36 +0800304 const TString *name)
305{
306 TInterfaceBlockName *blockNameSymbol = new TInterfaceBlockName(this, name);
307 if (insert(level, ext, blockNameSymbol))
308 {
309 return blockNameSymbol;
310 }
311 return nullptr;
312}
313
Olli Etuaho0f684632017-07-13 12:42:15 +0300314TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType &type)
315{
316 return insertVariable(level, NewPoolTString(name), type);
317}
318
319TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const TString *name, const TType &type)
320{
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300321 TVariable *var = new TVariable(this, name, type);
Olli Etuaho0f684632017-07-13 12:42:15 +0300322 if (insert(level, var))
323 {
324 // Do lazy initialization for struct types, so we allocate to the current scope.
325 if (var->getType().getBasicType() == EbtStruct)
326 {
327 var->getType().realize();
328 }
329 return var;
330 }
331 return nullptr;
332}
333
334TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300335 TExtension ext,
Olli Etuaho0f684632017-07-13 12:42:15 +0300336 const char *name,
337 const TType &type)
338{
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300339 TVariable *var = new TVariable(this, NewPoolTString(name), type);
Olli Etuaho0f684632017-07-13 12:42:15 +0300340 if (insert(level, ext, var))
341 {
342 if (var->getType().getBasicType() == EbtStruct)
343 {
344 var->getType().realize();
345 }
346 return var;
347 }
348 return nullptr;
349}
350
351TVariable *TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str)
352{
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300353 TVariable *var = new TVariable(this, &str->name(), TType(str), true);
Olli Etuaho0f684632017-07-13 12:42:15 +0300354 if (insert(level, var))
355 {
356 var->getType().realize();
357 return var;
358 }
359 return nullptr;
360}
361
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500362void TSymbolTable::insertBuiltIn(ESymbolLevel level,
363 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300364 TExtension ext,
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500365 const TType *rvalue,
366 const char *name,
367 const TType *ptype1,
368 const TType *ptype2,
369 const TType *ptype3,
370 const TType *ptype4,
371 const TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700372{
373 if (ptype1->getBasicType() == EbtGSampler2D)
374 {
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(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
379 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
380 TCache::getType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
381 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
382 TCache::getType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700383 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500384 else if (ptype1->getBasicType() == EbtGSampler3D)
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(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
390 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
391 TCache::getType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
392 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
393 TCache::getType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700394 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500395 else if (ptype1->getBasicType() == EbtGSamplerCube)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700396 {
Martin Radevda6254b2016-12-14 17:00:36 +0200397 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700398 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500399 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
400 TCache::getType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
401 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
402 TCache::getType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
403 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
404 TCache::getType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700405 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500406 else if (ptype1->getBasicType() == EbtGSampler2DArray)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700407 {
Martin Radevda6254b2016-12-14 17:00:36 +0200408 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700409 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500410 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
411 TCache::getType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
412 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
413 TCache::getType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
414 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
415 TCache::getType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700416 }
JiangYizhou40219322016-12-09 09:50:51 +0800417 else if (ptype1->getBasicType() == EbtGSampler2DMS)
418 {
419 insertUnmangledBuiltInName(name, level);
420 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
421 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
422 TCache::getType(EbtSampler2DMS), ptype2, ptype3, ptype4, ptype5);
423 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
424 TCache::getType(EbtISampler2DMS), ptype2, ptype3, ptype4, ptype5);
425 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
426 TCache::getType(EbtUSampler2DMS), ptype2, ptype3, ptype4, ptype5);
427 }
Martin Radev2cc85b32016-08-05 16:22:53 +0300428 else if (IsGImage(ptype1->getBasicType()))
429 {
Martin Radevda6254b2016-12-14 17:00:36 +0200430 insertUnmangledBuiltInName(name, level);
Martin Radev2cc85b32016-08-05 16:22:53 +0300431
432 const TType *floatType = TCache::getType(EbtFloat, 4);
433 const TType *intType = TCache::getType(EbtInt, 4);
434 const TType *unsignedType = TCache::getType(EbtUInt, 4);
435
436 const TType *floatImage =
437 TCache::getType(convertGImageToFloatImage(ptype1->getBasicType()));
438 const TType *intImage = TCache::getType(convertGImageToIntImage(ptype1->getBasicType()));
439 const TType *unsignedImage =
440 TCache::getType(convertGImageToUnsignedImage(ptype1->getBasicType()));
441
442 // GLSL ES 3.10, Revision 4, 8.12 Image Functions
443 if (rvalue->getBasicType() == EbtGVec4)
444 {
445 // imageLoad
446 insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
447 insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
448 insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
449 }
450 else if (rvalue->getBasicType() == EbtVoid)
451 {
452 // imageStore
453 insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
454 insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
455 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
456 }
457 else
458 {
459 // imageSize
460 insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
461 insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
462 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
463 }
464 }
Olli Etuaho9250cb22017-01-21 10:51:27 +0000465 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3) ||
466 IsGenType(ptype4))
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500467 {
Olli Etuaho9250cb22017-01-21 10:51:27 +0000468 ASSERT(!ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200469 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500470 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000471 SpecificType(ptype2, 1), SpecificType(ptype3, 1), SpecificType(ptype4, 1));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500472 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000473 SpecificType(ptype2, 2), SpecificType(ptype3, 2), SpecificType(ptype4, 2));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500474 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000475 SpecificType(ptype2, 3), SpecificType(ptype3, 3), SpecificType(ptype4, 3));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500476 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000477 SpecificType(ptype2, 4), SpecificType(ptype3, 4), SpecificType(ptype4, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500478 }
479 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
480 {
481 ASSERT(!ptype4 && !ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200482 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500483 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2),
484 VectorType(ptype2, 2), VectorType(ptype3, 2));
485 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3),
486 VectorType(ptype2, 3), VectorType(ptype3, 3));
487 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4),
488 VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500489 }
490 else
491 {
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300492 TFunction *function = new TFunction(this, NewPoolTString(name), rvalue, op, ext);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700493
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700494 function->addParameter(TConstParameter(ptype1));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700495
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500496 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700497 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700498 function->addParameter(TConstParameter(ptype2));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700499 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700500
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500501 if (ptype3)
502 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700503 function->addParameter(TConstParameter(ptype3));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500504 }
505
506 if (ptype4)
507 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700508 function->addParameter(TConstParameter(ptype4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500509 }
510
511 if (ptype5)
512 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700513 function->addParameter(TConstParameter(ptype5));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500514 }
515
Martin Radevda6254b2016-12-14 17:00:36 +0200516 ASSERT(hasUnmangledBuiltInAtLevel(name, level));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500517 insert(level, function);
518 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700519}
520
Olli Etuaho492cfab2017-01-20 21:18:29 +0000521void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
522 TOperator op,
523 const TType *rvalue,
524 const TType *ptype1,
525 const TType *ptype2,
526 const TType *ptype3,
527 const TType *ptype4,
528 const TType *ptype5)
529{
530 const char *name = GetOperatorString(op);
531 ASSERT(strlen(name) > 0);
532 insertUnmangledBuiltInName(name, level);
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300533 insertBuiltIn(level, op, TExtension::UNDEFINED, rvalue, name, ptype1, ptype2, ptype3, ptype4,
534 ptype5);
Olli Etuaho492cfab2017-01-20 21:18:29 +0000535}
536
537void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
538 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300539 TExtension ext,
Olli Etuaho492cfab2017-01-20 21:18:29 +0000540 const TType *rvalue,
541 const TType *ptype1,
542 const TType *ptype2,
543 const TType *ptype3,
544 const TType *ptype4,
545 const TType *ptype5)
546{
547 const char *name = GetOperatorString(op);
548 insertUnmangledBuiltInName(name, level);
549 insertBuiltIn(level, op, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
550}
551
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300552void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
553 TOperator op,
554 const TType *rvalue,
555 const char *name)
556{
557 insertUnmangledBuiltInName(name, level);
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300558 insert(level, new TFunction(this, NewPoolTString(name), rvalue, op));
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300559}
560
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800561void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300562 TExtension ext,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800563 TOperator op,
564 const TType *rvalue,
565 const char *name)
566{
567 insertUnmangledBuiltInName(name, level);
568 insert(level, new TFunction(this, NewPoolTString(name), rvalue, op, ext));
569}
570
Zhenyao Moe740add2014-07-18 17:01:01 -0700571TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700572{
573 if (!SupportsPrecision(type))
574 return EbpUndefined;
575
576 // unsigned integers use the same precision as signed
577 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
578
579 int level = static_cast<int>(precisionStack.size()) - 1;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500580 assert(level >= 0); // Just to be safe. Should not happen.
Olli Etuaho183d7e22015-11-20 15:59:09 +0200581 // If we dont find anything we return this. Some types don't have predefined default precision.
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700582 TPrecision prec = EbpUndefined;
583 while (level >= 0)
584 {
585 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
586 if (it != precisionStack[level]->end())
587 {
588 prec = (*it).second;
589 break;
590 }
591 level--;
592 }
593 return prec;
594}
Jamie Madill45bcc782016-11-07 13:58:48 -0500595
Martin Radevda6254b2016-12-14 17:00:36 +0200596void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
597{
598 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
599 table[level]->insertUnmangledBuiltInName(std::string(name));
600}
601
602bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level)
603{
604 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
605 return table[level]->hasUnmangledBuiltIn(std::string(name));
606}
607
608bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion)
609{
610 ASSERT(static_cast<ESymbolLevel>(table.size()) > LAST_BUILTIN_LEVEL);
611
612 for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
613 {
614 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
615 {
616 --level;
617 }
618 if (level == ESSL3_BUILTINS && shaderVersion < 300)
619 {
620 --level;
621 }
622 if (level == ESSL1_BUILTINS && shaderVersion != 100)
623 {
624 --level;
625 }
626
627 if (table[level]->hasUnmangledBuiltIn(name))
628 {
629 return true;
630 }
631 }
632 return false;
633}
634
Jamie Madill45bcc782016-11-07 13:58:48 -0500635} // namespace sh