blob: 3cfa8b7d0c83eb6a47a438138dbd95c3b0cc9674 [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);
294 if (insert(level, ext, blockNameSymbol))
295 {
296 return blockNameSymbol;
297 }
298 return nullptr;
299}
300
Olli Etuaho0f684632017-07-13 12:42:15 +0300301TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType &type)
302{
303 return insertVariable(level, NewPoolTString(name), type);
304}
305
306TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const TString *name, const TType &type)
307{
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300308 TVariable *var = new TVariable(this, name, type);
Olli Etuaho0f684632017-07-13 12:42:15 +0300309 if (insert(level, var))
310 {
311 // Do lazy initialization for struct types, so we allocate to the current scope.
312 if (var->getType().getBasicType() == EbtStruct)
313 {
314 var->getType().realize();
315 }
316 return var;
317 }
318 return nullptr;
319}
320
321TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300322 TExtension ext,
Olli Etuaho0f684632017-07-13 12:42:15 +0300323 const char *name,
324 const TType &type)
325{
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300326 TVariable *var = new TVariable(this, NewPoolTString(name), type);
Olli Etuaho0f684632017-07-13 12:42:15 +0300327 if (insert(level, ext, var))
328 {
329 if (var->getType().getBasicType() == EbtStruct)
330 {
331 var->getType().realize();
332 }
333 return var;
334 }
335 return nullptr;
336}
337
338TVariable *TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str)
339{
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300340 TVariable *var = new TVariable(this, &str->name(), TType(str), true);
Olli Etuaho0f684632017-07-13 12:42:15 +0300341 if (insert(level, var))
342 {
343 var->getType().realize();
344 return var;
345 }
346 return nullptr;
347}
348
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500349void TSymbolTable::insertBuiltIn(ESymbolLevel level,
350 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300351 TExtension ext,
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500352 const TType *rvalue,
353 const char *name,
354 const TType *ptype1,
355 const TType *ptype2,
356 const TType *ptype3,
357 const TType *ptype4,
358 const TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700359{
360 if (ptype1->getBasicType() == EbtGSampler2D)
361 {
Martin Radevda6254b2016-12-14 17:00:36 +0200362 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700363 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500364 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
365 TCache::getType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
366 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
367 TCache::getType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
368 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
369 TCache::getType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700370 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500371 else if (ptype1->getBasicType() == EbtGSampler3D)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700372 {
Martin Radevda6254b2016-12-14 17:00:36 +0200373 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700374 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500375 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
376 TCache::getType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
377 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
378 TCache::getType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
379 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
380 TCache::getType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700381 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500382 else if (ptype1->getBasicType() == EbtGSamplerCube)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700383 {
Martin Radevda6254b2016-12-14 17:00:36 +0200384 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700385 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500386 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
387 TCache::getType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
388 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
389 TCache::getType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
390 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
391 TCache::getType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700392 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500393 else if (ptype1->getBasicType() == EbtGSampler2DArray)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700394 {
Martin Radevda6254b2016-12-14 17:00:36 +0200395 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700396 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500397 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
398 TCache::getType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
399 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
400 TCache::getType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
401 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
402 TCache::getType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700403 }
JiangYizhou40219322016-12-09 09:50:51 +0800404 else if (ptype1->getBasicType() == EbtGSampler2DMS)
405 {
406 insertUnmangledBuiltInName(name, level);
407 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
408 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
409 TCache::getType(EbtSampler2DMS), ptype2, ptype3, ptype4, ptype5);
410 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
411 TCache::getType(EbtISampler2DMS), ptype2, ptype3, ptype4, ptype5);
412 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
413 TCache::getType(EbtUSampler2DMS), ptype2, ptype3, ptype4, ptype5);
414 }
Martin Radev2cc85b32016-08-05 16:22:53 +0300415 else if (IsGImage(ptype1->getBasicType()))
416 {
Martin Radevda6254b2016-12-14 17:00:36 +0200417 insertUnmangledBuiltInName(name, level);
Martin Radev2cc85b32016-08-05 16:22:53 +0300418
419 const TType *floatType = TCache::getType(EbtFloat, 4);
420 const TType *intType = TCache::getType(EbtInt, 4);
421 const TType *unsignedType = TCache::getType(EbtUInt, 4);
422
423 const TType *floatImage =
424 TCache::getType(convertGImageToFloatImage(ptype1->getBasicType()));
425 const TType *intImage = TCache::getType(convertGImageToIntImage(ptype1->getBasicType()));
426 const TType *unsignedImage =
427 TCache::getType(convertGImageToUnsignedImage(ptype1->getBasicType()));
428
429 // GLSL ES 3.10, Revision 4, 8.12 Image Functions
430 if (rvalue->getBasicType() == EbtGVec4)
431 {
432 // imageLoad
433 insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
434 insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
435 insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
436 }
437 else if (rvalue->getBasicType() == EbtVoid)
438 {
439 // imageStore
440 insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
441 insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
442 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
443 }
444 else
445 {
446 // imageSize
447 insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
448 insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
449 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
450 }
451 }
Olli Etuaho9250cb22017-01-21 10:51:27 +0000452 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3) ||
453 IsGenType(ptype4))
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500454 {
Olli Etuaho9250cb22017-01-21 10:51:27 +0000455 ASSERT(!ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200456 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500457 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000458 SpecificType(ptype2, 1), SpecificType(ptype3, 1), SpecificType(ptype4, 1));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500459 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000460 SpecificType(ptype2, 2), SpecificType(ptype3, 2), SpecificType(ptype4, 2));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500461 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000462 SpecificType(ptype2, 3), SpecificType(ptype3, 3), SpecificType(ptype4, 3));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500463 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000464 SpecificType(ptype2, 4), SpecificType(ptype3, 4), SpecificType(ptype4, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500465 }
466 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
467 {
468 ASSERT(!ptype4 && !ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200469 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500470 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2),
471 VectorType(ptype2, 2), VectorType(ptype3, 2));
472 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3),
473 VectorType(ptype2, 3), VectorType(ptype3, 3));
474 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4),
475 VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500476 }
477 else
478 {
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300479 TFunction *function = new TFunction(this, NewPoolTString(name), rvalue, op, ext);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700480
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700481 function->addParameter(TConstParameter(ptype1));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700482
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500483 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700484 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700485 function->addParameter(TConstParameter(ptype2));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700486 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700487
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500488 if (ptype3)
489 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700490 function->addParameter(TConstParameter(ptype3));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500491 }
492
493 if (ptype4)
494 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700495 function->addParameter(TConstParameter(ptype4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500496 }
497
498 if (ptype5)
499 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700500 function->addParameter(TConstParameter(ptype5));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500501 }
502
Martin Radevda6254b2016-12-14 17:00:36 +0200503 ASSERT(hasUnmangledBuiltInAtLevel(name, level));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500504 insert(level, function);
505 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700506}
507
Olli Etuaho492cfab2017-01-20 21:18:29 +0000508void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
509 TOperator op,
510 const TType *rvalue,
511 const TType *ptype1,
512 const TType *ptype2,
513 const TType *ptype3,
514 const TType *ptype4,
515 const TType *ptype5)
516{
517 const char *name = GetOperatorString(op);
518 ASSERT(strlen(name) > 0);
519 insertUnmangledBuiltInName(name, level);
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300520 insertBuiltIn(level, op, TExtension::UNDEFINED, rvalue, name, ptype1, ptype2, ptype3, ptype4,
521 ptype5);
Olli Etuaho492cfab2017-01-20 21:18:29 +0000522}
523
524void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
525 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300526 TExtension ext,
Olli Etuaho492cfab2017-01-20 21:18:29 +0000527 const TType *rvalue,
528 const TType *ptype1,
529 const TType *ptype2,
530 const TType *ptype3,
531 const TType *ptype4,
532 const TType *ptype5)
533{
534 const char *name = GetOperatorString(op);
535 insertUnmangledBuiltInName(name, level);
536 insertBuiltIn(level, op, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
537}
538
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300539void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
540 TOperator op,
541 const TType *rvalue,
542 const char *name)
543{
544 insertUnmangledBuiltInName(name, level);
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300545 insert(level, new TFunction(this, NewPoolTString(name), rvalue, op));
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300546}
547
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800548void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300549 TExtension ext,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800550 TOperator op,
551 const TType *rvalue,
552 const char *name)
553{
554 insertUnmangledBuiltInName(name, level);
555 insert(level, new TFunction(this, NewPoolTString(name), rvalue, op, ext));
556}
557
Zhenyao Moe740add2014-07-18 17:01:01 -0700558TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700559{
560 if (!SupportsPrecision(type))
561 return EbpUndefined;
562
563 // unsigned integers use the same precision as signed
564 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
565
566 int level = static_cast<int>(precisionStack.size()) - 1;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500567 assert(level >= 0); // Just to be safe. Should not happen.
Olli Etuaho183d7e22015-11-20 15:59:09 +0200568 // If we dont find anything we return this. Some types don't have predefined default precision.
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700569 TPrecision prec = EbpUndefined;
570 while (level >= 0)
571 {
572 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
573 if (it != precisionStack[level]->end())
574 {
575 prec = (*it).second;
576 break;
577 }
578 level--;
579 }
580 return prec;
581}
Jamie Madill45bcc782016-11-07 13:58:48 -0500582
Martin Radevda6254b2016-12-14 17:00:36 +0200583void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
584{
585 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
586 table[level]->insertUnmangledBuiltInName(std::string(name));
587}
588
589bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level)
590{
591 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
592 return table[level]->hasUnmangledBuiltIn(std::string(name));
593}
594
595bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion)
596{
597 ASSERT(static_cast<ESymbolLevel>(table.size()) > LAST_BUILTIN_LEVEL);
598
599 for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
600 {
601 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
602 {
603 --level;
604 }
605 if (level == ESSL3_BUILTINS && shaderVersion < 300)
606 {
607 --level;
608 }
609 if (level == ESSL1_BUILTINS && shaderVersion != 100)
610 {
611 --level;
612 }
613
614 if (table[level]->hasUnmangledBuiltIn(name))
615 {
616 return true;
617 }
618 }
619 return false;
620}
621
Jamie Madill45bcc782016-11-07 13:58:48 -0500622} // namespace sh