blob: 04956d30263b223bcf9397ba2efe32e80ee3b7a1 [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 Etuaho9d4d7f02017-12-07 17:11:41 +010032TSymbol::TSymbol(TSymbolTable *symbolTable,
33 const TString *name,
34 SymbolType symbolType,
35 TExtension extension)
36 : mName(name),
37 mUniqueId(symbolTable->nextUniqueId()),
38 mSymbolType(symbolType),
39 mExtension(extension)
Olli Etuaho476197f2016-10-11 13:59:08 +010040{
Olli Etuaho9d4d7f02017-12-07 17:11:41 +010041 ASSERT(mSymbolType == SymbolType::BuiltIn || mExtension == TExtension::UNDEFINED);
Olli Etuaho195be942017-12-04 23:40:14 +020042 ASSERT(mName != nullptr || mSymbolType == SymbolType::AngleInternal ||
43 mSymbolType == SymbolType::NotResolved);
44}
45
46const TString &TSymbol::name() const
47{
48 if (mName != nullptr)
49 {
50 return *mName;
51 }
52 ASSERT(mSymbolType == SymbolType::AngleInternal);
53 TInfoSinkBase symbolNameOut;
54 symbolNameOut << "s" << mUniqueId.get();
55 return *NewPoolTString(symbolNameOut.c_str());
Olli Etuaho476197f2016-10-11 13:59:08 +010056}
57
Olli Etuahod5f1afb2017-12-04 15:42:59 +020058TVariable::TVariable(TSymbolTable *symbolTable,
59 const TString *name,
60 const TType &t,
Olli Etuaho9d4d7f02017-12-07 17:11:41 +010061 SymbolType symbolType,
Olli Etuahod5f1afb2017-12-04 15:42:59 +020062 TExtension extension)
Olli Etuaho9d4d7f02017-12-07 17:11:41 +010063 : TSymbol(symbolTable, name, symbolType, extension), type(t), unionArray(nullptr)
Olli Etuaho035419f2017-11-28 14:27:15 +020064{
65}
66
Olli Etuaho9d4d7f02017-12-07 17:11:41 +010067TStructure::TStructure(TSymbolTable *symbolTable,
68 const TString *name,
69 const TFieldList *fields,
70 SymbolType symbolType)
71 : TSymbol(symbolTable, name, symbolType), TFieldListCollection(fields)
Olli Etuaho035419f2017-11-28 14:27:15 +020072{
73}
74
75void TStructure::createSamplerSymbols(const TString &namePrefix,
76 const TString &apiNamePrefix,
77 TVector<TIntermSymbol *> *outputSymbols,
78 TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames,
79 TSymbolTable *symbolTable) const
80{
81 ASSERT(containsSamplers());
82 for (const auto *field : *mFields)
83 {
84 const TType *fieldType = field->type();
85 if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
86 {
87 TString fieldName = namePrefix + "_" + field->name();
88 TString fieldApiName = apiNamePrefix + "." + field->name();
89 fieldType->createSamplerSymbols(fieldName, fieldApiName, outputSymbols,
90 outputSymbolsToAPINames, symbolTable);
91 }
92 }
93}
94
95void TStructure::setName(const TString &name)
96{
97 TString *mutableName = const_cast<TString *>(mName);
98 *mutableName = name;
99}
100
Olli Etuaho378c3a52017-12-04 11:32:13 +0200101TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable,
102 const TString *name,
103 const TFieldList *fields,
Olli Etuahod5f1afb2017-12-04 15:42:59 +0200104 const TLayoutQualifier &layoutQualifier,
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100105 SymbolType symbolType,
Olli Etuahod5f1afb2017-12-04 15:42:59 +0200106 TExtension extension)
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100107 : TSymbol(symbolTable, name, symbolType, extension),
Olli Etuaho378c3a52017-12-04 11:32:13 +0200108 TFieldListCollection(fields),
109 mBlockStorage(layoutQualifier.blockStorage),
110 mBinding(layoutQualifier.binding)
111{
112}
113
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000114//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000115// Functions have buried pointers to delete.
116//
117TFunction::~TFunction()
118{
Olli Etuaho476197f2016-10-11 13:59:08 +0100119 clearParameters();
120}
121
122void TFunction::clearParameters()
123{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000124 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
125 delete (*i).type;
Olli Etuaho476197f2016-10-11 13:59:08 +0100126 parameters.clear();
127 mangledName = nullptr;
128}
129
130void TFunction::swapParameters(const TFunction &parametersSource)
131{
132 clearParameters();
133 for (auto parameter : parametersSource.parameters)
134 {
135 addParameter(parameter);
136 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000137}
138
Dmitry Skiba58832202015-07-06 16:11:13 -0700139const TString *TFunction::buildMangledName() const
140{
Olli Etuaho54a29ff2017-11-28 17:35:20 +0200141 std::string newName = name().c_str();
Olli Etuahof2209f72017-04-01 12:45:55 +0300142 newName += kFunctionMangledNameSeparator;
Dmitry Skiba58832202015-07-06 16:11:13 -0700143
144 for (const auto &p : parameters)
145 {
Jamie Madill902e8c12017-11-18 09:34:16 -0500146 newName += p.type->getMangledName();
Dmitry Skiba58832202015-07-06 16:11:13 -0700147 }
Cooper Partin149e6e62015-08-07 16:18:18 -0700148 return NewPoolTString(newName.c_str());
Dmitry Skiba58832202015-07-06 16:11:13 -0700149}
150
Olli Etuahof2209f72017-04-01 12:45:55 +0300151const TString &TFunction::GetMangledNameFromCall(const TString &functionName,
152 const TIntermSequence &arguments)
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800153{
Olli Etuahof2209f72017-04-01 12:45:55 +0300154 std::string newName = functionName.c_str();
155 newName += kFunctionMangledNameSeparator;
156
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800157 for (TIntermNode *argument : arguments)
158 {
Jamie Madill902e8c12017-11-18 09:34:16 -0500159 newName += argument->getAsTyped()->getType().getMangledName();
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800160 }
161 return *NewPoolTString(newName.c_str());
162}
163
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000164//
165// Symbol table levels are a map of pointers to symbols that have to be deleted.
166//
167TSymbolTableLevel::~TSymbolTableLevel()
168{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000169 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
170 delete (*it).second;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000171}
172
Nicolas Capensadfffe42014-06-17 02:13:36 -0400173bool TSymbolTableLevel::insert(TSymbol *symbol)
Jamie Madillbfa91f42014-06-05 15:45:18 -0400174{
Jamie Madillbfa91f42014-06-05 15:45:18 -0400175 // returning true means symbol was added to the table
Nicolas Capensadfffe42014-06-17 02:13:36 -0400176 tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
Jamie Madillbfa91f42014-06-05 15:45:18 -0400177
178 return result.second;
179}
180
Olli Etuahob2983c92015-03-18 14:02:46 +0200181bool TSymbolTableLevel::insertUnmangled(TFunction *function)
182{
Olli Etuahob2983c92015-03-18 14:02:46 +0200183 // returning true means symbol was added to the table
Olli Etuaho54a29ff2017-11-28 17:35:20 +0200184 tInsertResult result = level.insert(tLevelPair(function->name(), function));
Olli Etuahob2983c92015-03-18 14:02:46 +0200185
186 return result.second;
187}
188
Jamie Madillbfa91f42014-06-05 15:45:18 -0400189TSymbol *TSymbolTableLevel::find(const TString &name) const
190{
191 tLevel::const_iterator it = level.find(name);
192 if (it == level.end())
193 return 0;
194 else
195 return (*it).second;
196}
197
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500198TSymbol *TSymbolTable::find(const TString &name,
199 int shaderVersion,
200 bool *builtIn,
201 bool *sameScope) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000202{
203 int level = currentLevel();
204 TSymbol *symbol;
205
206 do
207 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300208 if (level == GLSL_BUILTINS)
209 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +0300210 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
211 level--;
212 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700213 level--;
214 if (level == ESSL1_BUILTINS && shaderVersion != 100)
215 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000216
217 symbol = table[level]->find(name);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500218 } while (symbol == 0 && --level >= 0);
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000219
220 if (builtIn)
221 *builtIn = (level <= LAST_BUILTIN_LEVEL);
222 if (sameScope)
223 *sameScope = (level == currentLevel());
224
225 return symbol;
226}
227
Zhenyao Mod7490962016-11-09 15:49:51 -0800228TSymbol *TSymbolTable::findGlobal(const TString &name) const
229{
230 ASSERT(table.size() > GLOBAL_LEVEL);
231 return table[GLOBAL_LEVEL]->find(name);
232}
233
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500234TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000235{
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300236 return findBuiltIn(name, shaderVersion, false);
237}
238
239TSymbol *TSymbolTable::findBuiltIn(const TString &name,
240 int shaderVersion,
241 bool includeGLSLBuiltins) const
242{
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000243 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
244 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300245 if (level == GLSL_BUILTINS && !includeGLSLBuiltins)
246 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +0300247 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
248 level--;
249 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700250 level--;
251 if (level == ESSL1_BUILTINS && shaderVersion != 100)
252 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000253
254 TSymbol *symbol = table[level]->find(name);
255
256 if (symbol)
257 return symbol;
258 }
259
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300260 return nullptr;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000261}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400262
263TSymbolTable::~TSymbolTable()
264{
265 while (table.size() > 0)
266 pop();
267}
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700268
Kai Ninomiya030017a2017-12-06 14:06:53 -0800269constexpr bool IsGenType(const TType *type)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500270{
271 if (type)
272 {
273 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500274 return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType ||
275 basicType == EbtGenBType;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500276 }
277
278 return false;
279}
280
Kai Ninomiya030017a2017-12-06 14:06:53 -0800281constexpr bool IsVecType(const TType *type)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500282{
283 if (type)
284 {
285 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500286 return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec ||
287 basicType == EbtBVec;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500288 }
289
290 return false;
291}
292
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800293constexpr const TType *SpecificType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500294{
295 ASSERT(size >= 1 && size <= 4);
296
297 if (!type)
298 {
299 return nullptr;
300 }
301
302 ASSERT(!IsVecType(type));
303
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500304 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500305 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500306 case EbtGenType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800307 return StaticType::GetForVec<EbtFloat>(type->getQualifier(),
308 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500309 case EbtGenIType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800310 return StaticType::GetForVec<EbtInt>(type->getQualifier(),
311 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500312 case EbtGenUType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800313 return StaticType::GetForVec<EbtUInt>(type->getQualifier(),
314 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500315 case EbtGenBType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800316 return StaticType::GetForVec<EbtBool>(type->getQualifier(),
317 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
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800323constexpr const TType *VectorType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500324{
325 ASSERT(size >= 2 && size <= 4);
326
327 if (!type)
328 {
329 return nullptr;
330 }
331
332 ASSERT(!IsGenType(type));
333
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500334 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500335 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500336 case EbtVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800337 return StaticType::GetForVecMat<EbtFloat>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500338 case EbtIVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800339 return StaticType::GetForVecMat<EbtInt>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500340 case EbtUVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800341 return StaticType::GetForVecMat<EbtUInt>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500342 case EbtBVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800343 return StaticType::GetForVecMat<EbtBool>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500344 default:
345 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500346 }
347}
348
Olli Etuaho195be942017-12-04 23:40:14 +0200349bool TSymbolTable::declareVariable(TVariable *variable)
Olli Etuaho0f684632017-07-13 12:42:15 +0300350{
Olli Etuaho195be942017-12-04 23:40:14 +0200351 ASSERT(variable->symbolType() == SymbolType::UserDefined);
352 return insertVariable(currentLevel(), variable);
Olli Etuaho0f684632017-07-13 12:42:15 +0300353}
354
Olli Etuaho035419f2017-11-28 14:27:15 +0200355bool TSymbolTable::declareStructType(TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300356{
357 return insertStructType(currentLevel(), str);
358}
359
Olli Etuaho378c3a52017-12-04 11:32:13 +0200360bool TSymbolTable::declareInterfaceBlock(TInterfaceBlock *interfaceBlock)
Olli Etuaho0f684632017-07-13 12:42:15 +0300361{
Olli Etuaho378c3a52017-12-04 11:32:13 +0200362 return insert(currentLevel(), interfaceBlock);
Jiawei Shaod8105a02017-08-08 09:54:36 +0800363}
364
Olli Etuaho0f684632017-07-13 12:42:15 +0300365TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType &type)
366{
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100367 ASSERT(level <= LAST_BUILTIN_LEVEL);
368 return insertVariable(level, NewPoolTString(name), type, SymbolType::BuiltIn);
Olli Etuaho0f684632017-07-13 12:42:15 +0300369}
370
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100371TVariable *TSymbolTable::insertVariable(ESymbolLevel level,
372 const TString *name,
373 const TType &type,
374 SymbolType symbolType)
Olli Etuaho0f684632017-07-13 12:42:15 +0300375{
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100376 TVariable *var = new TVariable(this, name, type, symbolType);
Olli Etuaho0f684632017-07-13 12:42:15 +0300377 if (insert(level, var))
378 {
379 // Do lazy initialization for struct types, so we allocate to the current scope.
380 if (var->getType().getBasicType() == EbtStruct)
381 {
382 var->getType().realize();
383 }
384 return var;
385 }
386 return nullptr;
387}
388
389TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300390 TExtension ext,
Olli Etuaho0f684632017-07-13 12:42:15 +0300391 const char *name,
392 const TType &type)
393{
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100394 TVariable *var = new TVariable(this, NewPoolTString(name), type, SymbolType::BuiltIn, ext);
Olli Etuaho5d69db12017-11-24 16:51:15 +0200395 if (insert(level, var))
Olli Etuaho0f684632017-07-13 12:42:15 +0300396 {
397 if (var->getType().getBasicType() == EbtStruct)
398 {
399 var->getType().realize();
400 }
401 return var;
402 }
403 return nullptr;
404}
405
Olli Etuaho195be942017-12-04 23:40:14 +0200406bool TSymbolTable::insertVariable(ESymbolLevel level, TVariable *variable)
407{
408 ASSERT(variable);
409 return insert(level, variable);
410}
411
Olli Etuaho035419f2017-11-28 14:27:15 +0200412bool TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300413{
Olli Etuaho035419f2017-11-28 14:27:15 +0200414 ASSERT(str);
Olli Etuaho378c3a52017-12-04 11:32:13 +0200415 return insert(level, str);
416}
417
418bool TSymbolTable::insertInterfaceBlock(ESymbolLevel level, TInterfaceBlock *interfaceBlock)
419{
420 ASSERT(interfaceBlock);
421 return insert(level, interfaceBlock);
Olli Etuaho0f684632017-07-13 12:42:15 +0300422}
423
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500424void TSymbolTable::insertBuiltIn(ESymbolLevel level,
425 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300426 TExtension ext,
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500427 const TType *rvalue,
428 const char *name,
429 const TType *ptype1,
430 const TType *ptype2,
431 const TType *ptype3,
432 const TType *ptype4,
433 const TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700434{
435 if (ptype1->getBasicType() == EbtGSampler2D)
436 {
Martin Radevda6254b2016-12-14 17:00:36 +0200437 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700438 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800439 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
440 StaticType::GetBasic<EbtSampler2D>(), ptype2, ptype3, ptype4, ptype5);
441 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
442 StaticType::GetBasic<EbtISampler2D>(), ptype2, ptype3, ptype4, ptype5);
443 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
444 StaticType::GetBasic<EbtUSampler2D>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700445 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500446 else if (ptype1->getBasicType() == EbtGSampler3D)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700447 {
Martin Radevda6254b2016-12-14 17:00:36 +0200448 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700449 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800450 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
451 StaticType::GetBasic<EbtSampler3D>(), ptype2, ptype3, ptype4, ptype5);
452 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
453 StaticType::GetBasic<EbtISampler3D>(), ptype2, ptype3, ptype4, ptype5);
454 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
455 StaticType::GetBasic<EbtUSampler3D>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700456 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500457 else if (ptype1->getBasicType() == EbtGSamplerCube)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700458 {
Martin Radevda6254b2016-12-14 17:00:36 +0200459 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700460 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800461 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
462 StaticType::GetBasic<EbtSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
463 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
464 StaticType::GetBasic<EbtISamplerCube>(), ptype2, ptype3, ptype4, ptype5);
465 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
466 StaticType::GetBasic<EbtUSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700467 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500468 else if (ptype1->getBasicType() == EbtGSampler2DArray)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700469 {
Martin Radevda6254b2016-12-14 17:00:36 +0200470 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700471 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800472 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
473 StaticType::GetBasic<EbtSampler2DArray>(), ptype2, ptype3, ptype4,
474 ptype5);
475 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
476 StaticType::GetBasic<EbtISampler2DArray>(), ptype2, ptype3, ptype4,
477 ptype5);
478 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
479 StaticType::GetBasic<EbtUSampler2DArray>(), ptype2, ptype3, ptype4,
480 ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700481 }
JiangYizhou40219322016-12-09 09:50:51 +0800482 else if (ptype1->getBasicType() == EbtGSampler2DMS)
483 {
484 insertUnmangledBuiltInName(name, level);
485 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800486 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
487 StaticType::GetBasic<EbtSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
488 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
489 StaticType::GetBasic<EbtISampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
490 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
491 StaticType::GetBasic<EbtUSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
JiangYizhou40219322016-12-09 09:50:51 +0800492 }
Martin Radev2cc85b32016-08-05 16:22:53 +0300493 else if (IsGImage(ptype1->getBasicType()))
494 {
Martin Radevda6254b2016-12-14 17:00:36 +0200495 insertUnmangledBuiltInName(name, level);
Martin Radev2cc85b32016-08-05 16:22:53 +0300496
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800497 const TType *floatType = StaticType::GetBasic<EbtFloat, 4>();
498 const TType *intType = StaticType::GetBasic<EbtInt, 4>();
499 const TType *unsignedType = StaticType::GetBasic<EbtUInt, 4>();
Martin Radev2cc85b32016-08-05 16:22:53 +0300500
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800501 const TType *floatImage = StaticType::GetForFloatImage(ptype1->getBasicType());
502 const TType *intImage = StaticType::GetForIntImage(ptype1->getBasicType());
503 const TType *unsignedImage = StaticType::GetForUintImage(ptype1->getBasicType());
Martin Radev2cc85b32016-08-05 16:22:53 +0300504
505 // GLSL ES 3.10, Revision 4, 8.12 Image Functions
506 if (rvalue->getBasicType() == EbtGVec4)
507 {
508 // imageLoad
509 insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
510 insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
511 insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
512 }
513 else if (rvalue->getBasicType() == EbtVoid)
514 {
515 // imageStore
516 insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
517 insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
518 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
519 }
520 else
521 {
522 // imageSize
523 insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
524 insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
525 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
526 }
527 }
Olli Etuaho9250cb22017-01-21 10:51:27 +0000528 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3) ||
529 IsGenType(ptype4))
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500530 {
Olli Etuaho9250cb22017-01-21 10:51:27 +0000531 ASSERT(!ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200532 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500533 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000534 SpecificType(ptype2, 1), SpecificType(ptype3, 1), SpecificType(ptype4, 1));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500535 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000536 SpecificType(ptype2, 2), SpecificType(ptype3, 2), SpecificType(ptype4, 2));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500537 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000538 SpecificType(ptype2, 3), SpecificType(ptype3, 3), SpecificType(ptype4, 3));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500539 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000540 SpecificType(ptype2, 4), SpecificType(ptype3, 4), SpecificType(ptype4, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500541 }
542 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
543 {
544 ASSERT(!ptype4 && !ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200545 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500546 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2),
547 VectorType(ptype2, 2), VectorType(ptype3, 2));
548 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3),
549 VectorType(ptype2, 3), VectorType(ptype3, 3));
550 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4),
551 VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500552 }
553 else
554 {
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100555 TFunction *function =
556 new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, op, ext);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700557
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700558 function->addParameter(TConstParameter(ptype1));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700559
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500560 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700561 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700562 function->addParameter(TConstParameter(ptype2));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700563 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700564
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500565 if (ptype3)
566 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700567 function->addParameter(TConstParameter(ptype3));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500568 }
569
570 if (ptype4)
571 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700572 function->addParameter(TConstParameter(ptype4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500573 }
574
575 if (ptype5)
576 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700577 function->addParameter(TConstParameter(ptype5));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500578 }
579
Martin Radevda6254b2016-12-14 17:00:36 +0200580 ASSERT(hasUnmangledBuiltInAtLevel(name, level));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500581 insert(level, function);
582 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700583}
584
Olli Etuaho492cfab2017-01-20 21:18:29 +0000585void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
586 TOperator op,
587 const TType *rvalue,
588 const TType *ptype1,
589 const TType *ptype2,
590 const TType *ptype3,
591 const TType *ptype4,
592 const TType *ptype5)
593{
594 const char *name = GetOperatorString(op);
595 ASSERT(strlen(name) > 0);
596 insertUnmangledBuiltInName(name, level);
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300597 insertBuiltIn(level, op, TExtension::UNDEFINED, rvalue, name, ptype1, ptype2, ptype3, ptype4,
598 ptype5);
Olli Etuaho492cfab2017-01-20 21:18:29 +0000599}
600
601void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
602 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300603 TExtension ext,
Olli Etuaho492cfab2017-01-20 21:18:29 +0000604 const TType *rvalue,
605 const TType *ptype1,
606 const TType *ptype2,
607 const TType *ptype3,
608 const TType *ptype4,
609 const TType *ptype5)
610{
611 const char *name = GetOperatorString(op);
612 insertUnmangledBuiltInName(name, level);
613 insertBuiltIn(level, op, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
614}
615
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300616void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
617 TOperator op,
618 const TType *rvalue,
619 const char *name)
620{
621 insertUnmangledBuiltInName(name, level);
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100622 insert(level, new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, op));
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300623}
624
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800625void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300626 TExtension ext,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800627 TOperator op,
628 const TType *rvalue,
629 const char *name)
630{
631 insertUnmangledBuiltInName(name, level);
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100632 insert(level, new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, op, ext));
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800633}
634
Zhenyao Moe740add2014-07-18 17:01:01 -0700635TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700636{
637 if (!SupportsPrecision(type))
638 return EbpUndefined;
639
640 // unsigned integers use the same precision as signed
641 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
642
643 int level = static_cast<int>(precisionStack.size()) - 1;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500644 assert(level >= 0); // Just to be safe. Should not happen.
Olli Etuaho183d7e22015-11-20 15:59:09 +0200645 // If we dont find anything we return this. Some types don't have predefined default precision.
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700646 TPrecision prec = EbpUndefined;
647 while (level >= 0)
648 {
649 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
650 if (it != precisionStack[level]->end())
651 {
652 prec = (*it).second;
653 break;
654 }
655 level--;
656 }
657 return prec;
658}
Jamie Madill45bcc782016-11-07 13:58:48 -0500659
Martin Radevda6254b2016-12-14 17:00:36 +0200660void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
661{
662 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
Olli Etuaho5d69db12017-11-24 16:51:15 +0200663 ASSERT(mUserDefinedUniqueIdsStart == -1);
Martin Radevda6254b2016-12-14 17:00:36 +0200664 table[level]->insertUnmangledBuiltInName(std::string(name));
665}
666
667bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level)
668{
669 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
670 return table[level]->hasUnmangledBuiltIn(std::string(name));
671}
672
673bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion)
674{
675 ASSERT(static_cast<ESymbolLevel>(table.size()) > LAST_BUILTIN_LEVEL);
676
677 for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
678 {
679 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
680 {
681 --level;
682 }
683 if (level == ESSL3_BUILTINS && shaderVersion < 300)
684 {
685 --level;
686 }
687 if (level == ESSL1_BUILTINS && shaderVersion != 100)
688 {
689 --level;
690 }
691
692 if (table[level]->hasUnmangledBuiltIn(name))
693 {
694 return true;
695 }
696 }
697 return false;
698}
699
Olli Etuaho5d69db12017-11-24 16:51:15 +0200700void TSymbolTable::markBuiltInInitializationFinished()
701{
702 mUserDefinedUniqueIdsStart = mUniqueIdCounter;
703}
704
705void TSymbolTable::clearCompilationResults()
706{
707 mUniqueIdCounter = mUserDefinedUniqueIdsStart;
708
709 // User-defined scopes should have already been cleared when the compilation finished.
710 ASSERT(table.size() == LAST_BUILTIN_LEVEL + 1u);
711}
712
713int TSymbolTable::nextUniqueIdValue()
714{
715 ASSERT(mUniqueIdCounter < std::numeric_limits<int>::max());
716 return ++mUniqueIdCounter;
717}
718
Jamie Madill45bcc782016-11-07 13:58:48 -0500719} // namespace sh