blob: 90a88cd6895a0a007fa06873fa552eec48dbe38c [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"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000017
apatrick@chromium.org8187fa82010-06-15 22:09:28 +000018#include <stdio.h>
kbr@chromium.org476541f2011-10-27 21:14:51 +000019#include <algorithm>
20
Jamie Madill45bcc782016-11-07 13:58:48 -050021namespace sh
22{
23
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000024//
25// Symbol table levels are a map of pointers to symbols that have to be deleted.
26//
27TSymbolTableLevel::~TSymbolTableLevel()
28{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000029 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
30 delete (*it).second;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000031}
32
Nicolas Capensadfffe42014-06-17 02:13:36 -040033bool TSymbolTableLevel::insert(TSymbol *symbol)
Jamie Madillbfa91f42014-06-05 15:45:18 -040034{
Jamie Madillbfa91f42014-06-05 15:45:18 -040035 // returning true means symbol was added to the table
Nicolas Capensadfffe42014-06-17 02:13:36 -040036 tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
Jamie Madillbfa91f42014-06-05 15:45:18 -040037
38 return result.second;
39}
40
Olli Etuahob2983c92015-03-18 14:02:46 +020041bool TSymbolTableLevel::insertUnmangled(TFunction *function)
42{
Olli Etuahob2983c92015-03-18 14:02:46 +020043 // returning true means symbol was added to the table
Olli Etuahobed35d72017-12-20 16:36:26 +020044 tInsertResult result = level.insert(tLevelPair(function->name(), function));
Olli Etuahob2983c92015-03-18 14:02:46 +020045
46 return result.second;
47}
48
Jamie Madillbfa91f42014-06-05 15:45:18 -040049TSymbol *TSymbolTableLevel::find(const TString &name) const
50{
51 tLevel::const_iterator it = level.find(name);
52 if (it == level.end())
53 return 0;
54 else
55 return (*it).second;
56}
57
Jamie Madilld7b1ab52016-12-12 14:42:19 -050058TSymbol *TSymbolTable::find(const TString &name,
59 int shaderVersion,
60 bool *builtIn,
61 bool *sameScope) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000062{
63 int level = currentLevel();
64 TSymbol *symbol;
65
66 do
67 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +030068 if (level == GLSL_BUILTINS)
69 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +030070 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
71 level--;
72 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -070073 level--;
74 if (level == ESSL1_BUILTINS && shaderVersion != 100)
75 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000076
77 symbol = table[level]->find(name);
Jamie Madilld7b1ab52016-12-12 14:42:19 -050078 } while (symbol == 0 && --level >= 0);
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000079
80 if (builtIn)
81 *builtIn = (level <= LAST_BUILTIN_LEVEL);
82 if (sameScope)
83 *sameScope = (level == currentLevel());
84
85 return symbol;
86}
87
Zhenyao Mod7490962016-11-09 15:49:51 -080088TSymbol *TSymbolTable::findGlobal(const TString &name) const
89{
90 ASSERT(table.size() > GLOBAL_LEVEL);
91 return table[GLOBAL_LEVEL]->find(name);
92}
93
Jamie Madilld7b1ab52016-12-12 14:42:19 -050094TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000095{
Olli Etuaho977ee7e2017-07-21 11:38:27 +030096 return findBuiltIn(name, shaderVersion, false);
97}
98
99TSymbol *TSymbolTable::findBuiltIn(const TString &name,
100 int shaderVersion,
101 bool includeGLSLBuiltins) const
102{
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000103 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
104 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300105 if (level == GLSL_BUILTINS && !includeGLSLBuiltins)
106 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +0300107 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
108 level--;
109 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700110 level--;
111 if (level == ESSL1_BUILTINS && shaderVersion != 100)
112 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000113
114 TSymbol *symbol = table[level]->find(name);
115
116 if (symbol)
117 return symbol;
118 }
119
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300120 return nullptr;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000121}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400122
123TSymbolTable::~TSymbolTable()
124{
125 while (table.size() > 0)
126 pop();
127}
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700128
Kai Ninomiya030017a2017-12-06 14:06:53 -0800129constexpr bool IsGenType(const TType *type)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500130{
131 if (type)
132 {
133 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500134 return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType ||
135 basicType == EbtGenBType;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500136 }
137
138 return false;
139}
140
Kai Ninomiya030017a2017-12-06 14:06:53 -0800141constexpr bool IsVecType(const TType *type)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500142{
143 if (type)
144 {
145 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500146 return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec ||
147 basicType == EbtBVec;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500148 }
149
150 return false;
151}
152
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800153constexpr const TType *SpecificType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500154{
155 ASSERT(size >= 1 && size <= 4);
156
157 if (!type)
158 {
159 return nullptr;
160 }
161
162 ASSERT(!IsVecType(type));
163
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500164 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500165 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500166 case EbtGenType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800167 return StaticType::GetForVec<EbtFloat>(type->getQualifier(),
168 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500169 case EbtGenIType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800170 return StaticType::GetForVec<EbtInt>(type->getQualifier(),
171 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500172 case EbtGenUType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800173 return StaticType::GetForVec<EbtUInt>(type->getQualifier(),
174 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500175 case EbtGenBType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800176 return StaticType::GetForVec<EbtBool>(type->getQualifier(),
177 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500178 default:
179 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500180 }
181}
182
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800183constexpr const TType *VectorType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500184{
185 ASSERT(size >= 2 && size <= 4);
186
187 if (!type)
188 {
189 return nullptr;
190 }
191
192 ASSERT(!IsGenType(type));
193
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500194 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500195 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500196 case EbtVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800197 return StaticType::GetForVecMat<EbtFloat>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500198 case EbtIVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800199 return StaticType::GetForVecMat<EbtInt>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500200 case EbtUVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800201 return StaticType::GetForVecMat<EbtUInt>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500202 case EbtBVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800203 return StaticType::GetForVecMat<EbtBool>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500204 default:
205 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500206 }
207}
208
Olli Etuaho195be942017-12-04 23:40:14 +0200209bool TSymbolTable::declareVariable(TVariable *variable)
Olli Etuaho0f684632017-07-13 12:42:15 +0300210{
Olli Etuaho195be942017-12-04 23:40:14 +0200211 ASSERT(variable->symbolType() == SymbolType::UserDefined);
212 return insertVariable(currentLevel(), variable);
Olli Etuaho0f684632017-07-13 12:42:15 +0300213}
214
Olli Etuaho035419f2017-11-28 14:27:15 +0200215bool TSymbolTable::declareStructType(TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300216{
217 return insertStructType(currentLevel(), str);
218}
219
Olli Etuaho378c3a52017-12-04 11:32:13 +0200220bool TSymbolTable::declareInterfaceBlock(TInterfaceBlock *interfaceBlock)
Olli Etuaho0f684632017-07-13 12:42:15 +0300221{
Olli Etuaho378c3a52017-12-04 11:32:13 +0200222 return insert(currentLevel(), interfaceBlock);
Jiawei Shaod8105a02017-08-08 09:54:36 +0800223}
224
Olli Etuahob60d30f2018-01-16 12:31:06 +0200225TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType *type)
Olli Etuaho0f684632017-07-13 12:42:15 +0300226{
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100227 ASSERT(level <= LAST_BUILTIN_LEVEL);
Olli Etuahob60d30f2018-01-16 12:31:06 +0200228 ASSERT(type->isRealized());
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100229 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,
Olli Etuahob60d30f2018-01-16 12:31:06 +0200234 const TType *type,
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100235 SymbolType symbolType)
Olli Etuaho0f684632017-07-13 12:42:15 +0300236{
Olli Etuahob60d30f2018-01-16 12:31:06 +0200237 ASSERT(level > LAST_BUILTIN_LEVEL || type->isRealized());
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 {
Olli Etuaho0f684632017-07-13 12:42:15 +0300241 return var;
242 }
243 return nullptr;
244}
245
246TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300247 TExtension ext,
Olli Etuaho0f684632017-07-13 12:42:15 +0300248 const char *name,
Olli Etuahob60d30f2018-01-16 12:31:06 +0200249 const TType *type)
Olli Etuaho0f684632017-07-13 12:42:15 +0300250{
Olli Etuahob60d30f2018-01-16 12:31:06 +0200251 ASSERT(level <= LAST_BUILTIN_LEVEL);
252 ASSERT(type->isRealized());
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100253 TVariable *var = new TVariable(this, NewPoolTString(name), type, SymbolType::BuiltIn, ext);
Olli Etuaho5d69db12017-11-24 16:51:15 +0200254 if (insert(level, var))
Olli Etuaho0f684632017-07-13 12:42:15 +0300255 {
Olli Etuaho0f684632017-07-13 12:42:15 +0300256 return var;
257 }
258 return nullptr;
259}
260
Olli Etuaho195be942017-12-04 23:40:14 +0200261bool TSymbolTable::insertVariable(ESymbolLevel level, TVariable *variable)
262{
263 ASSERT(variable);
Olli Etuahob60d30f2018-01-16 12:31:06 +0200264 ASSERT(level > LAST_BUILTIN_LEVEL || variable->getType().isRealized());
Olli Etuaho195be942017-12-04 23:40:14 +0200265 return insert(level, variable);
266}
267
Olli Etuaho035419f2017-11-28 14:27:15 +0200268bool TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300269{
Olli Etuaho035419f2017-11-28 14:27:15 +0200270 ASSERT(str);
Olli Etuaho378c3a52017-12-04 11:32:13 +0200271 return insert(level, str);
272}
273
274bool TSymbolTable::insertInterfaceBlock(ESymbolLevel level, TInterfaceBlock *interfaceBlock)
275{
276 ASSERT(interfaceBlock);
277 return insert(level, interfaceBlock);
Olli Etuaho0f684632017-07-13 12:42:15 +0300278}
279
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500280void TSymbolTable::insertBuiltIn(ESymbolLevel level,
281 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300282 TExtension ext,
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500283 const TType *rvalue,
284 const char *name,
285 const TType *ptype1,
286 const TType *ptype2,
287 const TType *ptype3,
288 const TType *ptype4,
289 const TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700290{
291 if (ptype1->getBasicType() == EbtGSampler2D)
292 {
Martin Radevda6254b2016-12-14 17:00:36 +0200293 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700294 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800295 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
296 StaticType::GetBasic<EbtSampler2D>(), ptype2, ptype3, ptype4, ptype5);
297 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
298 StaticType::GetBasic<EbtISampler2D>(), ptype2, ptype3, ptype4, ptype5);
299 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
300 StaticType::GetBasic<EbtUSampler2D>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700301 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500302 else if (ptype1->getBasicType() == EbtGSampler3D)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700303 {
Martin Radevda6254b2016-12-14 17:00:36 +0200304 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700305 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800306 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
307 StaticType::GetBasic<EbtSampler3D>(), ptype2, ptype3, ptype4, ptype5);
308 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
309 StaticType::GetBasic<EbtISampler3D>(), ptype2, ptype3, ptype4, ptype5);
310 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
311 StaticType::GetBasic<EbtUSampler3D>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700312 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500313 else if (ptype1->getBasicType() == EbtGSamplerCube)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700314 {
Martin Radevda6254b2016-12-14 17:00:36 +0200315 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700316 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800317 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
318 StaticType::GetBasic<EbtSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
319 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
320 StaticType::GetBasic<EbtISamplerCube>(), ptype2, ptype3, ptype4, ptype5);
321 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
322 StaticType::GetBasic<EbtUSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700323 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500324 else if (ptype1->getBasicType() == EbtGSampler2DArray)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700325 {
Martin Radevda6254b2016-12-14 17:00:36 +0200326 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700327 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800328 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
329 StaticType::GetBasic<EbtSampler2DArray>(), ptype2, ptype3, ptype4,
330 ptype5);
331 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
332 StaticType::GetBasic<EbtISampler2DArray>(), ptype2, ptype3, ptype4,
333 ptype5);
334 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
335 StaticType::GetBasic<EbtUSampler2DArray>(), ptype2, ptype3, ptype4,
336 ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700337 }
JiangYizhou40219322016-12-09 09:50:51 +0800338 else if (ptype1->getBasicType() == EbtGSampler2DMS)
339 {
340 insertUnmangledBuiltInName(name, level);
341 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800342 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
343 StaticType::GetBasic<EbtSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
344 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
345 StaticType::GetBasic<EbtISampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
346 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
347 StaticType::GetBasic<EbtUSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
JiangYizhou40219322016-12-09 09:50:51 +0800348 }
Martin Radev2cc85b32016-08-05 16:22:53 +0300349 else if (IsGImage(ptype1->getBasicType()))
350 {
Martin Radevda6254b2016-12-14 17:00:36 +0200351 insertUnmangledBuiltInName(name, level);
Martin Radev2cc85b32016-08-05 16:22:53 +0300352
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800353 const TType *floatType = StaticType::GetBasic<EbtFloat, 4>();
354 const TType *intType = StaticType::GetBasic<EbtInt, 4>();
355 const TType *unsignedType = StaticType::GetBasic<EbtUInt, 4>();
Martin Radev2cc85b32016-08-05 16:22:53 +0300356
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800357 const TType *floatImage = StaticType::GetForFloatImage(ptype1->getBasicType());
358 const TType *intImage = StaticType::GetForIntImage(ptype1->getBasicType());
359 const TType *unsignedImage = StaticType::GetForUintImage(ptype1->getBasicType());
Martin Radev2cc85b32016-08-05 16:22:53 +0300360
361 // GLSL ES 3.10, Revision 4, 8.12 Image Functions
362 if (rvalue->getBasicType() == EbtGVec4)
363 {
364 // imageLoad
365 insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
366 insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
367 insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
368 }
369 else if (rvalue->getBasicType() == EbtVoid)
370 {
371 // imageStore
372 insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
373 insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
374 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
375 }
376 else
377 {
378 // imageSize
379 insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
380 insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
381 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
382 }
383 }
Olli Etuaho9250cb22017-01-21 10:51:27 +0000384 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3) ||
385 IsGenType(ptype4))
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500386 {
Olli Etuaho9250cb22017-01-21 10:51:27 +0000387 ASSERT(!ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200388 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500389 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000390 SpecificType(ptype2, 1), SpecificType(ptype3, 1), SpecificType(ptype4, 1));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500391 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000392 SpecificType(ptype2, 2), SpecificType(ptype3, 2), SpecificType(ptype4, 2));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500393 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000394 SpecificType(ptype2, 3), SpecificType(ptype3, 3), SpecificType(ptype4, 3));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500395 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000396 SpecificType(ptype2, 4), SpecificType(ptype3, 4), SpecificType(ptype4, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500397 }
398 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
399 {
400 ASSERT(!ptype4 && !ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200401 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500402 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2),
403 VectorType(ptype2, 2), VectorType(ptype3, 2));
404 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3),
405 VectorType(ptype2, 3), VectorType(ptype3, 3));
406 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4),
407 VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500408 }
409 else
410 {
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100411 TFunction *function =
Olli Etuaho0c371002017-12-13 17:00:25 +0400412 new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, false, op, ext);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700413
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700414 function->addParameter(TConstParameter(ptype1));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700415
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500416 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700417 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700418 function->addParameter(TConstParameter(ptype2));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700419 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700420
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500421 if (ptype3)
422 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700423 function->addParameter(TConstParameter(ptype3));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500424 }
425
426 if (ptype4)
427 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700428 function->addParameter(TConstParameter(ptype4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500429 }
430
431 if (ptype5)
432 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700433 function->addParameter(TConstParameter(ptype5));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500434 }
435
Martin Radevda6254b2016-12-14 17:00:36 +0200436 ASSERT(hasUnmangledBuiltInAtLevel(name, level));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500437 insert(level, function);
438 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700439}
440
Olli Etuaho492cfab2017-01-20 21:18:29 +0000441void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
442 TOperator op,
443 const TType *rvalue,
444 const TType *ptype1,
445 const TType *ptype2,
446 const TType *ptype3,
447 const TType *ptype4,
448 const TType *ptype5)
449{
450 const char *name = GetOperatorString(op);
451 ASSERT(strlen(name) > 0);
452 insertUnmangledBuiltInName(name, level);
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300453 insertBuiltIn(level, op, TExtension::UNDEFINED, rvalue, name, ptype1, ptype2, ptype3, ptype4,
454 ptype5);
Olli Etuaho492cfab2017-01-20 21:18:29 +0000455}
456
457void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
458 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300459 TExtension ext,
Olli Etuaho492cfab2017-01-20 21:18:29 +0000460 const TType *rvalue,
461 const TType *ptype1,
462 const TType *ptype2,
463 const TType *ptype3,
464 const TType *ptype4,
465 const TType *ptype5)
466{
467 const char *name = GetOperatorString(op);
468 insertUnmangledBuiltInName(name, level);
469 insertBuiltIn(level, op, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
470}
471
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300472void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
473 TOperator op,
474 const TType *rvalue,
475 const char *name)
476{
477 insertUnmangledBuiltInName(name, level);
Olli Etuaho0c371002017-12-13 17:00:25 +0400478 insert(level,
479 new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, false, op));
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300480}
481
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800482void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300483 TExtension ext,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800484 TOperator op,
485 const TType *rvalue,
486 const char *name)
487{
488 insertUnmangledBuiltInName(name, level);
Olli Etuaho0c371002017-12-13 17:00:25 +0400489 insert(level,
490 new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, false, op, ext));
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800491}
492
Zhenyao Moe740add2014-07-18 17:01:01 -0700493TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700494{
495 if (!SupportsPrecision(type))
496 return EbpUndefined;
497
498 // unsigned integers use the same precision as signed
499 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
500
501 int level = static_cast<int>(precisionStack.size()) - 1;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500502 assert(level >= 0); // Just to be safe. Should not happen.
Olli Etuaho183d7e22015-11-20 15:59:09 +0200503 // If we dont find anything we return this. Some types don't have predefined default precision.
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700504 TPrecision prec = EbpUndefined;
505 while (level >= 0)
506 {
507 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
508 if (it != precisionStack[level]->end())
509 {
510 prec = (*it).second;
511 break;
512 }
513 level--;
514 }
515 return prec;
516}
Jamie Madill45bcc782016-11-07 13:58:48 -0500517
Martin Radevda6254b2016-12-14 17:00:36 +0200518void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
519{
520 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
Olli Etuaho5d69db12017-11-24 16:51:15 +0200521 ASSERT(mUserDefinedUniqueIdsStart == -1);
Martin Radevda6254b2016-12-14 17:00:36 +0200522 table[level]->insertUnmangledBuiltInName(std::string(name));
523}
524
525bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level)
526{
527 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
528 return table[level]->hasUnmangledBuiltIn(std::string(name));
529}
530
531bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion)
532{
533 ASSERT(static_cast<ESymbolLevel>(table.size()) > LAST_BUILTIN_LEVEL);
534
535 for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
536 {
537 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
538 {
539 --level;
540 }
541 if (level == ESSL3_BUILTINS && shaderVersion < 300)
542 {
543 --level;
544 }
545 if (level == ESSL1_BUILTINS && shaderVersion != 100)
546 {
547 --level;
548 }
549
550 if (table[level]->hasUnmangledBuiltIn(name))
551 {
552 return true;
553 }
554 }
555 return false;
556}
557
Olli Etuaho5d69db12017-11-24 16:51:15 +0200558void TSymbolTable::markBuiltInInitializationFinished()
559{
560 mUserDefinedUniqueIdsStart = mUniqueIdCounter;
561}
562
563void TSymbolTable::clearCompilationResults()
564{
565 mUniqueIdCounter = mUserDefinedUniqueIdsStart;
566
567 // User-defined scopes should have already been cleared when the compilation finished.
568 ASSERT(table.size() == LAST_BUILTIN_LEVEL + 1u);
569}
570
571int TSymbolTable::nextUniqueIdValue()
572{
573 ASSERT(mUniqueIdCounter < std::numeric_limits<int>::max());
574 return ++mUniqueIdCounter;
575}
576
Jamie Madill45bcc782016-11-07 13:58:48 -0500577} // namespace sh