blob: 39f4f5455d094e17239ca2d16aa1f253dd4f4eba [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)
Olli Etuaho035419f2017-11-28 14:27:15 +020033 : mName(name), mUniqueId(symbolTable->nextUniqueId()), mExtension(TExtension::UNDEFINED)
Olli Etuaho476197f2016-10-11 13:59:08 +010034{
35}
36
Olli Etuaho035419f2017-11-28 14:27:15 +020037TVariable::TVariable(TSymbolTable *symbolTable, const TString *name, const TType &t)
38 : TSymbol(symbolTable, name), type(t), unionArray(nullptr)
39{
40}
41
42TStructure::TStructure(TSymbolTable *symbolTable, const TString *name, const TFieldList *fields)
43 : TSymbol(symbolTable, name), TFieldListCollection(fields)
44{
45}
46
47void TStructure::createSamplerSymbols(const TString &namePrefix,
48 const TString &apiNamePrefix,
49 TVector<TIntermSymbol *> *outputSymbols,
50 TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames,
51 TSymbolTable *symbolTable) const
52{
53 ASSERT(containsSamplers());
54 for (const auto *field : *mFields)
55 {
56 const TType *fieldType = field->type();
57 if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
58 {
59 TString fieldName = namePrefix + "_" + field->name();
60 TString fieldApiName = apiNamePrefix + "." + field->name();
61 fieldType->createSamplerSymbols(fieldName, fieldApiName, outputSymbols,
62 outputSymbolsToAPINames, symbolTable);
63 }
64 }
65}
66
67void TStructure::setName(const TString &name)
68{
69 TString *mutableName = const_cast<TString *>(mName);
70 *mutableName = name;
71}
72
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000073//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000074// Functions have buried pointers to delete.
75//
76TFunction::~TFunction()
77{
Olli Etuaho476197f2016-10-11 13:59:08 +010078 clearParameters();
79}
80
81void TFunction::clearParameters()
82{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000083 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
84 delete (*i).type;
Olli Etuaho476197f2016-10-11 13:59:08 +010085 parameters.clear();
86 mangledName = nullptr;
87}
88
89void TFunction::swapParameters(const TFunction &parametersSource)
90{
91 clearParameters();
92 for (auto parameter : parametersSource.parameters)
93 {
94 addParameter(parameter);
95 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000096}
97
Dmitry Skiba58832202015-07-06 16:11:13 -070098const TString *TFunction::buildMangledName() const
99{
Olli Etuaho54a29ff2017-11-28 17:35:20 +0200100 std::string newName = name().c_str();
Olli Etuahof2209f72017-04-01 12:45:55 +0300101 newName += kFunctionMangledNameSeparator;
Dmitry Skiba58832202015-07-06 16:11:13 -0700102
103 for (const auto &p : parameters)
104 {
Jamie Madill902e8c12017-11-18 09:34:16 -0500105 newName += p.type->getMangledName();
Dmitry Skiba58832202015-07-06 16:11:13 -0700106 }
Cooper Partin149e6e62015-08-07 16:18:18 -0700107 return NewPoolTString(newName.c_str());
Dmitry Skiba58832202015-07-06 16:11:13 -0700108}
109
Olli Etuahof2209f72017-04-01 12:45:55 +0300110const TString &TFunction::GetMangledNameFromCall(const TString &functionName,
111 const TIntermSequence &arguments)
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800112{
Olli Etuahof2209f72017-04-01 12:45:55 +0300113 std::string newName = functionName.c_str();
114 newName += kFunctionMangledNameSeparator;
115
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800116 for (TIntermNode *argument : arguments)
117 {
Jamie Madill902e8c12017-11-18 09:34:16 -0500118 newName += argument->getAsTyped()->getType().getMangledName();
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800119 }
120 return *NewPoolTString(newName.c_str());
121}
122
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000123//
124// Symbol table levels are a map of pointers to symbols that have to be deleted.
125//
126TSymbolTableLevel::~TSymbolTableLevel()
127{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000128 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
129 delete (*it).second;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000130}
131
Nicolas Capensadfffe42014-06-17 02:13:36 -0400132bool TSymbolTableLevel::insert(TSymbol *symbol)
Jamie Madillbfa91f42014-06-05 15:45:18 -0400133{
Jamie Madillbfa91f42014-06-05 15:45:18 -0400134 // returning true means symbol was added to the table
Nicolas Capensadfffe42014-06-17 02:13:36 -0400135 tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
Jamie Madillbfa91f42014-06-05 15:45:18 -0400136
137 return result.second;
138}
139
Olli Etuahob2983c92015-03-18 14:02:46 +0200140bool TSymbolTableLevel::insertUnmangled(TFunction *function)
141{
Olli Etuahob2983c92015-03-18 14:02:46 +0200142 // returning true means symbol was added to the table
Olli Etuaho54a29ff2017-11-28 17:35:20 +0200143 tInsertResult result = level.insert(tLevelPair(function->name(), function));
Olli Etuahob2983c92015-03-18 14:02:46 +0200144
145 return result.second;
146}
147
Jamie Madillbfa91f42014-06-05 15:45:18 -0400148TSymbol *TSymbolTableLevel::find(const TString &name) const
149{
150 tLevel::const_iterator it = level.find(name);
151 if (it == level.end())
152 return 0;
153 else
154 return (*it).second;
155}
156
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500157TSymbol *TSymbolTable::find(const TString &name,
158 int shaderVersion,
159 bool *builtIn,
160 bool *sameScope) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000161{
162 int level = currentLevel();
163 TSymbol *symbol;
164
165 do
166 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300167 if (level == GLSL_BUILTINS)
168 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +0300169 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
170 level--;
171 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700172 level--;
173 if (level == ESSL1_BUILTINS && shaderVersion != 100)
174 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000175
176 symbol = table[level]->find(name);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500177 } while (symbol == 0 && --level >= 0);
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000178
179 if (builtIn)
180 *builtIn = (level <= LAST_BUILTIN_LEVEL);
181 if (sameScope)
182 *sameScope = (level == currentLevel());
183
184 return symbol;
185}
186
Zhenyao Mod7490962016-11-09 15:49:51 -0800187TSymbol *TSymbolTable::findGlobal(const TString &name) const
188{
189 ASSERT(table.size() > GLOBAL_LEVEL);
190 return table[GLOBAL_LEVEL]->find(name);
191}
192
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500193TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000194{
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300195 return findBuiltIn(name, shaderVersion, false);
196}
197
198TSymbol *TSymbolTable::findBuiltIn(const TString &name,
199 int shaderVersion,
200 bool includeGLSLBuiltins) const
201{
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000202 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
203 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300204 if (level == GLSL_BUILTINS && !includeGLSLBuiltins)
205 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +0300206 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
207 level--;
208 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700209 level--;
210 if (level == ESSL1_BUILTINS && shaderVersion != 100)
211 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000212
213 TSymbol *symbol = table[level]->find(name);
214
215 if (symbol)
216 return symbol;
217 }
218
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300219 return nullptr;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000220}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400221
222TSymbolTable::~TSymbolTable()
223{
224 while (table.size() > 0)
225 pop();
226}
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700227
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500228bool IsGenType(const TType *type)
229{
230 if (type)
231 {
232 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500233 return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType ||
234 basicType == EbtGenBType;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500235 }
236
237 return false;
238}
239
240bool IsVecType(const TType *type)
241{
242 if (type)
243 {
244 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500245 return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec ||
246 basicType == EbtBVec;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500247 }
248
249 return false;
250}
251
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700252const TType *SpecificType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500253{
254 ASSERT(size >= 1 && size <= 4);
255
256 if (!type)
257 {
258 return nullptr;
259 }
260
261 ASSERT(!IsVecType(type));
262
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500263 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500264 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500265 case EbtGenType:
Olli Etuaho9250cb22017-01-21 10:51:27 +0000266 return TCache::getType(EbtFloat, type->getQualifier(),
267 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500268 case EbtGenIType:
Olli Etuaho9250cb22017-01-21 10:51:27 +0000269 return TCache::getType(EbtInt, type->getQualifier(), static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500270 case EbtGenUType:
Olli Etuaho9250cb22017-01-21 10:51:27 +0000271 return TCache::getType(EbtUInt, type->getQualifier(), static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500272 case EbtGenBType:
Olli Etuaho9250cb22017-01-21 10:51:27 +0000273 return TCache::getType(EbtBool, type->getQualifier(), static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500274 default:
275 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500276 }
277}
278
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700279const TType *VectorType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500280{
281 ASSERT(size >= 2 && size <= 4);
282
283 if (!type)
284 {
285 return nullptr;
286 }
287
288 ASSERT(!IsGenType(type));
289
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500290 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500291 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500292 case EbtVec:
293 return TCache::getType(EbtFloat, static_cast<unsigned char>(size));
294 case EbtIVec:
295 return TCache::getType(EbtInt, static_cast<unsigned char>(size));
296 case EbtUVec:
297 return TCache::getType(EbtUInt, static_cast<unsigned char>(size));
298 case EbtBVec:
299 return TCache::getType(EbtBool, static_cast<unsigned char>(size));
300 default:
301 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500302 }
303}
304
Olli Etuaho0f684632017-07-13 12:42:15 +0300305TVariable *TSymbolTable::declareVariable(const TString *name, const TType &type)
306{
307 return insertVariable(currentLevel(), name, type);
308}
309
Olli Etuaho035419f2017-11-28 14:27:15 +0200310bool TSymbolTable::declareStructType(TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300311{
312 return insertStructType(currentLevel(), str);
313}
314
315TInterfaceBlockName *TSymbolTable::declareInterfaceBlockName(const TString *name)
316{
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300317 TInterfaceBlockName *blockNameSymbol = new TInterfaceBlockName(this, name);
Olli Etuaho0f684632017-07-13 12:42:15 +0300318 if (insert(currentLevel(), blockNameSymbol))
319 {
320 return blockNameSymbol;
321 }
322 return nullptr;
323}
324
Jiawei Shaod8105a02017-08-08 09:54:36 +0800325TInterfaceBlockName *TSymbolTable::insertInterfaceBlockNameExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300326 TExtension ext,
Jiawei Shaod8105a02017-08-08 09:54:36 +0800327 const TString *name)
328{
329 TInterfaceBlockName *blockNameSymbol = new TInterfaceBlockName(this, name);
Olli Etuaho5d69db12017-11-24 16:51:15 +0200330 blockNameSymbol->relateToExtension(ext);
331 if (insert(level, blockNameSymbol))
Jiawei Shaod8105a02017-08-08 09:54:36 +0800332 {
333 return blockNameSymbol;
334 }
335 return nullptr;
336}
337
Olli Etuaho0f684632017-07-13 12:42:15 +0300338TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType &type)
339{
340 return insertVariable(level, NewPoolTString(name), type);
341}
342
343TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const TString *name, const TType &type)
344{
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300345 TVariable *var = new TVariable(this, name, type);
Olli Etuaho0f684632017-07-13 12:42:15 +0300346 if (insert(level, var))
347 {
348 // Do lazy initialization for struct types, so we allocate to the current scope.
349 if (var->getType().getBasicType() == EbtStruct)
350 {
351 var->getType().realize();
352 }
353 return var;
354 }
355 return nullptr;
356}
357
358TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300359 TExtension ext,
Olli Etuaho0f684632017-07-13 12:42:15 +0300360 const char *name,
361 const TType &type)
362{
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300363 TVariable *var = new TVariable(this, NewPoolTString(name), type);
Olli Etuaho5d69db12017-11-24 16:51:15 +0200364 var->relateToExtension(ext);
365 if (insert(level, var))
Olli Etuaho0f684632017-07-13 12:42:15 +0300366 {
367 if (var->getType().getBasicType() == EbtStruct)
368 {
369 var->getType().realize();
370 }
371 return var;
372 }
373 return nullptr;
374}
375
Olli Etuaho035419f2017-11-28 14:27:15 +0200376bool TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300377{
Olli Etuaho035419f2017-11-28 14:27:15 +0200378 ASSERT(str);
379 if (insert(level, str))
Olli Etuaho0f684632017-07-13 12:42:15 +0300380 {
Olli Etuaho035419f2017-11-28 14:27:15 +0200381 return true;
Olli Etuaho0f684632017-07-13 12:42:15 +0300382 }
Olli Etuaho035419f2017-11-28 14:27:15 +0200383 return false;
Olli Etuaho0f684632017-07-13 12:42:15 +0300384}
385
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500386void TSymbolTable::insertBuiltIn(ESymbolLevel level,
387 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300388 TExtension ext,
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500389 const TType *rvalue,
390 const char *name,
391 const TType *ptype1,
392 const TType *ptype2,
393 const TType *ptype3,
394 const TType *ptype4,
395 const TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700396{
397 if (ptype1->getBasicType() == EbtGSampler2D)
398 {
Martin Radevda6254b2016-12-14 17:00:36 +0200399 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700400 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500401 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
402 TCache::getType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
403 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
404 TCache::getType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
405 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
406 TCache::getType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700407 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500408 else if (ptype1->getBasicType() == EbtGSampler3D)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700409 {
Martin Radevda6254b2016-12-14 17:00:36 +0200410 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700411 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500412 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
413 TCache::getType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
414 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
415 TCache::getType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
416 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
417 TCache::getType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700418 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500419 else if (ptype1->getBasicType() == EbtGSamplerCube)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700420 {
Martin Radevda6254b2016-12-14 17:00:36 +0200421 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700422 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500423 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
424 TCache::getType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
425 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
426 TCache::getType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
427 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
428 TCache::getType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700429 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500430 else if (ptype1->getBasicType() == EbtGSampler2DArray)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700431 {
Martin Radevda6254b2016-12-14 17:00:36 +0200432 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700433 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500434 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
435 TCache::getType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
436 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
437 TCache::getType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
438 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
439 TCache::getType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700440 }
JiangYizhou40219322016-12-09 09:50:51 +0800441 else if (ptype1->getBasicType() == EbtGSampler2DMS)
442 {
443 insertUnmangledBuiltInName(name, level);
444 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
445 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
446 TCache::getType(EbtSampler2DMS), ptype2, ptype3, ptype4, ptype5);
447 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
448 TCache::getType(EbtISampler2DMS), ptype2, ptype3, ptype4, ptype5);
449 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
450 TCache::getType(EbtUSampler2DMS), ptype2, ptype3, ptype4, ptype5);
451 }
Martin Radev2cc85b32016-08-05 16:22:53 +0300452 else if (IsGImage(ptype1->getBasicType()))
453 {
Martin Radevda6254b2016-12-14 17:00:36 +0200454 insertUnmangledBuiltInName(name, level);
Martin Radev2cc85b32016-08-05 16:22:53 +0300455
456 const TType *floatType = TCache::getType(EbtFloat, 4);
457 const TType *intType = TCache::getType(EbtInt, 4);
458 const TType *unsignedType = TCache::getType(EbtUInt, 4);
459
460 const TType *floatImage =
461 TCache::getType(convertGImageToFloatImage(ptype1->getBasicType()));
462 const TType *intImage = TCache::getType(convertGImageToIntImage(ptype1->getBasicType()));
463 const TType *unsignedImage =
464 TCache::getType(convertGImageToUnsignedImage(ptype1->getBasicType()));
465
466 // GLSL ES 3.10, Revision 4, 8.12 Image Functions
467 if (rvalue->getBasicType() == EbtGVec4)
468 {
469 // imageLoad
470 insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
471 insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
472 insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
473 }
474 else if (rvalue->getBasicType() == EbtVoid)
475 {
476 // imageStore
477 insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
478 insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
479 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
480 }
481 else
482 {
483 // imageSize
484 insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
485 insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
486 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
487 }
488 }
Olli Etuaho9250cb22017-01-21 10:51:27 +0000489 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3) ||
490 IsGenType(ptype4))
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500491 {
Olli Etuaho9250cb22017-01-21 10:51:27 +0000492 ASSERT(!ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200493 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500494 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000495 SpecificType(ptype2, 1), SpecificType(ptype3, 1), SpecificType(ptype4, 1));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500496 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000497 SpecificType(ptype2, 2), SpecificType(ptype3, 2), SpecificType(ptype4, 2));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500498 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000499 SpecificType(ptype2, 3), SpecificType(ptype3, 3), SpecificType(ptype4, 3));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500500 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000501 SpecificType(ptype2, 4), SpecificType(ptype3, 4), SpecificType(ptype4, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500502 }
503 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
504 {
505 ASSERT(!ptype4 && !ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200506 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500507 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2),
508 VectorType(ptype2, 2), VectorType(ptype3, 2));
509 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3),
510 VectorType(ptype2, 3), VectorType(ptype3, 3));
511 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4),
512 VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500513 }
514 else
515 {
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300516 TFunction *function = new TFunction(this, NewPoolTString(name), rvalue, op, ext);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700517
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700518 function->addParameter(TConstParameter(ptype1));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700519
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500520 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700521 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700522 function->addParameter(TConstParameter(ptype2));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700523 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700524
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500525 if (ptype3)
526 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700527 function->addParameter(TConstParameter(ptype3));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500528 }
529
530 if (ptype4)
531 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700532 function->addParameter(TConstParameter(ptype4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500533 }
534
535 if (ptype5)
536 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700537 function->addParameter(TConstParameter(ptype5));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500538 }
539
Martin Radevda6254b2016-12-14 17:00:36 +0200540 ASSERT(hasUnmangledBuiltInAtLevel(name, level));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500541 insert(level, function);
542 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700543}
544
Olli Etuaho492cfab2017-01-20 21:18:29 +0000545void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
546 TOperator op,
547 const TType *rvalue,
548 const TType *ptype1,
549 const TType *ptype2,
550 const TType *ptype3,
551 const TType *ptype4,
552 const TType *ptype5)
553{
554 const char *name = GetOperatorString(op);
555 ASSERT(strlen(name) > 0);
556 insertUnmangledBuiltInName(name, level);
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300557 insertBuiltIn(level, op, TExtension::UNDEFINED, rvalue, name, ptype1, ptype2, ptype3, ptype4,
558 ptype5);
Olli Etuaho492cfab2017-01-20 21:18:29 +0000559}
560
561void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
562 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300563 TExtension ext,
Olli Etuaho492cfab2017-01-20 21:18:29 +0000564 const TType *rvalue,
565 const TType *ptype1,
566 const TType *ptype2,
567 const TType *ptype3,
568 const TType *ptype4,
569 const TType *ptype5)
570{
571 const char *name = GetOperatorString(op);
572 insertUnmangledBuiltInName(name, level);
573 insertBuiltIn(level, op, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
574}
575
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300576void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
577 TOperator op,
578 const TType *rvalue,
579 const char *name)
580{
581 insertUnmangledBuiltInName(name, level);
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300582 insert(level, new TFunction(this, NewPoolTString(name), rvalue, op));
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300583}
584
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800585void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300586 TExtension ext,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800587 TOperator op,
588 const TType *rvalue,
589 const char *name)
590{
591 insertUnmangledBuiltInName(name, level);
592 insert(level, new TFunction(this, NewPoolTString(name), rvalue, op, ext));
593}
594
Zhenyao Moe740add2014-07-18 17:01:01 -0700595TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700596{
597 if (!SupportsPrecision(type))
598 return EbpUndefined;
599
600 // unsigned integers use the same precision as signed
601 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
602
603 int level = static_cast<int>(precisionStack.size()) - 1;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500604 assert(level >= 0); // Just to be safe. Should not happen.
Olli Etuaho183d7e22015-11-20 15:59:09 +0200605 // If we dont find anything we return this. Some types don't have predefined default precision.
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700606 TPrecision prec = EbpUndefined;
607 while (level >= 0)
608 {
609 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
610 if (it != precisionStack[level]->end())
611 {
612 prec = (*it).second;
613 break;
614 }
615 level--;
616 }
617 return prec;
618}
Jamie Madill45bcc782016-11-07 13:58:48 -0500619
Martin Radevda6254b2016-12-14 17:00:36 +0200620void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
621{
622 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
Olli Etuaho5d69db12017-11-24 16:51:15 +0200623 ASSERT(mUserDefinedUniqueIdsStart == -1);
Martin Radevda6254b2016-12-14 17:00:36 +0200624 table[level]->insertUnmangledBuiltInName(std::string(name));
625}
626
627bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level)
628{
629 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
630 return table[level]->hasUnmangledBuiltIn(std::string(name));
631}
632
633bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion)
634{
635 ASSERT(static_cast<ESymbolLevel>(table.size()) > LAST_BUILTIN_LEVEL);
636
637 for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
638 {
639 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
640 {
641 --level;
642 }
643 if (level == ESSL3_BUILTINS && shaderVersion < 300)
644 {
645 --level;
646 }
647 if (level == ESSL1_BUILTINS && shaderVersion != 100)
648 {
649 --level;
650 }
651
652 if (table[level]->hasUnmangledBuiltIn(name))
653 {
654 return true;
655 }
656 }
657 return false;
658}
659
Olli Etuaho5d69db12017-11-24 16:51:15 +0200660void TSymbolTable::markBuiltInInitializationFinished()
661{
662 mUserDefinedUniqueIdsStart = mUniqueIdCounter;
663}
664
665void TSymbolTable::clearCompilationResults()
666{
667 mUniqueIdCounter = mUserDefinedUniqueIdsStart;
668
669 // User-defined scopes should have already been cleared when the compilation finished.
670 ASSERT(table.size() == LAST_BUILTIN_LEVEL + 1u);
671}
672
673int TSymbolTable::nextUniqueIdValue()
674{
675 ASSERT(mUniqueIdCounter < std::numeric_limits<int>::max());
676 return ++mUniqueIdCounter;
677}
678
Jamie Madill45bcc782016-11-07 13:58:48 -0500679} // namespace sh