blob: 7a9d57e4ed1330b182af06a47e0fd97f74220250 [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 Etuahod5f1afb2017-12-04 15:42:59 +020032TSymbol::TSymbol(TSymbolTable *symbolTable, const TString *name, TExtension extension)
33 : mName(name), mUniqueId(symbolTable->nextUniqueId()), mExtension(extension)
Olli Etuaho476197f2016-10-11 13:59:08 +010034{
35}
36
Olli Etuahod5f1afb2017-12-04 15:42:59 +020037TVariable::TVariable(TSymbolTable *symbolTable,
38 const TString *name,
39 const TType &t,
40 TExtension extension)
41 : TSymbol(symbolTable, name, extension), type(t), unionArray(nullptr)
Olli Etuaho035419f2017-11-28 14:27:15 +020042{
43}
44
45TStructure::TStructure(TSymbolTable *symbolTable, const TString *name, const TFieldList *fields)
46 : TSymbol(symbolTable, name), TFieldListCollection(fields)
47{
48}
49
50void TStructure::createSamplerSymbols(const TString &namePrefix,
51 const TString &apiNamePrefix,
52 TVector<TIntermSymbol *> *outputSymbols,
53 TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames,
54 TSymbolTable *symbolTable) const
55{
56 ASSERT(containsSamplers());
57 for (const auto *field : *mFields)
58 {
59 const TType *fieldType = field->type();
60 if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
61 {
62 TString fieldName = namePrefix + "_" + field->name();
63 TString fieldApiName = apiNamePrefix + "." + field->name();
64 fieldType->createSamplerSymbols(fieldName, fieldApiName, outputSymbols,
65 outputSymbolsToAPINames, symbolTable);
66 }
67 }
68}
69
70void TStructure::setName(const TString &name)
71{
72 TString *mutableName = const_cast<TString *>(mName);
73 *mutableName = name;
74}
75
Olli Etuaho378c3a52017-12-04 11:32:13 +020076TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable,
77 const TString *name,
78 const TFieldList *fields,
Olli Etuahod5f1afb2017-12-04 15:42:59 +020079 const TLayoutQualifier &layoutQualifier,
80 TExtension extension)
81 : TSymbol(symbolTable, name, extension),
Olli Etuaho378c3a52017-12-04 11:32:13 +020082 TFieldListCollection(fields),
83 mBlockStorage(layoutQualifier.blockStorage),
84 mBinding(layoutQualifier.binding)
85{
86}
87
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000088//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000089// Functions have buried pointers to delete.
90//
91TFunction::~TFunction()
92{
Olli Etuaho476197f2016-10-11 13:59:08 +010093 clearParameters();
94}
95
96void TFunction::clearParameters()
97{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000098 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
99 delete (*i).type;
Olli Etuaho476197f2016-10-11 13:59:08 +0100100 parameters.clear();
101 mangledName = nullptr;
102}
103
104void TFunction::swapParameters(const TFunction &parametersSource)
105{
106 clearParameters();
107 for (auto parameter : parametersSource.parameters)
108 {
109 addParameter(parameter);
110 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000111}
112
Dmitry Skiba58832202015-07-06 16:11:13 -0700113const TString *TFunction::buildMangledName() const
114{
Olli Etuaho54a29ff2017-11-28 17:35:20 +0200115 std::string newName = name().c_str();
Olli Etuahof2209f72017-04-01 12:45:55 +0300116 newName += kFunctionMangledNameSeparator;
Dmitry Skiba58832202015-07-06 16:11:13 -0700117
118 for (const auto &p : parameters)
119 {
Jamie Madill902e8c12017-11-18 09:34:16 -0500120 newName += p.type->getMangledName();
Dmitry Skiba58832202015-07-06 16:11:13 -0700121 }
Cooper Partin149e6e62015-08-07 16:18:18 -0700122 return NewPoolTString(newName.c_str());
Dmitry Skiba58832202015-07-06 16:11:13 -0700123}
124
Olli Etuahof2209f72017-04-01 12:45:55 +0300125const TString &TFunction::GetMangledNameFromCall(const TString &functionName,
126 const TIntermSequence &arguments)
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800127{
Olli Etuahof2209f72017-04-01 12:45:55 +0300128 std::string newName = functionName.c_str();
129 newName += kFunctionMangledNameSeparator;
130
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800131 for (TIntermNode *argument : arguments)
132 {
Jamie Madill902e8c12017-11-18 09:34:16 -0500133 newName += argument->getAsTyped()->getType().getMangledName();
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800134 }
135 return *NewPoolTString(newName.c_str());
136}
137
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000138//
139// Symbol table levels are a map of pointers to symbols that have to be deleted.
140//
141TSymbolTableLevel::~TSymbolTableLevel()
142{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000143 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
144 delete (*it).second;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000145}
146
Nicolas Capensadfffe42014-06-17 02:13:36 -0400147bool TSymbolTableLevel::insert(TSymbol *symbol)
Jamie Madillbfa91f42014-06-05 15:45:18 -0400148{
Jamie Madillbfa91f42014-06-05 15:45:18 -0400149 // returning true means symbol was added to the table
Nicolas Capensadfffe42014-06-17 02:13:36 -0400150 tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
Jamie Madillbfa91f42014-06-05 15:45:18 -0400151
152 return result.second;
153}
154
Olli Etuahob2983c92015-03-18 14:02:46 +0200155bool TSymbolTableLevel::insertUnmangled(TFunction *function)
156{
Olli Etuahob2983c92015-03-18 14:02:46 +0200157 // returning true means symbol was added to the table
Olli Etuaho54a29ff2017-11-28 17:35:20 +0200158 tInsertResult result = level.insert(tLevelPair(function->name(), function));
Olli Etuahob2983c92015-03-18 14:02:46 +0200159
160 return result.second;
161}
162
Jamie Madillbfa91f42014-06-05 15:45:18 -0400163TSymbol *TSymbolTableLevel::find(const TString &name) const
164{
165 tLevel::const_iterator it = level.find(name);
166 if (it == level.end())
167 return 0;
168 else
169 return (*it).second;
170}
171
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500172TSymbol *TSymbolTable::find(const TString &name,
173 int shaderVersion,
174 bool *builtIn,
175 bool *sameScope) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000176{
177 int level = currentLevel();
178 TSymbol *symbol;
179
180 do
181 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300182 if (level == GLSL_BUILTINS)
183 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +0300184 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
185 level--;
186 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700187 level--;
188 if (level == ESSL1_BUILTINS && shaderVersion != 100)
189 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000190
191 symbol = table[level]->find(name);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500192 } while (symbol == 0 && --level >= 0);
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000193
194 if (builtIn)
195 *builtIn = (level <= LAST_BUILTIN_LEVEL);
196 if (sameScope)
197 *sameScope = (level == currentLevel());
198
199 return symbol;
200}
201
Zhenyao Mod7490962016-11-09 15:49:51 -0800202TSymbol *TSymbolTable::findGlobal(const TString &name) const
203{
204 ASSERT(table.size() > GLOBAL_LEVEL);
205 return table[GLOBAL_LEVEL]->find(name);
206}
207
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500208TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000209{
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300210 return findBuiltIn(name, shaderVersion, false);
211}
212
213TSymbol *TSymbolTable::findBuiltIn(const TString &name,
214 int shaderVersion,
215 bool includeGLSLBuiltins) const
216{
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000217 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
218 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300219 if (level == GLSL_BUILTINS && !includeGLSLBuiltins)
220 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +0300221 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
222 level--;
223 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700224 level--;
225 if (level == ESSL1_BUILTINS && shaderVersion != 100)
226 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000227
228 TSymbol *symbol = table[level]->find(name);
229
230 if (symbol)
231 return symbol;
232 }
233
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300234 return nullptr;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000235}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400236
237TSymbolTable::~TSymbolTable()
238{
239 while (table.size() > 0)
240 pop();
241}
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700242
Kai Ninomiya030017a2017-12-06 14:06:53 -0800243constexpr bool IsGenType(const TType *type)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500244{
245 if (type)
246 {
247 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500248 return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType ||
249 basicType == EbtGenBType;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500250 }
251
252 return false;
253}
254
Kai Ninomiya030017a2017-12-06 14:06:53 -0800255constexpr bool IsVecType(const TType *type)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500256{
257 if (type)
258 {
259 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500260 return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec ||
261 basicType == EbtBVec;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500262 }
263
264 return false;
265}
266
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800267constexpr const TType *SpecificType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500268{
269 ASSERT(size >= 1 && size <= 4);
270
271 if (!type)
272 {
273 return nullptr;
274 }
275
276 ASSERT(!IsVecType(type));
277
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500278 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500279 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500280 case EbtGenType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800281 return StaticType::GetForVec<EbtFloat>(type->getQualifier(),
282 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500283 case EbtGenIType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800284 return StaticType::GetForVec<EbtInt>(type->getQualifier(),
285 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500286 case EbtGenUType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800287 return StaticType::GetForVec<EbtUInt>(type->getQualifier(),
288 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500289 case EbtGenBType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800290 return StaticType::GetForVec<EbtBool>(type->getQualifier(),
291 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500292 default:
293 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500294 }
295}
296
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800297constexpr const TType *VectorType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500298{
299 ASSERT(size >= 2 && size <= 4);
300
301 if (!type)
302 {
303 return nullptr;
304 }
305
306 ASSERT(!IsGenType(type));
307
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500308 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500309 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500310 case EbtVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800311 return StaticType::GetForVecMat<EbtFloat>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500312 case EbtIVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800313 return StaticType::GetForVecMat<EbtInt>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500314 case EbtUVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800315 return StaticType::GetForVecMat<EbtUInt>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500316 case EbtBVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800317 return StaticType::GetForVecMat<EbtBool>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500318 default:
319 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500320 }
321}
322
Olli Etuaho0f684632017-07-13 12:42:15 +0300323TVariable *TSymbolTable::declareVariable(const TString *name, const TType &type)
324{
325 return insertVariable(currentLevel(), name, type);
326}
327
Olli Etuaho035419f2017-11-28 14:27:15 +0200328bool TSymbolTable::declareStructType(TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300329{
330 return insertStructType(currentLevel(), str);
331}
332
Olli Etuaho378c3a52017-12-04 11:32:13 +0200333bool TSymbolTable::declareInterfaceBlock(TInterfaceBlock *interfaceBlock)
Olli Etuaho0f684632017-07-13 12:42:15 +0300334{
Olli Etuaho378c3a52017-12-04 11:32:13 +0200335 return insert(currentLevel(), interfaceBlock);
Jiawei Shaod8105a02017-08-08 09:54:36 +0800336}
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 Etuahod5f1afb2017-12-04 15:42:59 +0200363 TVariable *var = new TVariable(this, NewPoolTString(name), type, ext);
Olli Etuaho5d69db12017-11-24 16:51:15 +0200364 if (insert(level, var))
Olli Etuaho0f684632017-07-13 12:42:15 +0300365 {
366 if (var->getType().getBasicType() == EbtStruct)
367 {
368 var->getType().realize();
369 }
370 return var;
371 }
372 return nullptr;
373}
374
Olli Etuaho035419f2017-11-28 14:27:15 +0200375bool TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300376{
Olli Etuaho035419f2017-11-28 14:27:15 +0200377 ASSERT(str);
Olli Etuaho378c3a52017-12-04 11:32:13 +0200378 return insert(level, str);
379}
380
381bool TSymbolTable::insertInterfaceBlock(ESymbolLevel level, TInterfaceBlock *interfaceBlock)
382{
383 ASSERT(interfaceBlock);
384 return insert(level, interfaceBlock);
Olli Etuaho0f684632017-07-13 12:42:15 +0300385}
386
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500387void TSymbolTable::insertBuiltIn(ESymbolLevel level,
388 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300389 TExtension ext,
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500390 const TType *rvalue,
391 const char *name,
392 const TType *ptype1,
393 const TType *ptype2,
394 const TType *ptype3,
395 const TType *ptype4,
396 const TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700397{
398 if (ptype1->getBasicType() == EbtGSampler2D)
399 {
Martin Radevda6254b2016-12-14 17:00:36 +0200400 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700401 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800402 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
403 StaticType::GetBasic<EbtSampler2D>(), ptype2, ptype3, ptype4, ptype5);
404 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
405 StaticType::GetBasic<EbtISampler2D>(), ptype2, ptype3, ptype4, ptype5);
406 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
407 StaticType::GetBasic<EbtUSampler2D>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700408 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500409 else if (ptype1->getBasicType() == EbtGSampler3D)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700410 {
Martin Radevda6254b2016-12-14 17:00:36 +0200411 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700412 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800413 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
414 StaticType::GetBasic<EbtSampler3D>(), ptype2, ptype3, ptype4, ptype5);
415 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
416 StaticType::GetBasic<EbtISampler3D>(), ptype2, ptype3, ptype4, ptype5);
417 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
418 StaticType::GetBasic<EbtUSampler3D>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700419 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500420 else if (ptype1->getBasicType() == EbtGSamplerCube)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700421 {
Martin Radevda6254b2016-12-14 17:00:36 +0200422 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700423 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800424 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
425 StaticType::GetBasic<EbtSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
426 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
427 StaticType::GetBasic<EbtISamplerCube>(), ptype2, ptype3, ptype4, ptype5);
428 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
429 StaticType::GetBasic<EbtUSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700430 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500431 else if (ptype1->getBasicType() == EbtGSampler2DArray)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700432 {
Martin Radevda6254b2016-12-14 17:00:36 +0200433 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700434 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800435 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
436 StaticType::GetBasic<EbtSampler2DArray>(), ptype2, ptype3, ptype4,
437 ptype5);
438 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
439 StaticType::GetBasic<EbtISampler2DArray>(), ptype2, ptype3, ptype4,
440 ptype5);
441 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
442 StaticType::GetBasic<EbtUSampler2DArray>(), ptype2, ptype3, ptype4,
443 ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700444 }
JiangYizhou40219322016-12-09 09:50:51 +0800445 else if (ptype1->getBasicType() == EbtGSampler2DMS)
446 {
447 insertUnmangledBuiltInName(name, level);
448 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800449 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
450 StaticType::GetBasic<EbtSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
451 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
452 StaticType::GetBasic<EbtISampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
453 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
454 StaticType::GetBasic<EbtUSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
JiangYizhou40219322016-12-09 09:50:51 +0800455 }
Martin Radev2cc85b32016-08-05 16:22:53 +0300456 else if (IsGImage(ptype1->getBasicType()))
457 {
Martin Radevda6254b2016-12-14 17:00:36 +0200458 insertUnmangledBuiltInName(name, level);
Martin Radev2cc85b32016-08-05 16:22:53 +0300459
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800460 const TType *floatType = StaticType::GetBasic<EbtFloat, 4>();
461 const TType *intType = StaticType::GetBasic<EbtInt, 4>();
462 const TType *unsignedType = StaticType::GetBasic<EbtUInt, 4>();
Martin Radev2cc85b32016-08-05 16:22:53 +0300463
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800464 const TType *floatImage = StaticType::GetForFloatImage(ptype1->getBasicType());
465 const TType *intImage = StaticType::GetForIntImage(ptype1->getBasicType());
466 const TType *unsignedImage = StaticType::GetForUintImage(ptype1->getBasicType());
Martin Radev2cc85b32016-08-05 16:22:53 +0300467
468 // GLSL ES 3.10, Revision 4, 8.12 Image Functions
469 if (rvalue->getBasicType() == EbtGVec4)
470 {
471 // imageLoad
472 insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
473 insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
474 insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
475 }
476 else if (rvalue->getBasicType() == EbtVoid)
477 {
478 // imageStore
479 insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
480 insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
481 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
482 }
483 else
484 {
485 // imageSize
486 insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
487 insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
488 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
489 }
490 }
Olli Etuaho9250cb22017-01-21 10:51:27 +0000491 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3) ||
492 IsGenType(ptype4))
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500493 {
Olli Etuaho9250cb22017-01-21 10:51:27 +0000494 ASSERT(!ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200495 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500496 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000497 SpecificType(ptype2, 1), SpecificType(ptype3, 1), SpecificType(ptype4, 1));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500498 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000499 SpecificType(ptype2, 2), SpecificType(ptype3, 2), SpecificType(ptype4, 2));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500500 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000501 SpecificType(ptype2, 3), SpecificType(ptype3, 3), SpecificType(ptype4, 3));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500502 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000503 SpecificType(ptype2, 4), SpecificType(ptype3, 4), SpecificType(ptype4, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500504 }
505 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
506 {
507 ASSERT(!ptype4 && !ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200508 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500509 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2),
510 VectorType(ptype2, 2), VectorType(ptype3, 2));
511 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3),
512 VectorType(ptype2, 3), VectorType(ptype3, 3));
513 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4),
514 VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500515 }
516 else
517 {
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300518 TFunction *function = new TFunction(this, NewPoolTString(name), rvalue, op, ext);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700519
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700520 function->addParameter(TConstParameter(ptype1));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700521
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500522 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700523 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700524 function->addParameter(TConstParameter(ptype2));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700525 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700526
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500527 if (ptype3)
528 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700529 function->addParameter(TConstParameter(ptype3));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500530 }
531
532 if (ptype4)
533 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700534 function->addParameter(TConstParameter(ptype4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500535 }
536
537 if (ptype5)
538 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700539 function->addParameter(TConstParameter(ptype5));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500540 }
541
Martin Radevda6254b2016-12-14 17:00:36 +0200542 ASSERT(hasUnmangledBuiltInAtLevel(name, level));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500543 insert(level, function);
544 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700545}
546
Olli Etuaho492cfab2017-01-20 21:18:29 +0000547void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
548 TOperator op,
549 const TType *rvalue,
550 const TType *ptype1,
551 const TType *ptype2,
552 const TType *ptype3,
553 const TType *ptype4,
554 const TType *ptype5)
555{
556 const char *name = GetOperatorString(op);
557 ASSERT(strlen(name) > 0);
558 insertUnmangledBuiltInName(name, level);
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300559 insertBuiltIn(level, op, TExtension::UNDEFINED, rvalue, name, ptype1, ptype2, ptype3, ptype4,
560 ptype5);
Olli Etuaho492cfab2017-01-20 21:18:29 +0000561}
562
563void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
564 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300565 TExtension ext,
Olli Etuaho492cfab2017-01-20 21:18:29 +0000566 const TType *rvalue,
567 const TType *ptype1,
568 const TType *ptype2,
569 const TType *ptype3,
570 const TType *ptype4,
571 const TType *ptype5)
572{
573 const char *name = GetOperatorString(op);
574 insertUnmangledBuiltInName(name, level);
575 insertBuiltIn(level, op, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
576}
577
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300578void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
579 TOperator op,
580 const TType *rvalue,
581 const char *name)
582{
583 insertUnmangledBuiltInName(name, level);
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300584 insert(level, new TFunction(this, NewPoolTString(name), rvalue, op));
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300585}
586
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800587void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300588 TExtension ext,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800589 TOperator op,
590 const TType *rvalue,
591 const char *name)
592{
593 insertUnmangledBuiltInName(name, level);
594 insert(level, new TFunction(this, NewPoolTString(name), rvalue, op, ext));
595}
596
Zhenyao Moe740add2014-07-18 17:01:01 -0700597TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700598{
599 if (!SupportsPrecision(type))
600 return EbpUndefined;
601
602 // unsigned integers use the same precision as signed
603 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
604
605 int level = static_cast<int>(precisionStack.size()) - 1;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500606 assert(level >= 0); // Just to be safe. Should not happen.
Olli Etuaho183d7e22015-11-20 15:59:09 +0200607 // If we dont find anything we return this. Some types don't have predefined default precision.
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700608 TPrecision prec = EbpUndefined;
609 while (level >= 0)
610 {
611 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
612 if (it != precisionStack[level]->end())
613 {
614 prec = (*it).second;
615 break;
616 }
617 level--;
618 }
619 return prec;
620}
Jamie Madill45bcc782016-11-07 13:58:48 -0500621
Martin Radevda6254b2016-12-14 17:00:36 +0200622void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
623{
624 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
Olli Etuaho5d69db12017-11-24 16:51:15 +0200625 ASSERT(mUserDefinedUniqueIdsStart == -1);
Martin Radevda6254b2016-12-14 17:00:36 +0200626 table[level]->insertUnmangledBuiltInName(std::string(name));
627}
628
629bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level)
630{
631 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
632 return table[level]->hasUnmangledBuiltIn(std::string(name));
633}
634
635bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion)
636{
637 ASSERT(static_cast<ESymbolLevel>(table.size()) > LAST_BUILTIN_LEVEL);
638
639 for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
640 {
641 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
642 {
643 --level;
644 }
645 if (level == ESSL3_BUILTINS && shaderVersion < 300)
646 {
647 --level;
648 }
649 if (level == ESSL1_BUILTINS && shaderVersion != 100)
650 {
651 --level;
652 }
653
654 if (table[level]->hasUnmangledBuiltIn(name))
655 {
656 return true;
657 }
658 }
659 return false;
660}
661
Olli Etuaho5d69db12017-11-24 16:51:15 +0200662void TSymbolTable::markBuiltInInitializationFinished()
663{
664 mUserDefinedUniqueIdsStart = mUniqueIdCounter;
665}
666
667void TSymbolTable::clearCompilationResults()
668{
669 mUniqueIdCounter = mUserDefinedUniqueIdsStart;
670
671 // User-defined scopes should have already been cleared when the compilation finished.
672 ASSERT(table.size() == LAST_BUILTIN_LEVEL + 1u);
673}
674
675int TSymbolTable::nextUniqueIdValue()
676{
677 ASSERT(mUniqueIdCounter < std::numeric_limits<int>::max());
678 return ++mUniqueIdCounter;
679}
680
Jamie Madill45bcc782016-11-07 13:58:48 -0500681} // namespace sh