blob: e25cf370485e1ea1e3f5375c48fc9cd3a92b38aa [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
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000025//
26// Symbol table levels are a map of pointers to symbols that have to be deleted.
27//
28TSymbolTableLevel::~TSymbolTableLevel()
29{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000030 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
31 delete (*it).second;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000032}
33
Nicolas Capensadfffe42014-06-17 02:13:36 -040034bool TSymbolTableLevel::insert(TSymbol *symbol)
Jamie Madillbfa91f42014-06-05 15:45:18 -040035{
Jamie Madillbfa91f42014-06-05 15:45:18 -040036 // returning true means symbol was added to the table
Nicolas Capensadfffe42014-06-17 02:13:36 -040037 tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
Jamie Madillbfa91f42014-06-05 15:45:18 -040038
39 return result.second;
40}
41
Olli Etuahob2983c92015-03-18 14:02:46 +020042bool TSymbolTableLevel::insertUnmangled(TFunction *function)
43{
Olli Etuahob2983c92015-03-18 14:02:46 +020044 // returning true means symbol was added to the table
Olli Etuahoae4dbf32017-12-08 20:49:00 +010045 ASSERT(function->name() != nullptr);
46 tInsertResult result = level.insert(tLevelPair(*function->name(), function));
Olli Etuahob2983c92015-03-18 14:02:46 +020047
48 return result.second;
49}
50
Jamie Madillbfa91f42014-06-05 15:45:18 -040051TSymbol *TSymbolTableLevel::find(const TString &name) const
52{
53 tLevel::const_iterator it = level.find(name);
54 if (it == level.end())
55 return 0;
56 else
57 return (*it).second;
58}
59
Jamie Madilld7b1ab52016-12-12 14:42:19 -050060TSymbol *TSymbolTable::find(const TString &name,
61 int shaderVersion,
62 bool *builtIn,
63 bool *sameScope) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000064{
65 int level = currentLevel();
66 TSymbol *symbol;
67
68 do
69 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +030070 if (level == GLSL_BUILTINS)
71 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +030072 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
73 level--;
74 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -070075 level--;
76 if (level == ESSL1_BUILTINS && shaderVersion != 100)
77 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000078
79 symbol = table[level]->find(name);
Jamie Madilld7b1ab52016-12-12 14:42:19 -050080 } while (symbol == 0 && --level >= 0);
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000081
82 if (builtIn)
83 *builtIn = (level <= LAST_BUILTIN_LEVEL);
84 if (sameScope)
85 *sameScope = (level == currentLevel());
86
87 return symbol;
88}
89
Zhenyao Mod7490962016-11-09 15:49:51 -080090TSymbol *TSymbolTable::findGlobal(const TString &name) const
91{
92 ASSERT(table.size() > GLOBAL_LEVEL);
93 return table[GLOBAL_LEVEL]->find(name);
94}
95
Jamie Madilld7b1ab52016-12-12 14:42:19 -050096TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000097{
Olli Etuaho977ee7e2017-07-21 11:38:27 +030098 return findBuiltIn(name, shaderVersion, false);
99}
100
101TSymbol *TSymbolTable::findBuiltIn(const TString &name,
102 int shaderVersion,
103 bool includeGLSLBuiltins) const
104{
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000105 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
106 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300107 if (level == GLSL_BUILTINS && !includeGLSLBuiltins)
108 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +0300109 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
110 level--;
111 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700112 level--;
113 if (level == ESSL1_BUILTINS && shaderVersion != 100)
114 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000115
116 TSymbol *symbol = table[level]->find(name);
117
118 if (symbol)
119 return symbol;
120 }
121
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300122 return nullptr;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000123}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400124
125TSymbolTable::~TSymbolTable()
126{
127 while (table.size() > 0)
128 pop();
129}
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700130
Kai Ninomiya030017a2017-12-06 14:06:53 -0800131constexpr bool IsGenType(const TType *type)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500132{
133 if (type)
134 {
135 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500136 return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType ||
137 basicType == EbtGenBType;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500138 }
139
140 return false;
141}
142
Kai Ninomiya030017a2017-12-06 14:06:53 -0800143constexpr bool IsVecType(const TType *type)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500144{
145 if (type)
146 {
147 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500148 return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec ||
149 basicType == EbtBVec;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500150 }
151
152 return false;
153}
154
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800155constexpr const TType *SpecificType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500156{
157 ASSERT(size >= 1 && size <= 4);
158
159 if (!type)
160 {
161 return nullptr;
162 }
163
164 ASSERT(!IsVecType(type));
165
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500166 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500167 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500168 case EbtGenType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800169 return StaticType::GetForVec<EbtFloat>(type->getQualifier(),
170 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500171 case EbtGenIType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800172 return StaticType::GetForVec<EbtInt>(type->getQualifier(),
173 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500174 case EbtGenUType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800175 return StaticType::GetForVec<EbtUInt>(type->getQualifier(),
176 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500177 case EbtGenBType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800178 return StaticType::GetForVec<EbtBool>(type->getQualifier(),
179 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500180 default:
181 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500182 }
183}
184
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800185constexpr const TType *VectorType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500186{
187 ASSERT(size >= 2 && size <= 4);
188
189 if (!type)
190 {
191 return nullptr;
192 }
193
194 ASSERT(!IsGenType(type));
195
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500196 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500197 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500198 case EbtVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800199 return StaticType::GetForVecMat<EbtFloat>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500200 case EbtIVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800201 return StaticType::GetForVecMat<EbtInt>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500202 case EbtUVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800203 return StaticType::GetForVecMat<EbtUInt>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500204 case EbtBVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800205 return StaticType::GetForVecMat<EbtBool>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500206 default:
207 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500208 }
209}
210
Olli Etuaho195be942017-12-04 23:40:14 +0200211bool TSymbolTable::declareVariable(TVariable *variable)
Olli Etuaho0f684632017-07-13 12:42:15 +0300212{
Olli Etuaho195be942017-12-04 23:40:14 +0200213 ASSERT(variable->symbolType() == SymbolType::UserDefined);
214 return insertVariable(currentLevel(), variable);
Olli Etuaho0f684632017-07-13 12:42:15 +0300215}
216
Olli Etuaho035419f2017-11-28 14:27:15 +0200217bool TSymbolTable::declareStructType(TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300218{
219 return insertStructType(currentLevel(), str);
220}
221
Olli Etuaho378c3a52017-12-04 11:32:13 +0200222bool TSymbolTable::declareInterfaceBlock(TInterfaceBlock *interfaceBlock)
Olli Etuaho0f684632017-07-13 12:42:15 +0300223{
Olli Etuaho378c3a52017-12-04 11:32:13 +0200224 return insert(currentLevel(), interfaceBlock);
Jiawei Shaod8105a02017-08-08 09:54:36 +0800225}
226
Olli Etuaho0f684632017-07-13 12:42:15 +0300227TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType &type)
228{
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100229 ASSERT(level <= LAST_BUILTIN_LEVEL);
230 return insertVariable(level, NewPoolTString(name), type, SymbolType::BuiltIn);
Olli Etuaho0f684632017-07-13 12:42:15 +0300231}
232
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100233TVariable *TSymbolTable::insertVariable(ESymbolLevel level,
234 const TString *name,
235 const TType &type,
236 SymbolType symbolType)
Olli Etuaho0f684632017-07-13 12:42:15 +0300237{
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100238 TVariable *var = new TVariable(this, name, type, symbolType);
Olli Etuaho0f684632017-07-13 12:42:15 +0300239 if (insert(level, var))
240 {
241 // Do lazy initialization for struct types, so we allocate to the current scope.
242 if (var->getType().getBasicType() == EbtStruct)
243 {
244 var->getType().realize();
245 }
246 return var;
247 }
248 return nullptr;
249}
250
251TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300252 TExtension ext,
Olli Etuaho0f684632017-07-13 12:42:15 +0300253 const char *name,
254 const TType &type)
255{
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100256 TVariable *var = new TVariable(this, NewPoolTString(name), type, SymbolType::BuiltIn, ext);
Olli Etuaho5d69db12017-11-24 16:51:15 +0200257 if (insert(level, var))
Olli Etuaho0f684632017-07-13 12:42:15 +0300258 {
259 if (var->getType().getBasicType() == EbtStruct)
260 {
261 var->getType().realize();
262 }
263 return var;
264 }
265 return nullptr;
266}
267
Olli Etuaho195be942017-12-04 23:40:14 +0200268bool TSymbolTable::insertVariable(ESymbolLevel level, TVariable *variable)
269{
270 ASSERT(variable);
271 return insert(level, variable);
272}
273
Olli Etuaho035419f2017-11-28 14:27:15 +0200274bool TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300275{
Olli Etuaho035419f2017-11-28 14:27:15 +0200276 ASSERT(str);
Olli Etuaho378c3a52017-12-04 11:32:13 +0200277 return insert(level, str);
278}
279
280bool TSymbolTable::insertInterfaceBlock(ESymbolLevel level, TInterfaceBlock *interfaceBlock)
281{
282 ASSERT(interfaceBlock);
283 return insert(level, interfaceBlock);
Olli Etuaho0f684632017-07-13 12:42:15 +0300284}
285
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500286void TSymbolTable::insertBuiltIn(ESymbolLevel level,
287 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300288 TExtension ext,
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500289 const TType *rvalue,
290 const char *name,
291 const TType *ptype1,
292 const TType *ptype2,
293 const TType *ptype3,
294 const TType *ptype4,
295 const TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700296{
297 if (ptype1->getBasicType() == EbtGSampler2D)
298 {
Martin Radevda6254b2016-12-14 17:00:36 +0200299 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700300 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800301 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
302 StaticType::GetBasic<EbtSampler2D>(), ptype2, ptype3, ptype4, ptype5);
303 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
304 StaticType::GetBasic<EbtISampler2D>(), ptype2, ptype3, ptype4, ptype5);
305 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
306 StaticType::GetBasic<EbtUSampler2D>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700307 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500308 else if (ptype1->getBasicType() == EbtGSampler3D)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700309 {
Martin Radevda6254b2016-12-14 17:00:36 +0200310 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700311 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800312 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
313 StaticType::GetBasic<EbtSampler3D>(), ptype2, ptype3, ptype4, ptype5);
314 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
315 StaticType::GetBasic<EbtISampler3D>(), ptype2, ptype3, ptype4, ptype5);
316 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
317 StaticType::GetBasic<EbtUSampler3D>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700318 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500319 else if (ptype1->getBasicType() == EbtGSamplerCube)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700320 {
Martin Radevda6254b2016-12-14 17:00:36 +0200321 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700322 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800323 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
324 StaticType::GetBasic<EbtSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
325 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
326 StaticType::GetBasic<EbtISamplerCube>(), ptype2, ptype3, ptype4, ptype5);
327 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
328 StaticType::GetBasic<EbtUSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700329 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500330 else if (ptype1->getBasicType() == EbtGSampler2DArray)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700331 {
Martin Radevda6254b2016-12-14 17:00:36 +0200332 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700333 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800334 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
335 StaticType::GetBasic<EbtSampler2DArray>(), ptype2, ptype3, ptype4,
336 ptype5);
337 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
338 StaticType::GetBasic<EbtISampler2DArray>(), ptype2, ptype3, ptype4,
339 ptype5);
340 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
341 StaticType::GetBasic<EbtUSampler2DArray>(), ptype2, ptype3, ptype4,
342 ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700343 }
JiangYizhou40219322016-12-09 09:50:51 +0800344 else if (ptype1->getBasicType() == EbtGSampler2DMS)
345 {
346 insertUnmangledBuiltInName(name, level);
347 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800348 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
349 StaticType::GetBasic<EbtSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
350 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
351 StaticType::GetBasic<EbtISampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
352 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
353 StaticType::GetBasic<EbtUSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
JiangYizhou40219322016-12-09 09:50:51 +0800354 }
Martin Radev2cc85b32016-08-05 16:22:53 +0300355 else if (IsGImage(ptype1->getBasicType()))
356 {
Martin Radevda6254b2016-12-14 17:00:36 +0200357 insertUnmangledBuiltInName(name, level);
Martin Radev2cc85b32016-08-05 16:22:53 +0300358
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800359 const TType *floatType = StaticType::GetBasic<EbtFloat, 4>();
360 const TType *intType = StaticType::GetBasic<EbtInt, 4>();
361 const TType *unsignedType = StaticType::GetBasic<EbtUInt, 4>();
Martin Radev2cc85b32016-08-05 16:22:53 +0300362
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800363 const TType *floatImage = StaticType::GetForFloatImage(ptype1->getBasicType());
364 const TType *intImage = StaticType::GetForIntImage(ptype1->getBasicType());
365 const TType *unsignedImage = StaticType::GetForUintImage(ptype1->getBasicType());
Martin Radev2cc85b32016-08-05 16:22:53 +0300366
367 // GLSL ES 3.10, Revision 4, 8.12 Image Functions
368 if (rvalue->getBasicType() == EbtGVec4)
369 {
370 // imageLoad
371 insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
372 insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
373 insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
374 }
375 else if (rvalue->getBasicType() == EbtVoid)
376 {
377 // imageStore
378 insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
379 insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
380 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
381 }
382 else
383 {
384 // imageSize
385 insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
386 insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
387 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
388 }
389 }
Olli Etuaho9250cb22017-01-21 10:51:27 +0000390 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3) ||
391 IsGenType(ptype4))
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500392 {
Olli Etuaho9250cb22017-01-21 10:51:27 +0000393 ASSERT(!ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200394 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500395 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000396 SpecificType(ptype2, 1), SpecificType(ptype3, 1), SpecificType(ptype4, 1));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500397 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000398 SpecificType(ptype2, 2), SpecificType(ptype3, 2), SpecificType(ptype4, 2));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500399 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000400 SpecificType(ptype2, 3), SpecificType(ptype3, 3), SpecificType(ptype4, 3));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500401 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000402 SpecificType(ptype2, 4), SpecificType(ptype3, 4), SpecificType(ptype4, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500403 }
404 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
405 {
406 ASSERT(!ptype4 && !ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200407 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500408 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2),
409 VectorType(ptype2, 2), VectorType(ptype3, 2));
410 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3),
411 VectorType(ptype2, 3), VectorType(ptype3, 3));
412 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4),
413 VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500414 }
415 else
416 {
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100417 TFunction *function =
Olli Etuaho0c371002017-12-13 17:00:25 +0400418 new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, false, op, ext);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700419
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700420 function->addParameter(TConstParameter(ptype1));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700421
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500422 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700423 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700424 function->addParameter(TConstParameter(ptype2));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700425 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700426
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500427 if (ptype3)
428 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700429 function->addParameter(TConstParameter(ptype3));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500430 }
431
432 if (ptype4)
433 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700434 function->addParameter(TConstParameter(ptype4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500435 }
436
437 if (ptype5)
438 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700439 function->addParameter(TConstParameter(ptype5));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500440 }
441
Martin Radevda6254b2016-12-14 17:00:36 +0200442 ASSERT(hasUnmangledBuiltInAtLevel(name, level));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500443 insert(level, function);
444 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700445}
446
Olli Etuaho492cfab2017-01-20 21:18:29 +0000447void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
448 TOperator op,
449 const TType *rvalue,
450 const TType *ptype1,
451 const TType *ptype2,
452 const TType *ptype3,
453 const TType *ptype4,
454 const TType *ptype5)
455{
456 const char *name = GetOperatorString(op);
457 ASSERT(strlen(name) > 0);
458 insertUnmangledBuiltInName(name, level);
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300459 insertBuiltIn(level, op, TExtension::UNDEFINED, rvalue, name, ptype1, ptype2, ptype3, ptype4,
460 ptype5);
Olli Etuaho492cfab2017-01-20 21:18:29 +0000461}
462
463void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
464 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300465 TExtension ext,
Olli Etuaho492cfab2017-01-20 21:18:29 +0000466 const TType *rvalue,
467 const TType *ptype1,
468 const TType *ptype2,
469 const TType *ptype3,
470 const TType *ptype4,
471 const TType *ptype5)
472{
473 const char *name = GetOperatorString(op);
474 insertUnmangledBuiltInName(name, level);
475 insertBuiltIn(level, op, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
476}
477
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300478void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
479 TOperator op,
480 const TType *rvalue,
481 const char *name)
482{
483 insertUnmangledBuiltInName(name, level);
Olli Etuaho0c371002017-12-13 17:00:25 +0400484 insert(level,
485 new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, false, op));
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300486}
487
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800488void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300489 TExtension ext,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800490 TOperator op,
491 const TType *rvalue,
492 const char *name)
493{
494 insertUnmangledBuiltInName(name, level);
Olli Etuaho0c371002017-12-13 17:00:25 +0400495 insert(level,
496 new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, false, op, ext));
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800497}
498
Zhenyao Moe740add2014-07-18 17:01:01 -0700499TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700500{
501 if (!SupportsPrecision(type))
502 return EbpUndefined;
503
504 // unsigned integers use the same precision as signed
505 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
506
507 int level = static_cast<int>(precisionStack.size()) - 1;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500508 assert(level >= 0); // Just to be safe. Should not happen.
Olli Etuaho183d7e22015-11-20 15:59:09 +0200509 // If we dont find anything we return this. Some types don't have predefined default precision.
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700510 TPrecision prec = EbpUndefined;
511 while (level >= 0)
512 {
513 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
514 if (it != precisionStack[level]->end())
515 {
516 prec = (*it).second;
517 break;
518 }
519 level--;
520 }
521 return prec;
522}
Jamie Madill45bcc782016-11-07 13:58:48 -0500523
Martin Radevda6254b2016-12-14 17:00:36 +0200524void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
525{
526 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
Olli Etuaho5d69db12017-11-24 16:51:15 +0200527 ASSERT(mUserDefinedUniqueIdsStart == -1);
Martin Radevda6254b2016-12-14 17:00:36 +0200528 table[level]->insertUnmangledBuiltInName(std::string(name));
529}
530
531bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level)
532{
533 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
534 return table[level]->hasUnmangledBuiltIn(std::string(name));
535}
536
537bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion)
538{
539 ASSERT(static_cast<ESymbolLevel>(table.size()) > LAST_BUILTIN_LEVEL);
540
541 for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
542 {
543 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
544 {
545 --level;
546 }
547 if (level == ESSL3_BUILTINS && shaderVersion < 300)
548 {
549 --level;
550 }
551 if (level == ESSL1_BUILTINS && shaderVersion != 100)
552 {
553 --level;
554 }
555
556 if (table[level]->hasUnmangledBuiltIn(name))
557 {
558 return true;
559 }
560 }
561 return false;
562}
563
Olli Etuaho5d69db12017-11-24 16:51:15 +0200564void TSymbolTable::markBuiltInInitializationFinished()
565{
566 mUserDefinedUniqueIdsStart = mUniqueIdCounter;
567}
568
569void TSymbolTable::clearCompilationResults()
570{
571 mUniqueIdCounter = mUserDefinedUniqueIdsStart;
572
573 // User-defined scopes should have already been cleared when the compilation finished.
574 ASSERT(table.size() == LAST_BUILTIN_LEVEL + 1u);
575}
576
577int TSymbolTable::nextUniqueIdValue()
578{
579 ASSERT(mUniqueIdCounter < std::numeric_limits<int>::max());
580 return ++mUniqueIdCounter;
581}
582
Jamie Madill45bcc782016-11-07 13:58:48 -0500583} // namespace sh