blob: 5fa8741966d5ade9948ae468fe8bffadc1a4477a [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 Etuaho476197f2016-10-11 13:59:08 +010042}
43
Olli Etuahod5f1afb2017-12-04 15:42:59 +020044TVariable::TVariable(TSymbolTable *symbolTable,
45 const TString *name,
46 const TType &t,
Olli Etuaho9d4d7f02017-12-07 17:11:41 +010047 SymbolType symbolType,
Olli Etuahod5f1afb2017-12-04 15:42:59 +020048 TExtension extension)
Olli Etuaho9d4d7f02017-12-07 17:11:41 +010049 : TSymbol(symbolTable, name, symbolType, extension), type(t), unionArray(nullptr)
Olli Etuaho035419f2017-11-28 14:27:15 +020050{
51}
52
Olli Etuaho9d4d7f02017-12-07 17:11:41 +010053TStructure::TStructure(TSymbolTable *symbolTable,
54 const TString *name,
55 const TFieldList *fields,
56 SymbolType symbolType)
57 : TSymbol(symbolTable, name, symbolType), TFieldListCollection(fields)
Olli Etuaho035419f2017-11-28 14:27:15 +020058{
59}
60
61void TStructure::createSamplerSymbols(const TString &namePrefix,
62 const TString &apiNamePrefix,
63 TVector<TIntermSymbol *> *outputSymbols,
64 TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames,
65 TSymbolTable *symbolTable) const
66{
67 ASSERT(containsSamplers());
68 for (const auto *field : *mFields)
69 {
70 const TType *fieldType = field->type();
71 if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
72 {
73 TString fieldName = namePrefix + "_" + field->name();
74 TString fieldApiName = apiNamePrefix + "." + field->name();
75 fieldType->createSamplerSymbols(fieldName, fieldApiName, outputSymbols,
76 outputSymbolsToAPINames, symbolTable);
77 }
78 }
79}
80
81void TStructure::setName(const TString &name)
82{
83 TString *mutableName = const_cast<TString *>(mName);
84 *mutableName = name;
85}
86
Olli Etuaho378c3a52017-12-04 11:32:13 +020087TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable,
88 const TString *name,
89 const TFieldList *fields,
Olli Etuahod5f1afb2017-12-04 15:42:59 +020090 const TLayoutQualifier &layoutQualifier,
Olli Etuaho9d4d7f02017-12-07 17:11:41 +010091 SymbolType symbolType,
Olli Etuahod5f1afb2017-12-04 15:42:59 +020092 TExtension extension)
Olli Etuaho9d4d7f02017-12-07 17:11:41 +010093 : TSymbol(symbolTable, name, symbolType, extension),
Olli Etuaho378c3a52017-12-04 11:32:13 +020094 TFieldListCollection(fields),
95 mBlockStorage(layoutQualifier.blockStorage),
96 mBinding(layoutQualifier.binding)
97{
98}
99
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000100//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000101// Functions have buried pointers to delete.
102//
103TFunction::~TFunction()
104{
Olli Etuaho476197f2016-10-11 13:59:08 +0100105 clearParameters();
106}
107
108void TFunction::clearParameters()
109{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000110 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
111 delete (*i).type;
Olli Etuaho476197f2016-10-11 13:59:08 +0100112 parameters.clear();
113 mangledName = nullptr;
114}
115
116void TFunction::swapParameters(const TFunction &parametersSource)
117{
118 clearParameters();
119 for (auto parameter : parametersSource.parameters)
120 {
121 addParameter(parameter);
122 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000123}
124
Dmitry Skiba58832202015-07-06 16:11:13 -0700125const TString *TFunction::buildMangledName() const
126{
Olli Etuaho54a29ff2017-11-28 17:35:20 +0200127 std::string newName = name().c_str();
Olli Etuahof2209f72017-04-01 12:45:55 +0300128 newName += kFunctionMangledNameSeparator;
Dmitry Skiba58832202015-07-06 16:11:13 -0700129
130 for (const auto &p : parameters)
131 {
Jamie Madill902e8c12017-11-18 09:34:16 -0500132 newName += p.type->getMangledName();
Dmitry Skiba58832202015-07-06 16:11:13 -0700133 }
Cooper Partin149e6e62015-08-07 16:18:18 -0700134 return NewPoolTString(newName.c_str());
Dmitry Skiba58832202015-07-06 16:11:13 -0700135}
136
Olli Etuahof2209f72017-04-01 12:45:55 +0300137const TString &TFunction::GetMangledNameFromCall(const TString &functionName,
138 const TIntermSequence &arguments)
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800139{
Olli Etuahof2209f72017-04-01 12:45:55 +0300140 std::string newName = functionName.c_str();
141 newName += kFunctionMangledNameSeparator;
142
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800143 for (TIntermNode *argument : arguments)
144 {
Jamie Madill902e8c12017-11-18 09:34:16 -0500145 newName += argument->getAsTyped()->getType().getMangledName();
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800146 }
147 return *NewPoolTString(newName.c_str());
148}
149
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000150//
151// Symbol table levels are a map of pointers to symbols that have to be deleted.
152//
153TSymbolTableLevel::~TSymbolTableLevel()
154{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000155 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
156 delete (*it).second;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000157}
158
Nicolas Capensadfffe42014-06-17 02:13:36 -0400159bool TSymbolTableLevel::insert(TSymbol *symbol)
Jamie Madillbfa91f42014-06-05 15:45:18 -0400160{
Jamie Madillbfa91f42014-06-05 15:45:18 -0400161 // returning true means symbol was added to the table
Nicolas Capensadfffe42014-06-17 02:13:36 -0400162 tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
Jamie Madillbfa91f42014-06-05 15:45:18 -0400163
164 return result.second;
165}
166
Olli Etuahob2983c92015-03-18 14:02:46 +0200167bool TSymbolTableLevel::insertUnmangled(TFunction *function)
168{
Olli Etuahob2983c92015-03-18 14:02:46 +0200169 // returning true means symbol was added to the table
Olli Etuaho54a29ff2017-11-28 17:35:20 +0200170 tInsertResult result = level.insert(tLevelPair(function->name(), function));
Olli Etuahob2983c92015-03-18 14:02:46 +0200171
172 return result.second;
173}
174
Jamie Madillbfa91f42014-06-05 15:45:18 -0400175TSymbol *TSymbolTableLevel::find(const TString &name) const
176{
177 tLevel::const_iterator it = level.find(name);
178 if (it == level.end())
179 return 0;
180 else
181 return (*it).second;
182}
183
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500184TSymbol *TSymbolTable::find(const TString &name,
185 int shaderVersion,
186 bool *builtIn,
187 bool *sameScope) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000188{
189 int level = currentLevel();
190 TSymbol *symbol;
191
192 do
193 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300194 if (level == GLSL_BUILTINS)
195 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +0300196 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
197 level--;
198 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700199 level--;
200 if (level == ESSL1_BUILTINS && shaderVersion != 100)
201 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000202
203 symbol = table[level]->find(name);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500204 } while (symbol == 0 && --level >= 0);
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000205
206 if (builtIn)
207 *builtIn = (level <= LAST_BUILTIN_LEVEL);
208 if (sameScope)
209 *sameScope = (level == currentLevel());
210
211 return symbol;
212}
213
Zhenyao Mod7490962016-11-09 15:49:51 -0800214TSymbol *TSymbolTable::findGlobal(const TString &name) const
215{
216 ASSERT(table.size() > GLOBAL_LEVEL);
217 return table[GLOBAL_LEVEL]->find(name);
218}
219
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500220TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000221{
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300222 return findBuiltIn(name, shaderVersion, false);
223}
224
225TSymbol *TSymbolTable::findBuiltIn(const TString &name,
226 int shaderVersion,
227 bool includeGLSLBuiltins) const
228{
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000229 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
230 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300231 if (level == GLSL_BUILTINS && !includeGLSLBuiltins)
232 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +0300233 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
234 level--;
235 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700236 level--;
237 if (level == ESSL1_BUILTINS && shaderVersion != 100)
238 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000239
240 TSymbol *symbol = table[level]->find(name);
241
242 if (symbol)
243 return symbol;
244 }
245
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300246 return nullptr;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000247}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400248
249TSymbolTable::~TSymbolTable()
250{
251 while (table.size() > 0)
252 pop();
253}
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700254
Kai Ninomiya030017a2017-12-06 14:06:53 -0800255constexpr bool IsGenType(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 == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType ||
261 basicType == EbtGenBType;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500262 }
263
264 return false;
265}
266
Kai Ninomiya030017a2017-12-06 14:06:53 -0800267constexpr bool IsVecType(const TType *type)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500268{
269 if (type)
270 {
271 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500272 return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec ||
273 basicType == EbtBVec;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500274 }
275
276 return false;
277}
278
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800279constexpr const TType *SpecificType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500280{
281 ASSERT(size >= 1 && size <= 4);
282
283 if (!type)
284 {
285 return nullptr;
286 }
287
288 ASSERT(!IsVecType(type));
289
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500290 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500291 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500292 case EbtGenType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800293 return StaticType::GetForVec<EbtFloat>(type->getQualifier(),
294 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500295 case EbtGenIType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800296 return StaticType::GetForVec<EbtInt>(type->getQualifier(),
297 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500298 case EbtGenUType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800299 return StaticType::GetForVec<EbtUInt>(type->getQualifier(),
300 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500301 case EbtGenBType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800302 return StaticType::GetForVec<EbtBool>(type->getQualifier(),
303 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500304 default:
305 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500306 }
307}
308
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800309constexpr const TType *VectorType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500310{
311 ASSERT(size >= 2 && size <= 4);
312
313 if (!type)
314 {
315 return nullptr;
316 }
317
318 ASSERT(!IsGenType(type));
319
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500320 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500321 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500322 case EbtVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800323 return StaticType::GetForVecMat<EbtFloat>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500324 case EbtIVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800325 return StaticType::GetForVecMat<EbtInt>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500326 case EbtUVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800327 return StaticType::GetForVecMat<EbtUInt>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500328 case EbtBVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800329 return StaticType::GetForVecMat<EbtBool>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500330 default:
331 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500332 }
333}
334
Olli Etuaho0f684632017-07-13 12:42:15 +0300335TVariable *TSymbolTable::declareVariable(const TString *name, const TType &type)
336{
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100337 return insertVariable(currentLevel(), name, type, SymbolType::UserDefined);
Olli Etuaho0f684632017-07-13 12:42:15 +0300338}
339
Olli Etuaho035419f2017-11-28 14:27:15 +0200340bool TSymbolTable::declareStructType(TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300341{
342 return insertStructType(currentLevel(), str);
343}
344
Olli Etuaho378c3a52017-12-04 11:32:13 +0200345bool TSymbolTable::declareInterfaceBlock(TInterfaceBlock *interfaceBlock)
Olli Etuaho0f684632017-07-13 12:42:15 +0300346{
Olli Etuaho378c3a52017-12-04 11:32:13 +0200347 return insert(currentLevel(), interfaceBlock);
Jiawei Shaod8105a02017-08-08 09:54:36 +0800348}
349
Olli Etuaho0f684632017-07-13 12:42:15 +0300350TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType &type)
351{
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100352 ASSERT(level <= LAST_BUILTIN_LEVEL);
353 return insertVariable(level, NewPoolTString(name), type, SymbolType::BuiltIn);
Olli Etuaho0f684632017-07-13 12:42:15 +0300354}
355
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100356TVariable *TSymbolTable::insertVariable(ESymbolLevel level,
357 const TString *name,
358 const TType &type,
359 SymbolType symbolType)
Olli Etuaho0f684632017-07-13 12:42:15 +0300360{
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100361 TVariable *var = new TVariable(this, name, type, symbolType);
Olli Etuaho0f684632017-07-13 12:42:15 +0300362 if (insert(level, var))
363 {
364 // Do lazy initialization for struct types, so we allocate to the current scope.
365 if (var->getType().getBasicType() == EbtStruct)
366 {
367 var->getType().realize();
368 }
369 return var;
370 }
371 return nullptr;
372}
373
374TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300375 TExtension ext,
Olli Etuaho0f684632017-07-13 12:42:15 +0300376 const char *name,
377 const TType &type)
378{
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100379 TVariable *var = new TVariable(this, NewPoolTString(name), type, SymbolType::BuiltIn, ext);
Olli Etuaho5d69db12017-11-24 16:51:15 +0200380 if (insert(level, var))
Olli Etuaho0f684632017-07-13 12:42:15 +0300381 {
382 if (var->getType().getBasicType() == EbtStruct)
383 {
384 var->getType().realize();
385 }
386 return var;
387 }
388 return nullptr;
389}
390
Olli Etuaho035419f2017-11-28 14:27:15 +0200391bool TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300392{
Olli Etuaho035419f2017-11-28 14:27:15 +0200393 ASSERT(str);
Olli Etuaho378c3a52017-12-04 11:32:13 +0200394 return insert(level, str);
395}
396
397bool TSymbolTable::insertInterfaceBlock(ESymbolLevel level, TInterfaceBlock *interfaceBlock)
398{
399 ASSERT(interfaceBlock);
400 return insert(level, interfaceBlock);
Olli Etuaho0f684632017-07-13 12:42:15 +0300401}
402
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500403void TSymbolTable::insertBuiltIn(ESymbolLevel level,
404 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300405 TExtension ext,
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500406 const TType *rvalue,
407 const char *name,
408 const TType *ptype1,
409 const TType *ptype2,
410 const TType *ptype3,
411 const TType *ptype4,
412 const TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700413{
414 if (ptype1->getBasicType() == EbtGSampler2D)
415 {
Martin Radevda6254b2016-12-14 17:00:36 +0200416 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700417 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800418 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
419 StaticType::GetBasic<EbtSampler2D>(), ptype2, ptype3, ptype4, ptype5);
420 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
421 StaticType::GetBasic<EbtISampler2D>(), ptype2, ptype3, ptype4, ptype5);
422 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
423 StaticType::GetBasic<EbtUSampler2D>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700424 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500425 else if (ptype1->getBasicType() == EbtGSampler3D)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700426 {
Martin Radevda6254b2016-12-14 17:00:36 +0200427 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700428 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800429 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
430 StaticType::GetBasic<EbtSampler3D>(), ptype2, ptype3, ptype4, ptype5);
431 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
432 StaticType::GetBasic<EbtISampler3D>(), ptype2, ptype3, ptype4, ptype5);
433 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
434 StaticType::GetBasic<EbtUSampler3D>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700435 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500436 else if (ptype1->getBasicType() == EbtGSamplerCube)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700437 {
Martin Radevda6254b2016-12-14 17:00:36 +0200438 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700439 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800440 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
441 StaticType::GetBasic<EbtSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
442 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
443 StaticType::GetBasic<EbtISamplerCube>(), ptype2, ptype3, ptype4, ptype5);
444 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
445 StaticType::GetBasic<EbtUSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700446 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500447 else if (ptype1->getBasicType() == EbtGSampler2DArray)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700448 {
Martin Radevda6254b2016-12-14 17:00:36 +0200449 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700450 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<EbtSampler2DArray>(), ptype2, ptype3, ptype4,
453 ptype5);
454 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
455 StaticType::GetBasic<EbtISampler2DArray>(), ptype2, ptype3, ptype4,
456 ptype5);
457 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
458 StaticType::GetBasic<EbtUSampler2DArray>(), ptype2, ptype3, ptype4,
459 ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700460 }
JiangYizhou40219322016-12-09 09:50:51 +0800461 else if (ptype1->getBasicType() == EbtGSampler2DMS)
462 {
463 insertUnmangledBuiltInName(name, level);
464 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800465 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
466 StaticType::GetBasic<EbtSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
467 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
468 StaticType::GetBasic<EbtISampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
469 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
470 StaticType::GetBasic<EbtUSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
JiangYizhou40219322016-12-09 09:50:51 +0800471 }
Martin Radev2cc85b32016-08-05 16:22:53 +0300472 else if (IsGImage(ptype1->getBasicType()))
473 {
Martin Radevda6254b2016-12-14 17:00:36 +0200474 insertUnmangledBuiltInName(name, level);
Martin Radev2cc85b32016-08-05 16:22:53 +0300475
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800476 const TType *floatType = StaticType::GetBasic<EbtFloat, 4>();
477 const TType *intType = StaticType::GetBasic<EbtInt, 4>();
478 const TType *unsignedType = StaticType::GetBasic<EbtUInt, 4>();
Martin Radev2cc85b32016-08-05 16:22:53 +0300479
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800480 const TType *floatImage = StaticType::GetForFloatImage(ptype1->getBasicType());
481 const TType *intImage = StaticType::GetForIntImage(ptype1->getBasicType());
482 const TType *unsignedImage = StaticType::GetForUintImage(ptype1->getBasicType());
Martin Radev2cc85b32016-08-05 16:22:53 +0300483
484 // GLSL ES 3.10, Revision 4, 8.12 Image Functions
485 if (rvalue->getBasicType() == EbtGVec4)
486 {
487 // imageLoad
488 insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
489 insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
490 insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
491 }
492 else if (rvalue->getBasicType() == EbtVoid)
493 {
494 // imageStore
495 insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
496 insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
497 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
498 }
499 else
500 {
501 // imageSize
502 insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
503 insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
504 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
505 }
506 }
Olli Etuaho9250cb22017-01-21 10:51:27 +0000507 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3) ||
508 IsGenType(ptype4))
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500509 {
Olli Etuaho9250cb22017-01-21 10:51:27 +0000510 ASSERT(!ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200511 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500512 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000513 SpecificType(ptype2, 1), SpecificType(ptype3, 1), SpecificType(ptype4, 1));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500514 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000515 SpecificType(ptype2, 2), SpecificType(ptype3, 2), SpecificType(ptype4, 2));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500516 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000517 SpecificType(ptype2, 3), SpecificType(ptype3, 3), SpecificType(ptype4, 3));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500518 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000519 SpecificType(ptype2, 4), SpecificType(ptype3, 4), SpecificType(ptype4, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500520 }
521 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
522 {
523 ASSERT(!ptype4 && !ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200524 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500525 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2),
526 VectorType(ptype2, 2), VectorType(ptype3, 2));
527 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3),
528 VectorType(ptype2, 3), VectorType(ptype3, 3));
529 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4),
530 VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500531 }
532 else
533 {
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100534 TFunction *function =
535 new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, op, ext);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700536
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700537 function->addParameter(TConstParameter(ptype1));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700538
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500539 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700540 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700541 function->addParameter(TConstParameter(ptype2));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700542 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700543
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500544 if (ptype3)
545 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700546 function->addParameter(TConstParameter(ptype3));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500547 }
548
549 if (ptype4)
550 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700551 function->addParameter(TConstParameter(ptype4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500552 }
553
554 if (ptype5)
555 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700556 function->addParameter(TConstParameter(ptype5));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500557 }
558
Martin Radevda6254b2016-12-14 17:00:36 +0200559 ASSERT(hasUnmangledBuiltInAtLevel(name, level));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500560 insert(level, function);
561 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700562}
563
Olli Etuaho492cfab2017-01-20 21:18:29 +0000564void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
565 TOperator op,
566 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 ASSERT(strlen(name) > 0);
575 insertUnmangledBuiltInName(name, level);
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300576 insertBuiltIn(level, op, TExtension::UNDEFINED, rvalue, name, ptype1, ptype2, ptype3, ptype4,
577 ptype5);
Olli Etuaho492cfab2017-01-20 21:18:29 +0000578}
579
580void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
581 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300582 TExtension ext,
Olli Etuaho492cfab2017-01-20 21:18:29 +0000583 const TType *rvalue,
584 const TType *ptype1,
585 const TType *ptype2,
586 const TType *ptype3,
587 const TType *ptype4,
588 const TType *ptype5)
589{
590 const char *name = GetOperatorString(op);
591 insertUnmangledBuiltInName(name, level);
592 insertBuiltIn(level, op, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
593}
594
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300595void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
596 TOperator op,
597 const TType *rvalue,
598 const char *name)
599{
600 insertUnmangledBuiltInName(name, level);
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100601 insert(level, new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, op));
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300602}
603
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800604void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300605 TExtension ext,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800606 TOperator op,
607 const TType *rvalue,
608 const char *name)
609{
610 insertUnmangledBuiltInName(name, level);
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100611 insert(level, new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, op, ext));
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800612}
613
Zhenyao Moe740add2014-07-18 17:01:01 -0700614TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700615{
616 if (!SupportsPrecision(type))
617 return EbpUndefined;
618
619 // unsigned integers use the same precision as signed
620 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
621
622 int level = static_cast<int>(precisionStack.size()) - 1;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500623 assert(level >= 0); // Just to be safe. Should not happen.
Olli Etuaho183d7e22015-11-20 15:59:09 +0200624 // If we dont find anything we return this. Some types don't have predefined default precision.
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700625 TPrecision prec = EbpUndefined;
626 while (level >= 0)
627 {
628 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
629 if (it != precisionStack[level]->end())
630 {
631 prec = (*it).second;
632 break;
633 }
634 level--;
635 }
636 return prec;
637}
Jamie Madill45bcc782016-11-07 13:58:48 -0500638
Martin Radevda6254b2016-12-14 17:00:36 +0200639void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
640{
641 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
Olli Etuaho5d69db12017-11-24 16:51:15 +0200642 ASSERT(mUserDefinedUniqueIdsStart == -1);
Martin Radevda6254b2016-12-14 17:00:36 +0200643 table[level]->insertUnmangledBuiltInName(std::string(name));
644}
645
646bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level)
647{
648 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
649 return table[level]->hasUnmangledBuiltIn(std::string(name));
650}
651
652bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion)
653{
654 ASSERT(static_cast<ESymbolLevel>(table.size()) > LAST_BUILTIN_LEVEL);
655
656 for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
657 {
658 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
659 {
660 --level;
661 }
662 if (level == ESSL3_BUILTINS && shaderVersion < 300)
663 {
664 --level;
665 }
666 if (level == ESSL1_BUILTINS && shaderVersion != 100)
667 {
668 --level;
669 }
670
671 if (table[level]->hasUnmangledBuiltIn(name))
672 {
673 return true;
674 }
675 }
676 return false;
677}
678
Olli Etuaho5d69db12017-11-24 16:51:15 +0200679void TSymbolTable::markBuiltInInitializationFinished()
680{
681 mUserDefinedUniqueIdsStart = mUniqueIdCounter;
682}
683
684void TSymbolTable::clearCompilationResults()
685{
686 mUniqueIdCounter = mUserDefinedUniqueIdsStart;
687
688 // User-defined scopes should have already been cleared when the compilation finished.
689 ASSERT(table.size() == LAST_BUILTIN_LEVEL + 1u);
690}
691
692int TSymbolTable::nextUniqueIdValue()
693{
694 ASSERT(mUniqueIdCounter < std::numeric_limits<int>::max());
695 return ++mUniqueIdCounter;
696}
697
Jamie Madill45bcc782016-11-07 13:58:48 -0500698} // namespace sh