blob: 8e4b8b258d288c0e1d18669637d1642aee3d8530 [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 Etuahobed35d72017-12-20 16:36:26 +020045 tInsertResult result = level.insert(tLevelPair(function->name(), function));
Olli Etuahob2983c92015-03-18 14:02:46 +020046
47 return result.second;
48}
49
Jamie Madillbfa91f42014-06-05 15:45:18 -040050TSymbol *TSymbolTableLevel::find(const TString &name) const
51{
52 tLevel::const_iterator it = level.find(name);
53 if (it == level.end())
54 return 0;
55 else
56 return (*it).second;
57}
58
Jamie Madilld7b1ab52016-12-12 14:42:19 -050059TSymbol *TSymbolTable::find(const TString &name,
60 int shaderVersion,
61 bool *builtIn,
62 bool *sameScope) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000063{
64 int level = currentLevel();
65 TSymbol *symbol;
66
67 do
68 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +030069 if (level == GLSL_BUILTINS)
70 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +030071 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
72 level--;
73 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -070074 level--;
75 if (level == ESSL1_BUILTINS && shaderVersion != 100)
76 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000077
78 symbol = table[level]->find(name);
Jamie Madilld7b1ab52016-12-12 14:42:19 -050079 } while (symbol == 0 && --level >= 0);
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000080
81 if (builtIn)
82 *builtIn = (level <= LAST_BUILTIN_LEVEL);
83 if (sameScope)
84 *sameScope = (level == currentLevel());
85
86 return symbol;
87}
88
Zhenyao Mod7490962016-11-09 15:49:51 -080089TSymbol *TSymbolTable::findGlobal(const TString &name) const
90{
91 ASSERT(table.size() > GLOBAL_LEVEL);
92 return table[GLOBAL_LEVEL]->find(name);
93}
94
Jamie Madilld7b1ab52016-12-12 14:42:19 -050095TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000096{
Olli Etuaho977ee7e2017-07-21 11:38:27 +030097 return findBuiltIn(name, shaderVersion, false);
98}
99
100TSymbol *TSymbolTable::findBuiltIn(const TString &name,
101 int shaderVersion,
102 bool includeGLSLBuiltins) const
103{
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000104 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
105 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300106 if (level == GLSL_BUILTINS && !includeGLSLBuiltins)
107 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +0300108 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
109 level--;
110 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700111 level--;
112 if (level == ESSL1_BUILTINS && shaderVersion != 100)
113 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000114
115 TSymbol *symbol = table[level]->find(name);
116
117 if (symbol)
118 return symbol;
119 }
120
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300121 return nullptr;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000122}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400123
124TSymbolTable::~TSymbolTable()
125{
126 while (table.size() > 0)
127 pop();
128}
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700129
Kai Ninomiya030017a2017-12-06 14:06:53 -0800130constexpr bool IsGenType(const TType *type)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500131{
132 if (type)
133 {
134 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500135 return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType ||
136 basicType == EbtGenBType;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500137 }
138
139 return false;
140}
141
Kai Ninomiya030017a2017-12-06 14:06:53 -0800142constexpr bool IsVecType(const TType *type)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500143{
144 if (type)
145 {
146 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500147 return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec ||
148 basicType == EbtBVec;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500149 }
150
151 return false;
152}
153
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800154constexpr const TType *SpecificType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500155{
156 ASSERT(size >= 1 && size <= 4);
157
158 if (!type)
159 {
160 return nullptr;
161 }
162
163 ASSERT(!IsVecType(type));
164
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500165 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500166 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500167 case EbtGenType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800168 return StaticType::GetForVec<EbtFloat>(type->getQualifier(),
169 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500170 case EbtGenIType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800171 return StaticType::GetForVec<EbtInt>(type->getQualifier(),
172 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500173 case EbtGenUType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800174 return StaticType::GetForVec<EbtUInt>(type->getQualifier(),
175 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500176 case EbtGenBType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800177 return StaticType::GetForVec<EbtBool>(type->getQualifier(),
178 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500179 default:
180 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500181 }
182}
183
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800184constexpr const TType *VectorType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500185{
186 ASSERT(size >= 2 && size <= 4);
187
188 if (!type)
189 {
190 return nullptr;
191 }
192
193 ASSERT(!IsGenType(type));
194
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500195 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500196 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500197 case EbtVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800198 return StaticType::GetForVecMat<EbtFloat>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500199 case EbtIVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800200 return StaticType::GetForVecMat<EbtInt>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500201 case EbtUVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800202 return StaticType::GetForVecMat<EbtUInt>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500203 case EbtBVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800204 return StaticType::GetForVecMat<EbtBool>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500205 default:
206 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500207 }
208}
209
Olli Etuaho195be942017-12-04 23:40:14 +0200210bool TSymbolTable::declareVariable(TVariable *variable)
Olli Etuaho0f684632017-07-13 12:42:15 +0300211{
Olli Etuaho195be942017-12-04 23:40:14 +0200212 ASSERT(variable->symbolType() == SymbolType::UserDefined);
213 return insertVariable(currentLevel(), variable);
Olli Etuaho0f684632017-07-13 12:42:15 +0300214}
215
Olli Etuaho035419f2017-11-28 14:27:15 +0200216bool TSymbolTable::declareStructType(TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300217{
218 return insertStructType(currentLevel(), str);
219}
220
Olli Etuaho378c3a52017-12-04 11:32:13 +0200221bool TSymbolTable::declareInterfaceBlock(TInterfaceBlock *interfaceBlock)
Olli Etuaho0f684632017-07-13 12:42:15 +0300222{
Olli Etuaho378c3a52017-12-04 11:32:13 +0200223 return insert(currentLevel(), interfaceBlock);
Jiawei Shaod8105a02017-08-08 09:54:36 +0800224}
225
Olli Etuaho0f684632017-07-13 12:42:15 +0300226TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType &type)
227{
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100228 ASSERT(level <= LAST_BUILTIN_LEVEL);
229 return insertVariable(level, NewPoolTString(name), type, SymbolType::BuiltIn);
Olli Etuaho0f684632017-07-13 12:42:15 +0300230}
231
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100232TVariable *TSymbolTable::insertVariable(ESymbolLevel level,
233 const TString *name,
234 const TType &type,
235 SymbolType symbolType)
Olli Etuaho0f684632017-07-13 12:42:15 +0300236{
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100237 TVariable *var = new TVariable(this, name, type, symbolType);
Olli Etuaho0f684632017-07-13 12:42:15 +0300238 if (insert(level, var))
239 {
Olli Etuaho2c9cc8b2018-01-09 16:13:02 +0200240 if (level <= LAST_BUILTIN_LEVEL)
Olli Etuaho0f684632017-07-13 12:42:15 +0300241 {
242 var->getType().realize();
243 }
244 return var;
245 }
246 return nullptr;
247}
248
249TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300250 TExtension ext,
Olli Etuaho0f684632017-07-13 12:42:15 +0300251 const char *name,
252 const TType &type)
253{
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100254 TVariable *var = new TVariable(this, NewPoolTString(name), type, SymbolType::BuiltIn, ext);
Olli Etuaho5d69db12017-11-24 16:51:15 +0200255 if (insert(level, var))
Olli Etuaho0f684632017-07-13 12:42:15 +0300256 {
Olli Etuaho2c9cc8b2018-01-09 16:13:02 +0200257 if (level <= LAST_BUILTIN_LEVEL)
Olli Etuaho0f684632017-07-13 12:42:15 +0300258 {
259 var->getType().realize();
260 }
261 return var;
262 }
263 return nullptr;
264}
265
Olli Etuaho195be942017-12-04 23:40:14 +0200266bool TSymbolTable::insertVariable(ESymbolLevel level, TVariable *variable)
267{
268 ASSERT(variable);
269 return insert(level, variable);
270}
271
Olli Etuaho035419f2017-11-28 14:27:15 +0200272bool TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300273{
Olli Etuaho035419f2017-11-28 14:27:15 +0200274 ASSERT(str);
Olli Etuaho378c3a52017-12-04 11:32:13 +0200275 return insert(level, str);
276}
277
278bool TSymbolTable::insertInterfaceBlock(ESymbolLevel level, TInterfaceBlock *interfaceBlock)
279{
280 ASSERT(interfaceBlock);
281 return insert(level, interfaceBlock);
Olli Etuaho0f684632017-07-13 12:42:15 +0300282}
283
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500284void TSymbolTable::insertBuiltIn(ESymbolLevel level,
285 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300286 TExtension ext,
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500287 const TType *rvalue,
288 const char *name,
289 const TType *ptype1,
290 const TType *ptype2,
291 const TType *ptype3,
292 const TType *ptype4,
293 const TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700294{
295 if (ptype1->getBasicType() == EbtGSampler2D)
296 {
Martin Radevda6254b2016-12-14 17:00:36 +0200297 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700298 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800299 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
300 StaticType::GetBasic<EbtSampler2D>(), ptype2, ptype3, ptype4, ptype5);
301 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
302 StaticType::GetBasic<EbtISampler2D>(), ptype2, ptype3, ptype4, ptype5);
303 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
304 StaticType::GetBasic<EbtUSampler2D>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700305 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500306 else if (ptype1->getBasicType() == EbtGSampler3D)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700307 {
Martin Radevda6254b2016-12-14 17:00:36 +0200308 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700309 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800310 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
311 StaticType::GetBasic<EbtSampler3D>(), ptype2, ptype3, ptype4, ptype5);
312 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
313 StaticType::GetBasic<EbtISampler3D>(), ptype2, ptype3, ptype4, ptype5);
314 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
315 StaticType::GetBasic<EbtUSampler3D>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700316 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500317 else if (ptype1->getBasicType() == EbtGSamplerCube)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700318 {
Martin Radevda6254b2016-12-14 17:00:36 +0200319 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700320 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800321 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
322 StaticType::GetBasic<EbtSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
323 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
324 StaticType::GetBasic<EbtISamplerCube>(), ptype2, ptype3, ptype4, ptype5);
325 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
326 StaticType::GetBasic<EbtUSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700327 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500328 else if (ptype1->getBasicType() == EbtGSampler2DArray)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700329 {
Martin Radevda6254b2016-12-14 17:00:36 +0200330 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700331 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800332 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
333 StaticType::GetBasic<EbtSampler2DArray>(), ptype2, ptype3, ptype4,
334 ptype5);
335 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
336 StaticType::GetBasic<EbtISampler2DArray>(), ptype2, ptype3, ptype4,
337 ptype5);
338 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
339 StaticType::GetBasic<EbtUSampler2DArray>(), ptype2, ptype3, ptype4,
340 ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700341 }
JiangYizhou40219322016-12-09 09:50:51 +0800342 else if (ptype1->getBasicType() == EbtGSampler2DMS)
343 {
344 insertUnmangledBuiltInName(name, level);
345 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800346 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
347 StaticType::GetBasic<EbtSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
348 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
349 StaticType::GetBasic<EbtISampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
350 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
351 StaticType::GetBasic<EbtUSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
JiangYizhou40219322016-12-09 09:50:51 +0800352 }
Martin Radev2cc85b32016-08-05 16:22:53 +0300353 else if (IsGImage(ptype1->getBasicType()))
354 {
Martin Radevda6254b2016-12-14 17:00:36 +0200355 insertUnmangledBuiltInName(name, level);
Martin Radev2cc85b32016-08-05 16:22:53 +0300356
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800357 const TType *floatType = StaticType::GetBasic<EbtFloat, 4>();
358 const TType *intType = StaticType::GetBasic<EbtInt, 4>();
359 const TType *unsignedType = StaticType::GetBasic<EbtUInt, 4>();
Martin Radev2cc85b32016-08-05 16:22:53 +0300360
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800361 const TType *floatImage = StaticType::GetForFloatImage(ptype1->getBasicType());
362 const TType *intImage = StaticType::GetForIntImage(ptype1->getBasicType());
363 const TType *unsignedImage = StaticType::GetForUintImage(ptype1->getBasicType());
Martin Radev2cc85b32016-08-05 16:22:53 +0300364
365 // GLSL ES 3.10, Revision 4, 8.12 Image Functions
366 if (rvalue->getBasicType() == EbtGVec4)
367 {
368 // imageLoad
369 insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
370 insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
371 insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
372 }
373 else if (rvalue->getBasicType() == EbtVoid)
374 {
375 // imageStore
376 insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
377 insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
378 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
379 }
380 else
381 {
382 // imageSize
383 insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
384 insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
385 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
386 }
387 }
Olli Etuaho9250cb22017-01-21 10:51:27 +0000388 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3) ||
389 IsGenType(ptype4))
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500390 {
Olli Etuaho9250cb22017-01-21 10:51:27 +0000391 ASSERT(!ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200392 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500393 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000394 SpecificType(ptype2, 1), SpecificType(ptype3, 1), SpecificType(ptype4, 1));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500395 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000396 SpecificType(ptype2, 2), SpecificType(ptype3, 2), SpecificType(ptype4, 2));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500397 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000398 SpecificType(ptype2, 3), SpecificType(ptype3, 3), SpecificType(ptype4, 3));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500399 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000400 SpecificType(ptype2, 4), SpecificType(ptype3, 4), SpecificType(ptype4, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500401 }
402 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
403 {
404 ASSERT(!ptype4 && !ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200405 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500406 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2),
407 VectorType(ptype2, 2), VectorType(ptype3, 2));
408 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3),
409 VectorType(ptype2, 3), VectorType(ptype3, 3));
410 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4),
411 VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500412 }
413 else
414 {
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100415 TFunction *function =
Olli Etuaho0c371002017-12-13 17:00:25 +0400416 new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, false, op, ext);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700417
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700418 function->addParameter(TConstParameter(ptype1));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700419
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500420 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700421 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700422 function->addParameter(TConstParameter(ptype2));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700423 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700424
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500425 if (ptype3)
426 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700427 function->addParameter(TConstParameter(ptype3));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500428 }
429
430 if (ptype4)
431 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700432 function->addParameter(TConstParameter(ptype4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500433 }
434
435 if (ptype5)
436 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700437 function->addParameter(TConstParameter(ptype5));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500438 }
439
Martin Radevda6254b2016-12-14 17:00:36 +0200440 ASSERT(hasUnmangledBuiltInAtLevel(name, level));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500441 insert(level, function);
442 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700443}
444
Olli Etuaho492cfab2017-01-20 21:18:29 +0000445void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
446 TOperator op,
447 const TType *rvalue,
448 const TType *ptype1,
449 const TType *ptype2,
450 const TType *ptype3,
451 const TType *ptype4,
452 const TType *ptype5)
453{
454 const char *name = GetOperatorString(op);
455 ASSERT(strlen(name) > 0);
456 insertUnmangledBuiltInName(name, level);
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300457 insertBuiltIn(level, op, TExtension::UNDEFINED, rvalue, name, ptype1, ptype2, ptype3, ptype4,
458 ptype5);
Olli Etuaho492cfab2017-01-20 21:18:29 +0000459}
460
461void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
462 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300463 TExtension ext,
Olli Etuaho492cfab2017-01-20 21:18:29 +0000464 const TType *rvalue,
465 const TType *ptype1,
466 const TType *ptype2,
467 const TType *ptype3,
468 const TType *ptype4,
469 const TType *ptype5)
470{
471 const char *name = GetOperatorString(op);
472 insertUnmangledBuiltInName(name, level);
473 insertBuiltIn(level, op, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
474}
475
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300476void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
477 TOperator op,
478 const TType *rvalue,
479 const char *name)
480{
481 insertUnmangledBuiltInName(name, level);
Olli Etuaho0c371002017-12-13 17:00:25 +0400482 insert(level,
483 new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, false, op));
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300484}
485
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800486void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300487 TExtension ext,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800488 TOperator op,
489 const TType *rvalue,
490 const char *name)
491{
492 insertUnmangledBuiltInName(name, level);
Olli Etuaho0c371002017-12-13 17:00:25 +0400493 insert(level,
494 new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, false, op, ext));
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800495}
496
Zhenyao Moe740add2014-07-18 17:01:01 -0700497TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700498{
499 if (!SupportsPrecision(type))
500 return EbpUndefined;
501
502 // unsigned integers use the same precision as signed
503 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
504
505 int level = static_cast<int>(precisionStack.size()) - 1;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500506 assert(level >= 0); // Just to be safe. Should not happen.
Olli Etuaho183d7e22015-11-20 15:59:09 +0200507 // If we dont find anything we return this. Some types don't have predefined default precision.
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700508 TPrecision prec = EbpUndefined;
509 while (level >= 0)
510 {
511 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
512 if (it != precisionStack[level]->end())
513 {
514 prec = (*it).second;
515 break;
516 }
517 level--;
518 }
519 return prec;
520}
Jamie Madill45bcc782016-11-07 13:58:48 -0500521
Martin Radevda6254b2016-12-14 17:00:36 +0200522void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
523{
524 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
Olli Etuaho5d69db12017-11-24 16:51:15 +0200525 ASSERT(mUserDefinedUniqueIdsStart == -1);
Martin Radevda6254b2016-12-14 17:00:36 +0200526 table[level]->insertUnmangledBuiltInName(std::string(name));
527}
528
529bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level)
530{
531 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
532 return table[level]->hasUnmangledBuiltIn(std::string(name));
533}
534
535bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion)
536{
537 ASSERT(static_cast<ESymbolLevel>(table.size()) > LAST_BUILTIN_LEVEL);
538
539 for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
540 {
541 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
542 {
543 --level;
544 }
545 if (level == ESSL3_BUILTINS && shaderVersion < 300)
546 {
547 --level;
548 }
549 if (level == ESSL1_BUILTINS && shaderVersion != 100)
550 {
551 --level;
552 }
553
554 if (table[level]->hasUnmangledBuiltIn(name))
555 {
556 return true;
557 }
558 }
559 return false;
560}
561
Olli Etuaho5d69db12017-11-24 16:51:15 +0200562void TSymbolTable::markBuiltInInitializationFinished()
563{
564 mUserDefinedUniqueIdsStart = mUniqueIdCounter;
565}
566
567void TSymbolTable::clearCompilationResults()
568{
569 mUniqueIdCounter = mUserDefinedUniqueIdsStart;
570
571 // User-defined scopes should have already been cleared when the compilation finished.
572 ASSERT(table.size() == LAST_BUILTIN_LEVEL + 1u);
573}
574
575int TSymbolTable::nextUniqueIdValue()
576{
577 ASSERT(mUniqueIdCounter < std::numeric_limits<int>::max());
578 return ++mUniqueIdCounter;
579}
580
Jamie Madill45bcc782016-11-07 13:58:48 -0500581} // namespace sh