blob: 9e7270df778a60c9b9b16d0cd140215555b261fc [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 Etuaho54a29ff2017-11-28 17:35:20 +020032TSymbol::TSymbol(TSymbolTable *symbolTable, const TString *name)
33 : mUniqueId(symbolTable->nextUniqueId()), mName(name), mExtension(TExtension::UNDEFINED)
Olli Etuaho476197f2016-10-11 13:59:08 +010034{
35}
36
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000037//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000038// Functions have buried pointers to delete.
39//
40TFunction::~TFunction()
41{
Olli Etuaho476197f2016-10-11 13:59:08 +010042 clearParameters();
43}
44
45void TFunction::clearParameters()
46{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000047 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
48 delete (*i).type;
Olli Etuaho476197f2016-10-11 13:59:08 +010049 parameters.clear();
50 mangledName = nullptr;
51}
52
53void TFunction::swapParameters(const TFunction &parametersSource)
54{
55 clearParameters();
56 for (auto parameter : parametersSource.parameters)
57 {
58 addParameter(parameter);
59 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000060}
61
Dmitry Skiba58832202015-07-06 16:11:13 -070062const TString *TFunction::buildMangledName() const
63{
Olli Etuaho54a29ff2017-11-28 17:35:20 +020064 std::string newName = name().c_str();
Olli Etuahof2209f72017-04-01 12:45:55 +030065 newName += kFunctionMangledNameSeparator;
Dmitry Skiba58832202015-07-06 16:11:13 -070066
67 for (const auto &p : parameters)
68 {
Jamie Madill902e8c12017-11-18 09:34:16 -050069 newName += p.type->getMangledName();
Dmitry Skiba58832202015-07-06 16:11:13 -070070 }
Cooper Partin149e6e62015-08-07 16:18:18 -070071 return NewPoolTString(newName.c_str());
Dmitry Skiba58832202015-07-06 16:11:13 -070072}
73
Olli Etuahof2209f72017-04-01 12:45:55 +030074const TString &TFunction::GetMangledNameFromCall(const TString &functionName,
75 const TIntermSequence &arguments)
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -080076{
Olli Etuahof2209f72017-04-01 12:45:55 +030077 std::string newName = functionName.c_str();
78 newName += kFunctionMangledNameSeparator;
79
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -080080 for (TIntermNode *argument : arguments)
81 {
Jamie Madill902e8c12017-11-18 09:34:16 -050082 newName += argument->getAsTyped()->getType().getMangledName();
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -080083 }
84 return *NewPoolTString(newName.c_str());
85}
86
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000087//
88// Symbol table levels are a map of pointers to symbols that have to be deleted.
89//
90TSymbolTableLevel::~TSymbolTableLevel()
91{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000092 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
93 delete (*it).second;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000094}
95
Nicolas Capensadfffe42014-06-17 02:13:36 -040096bool TSymbolTableLevel::insert(TSymbol *symbol)
Jamie Madillbfa91f42014-06-05 15:45:18 -040097{
Jamie Madillbfa91f42014-06-05 15:45:18 -040098 // returning true means symbol was added to the table
Nicolas Capensadfffe42014-06-17 02:13:36 -040099 tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
Jamie Madillbfa91f42014-06-05 15:45:18 -0400100
101 return result.second;
102}
103
Olli Etuahob2983c92015-03-18 14:02:46 +0200104bool TSymbolTableLevel::insertUnmangled(TFunction *function)
105{
Olli Etuahob2983c92015-03-18 14:02:46 +0200106 // returning true means symbol was added to the table
Olli Etuaho54a29ff2017-11-28 17:35:20 +0200107 tInsertResult result = level.insert(tLevelPair(function->name(), function));
Olli Etuahob2983c92015-03-18 14:02:46 +0200108
109 return result.second;
110}
111
Jamie Madillbfa91f42014-06-05 15:45:18 -0400112TSymbol *TSymbolTableLevel::find(const TString &name) const
113{
114 tLevel::const_iterator it = level.find(name);
115 if (it == level.end())
116 return 0;
117 else
118 return (*it).second;
119}
120
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500121TSymbol *TSymbolTable::find(const TString &name,
122 int shaderVersion,
123 bool *builtIn,
124 bool *sameScope) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000125{
126 int level = currentLevel();
127 TSymbol *symbol;
128
129 do
130 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300131 if (level == GLSL_BUILTINS)
132 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +0300133 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
134 level--;
135 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700136 level--;
137 if (level == ESSL1_BUILTINS && shaderVersion != 100)
138 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000139
140 symbol = table[level]->find(name);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500141 } while (symbol == 0 && --level >= 0);
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000142
143 if (builtIn)
144 *builtIn = (level <= LAST_BUILTIN_LEVEL);
145 if (sameScope)
146 *sameScope = (level == currentLevel());
147
148 return symbol;
149}
150
Zhenyao Mod7490962016-11-09 15:49:51 -0800151TSymbol *TSymbolTable::findGlobal(const TString &name) const
152{
153 ASSERT(table.size() > GLOBAL_LEVEL);
154 return table[GLOBAL_LEVEL]->find(name);
155}
156
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500157TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000158{
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300159 return findBuiltIn(name, shaderVersion, false);
160}
161
162TSymbol *TSymbolTable::findBuiltIn(const TString &name,
163 int shaderVersion,
164 bool includeGLSLBuiltins) const
165{
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000166 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
167 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300168 if (level == GLSL_BUILTINS && !includeGLSLBuiltins)
169 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +0300170 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
171 level--;
172 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700173 level--;
174 if (level == ESSL1_BUILTINS && shaderVersion != 100)
175 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000176
177 TSymbol *symbol = table[level]->find(name);
178
179 if (symbol)
180 return symbol;
181 }
182
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300183 return nullptr;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000184}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400185
186TSymbolTable::~TSymbolTable()
187{
188 while (table.size() > 0)
189 pop();
190}
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700191
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500192bool IsGenType(const TType *type)
193{
194 if (type)
195 {
196 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500197 return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType ||
198 basicType == EbtGenBType;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500199 }
200
201 return false;
202}
203
204bool IsVecType(const TType *type)
205{
206 if (type)
207 {
208 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500209 return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec ||
210 basicType == EbtBVec;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500211 }
212
213 return false;
214}
215
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700216const TType *SpecificType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500217{
218 ASSERT(size >= 1 && size <= 4);
219
220 if (!type)
221 {
222 return nullptr;
223 }
224
225 ASSERT(!IsVecType(type));
226
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500227 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500228 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500229 case EbtGenType:
Olli Etuaho9250cb22017-01-21 10:51:27 +0000230 return TCache::getType(EbtFloat, type->getQualifier(),
231 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500232 case EbtGenIType:
Olli Etuaho9250cb22017-01-21 10:51:27 +0000233 return TCache::getType(EbtInt, type->getQualifier(), static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500234 case EbtGenUType:
Olli Etuaho9250cb22017-01-21 10:51:27 +0000235 return TCache::getType(EbtUInt, type->getQualifier(), static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500236 case EbtGenBType:
Olli Etuaho9250cb22017-01-21 10:51:27 +0000237 return TCache::getType(EbtBool, type->getQualifier(), static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500238 default:
239 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500240 }
241}
242
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700243const TType *VectorType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500244{
245 ASSERT(size >= 2 && size <= 4);
246
247 if (!type)
248 {
249 return nullptr;
250 }
251
252 ASSERT(!IsGenType(type));
253
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500254 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500255 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500256 case EbtVec:
257 return TCache::getType(EbtFloat, static_cast<unsigned char>(size));
258 case EbtIVec:
259 return TCache::getType(EbtInt, static_cast<unsigned char>(size));
260 case EbtUVec:
261 return TCache::getType(EbtUInt, static_cast<unsigned char>(size));
262 case EbtBVec:
263 return TCache::getType(EbtBool, static_cast<unsigned char>(size));
264 default:
265 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500266 }
267}
268
Olli Etuaho0f684632017-07-13 12:42:15 +0300269TVariable *TSymbolTable::declareVariable(const TString *name, const TType &type)
270{
271 return insertVariable(currentLevel(), name, type);
272}
273
274TVariable *TSymbolTable::declareStructType(TStructure *str)
275{
276 return insertStructType(currentLevel(), str);
277}
278
279TInterfaceBlockName *TSymbolTable::declareInterfaceBlockName(const TString *name)
280{
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300281 TInterfaceBlockName *blockNameSymbol = new TInterfaceBlockName(this, name);
Olli Etuaho0f684632017-07-13 12:42:15 +0300282 if (insert(currentLevel(), blockNameSymbol))
283 {
284 return blockNameSymbol;
285 }
286 return nullptr;
287}
288
Jiawei Shaod8105a02017-08-08 09:54:36 +0800289TInterfaceBlockName *TSymbolTable::insertInterfaceBlockNameExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300290 TExtension ext,
Jiawei Shaod8105a02017-08-08 09:54:36 +0800291 const TString *name)
292{
293 TInterfaceBlockName *blockNameSymbol = new TInterfaceBlockName(this, name);
Olli Etuaho5d69db12017-11-24 16:51:15 +0200294 blockNameSymbol->relateToExtension(ext);
295 if (insert(level, blockNameSymbol))
Jiawei Shaod8105a02017-08-08 09:54:36 +0800296 {
297 return blockNameSymbol;
298 }
299 return nullptr;
300}
301
Olli Etuaho0f684632017-07-13 12:42:15 +0300302TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType &type)
303{
304 return insertVariable(level, NewPoolTString(name), type);
305}
306
307TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const TString *name, const TType &type)
308{
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300309 TVariable *var = new TVariable(this, name, type);
Olli Etuaho0f684632017-07-13 12:42:15 +0300310 if (insert(level, var))
311 {
312 // Do lazy initialization for struct types, so we allocate to the current scope.
313 if (var->getType().getBasicType() == EbtStruct)
314 {
315 var->getType().realize();
316 }
317 return var;
318 }
319 return nullptr;
320}
321
322TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300323 TExtension ext,
Olli Etuaho0f684632017-07-13 12:42:15 +0300324 const char *name,
325 const TType &type)
326{
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300327 TVariable *var = new TVariable(this, NewPoolTString(name), type);
Olli Etuaho5d69db12017-11-24 16:51:15 +0200328 var->relateToExtension(ext);
329 if (insert(level, var))
Olli Etuaho0f684632017-07-13 12:42:15 +0300330 {
331 if (var->getType().getBasicType() == EbtStruct)
332 {
333 var->getType().realize();
334 }
335 return var;
336 }
337 return nullptr;
338}
339
340TVariable *TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str)
341{
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300342 TVariable *var = new TVariable(this, &str->name(), TType(str), true);
Olli Etuaho0f684632017-07-13 12:42:15 +0300343 if (insert(level, var))
344 {
345 var->getType().realize();
346 return var;
347 }
348 return nullptr;
349}
350
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500351void TSymbolTable::insertBuiltIn(ESymbolLevel level,
352 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300353 TExtension ext,
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500354 const TType *rvalue,
355 const char *name,
356 const TType *ptype1,
357 const TType *ptype2,
358 const TType *ptype3,
359 const TType *ptype4,
360 const TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700361{
362 if (ptype1->getBasicType() == EbtGSampler2D)
363 {
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(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
368 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
369 TCache::getType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
370 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
371 TCache::getType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700372 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500373 else if (ptype1->getBasicType() == EbtGSampler3D)
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(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
379 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
380 TCache::getType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
381 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
382 TCache::getType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700383 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500384 else if (ptype1->getBasicType() == EbtGSamplerCube)
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(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
390 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
391 TCache::getType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
392 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
393 TCache::getType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700394 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500395 else if (ptype1->getBasicType() == EbtGSampler2DArray)
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(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
401 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
402 TCache::getType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
403 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
404 TCache::getType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700405 }
JiangYizhou40219322016-12-09 09:50:51 +0800406 else if (ptype1->getBasicType() == EbtGSampler2DMS)
407 {
408 insertUnmangledBuiltInName(name, level);
409 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
410 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
411 TCache::getType(EbtSampler2DMS), ptype2, ptype3, ptype4, ptype5);
412 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
413 TCache::getType(EbtISampler2DMS), ptype2, ptype3, ptype4, ptype5);
414 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
415 TCache::getType(EbtUSampler2DMS), ptype2, ptype3, ptype4, ptype5);
416 }
Martin Radev2cc85b32016-08-05 16:22:53 +0300417 else if (IsGImage(ptype1->getBasicType()))
418 {
Martin Radevda6254b2016-12-14 17:00:36 +0200419 insertUnmangledBuiltInName(name, level);
Martin Radev2cc85b32016-08-05 16:22:53 +0300420
421 const TType *floatType = TCache::getType(EbtFloat, 4);
422 const TType *intType = TCache::getType(EbtInt, 4);
423 const TType *unsignedType = TCache::getType(EbtUInt, 4);
424
425 const TType *floatImage =
426 TCache::getType(convertGImageToFloatImage(ptype1->getBasicType()));
427 const TType *intImage = TCache::getType(convertGImageToIntImage(ptype1->getBasicType()));
428 const TType *unsignedImage =
429 TCache::getType(convertGImageToUnsignedImage(ptype1->getBasicType()));
430
431 // GLSL ES 3.10, Revision 4, 8.12 Image Functions
432 if (rvalue->getBasicType() == EbtGVec4)
433 {
434 // imageLoad
435 insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
436 insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
437 insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
438 }
439 else if (rvalue->getBasicType() == EbtVoid)
440 {
441 // imageStore
442 insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
443 insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
444 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
445 }
446 else
447 {
448 // imageSize
449 insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
450 insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
451 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
452 }
453 }
Olli Etuaho9250cb22017-01-21 10:51:27 +0000454 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3) ||
455 IsGenType(ptype4))
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500456 {
Olli Etuaho9250cb22017-01-21 10:51:27 +0000457 ASSERT(!ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200458 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500459 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000460 SpecificType(ptype2, 1), SpecificType(ptype3, 1), SpecificType(ptype4, 1));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500461 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000462 SpecificType(ptype2, 2), SpecificType(ptype3, 2), SpecificType(ptype4, 2));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500463 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000464 SpecificType(ptype2, 3), SpecificType(ptype3, 3), SpecificType(ptype4, 3));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500465 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000466 SpecificType(ptype2, 4), SpecificType(ptype3, 4), SpecificType(ptype4, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500467 }
468 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
469 {
470 ASSERT(!ptype4 && !ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200471 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500472 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2),
473 VectorType(ptype2, 2), VectorType(ptype3, 2));
474 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3),
475 VectorType(ptype2, 3), VectorType(ptype3, 3));
476 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4),
477 VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500478 }
479 else
480 {
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300481 TFunction *function = new TFunction(this, NewPoolTString(name), rvalue, op, ext);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700482
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700483 function->addParameter(TConstParameter(ptype1));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700484
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500485 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700486 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700487 function->addParameter(TConstParameter(ptype2));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700488 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700489
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500490 if (ptype3)
491 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700492 function->addParameter(TConstParameter(ptype3));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500493 }
494
495 if (ptype4)
496 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700497 function->addParameter(TConstParameter(ptype4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500498 }
499
500 if (ptype5)
501 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700502 function->addParameter(TConstParameter(ptype5));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500503 }
504
Martin Radevda6254b2016-12-14 17:00:36 +0200505 ASSERT(hasUnmangledBuiltInAtLevel(name, level));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500506 insert(level, function);
507 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700508}
509
Olli Etuaho492cfab2017-01-20 21:18:29 +0000510void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
511 TOperator op,
512 const TType *rvalue,
513 const TType *ptype1,
514 const TType *ptype2,
515 const TType *ptype3,
516 const TType *ptype4,
517 const TType *ptype5)
518{
519 const char *name = GetOperatorString(op);
520 ASSERT(strlen(name) > 0);
521 insertUnmangledBuiltInName(name, level);
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300522 insertBuiltIn(level, op, TExtension::UNDEFINED, rvalue, name, ptype1, ptype2, ptype3, ptype4,
523 ptype5);
Olli Etuaho492cfab2017-01-20 21:18:29 +0000524}
525
526void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
527 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300528 TExtension ext,
Olli Etuaho492cfab2017-01-20 21:18:29 +0000529 const TType *rvalue,
530 const TType *ptype1,
531 const TType *ptype2,
532 const TType *ptype3,
533 const TType *ptype4,
534 const TType *ptype5)
535{
536 const char *name = GetOperatorString(op);
537 insertUnmangledBuiltInName(name, level);
538 insertBuiltIn(level, op, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
539}
540
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300541void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
542 TOperator op,
543 const TType *rvalue,
544 const char *name)
545{
546 insertUnmangledBuiltInName(name, level);
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300547 insert(level, new TFunction(this, NewPoolTString(name), rvalue, op));
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300548}
549
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800550void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300551 TExtension ext,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800552 TOperator op,
553 const TType *rvalue,
554 const char *name)
555{
556 insertUnmangledBuiltInName(name, level);
557 insert(level, new TFunction(this, NewPoolTString(name), rvalue, op, ext));
558}
559
Zhenyao Moe740add2014-07-18 17:01:01 -0700560TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700561{
562 if (!SupportsPrecision(type))
563 return EbpUndefined;
564
565 // unsigned integers use the same precision as signed
566 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
567
568 int level = static_cast<int>(precisionStack.size()) - 1;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500569 assert(level >= 0); // Just to be safe. Should not happen.
Olli Etuaho183d7e22015-11-20 15:59:09 +0200570 // If we dont find anything we return this. Some types don't have predefined default precision.
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700571 TPrecision prec = EbpUndefined;
572 while (level >= 0)
573 {
574 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
575 if (it != precisionStack[level]->end())
576 {
577 prec = (*it).second;
578 break;
579 }
580 level--;
581 }
582 return prec;
583}
Jamie Madill45bcc782016-11-07 13:58:48 -0500584
Martin Radevda6254b2016-12-14 17:00:36 +0200585void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
586{
587 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
Olli Etuaho5d69db12017-11-24 16:51:15 +0200588 ASSERT(mUserDefinedUniqueIdsStart == -1);
Martin Radevda6254b2016-12-14 17:00:36 +0200589 table[level]->insertUnmangledBuiltInName(std::string(name));
590}
591
592bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level)
593{
594 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
595 return table[level]->hasUnmangledBuiltIn(std::string(name));
596}
597
598bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion)
599{
600 ASSERT(static_cast<ESymbolLevel>(table.size()) > LAST_BUILTIN_LEVEL);
601
602 for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
603 {
604 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
605 {
606 --level;
607 }
608 if (level == ESSL3_BUILTINS && shaderVersion < 300)
609 {
610 --level;
611 }
612 if (level == ESSL1_BUILTINS && shaderVersion != 100)
613 {
614 --level;
615 }
616
617 if (table[level]->hasUnmangledBuiltIn(name))
618 {
619 return true;
620 }
621 }
622 return false;
623}
624
Olli Etuaho5d69db12017-11-24 16:51:15 +0200625void TSymbolTable::markBuiltInInitializationFinished()
626{
627 mUserDefinedUniqueIdsStart = mUniqueIdCounter;
628}
629
630void TSymbolTable::clearCompilationResults()
631{
632 mUniqueIdCounter = mUserDefinedUniqueIdsStart;
633
634 // User-defined scopes should have already been cleared when the compilation finished.
635 ASSERT(table.size() == LAST_BUILTIN_LEVEL + 1u);
636}
637
638int TSymbolTable::nextUniqueIdValue()
639{
640 ASSERT(mUniqueIdCounter < std::numeric_limits<int>::max());
641 return ++mUniqueIdCounter;
642}
643
Jamie Madill45bcc782016-11-07 13:58:48 -0500644} // namespace sh