blob: 4ec871e901fc6ecb8f9ad59e13975fbb95daa7cd [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//
6
7//
8// Symbol table for parsing. Most functionaliy and main ideas
9// are documented in the header file.
10//
11
apatrick@chromium.orge057c5d2012-01-26 19:18:24 +000012#if defined(_MSC_VER)
Jamie Madilld7b1ab52016-12-12 14:42:19 -050013#pragma warning(disable : 4718)
apatrick@chromium.orge057c5d2012-01-26 19:18:24 +000014#endif
15
Geoff Lang17732822013-08-29 13:46:49 -040016#include "compiler/translator/SymbolTable.h"
Olli Etuaho01d0ad02017-01-22 14:51:23 -080017
Dmitry Skiba01971112015-07-10 14:54:00 -040018#include "compiler/translator/Cache.h"
Olli Etuaho01d0ad02017-01-22 14:51:23 -080019#include "compiler/translator/IntermNode.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000020
apatrick@chromium.org8187fa82010-06-15 22:09:28 +000021#include <stdio.h>
kbr@chromium.org476541f2011-10-27 21:14:51 +000022#include <algorithm>
23
Jamie Madill45bcc782016-11-07 13:58:48 -050024namespace sh
25{
26
Jamie Madillbfa91f42014-06-05 15:45:18 -040027int TSymbolTable::uniqueIdCounter = 0;
Nicolas Capensbd10cf52013-06-20 09:51:51 -040028
Olli Etuahofe486322017-03-21 09:30:54 +000029TSymbolUniqueId::TSymbolUniqueId() : mId(TSymbolTable::nextUniqueId())
30{
31}
32
33TSymbolUniqueId::TSymbolUniqueId(const TSymbol &symbol) : mId(symbol.getUniqueId())
34{
35}
36
37int TSymbolUniqueId::get() const
38{
39 return mId;
40}
41
Olli Etuaho476197f2016-10-11 13:59:08 +010042TSymbol::TSymbol(const TString *n) : uniqueId(TSymbolTable::nextUniqueId()), name(n)
43{
44}
45
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000046//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000047// Functions have buried pointers to delete.
48//
49TFunction::~TFunction()
50{
Olli Etuaho476197f2016-10-11 13:59:08 +010051 clearParameters();
52}
53
54void TFunction::clearParameters()
55{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000056 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
57 delete (*i).type;
Olli Etuaho476197f2016-10-11 13:59:08 +010058 parameters.clear();
59 mangledName = nullptr;
60}
61
62void TFunction::swapParameters(const TFunction &parametersSource)
63{
64 clearParameters();
65 for (auto parameter : parametersSource.parameters)
66 {
67 addParameter(parameter);
68 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000069}
70
Dmitry Skiba58832202015-07-06 16:11:13 -070071const TString *TFunction::buildMangledName() const
72{
Cooper Partin149e6e62015-08-07 16:18:18 -070073 std::string newName = mangleName(getName()).c_str();
Dmitry Skiba58832202015-07-06 16:11:13 -070074
75 for (const auto &p : parameters)
76 {
Cooper Partin149e6e62015-08-07 16:18:18 -070077 newName += p.type->getMangledName().c_str();
Dmitry Skiba58832202015-07-06 16:11:13 -070078 }
79
Cooper Partin149e6e62015-08-07 16:18:18 -070080 return NewPoolTString(newName.c_str());
Dmitry Skiba58832202015-07-06 16:11:13 -070081}
82
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -080083const TString &TFunction::GetMangledNameFromCall(const TString &unmangledFunctionName,
84 TIntermSequence &arguments)
85{
86 std::string newName = mangleName(unmangledFunctionName).c_str();
87 for (TIntermNode *argument : arguments)
88 {
89 newName += argument->getAsTyped()->getType().getMangledName().c_str();
90 }
91 return *NewPoolTString(newName.c_str());
92}
93
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000094//
95// Symbol table levels are a map of pointers to symbols that have to be deleted.
96//
97TSymbolTableLevel::~TSymbolTableLevel()
98{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000099 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
100 delete (*it).second;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000101}
102
Nicolas Capensadfffe42014-06-17 02:13:36 -0400103bool TSymbolTableLevel::insert(TSymbol *symbol)
Jamie Madillbfa91f42014-06-05 15:45:18 -0400104{
Jamie Madillbfa91f42014-06-05 15:45:18 -0400105 // returning true means symbol was added to the table
Nicolas Capensadfffe42014-06-17 02:13:36 -0400106 tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
Jamie Madillbfa91f42014-06-05 15:45:18 -0400107
108 return result.second;
109}
110
Olli Etuahob2983c92015-03-18 14:02:46 +0200111bool TSymbolTableLevel::insertUnmangled(TFunction *function)
112{
Olli Etuahob2983c92015-03-18 14:02:46 +0200113 // returning true means symbol was added to the table
114 tInsertResult result = level.insert(tLevelPair(function->getName(), function));
115
116 return result.second;
117}
118
Jamie Madillbfa91f42014-06-05 15:45:18 -0400119TSymbol *TSymbolTableLevel::find(const TString &name) const
120{
121 tLevel::const_iterator it = level.find(name);
122 if (it == level.end())
123 return 0;
124 else
125 return (*it).second;
126}
127
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500128TSymbol *TSymbolTable::find(const TString &name,
129 int shaderVersion,
130 bool *builtIn,
131 bool *sameScope) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000132{
133 int level = currentLevel();
134 TSymbol *symbol;
135
136 do
137 {
Martin Radeve93d24e2016-07-28 12:06:05 +0300138 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
139 level--;
140 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700141 level--;
142 if (level == ESSL1_BUILTINS && shaderVersion != 100)
143 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000144
145 symbol = table[level]->find(name);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500146 } while (symbol == 0 && --level >= 0);
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000147
148 if (builtIn)
149 *builtIn = (level <= LAST_BUILTIN_LEVEL);
150 if (sameScope)
151 *sameScope = (level == currentLevel());
152
153 return symbol;
154}
155
Zhenyao Mod7490962016-11-09 15:49:51 -0800156TSymbol *TSymbolTable::findGlobal(const TString &name) const
157{
158 ASSERT(table.size() > GLOBAL_LEVEL);
159 return table[GLOBAL_LEVEL]->find(name);
160}
161
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500162TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000163{
164 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
165 {
Martin Radeve93d24e2016-07-28 12:06:05 +0300166 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
167 level--;
168 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700169 level--;
170 if (level == ESSL1_BUILTINS && shaderVersion != 100)
171 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000172
173 TSymbol *symbol = table[level]->find(name);
174
175 if (symbol)
176 return symbol;
177 }
178
179 return 0;
180}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400181
Olli Etuaho01d0ad02017-01-22 14:51:23 -0800182TFunction *TSymbolTable::findBuiltInOp(TIntermAggregate *callNode, int shaderVersion) const
183{
184 ASSERT(!callNode->isConstructor());
Olli Etuaho1ecd14b2017-01-26 13:54:15 -0800185 ASSERT(!callNode->isFunctionCall());
Olli Etuaho01d0ad02017-01-22 14:51:23 -0800186 TString opString = GetOperatorString(callNode->getOp());
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800187 TSymbol *sym = findBuiltIn(
188 TFunction::GetMangledNameFromCall(opString, *callNode->getSequence()), shaderVersion);
Olli Etuaho01d0ad02017-01-22 14:51:23 -0800189 ASSERT(sym != nullptr && sym->isFunction());
190
191 TFunction *builtInFunc = static_cast<TFunction *>(sym);
Olli Etuahoaf6fc1b2017-01-26 17:45:35 -0800192 ASSERT(builtInFunc->getParamCount() == callNode->getSequence()->size());
Olli Etuaho01d0ad02017-01-22 14:51:23 -0800193 return builtInFunc;
194}
195
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400196TSymbolTable::~TSymbolTable()
197{
198 while (table.size() > 0)
199 pop();
200}
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700201
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500202bool IsGenType(const TType *type)
203{
204 if (type)
205 {
206 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500207 return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType ||
208 basicType == EbtGenBType;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500209 }
210
211 return false;
212}
213
214bool IsVecType(const TType *type)
215{
216 if (type)
217 {
218 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500219 return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec ||
220 basicType == EbtBVec;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500221 }
222
223 return false;
224}
225
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700226const TType *SpecificType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500227{
228 ASSERT(size >= 1 && size <= 4);
229
230 if (!type)
231 {
232 return nullptr;
233 }
234
235 ASSERT(!IsVecType(type));
236
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500237 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500238 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500239 case EbtGenType:
Olli Etuaho9250cb22017-01-21 10:51:27 +0000240 return TCache::getType(EbtFloat, type->getQualifier(),
241 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500242 case EbtGenIType:
Olli Etuaho9250cb22017-01-21 10:51:27 +0000243 return TCache::getType(EbtInt, type->getQualifier(), static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500244 case EbtGenUType:
Olli Etuaho9250cb22017-01-21 10:51:27 +0000245 return TCache::getType(EbtUInt, type->getQualifier(), static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500246 case EbtGenBType:
Olli Etuaho9250cb22017-01-21 10:51:27 +0000247 return TCache::getType(EbtBool, type->getQualifier(), static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500248 default:
249 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500250 }
251}
252
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700253const TType *VectorType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500254{
255 ASSERT(size >= 2 && size <= 4);
256
257 if (!type)
258 {
259 return nullptr;
260 }
261
262 ASSERT(!IsGenType(type));
263
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500264 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500265 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500266 case EbtVec:
267 return TCache::getType(EbtFloat, static_cast<unsigned char>(size));
268 case EbtIVec:
269 return TCache::getType(EbtInt, static_cast<unsigned char>(size));
270 case EbtUVec:
271 return TCache::getType(EbtUInt, static_cast<unsigned char>(size));
272 case EbtBVec:
273 return TCache::getType(EbtBool, static_cast<unsigned char>(size));
274 default:
275 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500276 }
277}
278
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500279void TSymbolTable::insertBuiltIn(ESymbolLevel level,
280 TOperator op,
281 const char *ext,
282 const TType *rvalue,
283 const char *name,
284 const TType *ptype1,
285 const TType *ptype2,
286 const TType *ptype3,
287 const TType *ptype4,
288 const TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700289{
290 if (ptype1->getBasicType() == EbtGSampler2D)
291 {
Martin Radevda6254b2016-12-14 17:00:36 +0200292 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700293 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500294 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
295 TCache::getType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
296 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
297 TCache::getType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
298 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
299 TCache::getType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700300 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500301 else if (ptype1->getBasicType() == EbtGSampler3D)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700302 {
Martin Radevda6254b2016-12-14 17:00:36 +0200303 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700304 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500305 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
306 TCache::getType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
307 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
308 TCache::getType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
309 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
310 TCache::getType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700311 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500312 else if (ptype1->getBasicType() == EbtGSamplerCube)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700313 {
Martin Radevda6254b2016-12-14 17:00:36 +0200314 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700315 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500316 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
317 TCache::getType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
318 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
319 TCache::getType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
320 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
321 TCache::getType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700322 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500323 else if (ptype1->getBasicType() == EbtGSampler2DArray)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700324 {
Martin Radevda6254b2016-12-14 17:00:36 +0200325 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700326 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500327 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
328 TCache::getType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
329 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
330 TCache::getType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
331 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
332 TCache::getType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700333 }
JiangYizhou40219322016-12-09 09:50:51 +0800334 else if (ptype1->getBasicType() == EbtGSampler2DMS)
335 {
336 insertUnmangledBuiltInName(name, level);
337 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
338 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
339 TCache::getType(EbtSampler2DMS), ptype2, ptype3, ptype4, ptype5);
340 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
341 TCache::getType(EbtISampler2DMS), ptype2, ptype3, ptype4, ptype5);
342 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
343 TCache::getType(EbtUSampler2DMS), ptype2, ptype3, ptype4, ptype5);
344 }
Martin Radev2cc85b32016-08-05 16:22:53 +0300345 else if (IsGImage(ptype1->getBasicType()))
346 {
Martin Radevda6254b2016-12-14 17:00:36 +0200347 insertUnmangledBuiltInName(name, level);
Martin Radev2cc85b32016-08-05 16:22:53 +0300348
349 const TType *floatType = TCache::getType(EbtFloat, 4);
350 const TType *intType = TCache::getType(EbtInt, 4);
351 const TType *unsignedType = TCache::getType(EbtUInt, 4);
352
353 const TType *floatImage =
354 TCache::getType(convertGImageToFloatImage(ptype1->getBasicType()));
355 const TType *intImage = TCache::getType(convertGImageToIntImage(ptype1->getBasicType()));
356 const TType *unsignedImage =
357 TCache::getType(convertGImageToUnsignedImage(ptype1->getBasicType()));
358
359 // GLSL ES 3.10, Revision 4, 8.12 Image Functions
360 if (rvalue->getBasicType() == EbtGVec4)
361 {
362 // imageLoad
363 insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
364 insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
365 insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
366 }
367 else if (rvalue->getBasicType() == EbtVoid)
368 {
369 // imageStore
370 insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
371 insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
372 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
373 }
374 else
375 {
376 // imageSize
377 insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
378 insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
379 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
380 }
381 }
Olli Etuaho9250cb22017-01-21 10:51:27 +0000382 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3) ||
383 IsGenType(ptype4))
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500384 {
Olli Etuaho9250cb22017-01-21 10:51:27 +0000385 ASSERT(!ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200386 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500387 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000388 SpecificType(ptype2, 1), SpecificType(ptype3, 1), SpecificType(ptype4, 1));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500389 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000390 SpecificType(ptype2, 2), SpecificType(ptype3, 2), SpecificType(ptype4, 2));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500391 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000392 SpecificType(ptype2, 3), SpecificType(ptype3, 3), SpecificType(ptype4, 3));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500393 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000394 SpecificType(ptype2, 4), SpecificType(ptype3, 4), SpecificType(ptype4, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500395 }
396 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
397 {
398 ASSERT(!ptype4 && !ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200399 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500400 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2),
401 VectorType(ptype2, 2), VectorType(ptype3, 2));
402 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3),
403 VectorType(ptype2, 3), VectorType(ptype3, 3));
404 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4),
405 VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500406 }
407 else
408 {
Dmitry Skiba7f17a502015-06-22 15:08:39 -0700409 TFunction *function = new TFunction(NewPoolTString(name), rvalue, op, ext);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700410
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700411 function->addParameter(TConstParameter(ptype1));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700412
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500413 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700414 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700415 function->addParameter(TConstParameter(ptype2));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700416 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700417
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500418 if (ptype3)
419 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700420 function->addParameter(TConstParameter(ptype3));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500421 }
422
423 if (ptype4)
424 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700425 function->addParameter(TConstParameter(ptype4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500426 }
427
428 if (ptype5)
429 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700430 function->addParameter(TConstParameter(ptype5));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500431 }
432
Martin Radevda6254b2016-12-14 17:00:36 +0200433 ASSERT(hasUnmangledBuiltInAtLevel(name, level));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500434 insert(level, function);
435 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700436}
437
Olli Etuaho492cfab2017-01-20 21:18:29 +0000438void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
439 TOperator op,
440 const TType *rvalue,
441 const TType *ptype1,
442 const TType *ptype2,
443 const TType *ptype3,
444 const TType *ptype4,
445 const TType *ptype5)
446{
447 const char *name = GetOperatorString(op);
448 ASSERT(strlen(name) > 0);
449 insertUnmangledBuiltInName(name, level);
450 insertBuiltIn(level, op, "", rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
451}
452
453void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
454 TOperator op,
455 const char *ext,
456 const TType *rvalue,
457 const TType *ptype1,
458 const TType *ptype2,
459 const TType *ptype3,
460 const TType *ptype4,
461 const TType *ptype5)
462{
463 const char *name = GetOperatorString(op);
464 insertUnmangledBuiltInName(name, level);
465 insertBuiltIn(level, op, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
466}
467
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300468void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
469 TOperator op,
470 const TType *rvalue,
471 const char *name)
472{
473 insertUnmangledBuiltInName(name, level);
474 insert(level, new TFunction(NewPoolTString(name), rvalue, op));
475}
476
Zhenyao Moe740add2014-07-18 17:01:01 -0700477TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700478{
479 if (!SupportsPrecision(type))
480 return EbpUndefined;
481
482 // unsigned integers use the same precision as signed
483 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
484
485 int level = static_cast<int>(precisionStack.size()) - 1;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500486 assert(level >= 0); // Just to be safe. Should not happen.
Olli Etuaho183d7e22015-11-20 15:59:09 +0200487 // If we dont find anything we return this. Some types don't have predefined default precision.
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700488 TPrecision prec = EbpUndefined;
489 while (level >= 0)
490 {
491 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
492 if (it != precisionStack[level]->end())
493 {
494 prec = (*it).second;
495 break;
496 }
497 level--;
498 }
499 return prec;
500}
Jamie Madill45bcc782016-11-07 13:58:48 -0500501
Martin Radevda6254b2016-12-14 17:00:36 +0200502void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
503{
504 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
505 table[level]->insertUnmangledBuiltInName(std::string(name));
506}
507
508bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level)
509{
510 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
511 return table[level]->hasUnmangledBuiltIn(std::string(name));
512}
513
514bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion)
515{
516 ASSERT(static_cast<ESymbolLevel>(table.size()) > LAST_BUILTIN_LEVEL);
517
518 for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
519 {
520 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
521 {
522 --level;
523 }
524 if (level == ESSL3_BUILTINS && shaderVersion < 300)
525 {
526 --level;
527 }
528 if (level == ESSL1_BUILTINS && shaderVersion != 100)
529 {
530 --level;
531 }
532
533 if (table[level]->hasUnmangledBuiltIn(name))
534 {
535 return true;
536 }
537 }
538 return false;
539}
540
Jamie Madill45bcc782016-11-07 13:58:48 -0500541} // namespace sh