blob: beda47adb935700016f68fc3d007caf048fb3c5c [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 Etuaho476197f2016-10-11 13:59:08 +010029TSymbol::TSymbol(const TString *n) : uniqueId(TSymbolTable::nextUniqueId()), name(n)
30{
31}
32
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000033//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000034// Functions have buried pointers to delete.
35//
36TFunction::~TFunction()
37{
Olli Etuaho476197f2016-10-11 13:59:08 +010038 clearParameters();
39}
40
41void TFunction::clearParameters()
42{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000043 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
44 delete (*i).type;
Olli Etuaho476197f2016-10-11 13:59:08 +010045 parameters.clear();
46 mangledName = nullptr;
47}
48
49void TFunction::swapParameters(const TFunction &parametersSource)
50{
51 clearParameters();
52 for (auto parameter : parametersSource.parameters)
53 {
54 addParameter(parameter);
55 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000056}
57
Dmitry Skiba58832202015-07-06 16:11:13 -070058const TString *TFunction::buildMangledName() const
59{
Cooper Partin149e6e62015-08-07 16:18:18 -070060 std::string newName = mangleName(getName()).c_str();
Dmitry Skiba58832202015-07-06 16:11:13 -070061
62 for (const auto &p : parameters)
63 {
Cooper Partin149e6e62015-08-07 16:18:18 -070064 newName += p.type->getMangledName().c_str();
Dmitry Skiba58832202015-07-06 16:11:13 -070065 }
66
Cooper Partin149e6e62015-08-07 16:18:18 -070067 return NewPoolTString(newName.c_str());
Dmitry Skiba58832202015-07-06 16:11:13 -070068}
69
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000070//
71// Symbol table levels are a map of pointers to symbols that have to be deleted.
72//
73TSymbolTableLevel::~TSymbolTableLevel()
74{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000075 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
76 delete (*it).second;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000077}
78
Nicolas Capensadfffe42014-06-17 02:13:36 -040079bool TSymbolTableLevel::insert(TSymbol *symbol)
Jamie Madillbfa91f42014-06-05 15:45:18 -040080{
Jamie Madillbfa91f42014-06-05 15:45:18 -040081 // returning true means symbol was added to the table
Nicolas Capensadfffe42014-06-17 02:13:36 -040082 tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
Jamie Madillbfa91f42014-06-05 15:45:18 -040083
84 return result.second;
85}
86
Olli Etuahob2983c92015-03-18 14:02:46 +020087bool TSymbolTableLevel::insertUnmangled(TFunction *function)
88{
Olli Etuahob2983c92015-03-18 14:02:46 +020089 // returning true means symbol was added to the table
90 tInsertResult result = level.insert(tLevelPair(function->getName(), function));
91
92 return result.second;
93}
94
Jamie Madillbfa91f42014-06-05 15:45:18 -040095TSymbol *TSymbolTableLevel::find(const TString &name) const
96{
97 tLevel::const_iterator it = level.find(name);
98 if (it == level.end())
99 return 0;
100 else
101 return (*it).second;
102}
103
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500104TSymbol *TSymbolTable::find(const TString &name,
105 int shaderVersion,
106 bool *builtIn,
107 bool *sameScope) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000108{
109 int level = currentLevel();
110 TSymbol *symbol;
111
112 do
113 {
Martin Radeve93d24e2016-07-28 12:06:05 +0300114 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
115 level--;
116 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700117 level--;
118 if (level == ESSL1_BUILTINS && shaderVersion != 100)
119 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000120
121 symbol = table[level]->find(name);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500122 } while (symbol == 0 && --level >= 0);
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000123
124 if (builtIn)
125 *builtIn = (level <= LAST_BUILTIN_LEVEL);
126 if (sameScope)
127 *sameScope = (level == currentLevel());
128
129 return symbol;
130}
131
Zhenyao Mod7490962016-11-09 15:49:51 -0800132TSymbol *TSymbolTable::findGlobal(const TString &name) const
133{
134 ASSERT(table.size() > GLOBAL_LEVEL);
135 return table[GLOBAL_LEVEL]->find(name);
136}
137
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500138TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000139{
140 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
141 {
Martin Radeve93d24e2016-07-28 12:06:05 +0300142 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
143 level--;
144 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700145 level--;
146 if (level == ESSL1_BUILTINS && shaderVersion != 100)
147 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000148
149 TSymbol *symbol = table[level]->find(name);
150
151 if (symbol)
152 return symbol;
153 }
154
155 return 0;
156}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400157
Olli Etuaho01d0ad02017-01-22 14:51:23 -0800158TFunction *TSymbolTable::findBuiltInOp(TIntermAggregate *callNode, int shaderVersion) const
159{
160 ASSERT(!callNode->isConstructor());
161 ASSERT(callNode->getOp() != EOpFunctionCall);
162 TString opString = GetOperatorString(callNode->getOp());
163 // The return type doesn't affect the mangled name of the function, which is used to look it up.
164 TType dummyReturnType;
165 TFunction call(&opString, &dummyReturnType, callNode->getOp());
166 TIntermSequence *sequence = callNode->getSequence();
167 for (auto *child : *sequence)
168 {
169 TType *paramType = child->getAsTyped()->getTypePointer();
170 TConstParameter p(paramType);
171 call.addParameter(p);
172 }
173
174 TSymbol *sym = findBuiltIn(call.getMangledName(), shaderVersion);
175 ASSERT(sym != nullptr && sym->isFunction());
176
177 TFunction *builtInFunc = static_cast<TFunction *>(sym);
178 ASSERT(builtInFunc->getParamCount() == sequence->size());
179 return builtInFunc;
180}
181
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400182TSymbolTable::~TSymbolTable()
183{
184 while (table.size() > 0)
185 pop();
186}
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700187
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500188bool IsGenType(const TType *type)
189{
190 if (type)
191 {
192 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500193 return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType ||
194 basicType == EbtGenBType;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500195 }
196
197 return false;
198}
199
200bool IsVecType(const TType *type)
201{
202 if (type)
203 {
204 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500205 return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec ||
206 basicType == EbtBVec;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500207 }
208
209 return false;
210}
211
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700212const TType *SpecificType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500213{
214 ASSERT(size >= 1 && size <= 4);
215
216 if (!type)
217 {
218 return nullptr;
219 }
220
221 ASSERT(!IsVecType(type));
222
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500223 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500224 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500225 case EbtGenType:
226 return TCache::getType(EbtFloat, static_cast<unsigned char>(size));
227 case EbtGenIType:
228 return TCache::getType(EbtInt, static_cast<unsigned char>(size));
229 case EbtGenUType:
230 return TCache::getType(EbtUInt, static_cast<unsigned char>(size));
231 case EbtGenBType:
232 return TCache::getType(EbtBool, static_cast<unsigned char>(size));
233 default:
234 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500235 }
236}
237
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700238const TType *VectorType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500239{
240 ASSERT(size >= 2 && size <= 4);
241
242 if (!type)
243 {
244 return nullptr;
245 }
246
247 ASSERT(!IsGenType(type));
248
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500249 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500250 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500251 case EbtVec:
252 return TCache::getType(EbtFloat, static_cast<unsigned char>(size));
253 case EbtIVec:
254 return TCache::getType(EbtInt, static_cast<unsigned char>(size));
255 case EbtUVec:
256 return TCache::getType(EbtUInt, static_cast<unsigned char>(size));
257 case EbtBVec:
258 return TCache::getType(EbtBool, static_cast<unsigned char>(size));
259 default:
260 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500261 }
262}
263
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500264void TSymbolTable::insertBuiltIn(ESymbolLevel level,
265 TOperator op,
266 const char *ext,
267 const TType *rvalue,
268 const char *name,
269 const TType *ptype1,
270 const TType *ptype2,
271 const TType *ptype3,
272 const TType *ptype4,
273 const TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700274{
275 if (ptype1->getBasicType() == EbtGSampler2D)
276 {
Martin Radevda6254b2016-12-14 17:00:36 +0200277 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700278 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500279 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
280 TCache::getType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
281 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
282 TCache::getType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
283 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
284 TCache::getType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700285 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500286 else if (ptype1->getBasicType() == EbtGSampler3D)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700287 {
Martin Radevda6254b2016-12-14 17:00:36 +0200288 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700289 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500290 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
291 TCache::getType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
292 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
293 TCache::getType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
294 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
295 TCache::getType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700296 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500297 else if (ptype1->getBasicType() == EbtGSamplerCube)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700298 {
Martin Radevda6254b2016-12-14 17:00:36 +0200299 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700300 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500301 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
302 TCache::getType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
303 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
304 TCache::getType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
305 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
306 TCache::getType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700307 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500308 else if (ptype1->getBasicType() == EbtGSampler2DArray)
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);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500312 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
313 TCache::getType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
314 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
315 TCache::getType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
316 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
317 TCache::getType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700318 }
JiangYizhou40219322016-12-09 09:50:51 +0800319 else if (ptype1->getBasicType() == EbtGSampler2DMS)
320 {
321 insertUnmangledBuiltInName(name, level);
322 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
323 insertBuiltIn(level, gvec4 ? TCache::getType(EbtFloat, 4) : rvalue, name,
324 TCache::getType(EbtSampler2DMS), ptype2, ptype3, ptype4, ptype5);
325 insertBuiltIn(level, gvec4 ? TCache::getType(EbtInt, 4) : rvalue, name,
326 TCache::getType(EbtISampler2DMS), ptype2, ptype3, ptype4, ptype5);
327 insertBuiltIn(level, gvec4 ? TCache::getType(EbtUInt, 4) : rvalue, name,
328 TCache::getType(EbtUSampler2DMS), ptype2, ptype3, ptype4, ptype5);
329 }
Martin Radev2cc85b32016-08-05 16:22:53 +0300330 else if (IsGImage(ptype1->getBasicType()))
331 {
Martin Radevda6254b2016-12-14 17:00:36 +0200332 insertUnmangledBuiltInName(name, level);
Martin Radev2cc85b32016-08-05 16:22:53 +0300333
334 const TType *floatType = TCache::getType(EbtFloat, 4);
335 const TType *intType = TCache::getType(EbtInt, 4);
336 const TType *unsignedType = TCache::getType(EbtUInt, 4);
337
338 const TType *floatImage =
339 TCache::getType(convertGImageToFloatImage(ptype1->getBasicType()));
340 const TType *intImage = TCache::getType(convertGImageToIntImage(ptype1->getBasicType()));
341 const TType *unsignedImage =
342 TCache::getType(convertGImageToUnsignedImage(ptype1->getBasicType()));
343
344 // GLSL ES 3.10, Revision 4, 8.12 Image Functions
345 if (rvalue->getBasicType() == EbtGVec4)
346 {
347 // imageLoad
348 insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
349 insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
350 insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
351 }
352 else if (rvalue->getBasicType() == EbtVoid)
353 {
354 // imageStore
355 insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
356 insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
357 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
358 }
359 else
360 {
361 // imageSize
362 insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
363 insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
364 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
365 }
366 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500367 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3))
368 {
369 ASSERT(!ptype4 && !ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200370 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500371 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1),
372 SpecificType(ptype2, 1), SpecificType(ptype3, 1));
373 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2),
374 SpecificType(ptype2, 2), SpecificType(ptype3, 2));
375 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3),
376 SpecificType(ptype2, 3), SpecificType(ptype3, 3));
377 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4),
378 SpecificType(ptype2, 4), SpecificType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500379 }
380 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
381 {
382 ASSERT(!ptype4 && !ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200383 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500384 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2),
385 VectorType(ptype2, 2), VectorType(ptype3, 2));
386 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3),
387 VectorType(ptype2, 3), VectorType(ptype3, 3));
388 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4),
389 VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500390 }
391 else
392 {
Dmitry Skiba7f17a502015-06-22 15:08:39 -0700393 TFunction *function = new TFunction(NewPoolTString(name), rvalue, op, ext);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700394
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700395 function->addParameter(TConstParameter(ptype1));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700396
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500397 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700398 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700399 function->addParameter(TConstParameter(ptype2));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700400 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700401
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500402 if (ptype3)
403 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700404 function->addParameter(TConstParameter(ptype3));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500405 }
406
407 if (ptype4)
408 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700409 function->addParameter(TConstParameter(ptype4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500410 }
411
412 if (ptype5)
413 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700414 function->addParameter(TConstParameter(ptype5));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500415 }
416
Martin Radevda6254b2016-12-14 17:00:36 +0200417 ASSERT(hasUnmangledBuiltInAtLevel(name, level));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500418 insert(level, function);
419 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700420}
421
Olli Etuaho492cfab2017-01-20 21:18:29 +0000422void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
423 TOperator op,
424 const TType *rvalue,
425 const TType *ptype1,
426 const TType *ptype2,
427 const TType *ptype3,
428 const TType *ptype4,
429 const TType *ptype5)
430{
431 const char *name = GetOperatorString(op);
432 ASSERT(strlen(name) > 0);
433 insertUnmangledBuiltInName(name, level);
434 insertBuiltIn(level, op, "", rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
435}
436
437void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
438 TOperator op,
439 const char *ext,
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 insertUnmangledBuiltInName(name, level);
449 insertBuiltIn(level, op, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
450}
451
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300452void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
453 TOperator op,
454 const TType *rvalue,
455 const char *name)
456{
457 insertUnmangledBuiltInName(name, level);
458 insert(level, new TFunction(NewPoolTString(name), rvalue, op));
459}
460
Zhenyao Moe740add2014-07-18 17:01:01 -0700461TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700462{
463 if (!SupportsPrecision(type))
464 return EbpUndefined;
465
466 // unsigned integers use the same precision as signed
467 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
468
469 int level = static_cast<int>(precisionStack.size()) - 1;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500470 assert(level >= 0); // Just to be safe. Should not happen.
Olli Etuaho183d7e22015-11-20 15:59:09 +0200471 // If we dont find anything we return this. Some types don't have predefined default precision.
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700472 TPrecision prec = EbpUndefined;
473 while (level >= 0)
474 {
475 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
476 if (it != precisionStack[level]->end())
477 {
478 prec = (*it).second;
479 break;
480 }
481 level--;
482 }
483 return prec;
484}
Jamie Madill45bcc782016-11-07 13:58:48 -0500485
Martin Radevda6254b2016-12-14 17:00:36 +0200486void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
487{
488 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
489 table[level]->insertUnmangledBuiltInName(std::string(name));
490}
491
492bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level)
493{
494 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
495 return table[level]->hasUnmangledBuiltIn(std::string(name));
496}
497
498bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion)
499{
500 ASSERT(static_cast<ESymbolLevel>(table.size()) > LAST_BUILTIN_LEVEL);
501
502 for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
503 {
504 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
505 {
506 --level;
507 }
508 if (level == ESSL3_BUILTINS && shaderVersion < 300)
509 {
510 --level;
511 }
512 if (level == ESSL1_BUILTINS && shaderVersion != 100)
513 {
514 --level;
515 }
516
517 if (table[level]->hasUnmangledBuiltIn(name))
518 {
519 return true;
520 }
521 }
522 return false;
523}
524
Jamie Madill45bcc782016-11-07 13:58:48 -0500525} // namespace sh