blob: 62bd3bab83c1cf9ab2872daafea99f84b086f610 [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
Olli Etuaho01d0ad02017-01-22 14:51:23 -080016#include "compiler/translator/IntermNode.h"
Kai Ninomiya614dd0f2017-11-22 14:04:48 -080017#include "compiler/translator/StaticType.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
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800252constexpr const 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:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800266 return StaticType::GetForVec<EbtFloat>(type->getQualifier(),
267 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500268 case EbtGenIType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800269 return StaticType::GetForVec<EbtInt>(type->getQualifier(),
270 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500271 case EbtGenUType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800272 return StaticType::GetForVec<EbtUInt>(type->getQualifier(),
273 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500274 case EbtGenBType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800275 return StaticType::GetForVec<EbtBool>(type->getQualifier(),
276 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500277 default:
278 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500279 }
280}
281
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800282constexpr const TType *VectorType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500283{
284 ASSERT(size >= 2 && size <= 4);
285
286 if (!type)
287 {
288 return nullptr;
289 }
290
291 ASSERT(!IsGenType(type));
292
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500293 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500294 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500295 case EbtVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800296 return StaticType::GetForVecMat<EbtFloat>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500297 case EbtIVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800298 return StaticType::GetForVecMat<EbtInt>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500299 case EbtUVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800300 return StaticType::GetForVecMat<EbtUInt>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500301 case EbtBVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800302 return StaticType::GetForVecMat<EbtBool>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500303 default:
304 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500305 }
306}
307
Olli Etuaho0f684632017-07-13 12:42:15 +0300308TVariable *TSymbolTable::declareVariable(const TString *name, const TType &type)
309{
310 return insertVariable(currentLevel(), name, type);
311}
312
Olli Etuaho035419f2017-11-28 14:27:15 +0200313bool TSymbolTable::declareStructType(TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300314{
315 return insertStructType(currentLevel(), str);
316}
317
318TInterfaceBlockName *TSymbolTable::declareInterfaceBlockName(const TString *name)
319{
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300320 TInterfaceBlockName *blockNameSymbol = new TInterfaceBlockName(this, name);
Olli Etuaho0f684632017-07-13 12:42:15 +0300321 if (insert(currentLevel(), blockNameSymbol))
322 {
323 return blockNameSymbol;
324 }
325 return nullptr;
326}
327
Jiawei Shaod8105a02017-08-08 09:54:36 +0800328TInterfaceBlockName *TSymbolTable::insertInterfaceBlockNameExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300329 TExtension ext,
Jiawei Shaod8105a02017-08-08 09:54:36 +0800330 const TString *name)
331{
332 TInterfaceBlockName *blockNameSymbol = new TInterfaceBlockName(this, name);
Olli Etuaho5d69db12017-11-24 16:51:15 +0200333 blockNameSymbol->relateToExtension(ext);
334 if (insert(level, blockNameSymbol))
Jiawei Shaod8105a02017-08-08 09:54:36 +0800335 {
336 return blockNameSymbol;
337 }
338 return nullptr;
339}
340
Olli Etuaho0f684632017-07-13 12:42:15 +0300341TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType &type)
342{
343 return insertVariable(level, NewPoolTString(name), type);
344}
345
346TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const TString *name, const TType &type)
347{
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300348 TVariable *var = new TVariable(this, name, type);
Olli Etuaho0f684632017-07-13 12:42:15 +0300349 if (insert(level, var))
350 {
351 // Do lazy initialization for struct types, so we allocate to the current scope.
352 if (var->getType().getBasicType() == EbtStruct)
353 {
354 var->getType().realize();
355 }
356 return var;
357 }
358 return nullptr;
359}
360
361TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300362 TExtension ext,
Olli Etuaho0f684632017-07-13 12:42:15 +0300363 const char *name,
364 const TType &type)
365{
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300366 TVariable *var = new TVariable(this, NewPoolTString(name), type);
Olli Etuaho5d69db12017-11-24 16:51:15 +0200367 var->relateToExtension(ext);
368 if (insert(level, var))
Olli Etuaho0f684632017-07-13 12:42:15 +0300369 {
370 if (var->getType().getBasicType() == EbtStruct)
371 {
372 var->getType().realize();
373 }
374 return var;
375 }
376 return nullptr;
377}
378
Olli Etuaho035419f2017-11-28 14:27:15 +0200379bool TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300380{
Olli Etuaho035419f2017-11-28 14:27:15 +0200381 ASSERT(str);
382 if (insert(level, str))
Olli Etuaho0f684632017-07-13 12:42:15 +0300383 {
Olli Etuaho035419f2017-11-28 14:27:15 +0200384 return true;
Olli Etuaho0f684632017-07-13 12:42:15 +0300385 }
Olli Etuaho035419f2017-11-28 14:27:15 +0200386 return false;
Olli Etuaho0f684632017-07-13 12:42:15 +0300387}
388
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500389void TSymbolTable::insertBuiltIn(ESymbolLevel level,
390 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300391 TExtension ext,
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500392 const TType *rvalue,
393 const char *name,
394 const TType *ptype1,
395 const TType *ptype2,
396 const TType *ptype3,
397 const TType *ptype4,
398 const TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700399{
400 if (ptype1->getBasicType() == EbtGSampler2D)
401 {
Martin Radevda6254b2016-12-14 17:00:36 +0200402 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700403 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800404 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
405 StaticType::GetBasic<EbtSampler2D>(), ptype2, ptype3, ptype4, ptype5);
406 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
407 StaticType::GetBasic<EbtISampler2D>(), ptype2, ptype3, ptype4, ptype5);
408 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
409 StaticType::GetBasic<EbtUSampler2D>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700410 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500411 else if (ptype1->getBasicType() == EbtGSampler3D)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700412 {
Martin Radevda6254b2016-12-14 17:00:36 +0200413 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700414 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800415 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
416 StaticType::GetBasic<EbtSampler3D>(), ptype2, ptype3, ptype4, ptype5);
417 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
418 StaticType::GetBasic<EbtISampler3D>(), ptype2, ptype3, ptype4, ptype5);
419 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
420 StaticType::GetBasic<EbtUSampler3D>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700421 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500422 else if (ptype1->getBasicType() == EbtGSamplerCube)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700423 {
Martin Radevda6254b2016-12-14 17:00:36 +0200424 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700425 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800426 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
427 StaticType::GetBasic<EbtSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
428 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
429 StaticType::GetBasic<EbtISamplerCube>(), ptype2, ptype3, ptype4, ptype5);
430 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
431 StaticType::GetBasic<EbtUSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700432 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500433 else if (ptype1->getBasicType() == EbtGSampler2DArray)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700434 {
Martin Radevda6254b2016-12-14 17:00:36 +0200435 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700436 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800437 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
438 StaticType::GetBasic<EbtSampler2DArray>(), ptype2, ptype3, ptype4,
439 ptype5);
440 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
441 StaticType::GetBasic<EbtISampler2DArray>(), ptype2, ptype3, ptype4,
442 ptype5);
443 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
444 StaticType::GetBasic<EbtUSampler2DArray>(), ptype2, ptype3, ptype4,
445 ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700446 }
JiangYizhou40219322016-12-09 09:50:51 +0800447 else if (ptype1->getBasicType() == EbtGSampler2DMS)
448 {
449 insertUnmangledBuiltInName(name, level);
450 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800451 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
452 StaticType::GetBasic<EbtSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
453 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
454 StaticType::GetBasic<EbtISampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
455 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
456 StaticType::GetBasic<EbtUSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
JiangYizhou40219322016-12-09 09:50:51 +0800457 }
Martin Radev2cc85b32016-08-05 16:22:53 +0300458 else if (IsGImage(ptype1->getBasicType()))
459 {
Martin Radevda6254b2016-12-14 17:00:36 +0200460 insertUnmangledBuiltInName(name, level);
Martin Radev2cc85b32016-08-05 16:22:53 +0300461
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800462 const TType *floatType = StaticType::GetBasic<EbtFloat, 4>();
463 const TType *intType = StaticType::GetBasic<EbtInt, 4>();
464 const TType *unsignedType = StaticType::GetBasic<EbtUInt, 4>();
Martin Radev2cc85b32016-08-05 16:22:53 +0300465
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800466 const TType *floatImage = StaticType::GetForFloatImage(ptype1->getBasicType());
467 const TType *intImage = StaticType::GetForIntImage(ptype1->getBasicType());
468 const TType *unsignedImage = StaticType::GetForUintImage(ptype1->getBasicType());
Martin Radev2cc85b32016-08-05 16:22:53 +0300469
470 // GLSL ES 3.10, Revision 4, 8.12 Image Functions
471 if (rvalue->getBasicType() == EbtGVec4)
472 {
473 // imageLoad
474 insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
475 insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
476 insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
477 }
478 else if (rvalue->getBasicType() == EbtVoid)
479 {
480 // imageStore
481 insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
482 insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
483 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
484 }
485 else
486 {
487 // imageSize
488 insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
489 insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
490 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
491 }
492 }
Olli Etuaho9250cb22017-01-21 10:51:27 +0000493 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3) ||
494 IsGenType(ptype4))
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500495 {
Olli Etuaho9250cb22017-01-21 10:51:27 +0000496 ASSERT(!ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200497 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500498 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000499 SpecificType(ptype2, 1), SpecificType(ptype3, 1), SpecificType(ptype4, 1));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500500 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000501 SpecificType(ptype2, 2), SpecificType(ptype3, 2), SpecificType(ptype4, 2));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500502 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000503 SpecificType(ptype2, 3), SpecificType(ptype3, 3), SpecificType(ptype4, 3));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500504 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000505 SpecificType(ptype2, 4), SpecificType(ptype3, 4), SpecificType(ptype4, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500506 }
507 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
508 {
509 ASSERT(!ptype4 && !ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200510 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500511 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2),
512 VectorType(ptype2, 2), VectorType(ptype3, 2));
513 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3),
514 VectorType(ptype2, 3), VectorType(ptype3, 3));
515 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4),
516 VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500517 }
518 else
519 {
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300520 TFunction *function = new TFunction(this, NewPoolTString(name), rvalue, op, ext);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700521
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700522 function->addParameter(TConstParameter(ptype1));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700523
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500524 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700525 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700526 function->addParameter(TConstParameter(ptype2));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700527 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700528
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500529 if (ptype3)
530 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700531 function->addParameter(TConstParameter(ptype3));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500532 }
533
534 if (ptype4)
535 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700536 function->addParameter(TConstParameter(ptype4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500537 }
538
539 if (ptype5)
540 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700541 function->addParameter(TConstParameter(ptype5));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500542 }
543
Martin Radevda6254b2016-12-14 17:00:36 +0200544 ASSERT(hasUnmangledBuiltInAtLevel(name, level));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500545 insert(level, function);
546 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700547}
548
Olli Etuaho492cfab2017-01-20 21:18:29 +0000549void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
550 TOperator op,
551 const TType *rvalue,
552 const TType *ptype1,
553 const TType *ptype2,
554 const TType *ptype3,
555 const TType *ptype4,
556 const TType *ptype5)
557{
558 const char *name = GetOperatorString(op);
559 ASSERT(strlen(name) > 0);
560 insertUnmangledBuiltInName(name, level);
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300561 insertBuiltIn(level, op, TExtension::UNDEFINED, rvalue, name, ptype1, ptype2, ptype3, ptype4,
562 ptype5);
Olli Etuaho492cfab2017-01-20 21:18:29 +0000563}
564
565void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
566 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300567 TExtension ext,
Olli Etuaho492cfab2017-01-20 21:18:29 +0000568 const TType *rvalue,
569 const TType *ptype1,
570 const TType *ptype2,
571 const TType *ptype3,
572 const TType *ptype4,
573 const TType *ptype5)
574{
575 const char *name = GetOperatorString(op);
576 insertUnmangledBuiltInName(name, level);
577 insertBuiltIn(level, op, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
578}
579
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300580void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
581 TOperator op,
582 const TType *rvalue,
583 const char *name)
584{
585 insertUnmangledBuiltInName(name, level);
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300586 insert(level, new TFunction(this, NewPoolTString(name), rvalue, op));
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300587}
588
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800589void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300590 TExtension ext,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800591 TOperator op,
592 const TType *rvalue,
593 const char *name)
594{
595 insertUnmangledBuiltInName(name, level);
596 insert(level, new TFunction(this, NewPoolTString(name), rvalue, op, ext));
597}
598
Zhenyao Moe740add2014-07-18 17:01:01 -0700599TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700600{
601 if (!SupportsPrecision(type))
602 return EbpUndefined;
603
604 // unsigned integers use the same precision as signed
605 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
606
607 int level = static_cast<int>(precisionStack.size()) - 1;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500608 assert(level >= 0); // Just to be safe. Should not happen.
Olli Etuaho183d7e22015-11-20 15:59:09 +0200609 // If we dont find anything we return this. Some types don't have predefined default precision.
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700610 TPrecision prec = EbpUndefined;
611 while (level >= 0)
612 {
613 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
614 if (it != precisionStack[level]->end())
615 {
616 prec = (*it).second;
617 break;
618 }
619 level--;
620 }
621 return prec;
622}
Jamie Madill45bcc782016-11-07 13:58:48 -0500623
Martin Radevda6254b2016-12-14 17:00:36 +0200624void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
625{
626 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
Olli Etuaho5d69db12017-11-24 16:51:15 +0200627 ASSERT(mUserDefinedUniqueIdsStart == -1);
Martin Radevda6254b2016-12-14 17:00:36 +0200628 table[level]->insertUnmangledBuiltInName(std::string(name));
629}
630
631bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level)
632{
633 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
634 return table[level]->hasUnmangledBuiltIn(std::string(name));
635}
636
637bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion)
638{
639 ASSERT(static_cast<ESymbolLevel>(table.size()) > LAST_BUILTIN_LEVEL);
640
641 for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
642 {
643 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
644 {
645 --level;
646 }
647 if (level == ESSL3_BUILTINS && shaderVersion < 300)
648 {
649 --level;
650 }
651 if (level == ESSL1_BUILTINS && shaderVersion != 100)
652 {
653 --level;
654 }
655
656 if (table[level]->hasUnmangledBuiltIn(name))
657 {
658 return true;
659 }
660 }
661 return false;
662}
663
Olli Etuaho5d69db12017-11-24 16:51:15 +0200664void TSymbolTable::markBuiltInInitializationFinished()
665{
666 mUserDefinedUniqueIdsStart = mUniqueIdCounter;
667}
668
669void TSymbolTable::clearCompilationResults()
670{
671 mUniqueIdCounter = mUserDefinedUniqueIdsStart;
672
673 // User-defined scopes should have already been cleared when the compilation finished.
674 ASSERT(table.size() == LAST_BUILTIN_LEVEL + 1u);
675}
676
677int TSymbolTable::nextUniqueIdValue()
678{
679 ASSERT(mUniqueIdCounter < std::numeric_limits<int>::max());
680 return ++mUniqueIdCounter;
681}
682
Jamie Madill45bcc782016-11-07 13:58:48 -0500683} // namespace sh