blob: adf1e4e0cb9ff78a7d639a956b2d6ad73401267c [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +00002// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003// Use of this source code is governed by a BSD-style license that can be
4// found in the LICENSE file.
5//
Olli Etuaho0f684632017-07-13 12:42:15 +03006// Symbol table for parsing. The design principles and most of the functionality are documented in
7// the header file.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00008//
9
apatrick@chromium.orge057c5d2012-01-26 19:18:24 +000010#if defined(_MSC_VER)
Jamie Madilld7b1ab52016-12-12 14:42:19 -050011#pragma warning(disable : 4718)
apatrick@chromium.orge057c5d2012-01-26 19:18:24 +000012#endif
13
Geoff Lang17732822013-08-29 13:46:49 -040014#include "compiler/translator/SymbolTable.h"
Olli Etuaho01d0ad02017-01-22 14:51:23 -080015
Olli Etuaho01d0ad02017-01-22 14:51:23 -080016#include "compiler/translator/IntermNode.h"
Kai Ninomiya614dd0f2017-11-22 14:04:48 -080017#include "compiler/translator/StaticType.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000018
apatrick@chromium.org8187fa82010-06-15 22:09:28 +000019#include <stdio.h>
kbr@chromium.org476541f2011-10-27 21:14:51 +000020#include <algorithm>
21
Jamie Madill45bcc782016-11-07 13:58:48 -050022namespace sh
23{
24
Olli Etuahof2209f72017-04-01 12:45:55 +030025namespace
26{
27
28static const char kFunctionMangledNameSeparator = '(';
29
30} // anonymous namespace
31
Olli Etuaho54a29ff2017-11-28 17:35:20 +020032TSymbol::TSymbol(TSymbolTable *symbolTable, const TString *name)
Olli Etuaho035419f2017-11-28 14:27:15 +020033 : mName(name), mUniqueId(symbolTable->nextUniqueId()), mExtension(TExtension::UNDEFINED)
Olli Etuaho476197f2016-10-11 13:59:08 +010034{
35}
36
Olli Etuaho035419f2017-11-28 14:27:15 +020037TVariable::TVariable(TSymbolTable *symbolTable, const TString *name, const TType &t)
38 : TSymbol(symbolTable, name), type(t), unionArray(nullptr)
39{
40}
41
42TStructure::TStructure(TSymbolTable *symbolTable, const TString *name, const TFieldList *fields)
43 : TSymbol(symbolTable, name), TFieldListCollection(fields)
44{
45}
46
47void TStructure::createSamplerSymbols(const TString &namePrefix,
48 const TString &apiNamePrefix,
49 TVector<TIntermSymbol *> *outputSymbols,
50 TMap<TIntermSymbol *, TString> *outputSymbolsToAPINames,
51 TSymbolTable *symbolTable) const
52{
53 ASSERT(containsSamplers());
54 for (const auto *field : *mFields)
55 {
56 const TType *fieldType = field->type();
57 if (IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
58 {
59 TString fieldName = namePrefix + "_" + field->name();
60 TString fieldApiName = apiNamePrefix + "." + field->name();
61 fieldType->createSamplerSymbols(fieldName, fieldApiName, outputSymbols,
62 outputSymbolsToAPINames, symbolTable);
63 }
64 }
65}
66
67void TStructure::setName(const TString &name)
68{
69 TString *mutableName = const_cast<TString *>(mName);
70 *mutableName = name;
71}
72
Olli Etuaho378c3a52017-12-04 11:32:13 +020073TInterfaceBlock::TInterfaceBlock(TSymbolTable *symbolTable,
74 const TString *name,
75 const TFieldList *fields,
76 const TLayoutQualifier &layoutQualifier)
77 : TSymbol(symbolTable, name),
78 TFieldListCollection(fields),
79 mBlockStorage(layoutQualifier.blockStorage),
80 mBinding(layoutQualifier.binding)
81{
82}
83
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000084//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000085// Functions have buried pointers to delete.
86//
87TFunction::~TFunction()
88{
Olli Etuaho476197f2016-10-11 13:59:08 +010089 clearParameters();
90}
91
92void TFunction::clearParameters()
93{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000094 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
95 delete (*i).type;
Olli Etuaho476197f2016-10-11 13:59:08 +010096 parameters.clear();
97 mangledName = nullptr;
98}
99
100void TFunction::swapParameters(const TFunction &parametersSource)
101{
102 clearParameters();
103 for (auto parameter : parametersSource.parameters)
104 {
105 addParameter(parameter);
106 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000107}
108
Dmitry Skiba58832202015-07-06 16:11:13 -0700109const TString *TFunction::buildMangledName() const
110{
Olli Etuaho54a29ff2017-11-28 17:35:20 +0200111 std::string newName = name().c_str();
Olli Etuahof2209f72017-04-01 12:45:55 +0300112 newName += kFunctionMangledNameSeparator;
Dmitry Skiba58832202015-07-06 16:11:13 -0700113
114 for (const auto &p : parameters)
115 {
Jamie Madill902e8c12017-11-18 09:34:16 -0500116 newName += p.type->getMangledName();
Dmitry Skiba58832202015-07-06 16:11:13 -0700117 }
Cooper Partin149e6e62015-08-07 16:18:18 -0700118 return NewPoolTString(newName.c_str());
Dmitry Skiba58832202015-07-06 16:11:13 -0700119}
120
Olli Etuahof2209f72017-04-01 12:45:55 +0300121const TString &TFunction::GetMangledNameFromCall(const TString &functionName,
122 const TIntermSequence &arguments)
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800123{
Olli Etuahof2209f72017-04-01 12:45:55 +0300124 std::string newName = functionName.c_str();
125 newName += kFunctionMangledNameSeparator;
126
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800127 for (TIntermNode *argument : arguments)
128 {
Jamie Madill902e8c12017-11-18 09:34:16 -0500129 newName += argument->getAsTyped()->getType().getMangledName();
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800130 }
131 return *NewPoolTString(newName.c_str());
132}
133
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000134//
135// Symbol table levels are a map of pointers to symbols that have to be deleted.
136//
137TSymbolTableLevel::~TSymbolTableLevel()
138{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000139 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
140 delete (*it).second;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000141}
142
Nicolas Capensadfffe42014-06-17 02:13:36 -0400143bool TSymbolTableLevel::insert(TSymbol *symbol)
Jamie Madillbfa91f42014-06-05 15:45:18 -0400144{
Jamie Madillbfa91f42014-06-05 15:45:18 -0400145 // returning true means symbol was added to the table
Nicolas Capensadfffe42014-06-17 02:13:36 -0400146 tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
Jamie Madillbfa91f42014-06-05 15:45:18 -0400147
148 return result.second;
149}
150
Olli Etuahob2983c92015-03-18 14:02:46 +0200151bool TSymbolTableLevel::insertUnmangled(TFunction *function)
152{
Olli Etuahob2983c92015-03-18 14:02:46 +0200153 // returning true means symbol was added to the table
Olli Etuaho54a29ff2017-11-28 17:35:20 +0200154 tInsertResult result = level.insert(tLevelPair(function->name(), function));
Olli Etuahob2983c92015-03-18 14:02:46 +0200155
156 return result.second;
157}
158
Jamie Madillbfa91f42014-06-05 15:45:18 -0400159TSymbol *TSymbolTableLevel::find(const TString &name) const
160{
161 tLevel::const_iterator it = level.find(name);
162 if (it == level.end())
163 return 0;
164 else
165 return (*it).second;
166}
167
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500168TSymbol *TSymbolTable::find(const TString &name,
169 int shaderVersion,
170 bool *builtIn,
171 bool *sameScope) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000172{
173 int level = currentLevel();
174 TSymbol *symbol;
175
176 do
177 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300178 if (level == GLSL_BUILTINS)
179 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +0300180 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
181 level--;
182 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700183 level--;
184 if (level == ESSL1_BUILTINS && shaderVersion != 100)
185 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000186
187 symbol = table[level]->find(name);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500188 } while (symbol == 0 && --level >= 0);
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000189
190 if (builtIn)
191 *builtIn = (level <= LAST_BUILTIN_LEVEL);
192 if (sameScope)
193 *sameScope = (level == currentLevel());
194
195 return symbol;
196}
197
Zhenyao Mod7490962016-11-09 15:49:51 -0800198TSymbol *TSymbolTable::findGlobal(const TString &name) const
199{
200 ASSERT(table.size() > GLOBAL_LEVEL);
201 return table[GLOBAL_LEVEL]->find(name);
202}
203
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500204TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000205{
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300206 return findBuiltIn(name, shaderVersion, false);
207}
208
209TSymbol *TSymbolTable::findBuiltIn(const TString &name,
210 int shaderVersion,
211 bool includeGLSLBuiltins) const
212{
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000213 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
214 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300215 if (level == GLSL_BUILTINS && !includeGLSLBuiltins)
216 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +0300217 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
218 level--;
219 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700220 level--;
221 if (level == ESSL1_BUILTINS && shaderVersion != 100)
222 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000223
224 TSymbol *symbol = table[level]->find(name);
225
226 if (symbol)
227 return symbol;
228 }
229
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300230 return nullptr;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000231}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400232
233TSymbolTable::~TSymbolTable()
234{
235 while (table.size() > 0)
236 pop();
237}
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700238
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500239bool IsGenType(const TType *type)
240{
241 if (type)
242 {
243 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500244 return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType ||
245 basicType == EbtGenBType;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500246 }
247
248 return false;
249}
250
251bool IsVecType(const TType *type)
252{
253 if (type)
254 {
255 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500256 return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec ||
257 basicType == EbtBVec;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500258 }
259
260 return false;
261}
262
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800263constexpr const TType *SpecificType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500264{
265 ASSERT(size >= 1 && size <= 4);
266
267 if (!type)
268 {
269 return nullptr;
270 }
271
272 ASSERT(!IsVecType(type));
273
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500274 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500275 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500276 case EbtGenType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800277 return StaticType::GetForVec<EbtFloat>(type->getQualifier(),
278 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500279 case EbtGenIType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800280 return StaticType::GetForVec<EbtInt>(type->getQualifier(),
281 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500282 case EbtGenUType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800283 return StaticType::GetForVec<EbtUInt>(type->getQualifier(),
284 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500285 case EbtGenBType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800286 return StaticType::GetForVec<EbtBool>(type->getQualifier(),
287 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500288 default:
289 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500290 }
291}
292
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800293constexpr const TType *VectorType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500294{
295 ASSERT(size >= 2 && size <= 4);
296
297 if (!type)
298 {
299 return nullptr;
300 }
301
302 ASSERT(!IsGenType(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 EbtVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800307 return StaticType::GetForVecMat<EbtFloat>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500308 case EbtIVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800309 return StaticType::GetForVecMat<EbtInt>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500310 case EbtUVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800311 return StaticType::GetForVecMat<EbtUInt>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500312 case EbtBVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800313 return StaticType::GetForVecMat<EbtBool>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500314 default:
315 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500316 }
317}
318
Olli Etuaho0f684632017-07-13 12:42:15 +0300319TVariable *TSymbolTable::declareVariable(const TString *name, const TType &type)
320{
321 return insertVariable(currentLevel(), name, type);
322}
323
Olli Etuaho035419f2017-11-28 14:27:15 +0200324bool TSymbolTable::declareStructType(TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300325{
326 return insertStructType(currentLevel(), str);
327}
328
Olli Etuaho378c3a52017-12-04 11:32:13 +0200329bool TSymbolTable::declareInterfaceBlock(TInterfaceBlock *interfaceBlock)
Olli Etuaho0f684632017-07-13 12:42:15 +0300330{
Olli Etuaho378c3a52017-12-04 11:32:13 +0200331 return insert(currentLevel(), interfaceBlock);
Jiawei Shaod8105a02017-08-08 09:54:36 +0800332}
333
Olli Etuaho0f684632017-07-13 12:42:15 +0300334TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType &type)
335{
336 return insertVariable(level, NewPoolTString(name), type);
337}
338
339TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const TString *name, const TType &type)
340{
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300341 TVariable *var = new TVariable(this, name, type);
Olli Etuaho0f684632017-07-13 12:42:15 +0300342 if (insert(level, var))
343 {
344 // Do lazy initialization for struct types, so we allocate to the current scope.
345 if (var->getType().getBasicType() == EbtStruct)
346 {
347 var->getType().realize();
348 }
349 return var;
350 }
351 return nullptr;
352}
353
354TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300355 TExtension ext,
Olli Etuaho0f684632017-07-13 12:42:15 +0300356 const char *name,
357 const TType &type)
358{
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300359 TVariable *var = new TVariable(this, NewPoolTString(name), type);
Olli Etuaho5d69db12017-11-24 16:51:15 +0200360 var->relateToExtension(ext);
361 if (insert(level, var))
Olli Etuaho0f684632017-07-13 12:42:15 +0300362 {
363 if (var->getType().getBasicType() == EbtStruct)
364 {
365 var->getType().realize();
366 }
367 return var;
368 }
369 return nullptr;
370}
371
Olli Etuaho035419f2017-11-28 14:27:15 +0200372bool TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300373{
Olli Etuaho035419f2017-11-28 14:27:15 +0200374 ASSERT(str);
Olli Etuaho378c3a52017-12-04 11:32:13 +0200375 return insert(level, str);
376}
377
378bool TSymbolTable::insertInterfaceBlock(ESymbolLevel level, TInterfaceBlock *interfaceBlock)
379{
380 ASSERT(interfaceBlock);
381 return insert(level, interfaceBlock);
Olli Etuaho0f684632017-07-13 12:42:15 +0300382}
383
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500384void TSymbolTable::insertBuiltIn(ESymbolLevel level,
385 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300386 TExtension ext,
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500387 const TType *rvalue,
388 const char *name,
389 const TType *ptype1,
390 const TType *ptype2,
391 const TType *ptype3,
392 const TType *ptype4,
393 const TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700394{
395 if (ptype1->getBasicType() == EbtGSampler2D)
396 {
Martin Radevda6254b2016-12-14 17:00:36 +0200397 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700398 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800399 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
400 StaticType::GetBasic<EbtSampler2D>(), ptype2, ptype3, ptype4, ptype5);
401 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
402 StaticType::GetBasic<EbtISampler2D>(), ptype2, ptype3, ptype4, ptype5);
403 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
404 StaticType::GetBasic<EbtUSampler2D>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700405 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500406 else if (ptype1->getBasicType() == EbtGSampler3D)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700407 {
Martin Radevda6254b2016-12-14 17:00:36 +0200408 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700409 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800410 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
411 StaticType::GetBasic<EbtSampler3D>(), ptype2, ptype3, ptype4, ptype5);
412 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
413 StaticType::GetBasic<EbtISampler3D>(), ptype2, ptype3, ptype4, ptype5);
414 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
415 StaticType::GetBasic<EbtUSampler3D>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700416 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500417 else if (ptype1->getBasicType() == EbtGSamplerCube)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700418 {
Martin Radevda6254b2016-12-14 17:00:36 +0200419 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700420 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800421 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
422 StaticType::GetBasic<EbtSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
423 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
424 StaticType::GetBasic<EbtISamplerCube>(), ptype2, ptype3, ptype4, ptype5);
425 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
426 StaticType::GetBasic<EbtUSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700427 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500428 else if (ptype1->getBasicType() == EbtGSampler2DArray)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700429 {
Martin Radevda6254b2016-12-14 17:00:36 +0200430 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700431 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800432 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
433 StaticType::GetBasic<EbtSampler2DArray>(), ptype2, ptype3, ptype4,
434 ptype5);
435 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
436 StaticType::GetBasic<EbtISampler2DArray>(), ptype2, ptype3, ptype4,
437 ptype5);
438 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
439 StaticType::GetBasic<EbtUSampler2DArray>(), ptype2, ptype3, ptype4,
440 ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700441 }
JiangYizhou40219322016-12-09 09:50:51 +0800442 else if (ptype1->getBasicType() == EbtGSampler2DMS)
443 {
444 insertUnmangledBuiltInName(name, level);
445 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800446 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
447 StaticType::GetBasic<EbtSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
448 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
449 StaticType::GetBasic<EbtISampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
450 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
451 StaticType::GetBasic<EbtUSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
JiangYizhou40219322016-12-09 09:50:51 +0800452 }
Martin Radev2cc85b32016-08-05 16:22:53 +0300453 else if (IsGImage(ptype1->getBasicType()))
454 {
Martin Radevda6254b2016-12-14 17:00:36 +0200455 insertUnmangledBuiltInName(name, level);
Martin Radev2cc85b32016-08-05 16:22:53 +0300456
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800457 const TType *floatType = StaticType::GetBasic<EbtFloat, 4>();
458 const TType *intType = StaticType::GetBasic<EbtInt, 4>();
459 const TType *unsignedType = StaticType::GetBasic<EbtUInt, 4>();
Martin Radev2cc85b32016-08-05 16:22:53 +0300460
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800461 const TType *floatImage = StaticType::GetForFloatImage(ptype1->getBasicType());
462 const TType *intImage = StaticType::GetForIntImage(ptype1->getBasicType());
463 const TType *unsignedImage = StaticType::GetForUintImage(ptype1->getBasicType());
Martin Radev2cc85b32016-08-05 16:22:53 +0300464
465 // GLSL ES 3.10, Revision 4, 8.12 Image Functions
466 if (rvalue->getBasicType() == EbtGVec4)
467 {
468 // imageLoad
469 insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
470 insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
471 insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
472 }
473 else if (rvalue->getBasicType() == EbtVoid)
474 {
475 // imageStore
476 insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
477 insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
478 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
479 }
480 else
481 {
482 // imageSize
483 insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
484 insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
485 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
486 }
487 }
Olli Etuaho9250cb22017-01-21 10:51:27 +0000488 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3) ||
489 IsGenType(ptype4))
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500490 {
Olli Etuaho9250cb22017-01-21 10:51:27 +0000491 ASSERT(!ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200492 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500493 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000494 SpecificType(ptype2, 1), SpecificType(ptype3, 1), SpecificType(ptype4, 1));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500495 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000496 SpecificType(ptype2, 2), SpecificType(ptype3, 2), SpecificType(ptype4, 2));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500497 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000498 SpecificType(ptype2, 3), SpecificType(ptype3, 3), SpecificType(ptype4, 3));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500499 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000500 SpecificType(ptype2, 4), SpecificType(ptype3, 4), SpecificType(ptype4, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500501 }
502 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
503 {
504 ASSERT(!ptype4 && !ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200505 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500506 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2),
507 VectorType(ptype2, 2), VectorType(ptype3, 2));
508 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3),
509 VectorType(ptype2, 3), VectorType(ptype3, 3));
510 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4),
511 VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500512 }
513 else
514 {
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300515 TFunction *function = new TFunction(this, NewPoolTString(name), rvalue, op, ext);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700516
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700517 function->addParameter(TConstParameter(ptype1));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700518
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500519 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700520 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700521 function->addParameter(TConstParameter(ptype2));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700522 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700523
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500524 if (ptype3)
525 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700526 function->addParameter(TConstParameter(ptype3));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500527 }
528
529 if (ptype4)
530 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700531 function->addParameter(TConstParameter(ptype4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500532 }
533
534 if (ptype5)
535 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700536 function->addParameter(TConstParameter(ptype5));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500537 }
538
Martin Radevda6254b2016-12-14 17:00:36 +0200539 ASSERT(hasUnmangledBuiltInAtLevel(name, level));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500540 insert(level, function);
541 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700542}
543
Olli Etuaho492cfab2017-01-20 21:18:29 +0000544void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
545 TOperator op,
546 const TType *rvalue,
547 const TType *ptype1,
548 const TType *ptype2,
549 const TType *ptype3,
550 const TType *ptype4,
551 const TType *ptype5)
552{
553 const char *name = GetOperatorString(op);
554 ASSERT(strlen(name) > 0);
555 insertUnmangledBuiltInName(name, level);
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300556 insertBuiltIn(level, op, TExtension::UNDEFINED, rvalue, name, ptype1, ptype2, ptype3, ptype4,
557 ptype5);
Olli Etuaho492cfab2017-01-20 21:18:29 +0000558}
559
560void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
561 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300562 TExtension ext,
Olli Etuaho492cfab2017-01-20 21:18:29 +0000563 const TType *rvalue,
564 const TType *ptype1,
565 const TType *ptype2,
566 const TType *ptype3,
567 const TType *ptype4,
568 const TType *ptype5)
569{
570 const char *name = GetOperatorString(op);
571 insertUnmangledBuiltInName(name, level);
572 insertBuiltIn(level, op, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
573}
574
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300575void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
576 TOperator op,
577 const TType *rvalue,
578 const char *name)
579{
580 insertUnmangledBuiltInName(name, level);
Olli Etuahoa5e693a2017-07-13 16:07:26 +0300581 insert(level, new TFunction(this, NewPoolTString(name), rvalue, op));
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300582}
583
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800584void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300585 TExtension ext,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800586 TOperator op,
587 const TType *rvalue,
588 const char *name)
589{
590 insertUnmangledBuiltInName(name, level);
591 insert(level, new TFunction(this, NewPoolTString(name), rvalue, op, ext));
592}
593
Zhenyao Moe740add2014-07-18 17:01:01 -0700594TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700595{
596 if (!SupportsPrecision(type))
597 return EbpUndefined;
598
599 // unsigned integers use the same precision as signed
600 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
601
602 int level = static_cast<int>(precisionStack.size()) - 1;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500603 assert(level >= 0); // Just to be safe. Should not happen.
Olli Etuaho183d7e22015-11-20 15:59:09 +0200604 // If we dont find anything we return this. Some types don't have predefined default precision.
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700605 TPrecision prec = EbpUndefined;
606 while (level >= 0)
607 {
608 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
609 if (it != precisionStack[level]->end())
610 {
611 prec = (*it).second;
612 break;
613 }
614 level--;
615 }
616 return prec;
617}
Jamie Madill45bcc782016-11-07 13:58:48 -0500618
Martin Radevda6254b2016-12-14 17:00:36 +0200619void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
620{
621 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
Olli Etuaho5d69db12017-11-24 16:51:15 +0200622 ASSERT(mUserDefinedUniqueIdsStart == -1);
Martin Radevda6254b2016-12-14 17:00:36 +0200623 table[level]->insertUnmangledBuiltInName(std::string(name));
624}
625
626bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level)
627{
628 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
629 return table[level]->hasUnmangledBuiltIn(std::string(name));
630}
631
632bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion)
633{
634 ASSERT(static_cast<ESymbolLevel>(table.size()) > LAST_BUILTIN_LEVEL);
635
636 for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
637 {
638 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
639 {
640 --level;
641 }
642 if (level == ESSL3_BUILTINS && shaderVersion < 300)
643 {
644 --level;
645 }
646 if (level == ESSL1_BUILTINS && shaderVersion != 100)
647 {
648 --level;
649 }
650
651 if (table[level]->hasUnmangledBuiltIn(name))
652 {
653 return true;
654 }
655 }
656 return false;
657}
658
Olli Etuaho5d69db12017-11-24 16:51:15 +0200659void TSymbolTable::markBuiltInInitializationFinished()
660{
661 mUserDefinedUniqueIdsStart = mUniqueIdCounter;
662}
663
664void TSymbolTable::clearCompilationResults()
665{
666 mUniqueIdCounter = mUserDefinedUniqueIdsStart;
667
668 // User-defined scopes should have already been cleared when the compilation finished.
669 ASSERT(table.size() == LAST_BUILTIN_LEVEL + 1u);
670}
671
672int TSymbolTable::nextUniqueIdValue()
673{
674 ASSERT(mUniqueIdCounter < std::numeric_limits<int>::max());
675 return ++mUniqueIdCounter;
676}
677
Jamie Madill45bcc782016-11-07 13:58:48 -0500678} // namespace sh