blob: 7d841b69b71c4c7a0a1fcc0b9be666ddd0c5a751 [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
Olli Etuahodd21ecf2018-01-10 12:42:09 +020024class TSymbolTable::TSymbolTableLevel
25{
26 public:
27 TSymbolTableLevel() : mGlobalInvariant(false) {}
28 ~TSymbolTableLevel();
29
30 bool insert(TSymbol *symbol);
31
32 // Insert a function using its unmangled name as the key.
33 bool insertUnmangled(TFunction *function);
34
35 TSymbol *find(const TString &name) const;
36
37 void addInvariantVarying(const std::string &name) { mInvariantVaryings.insert(name); }
38
39 bool isVaryingInvariant(const std::string &name)
40 {
41 return (mGlobalInvariant || mInvariantVaryings.count(name) > 0);
42 }
43
44 void setGlobalInvariant(bool invariant) { mGlobalInvariant = invariant; }
45
46 void insertUnmangledBuiltInName(const char *name);
47 bool hasUnmangledBuiltIn(const char *name) const;
48
49 private:
50 using tLevel = TUnorderedMap<TString, TSymbol *>;
51 using tLevelPair = const tLevel::value_type;
52 using tInsertResult = std::pair<tLevel::iterator, bool>;
53
54 tLevel level;
55 std::set<std::string> mInvariantVaryings;
56 bool mGlobalInvariant;
57
58 struct CharArrayComparator
59 {
60 bool operator()(const char *a, const char *b) const { return strcmp(a, b) < 0; }
61 };
62 std::set<const char *, CharArrayComparator> mUnmangledBuiltInNames;
63};
64
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000065//
66// Symbol table levels are a map of pointers to symbols that have to be deleted.
67//
Olli Etuahodd21ecf2018-01-10 12:42:09 +020068TSymbolTable::TSymbolTableLevel::~TSymbolTableLevel()
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000069{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000070 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
71 delete (*it).second;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000072}
73
Olli Etuahodd21ecf2018-01-10 12:42:09 +020074bool TSymbolTable::TSymbolTableLevel::insert(TSymbol *symbol)
Jamie Madillbfa91f42014-06-05 15:45:18 -040075{
Jamie Madillbfa91f42014-06-05 15:45:18 -040076 // returning true means symbol was added to the table
Nicolas Capensadfffe42014-06-17 02:13:36 -040077 tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
Jamie Madillbfa91f42014-06-05 15:45:18 -040078
79 return result.second;
80}
81
Olli Etuahodd21ecf2018-01-10 12:42:09 +020082bool TSymbolTable::TSymbolTableLevel::insertUnmangled(TFunction *function)
Olli Etuahob2983c92015-03-18 14:02:46 +020083{
Olli Etuahob2983c92015-03-18 14:02:46 +020084 // returning true means symbol was added to the table
Olli Etuahobed35d72017-12-20 16:36:26 +020085 tInsertResult result = level.insert(tLevelPair(function->name(), function));
Olli Etuahob2983c92015-03-18 14:02:46 +020086
87 return result.second;
88}
89
Olli Etuahodd21ecf2018-01-10 12:42:09 +020090TSymbol *TSymbolTable::TSymbolTableLevel::find(const TString &name) const
Jamie Madillbfa91f42014-06-05 15:45:18 -040091{
92 tLevel::const_iterator it = level.find(name);
93 if (it == level.end())
94 return 0;
95 else
96 return (*it).second;
97}
98
Olli Etuahodd21ecf2018-01-10 12:42:09 +020099void TSymbolTable::TSymbolTableLevel::insertUnmangledBuiltInName(const char *name)
Olli Etuaho342b83d2018-01-10 13:24:01 +0200100{
101 mUnmangledBuiltInNames.insert(name);
102}
103
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200104bool TSymbolTable::TSymbolTableLevel::hasUnmangledBuiltIn(const char *name) const
Olli Etuaho342b83d2018-01-10 13:24:01 +0200105{
106 return mUnmangledBuiltInNames.count(name) > 0;
107}
108
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200109void TSymbolTable::push()
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000110{
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200111 table.push_back(new TSymbolTableLevel);
112 precisionStack.push_back(new PrecisionStackLevel);
113}
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000114
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200115void TSymbolTable::pop()
116{
117 delete table.back();
118 table.pop_back();
119
120 delete precisionStack.back();
121 precisionStack.pop_back();
122}
123
124const TFunction *TSymbolTable::markUserDefinedFunctionHasPrototypeDeclaration(
125 const TString &mangledName,
126 bool *hadPrototypeDeclarationOut)
127{
128 TFunction *function = findUserDefinedFunction(mangledName);
129 *hadPrototypeDeclarationOut = function->hasPrototypeDeclaration();
130 function->setHasPrototypeDeclaration();
131 return function;
132}
133
134const TFunction *TSymbolTable::setUserDefinedFunctionParameterNamesFromDefinition(
135 const TFunction *function,
136 bool *wasDefinedOut)
137{
138 TFunction *firstDeclaration = findUserDefinedFunction(function->getMangledName());
139 ASSERT(firstDeclaration);
140 // Note: 'firstDeclaration' could be 'function' if this is the first time we've seen function as
141 // it would have just been put in the symbol table. Otherwise, we're looking up an earlier
142 // occurance.
143 if (function != firstDeclaration)
144 {
145 // Swap the parameters of the previous declaration to the parameters of the function
146 // definition (parameter names may differ).
147 firstDeclaration->swapParameters(*function);
148 }
149
150 *wasDefinedOut = firstDeclaration->isDefined();
151 firstDeclaration->setDefined();
152 return firstDeclaration;
153}
154
155const TSymbol *TSymbolTable::find(const TString &name,
156 int shaderVersion,
157 bool *builtIn,
158 bool *sameScope) const
159{
160 int level = currentLevel();
161 TSymbol *symbol = nullptr;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000162 do
163 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300164 if (level == GLSL_BUILTINS)
165 level--;
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 symbol = table[level]->find(name);
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200174 } while (symbol == nullptr && --level >= 0);
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000175
176 if (builtIn)
177 *builtIn = (level <= LAST_BUILTIN_LEVEL);
178 if (sameScope)
179 *sameScope = (level == currentLevel());
180
181 return symbol;
182}
183
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200184TFunction *TSymbolTable::findUserDefinedFunction(const TString &name) const
185{
186 // User-defined functions are always declared at the global level.
187 ASSERT(currentLevel() >= GLOBAL_LEVEL);
188 return static_cast<TFunction *>(table[GLOBAL_LEVEL]->find(name));
189}
190
191const TSymbol *TSymbolTable::findGlobal(const TString &name) const
Zhenyao Mod7490962016-11-09 15:49:51 -0800192{
193 ASSERT(table.size() > GLOBAL_LEVEL);
194 return table[GLOBAL_LEVEL]->find(name);
195}
196
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200197const TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000198{
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300199 return findBuiltIn(name, shaderVersion, false);
200}
201
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200202const TSymbol *TSymbolTable::findBuiltIn(const TString &name,
203 int shaderVersion,
204 bool includeGLSLBuiltins) const
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300205{
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000206 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
207 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300208 if (level == GLSL_BUILTINS && !includeGLSLBuiltins)
209 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +0300210 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
211 level--;
212 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700213 level--;
214 if (level == ESSL1_BUILTINS && shaderVersion != 100)
215 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000216
217 TSymbol *symbol = table[level]->find(name);
218
219 if (symbol)
220 return symbol;
221 }
222
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300223 return nullptr;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000224}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400225
226TSymbolTable::~TSymbolTable()
227{
228 while (table.size() > 0)
229 pop();
230}
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700231
Kai Ninomiya030017a2017-12-06 14:06:53 -0800232constexpr bool IsGenType(const TType *type)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500233{
234 if (type)
235 {
236 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500237 return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType ||
238 basicType == EbtGenBType;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500239 }
240
241 return false;
242}
243
Kai Ninomiya030017a2017-12-06 14:06:53 -0800244constexpr bool IsVecType(const TType *type)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500245{
246 if (type)
247 {
248 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500249 return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec ||
250 basicType == EbtBVec;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500251 }
252
253 return false;
254}
255
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800256constexpr const TType *SpecificType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500257{
258 ASSERT(size >= 1 && size <= 4);
259
260 if (!type)
261 {
262 return nullptr;
263 }
264
265 ASSERT(!IsVecType(type));
266
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500267 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500268 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500269 case EbtGenType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800270 return StaticType::GetForVec<EbtFloat>(type->getQualifier(),
271 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500272 case EbtGenIType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800273 return StaticType::GetForVec<EbtInt>(type->getQualifier(),
274 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500275 case EbtGenUType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800276 return StaticType::GetForVec<EbtUInt>(type->getQualifier(),
277 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500278 case EbtGenBType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800279 return StaticType::GetForVec<EbtBool>(type->getQualifier(),
280 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500281 default:
282 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500283 }
284}
285
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800286constexpr const TType *VectorType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500287{
288 ASSERT(size >= 2 && size <= 4);
289
290 if (!type)
291 {
292 return nullptr;
293 }
294
295 ASSERT(!IsGenType(type));
296
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500297 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500298 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500299 case EbtVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800300 return StaticType::GetForVecMat<EbtFloat>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500301 case EbtIVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800302 return StaticType::GetForVecMat<EbtInt>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500303 case EbtUVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800304 return StaticType::GetForVecMat<EbtUInt>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500305 case EbtBVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800306 return StaticType::GetForVecMat<EbtBool>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500307 default:
308 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500309 }
310}
311
Olli Etuaho195be942017-12-04 23:40:14 +0200312bool TSymbolTable::declareVariable(TVariable *variable)
Olli Etuaho0f684632017-07-13 12:42:15 +0300313{
Olli Etuaho195be942017-12-04 23:40:14 +0200314 ASSERT(variable->symbolType() == SymbolType::UserDefined);
315 return insertVariable(currentLevel(), variable);
Olli Etuaho0f684632017-07-13 12:42:15 +0300316}
317
Olli Etuaho035419f2017-11-28 14:27:15 +0200318bool TSymbolTable::declareStructType(TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300319{
320 return insertStructType(currentLevel(), str);
321}
322
Olli Etuaho378c3a52017-12-04 11:32:13 +0200323bool TSymbolTable::declareInterfaceBlock(TInterfaceBlock *interfaceBlock)
Olli Etuaho0f684632017-07-13 12:42:15 +0300324{
Olli Etuaho378c3a52017-12-04 11:32:13 +0200325 return insert(currentLevel(), interfaceBlock);
Jiawei Shaod8105a02017-08-08 09:54:36 +0800326}
327
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200328void TSymbolTable::declareUserDefinedFunction(TFunction *function, bool insertUnmangledName)
329{
330 ASSERT(currentLevel() >= GLOBAL_LEVEL);
331 if (insertUnmangledName)
332 {
333 // Insert the unmangled name to detect potential future redefinition as a variable.
334 table[GLOBAL_LEVEL]->insertUnmangled(function);
335 }
336 table[GLOBAL_LEVEL]->insert(function);
337}
338
Olli Etuahob60d30f2018-01-16 12:31:06 +0200339TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType *type)
Olli Etuaho0f684632017-07-13 12:42:15 +0300340{
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100341 ASSERT(level <= LAST_BUILTIN_LEVEL);
Olli Etuahob60d30f2018-01-16 12:31:06 +0200342 ASSERT(type->isRealized());
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100343 return insertVariable(level, NewPoolTString(name), type, SymbolType::BuiltIn);
Olli Etuaho0f684632017-07-13 12:42:15 +0300344}
345
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100346TVariable *TSymbolTable::insertVariable(ESymbolLevel level,
347 const TString *name,
Olli Etuahob60d30f2018-01-16 12:31:06 +0200348 const TType *type,
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100349 SymbolType symbolType)
Olli Etuaho0f684632017-07-13 12:42:15 +0300350{
Olli Etuahob60d30f2018-01-16 12:31:06 +0200351 ASSERT(level > LAST_BUILTIN_LEVEL || type->isRealized());
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100352 TVariable *var = new TVariable(this, name, type, symbolType);
Olli Etuaho0f684632017-07-13 12:42:15 +0300353 if (insert(level, var))
354 {
Olli Etuaho0f684632017-07-13 12:42:15 +0300355 return var;
356 }
357 return nullptr;
358}
359
360TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300361 TExtension ext,
Olli Etuaho0f684632017-07-13 12:42:15 +0300362 const char *name,
Olli Etuahob60d30f2018-01-16 12:31:06 +0200363 const TType *type)
Olli Etuaho0f684632017-07-13 12:42:15 +0300364{
Olli Etuahob60d30f2018-01-16 12:31:06 +0200365 ASSERT(level <= LAST_BUILTIN_LEVEL);
366 ASSERT(type->isRealized());
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100367 TVariable *var = new TVariable(this, NewPoolTString(name), type, SymbolType::BuiltIn, ext);
Olli Etuaho5d69db12017-11-24 16:51:15 +0200368 if (insert(level, var))
Olli Etuaho0f684632017-07-13 12:42:15 +0300369 {
Olli Etuaho0f684632017-07-13 12:42:15 +0300370 return var;
371 }
372 return nullptr;
373}
374
Olli Etuaho195be942017-12-04 23:40:14 +0200375bool TSymbolTable::insertVariable(ESymbolLevel level, TVariable *variable)
376{
377 ASSERT(variable);
Olli Etuahob60d30f2018-01-16 12:31:06 +0200378 ASSERT(level > LAST_BUILTIN_LEVEL || variable->getType().isRealized());
Olli Etuaho195be942017-12-04 23:40:14 +0200379 return insert(level, variable);
380}
381
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200382bool TSymbolTable::insert(ESymbolLevel level, TSymbol *symbol)
383{
384 ASSERT(level > LAST_BUILTIN_LEVEL || mUserDefinedUniqueIdsStart == -1);
385 return table[level]->insert(symbol);
386}
387
Olli Etuaho035419f2017-11-28 14:27:15 +0200388bool TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300389{
Olli Etuaho035419f2017-11-28 14:27:15 +0200390 ASSERT(str);
Olli Etuaho378c3a52017-12-04 11:32:13 +0200391 return insert(level, str);
392}
393
394bool TSymbolTable::insertInterfaceBlock(ESymbolLevel level, TInterfaceBlock *interfaceBlock)
395{
396 ASSERT(interfaceBlock);
397 return insert(level, interfaceBlock);
Olli Etuaho0f684632017-07-13 12:42:15 +0300398}
399
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500400void TSymbolTable::insertBuiltIn(ESymbolLevel level,
401 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300402 TExtension ext,
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500403 const TType *rvalue,
404 const char *name,
405 const TType *ptype1,
406 const TType *ptype2,
407 const TType *ptype3,
408 const TType *ptype4,
409 const TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700410{
411 if (ptype1->getBasicType() == EbtGSampler2D)
412 {
Martin Radevda6254b2016-12-14 17:00:36 +0200413 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700414 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800415 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
416 StaticType::GetBasic<EbtSampler2D>(), ptype2, ptype3, ptype4, ptype5);
417 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
418 StaticType::GetBasic<EbtISampler2D>(), ptype2, ptype3, ptype4, ptype5);
419 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
420 StaticType::GetBasic<EbtUSampler2D>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700421 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500422 else if (ptype1->getBasicType() == EbtGSampler3D)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700423 {
Martin Radevda6254b2016-12-14 17:00:36 +0200424 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700425 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800426 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
427 StaticType::GetBasic<EbtSampler3D>(), ptype2, ptype3, ptype4, ptype5);
428 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
429 StaticType::GetBasic<EbtISampler3D>(), ptype2, ptype3, ptype4, ptype5);
430 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
431 StaticType::GetBasic<EbtUSampler3D>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700432 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500433 else if (ptype1->getBasicType() == EbtGSamplerCube)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700434 {
Martin Radevda6254b2016-12-14 17:00:36 +0200435 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700436 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800437 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
438 StaticType::GetBasic<EbtSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
439 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
440 StaticType::GetBasic<EbtISamplerCube>(), ptype2, ptype3, ptype4, ptype5);
441 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
442 StaticType::GetBasic<EbtUSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700443 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500444 else if (ptype1->getBasicType() == EbtGSampler2DArray)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700445 {
Martin Radevda6254b2016-12-14 17:00:36 +0200446 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700447 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800448 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
449 StaticType::GetBasic<EbtSampler2DArray>(), ptype2, ptype3, ptype4,
450 ptype5);
451 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
452 StaticType::GetBasic<EbtISampler2DArray>(), ptype2, ptype3, ptype4,
453 ptype5);
454 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
455 StaticType::GetBasic<EbtUSampler2DArray>(), ptype2, ptype3, ptype4,
456 ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700457 }
JiangYizhou40219322016-12-09 09:50:51 +0800458 else if (ptype1->getBasicType() == EbtGSampler2DMS)
459 {
460 insertUnmangledBuiltInName(name, level);
461 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800462 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
463 StaticType::GetBasic<EbtSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
464 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
465 StaticType::GetBasic<EbtISampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
466 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
467 StaticType::GetBasic<EbtUSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
JiangYizhou40219322016-12-09 09:50:51 +0800468 }
Martin Radev2cc85b32016-08-05 16:22:53 +0300469 else if (IsGImage(ptype1->getBasicType()))
470 {
Martin Radevda6254b2016-12-14 17:00:36 +0200471 insertUnmangledBuiltInName(name, level);
Martin Radev2cc85b32016-08-05 16:22:53 +0300472
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800473 const TType *floatType = StaticType::GetBasic<EbtFloat, 4>();
474 const TType *intType = StaticType::GetBasic<EbtInt, 4>();
475 const TType *unsignedType = StaticType::GetBasic<EbtUInt, 4>();
Martin Radev2cc85b32016-08-05 16:22:53 +0300476
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800477 const TType *floatImage = StaticType::GetForFloatImage(ptype1->getBasicType());
478 const TType *intImage = StaticType::GetForIntImage(ptype1->getBasicType());
479 const TType *unsignedImage = StaticType::GetForUintImage(ptype1->getBasicType());
Martin Radev2cc85b32016-08-05 16:22:53 +0300480
481 // GLSL ES 3.10, Revision 4, 8.12 Image Functions
482 if (rvalue->getBasicType() == EbtGVec4)
483 {
484 // imageLoad
485 insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
486 insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
487 insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
488 }
489 else if (rvalue->getBasicType() == EbtVoid)
490 {
491 // imageStore
492 insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
493 insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
494 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
495 }
496 else
497 {
498 // imageSize
499 insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
500 insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
501 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
502 }
503 }
Olli Etuaho9250cb22017-01-21 10:51:27 +0000504 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3) ||
505 IsGenType(ptype4))
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500506 {
Olli Etuaho9250cb22017-01-21 10:51:27 +0000507 ASSERT(!ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200508 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500509 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000510 SpecificType(ptype2, 1), SpecificType(ptype3, 1), SpecificType(ptype4, 1));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500511 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000512 SpecificType(ptype2, 2), SpecificType(ptype3, 2), SpecificType(ptype4, 2));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500513 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000514 SpecificType(ptype2, 3), SpecificType(ptype3, 3), SpecificType(ptype4, 3));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500515 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000516 SpecificType(ptype2, 4), SpecificType(ptype3, 4), SpecificType(ptype4, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500517 }
518 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
519 {
520 ASSERT(!ptype4 && !ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200521 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500522 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2),
523 VectorType(ptype2, 2), VectorType(ptype3, 2));
524 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3),
525 VectorType(ptype2, 3), VectorType(ptype3, 3));
526 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4),
527 VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500528 }
529 else
530 {
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100531 TFunction *function =
Olli Etuaho0c371002017-12-13 17:00:25 +0400532 new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, false, op, ext);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700533
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700534 function->addParameter(TConstParameter(ptype1));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700535
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500536 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700537 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700538 function->addParameter(TConstParameter(ptype2));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700539 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700540
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500541 if (ptype3)
542 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700543 function->addParameter(TConstParameter(ptype3));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500544 }
545
546 if (ptype4)
547 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700548 function->addParameter(TConstParameter(ptype4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500549 }
550
551 if (ptype5)
552 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700553 function->addParameter(TConstParameter(ptype5));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500554 }
555
Martin Radevda6254b2016-12-14 17:00:36 +0200556 ASSERT(hasUnmangledBuiltInAtLevel(name, level));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500557 insert(level, function);
558 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700559}
560
Olli Etuaho492cfab2017-01-20 21:18:29 +0000561void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
562 TOperator op,
563 const TType *rvalue,
564 const TType *ptype1,
565 const TType *ptype2,
566 const TType *ptype3,
567 const TType *ptype4,
568 const TType *ptype5)
569{
570 const char *name = GetOperatorString(op);
571 ASSERT(strlen(name) > 0);
572 insertUnmangledBuiltInName(name, level);
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300573 insertBuiltIn(level, op, TExtension::UNDEFINED, rvalue, name, ptype1, ptype2, ptype3, ptype4,
574 ptype5);
Olli Etuaho492cfab2017-01-20 21:18:29 +0000575}
576
577void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
578 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300579 TExtension ext,
Olli Etuaho492cfab2017-01-20 21:18:29 +0000580 const TType *rvalue,
581 const TType *ptype1,
582 const TType *ptype2,
583 const TType *ptype3,
584 const TType *ptype4,
585 const TType *ptype5)
586{
587 const char *name = GetOperatorString(op);
588 insertUnmangledBuiltInName(name, level);
589 insertBuiltIn(level, op, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
590}
591
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300592void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
593 TOperator op,
594 const TType *rvalue,
595 const char *name)
596{
597 insertUnmangledBuiltInName(name, level);
Olli Etuaho0c371002017-12-13 17:00:25 +0400598 insert(level,
599 new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, false, op));
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300600}
601
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800602void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300603 TExtension ext,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800604 TOperator op,
605 const TType *rvalue,
606 const char *name)
607{
608 insertUnmangledBuiltInName(name, level);
Olli Etuaho0c371002017-12-13 17:00:25 +0400609 insert(level,
610 new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, false, op, ext));
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800611}
612
Zhenyao Moe740add2014-07-18 17:01:01 -0700613TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700614{
615 if (!SupportsPrecision(type))
616 return EbpUndefined;
617
618 // unsigned integers use the same precision as signed
619 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
620
621 int level = static_cast<int>(precisionStack.size()) - 1;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500622 assert(level >= 0); // Just to be safe. Should not happen.
Olli Etuaho183d7e22015-11-20 15:59:09 +0200623 // If we dont find anything we return this. Some types don't have predefined default precision.
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700624 TPrecision prec = EbpUndefined;
625 while (level >= 0)
626 {
627 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
628 if (it != precisionStack[level]->end())
629 {
630 prec = (*it).second;
631 break;
632 }
633 level--;
634 }
635 return prec;
636}
Jamie Madill45bcc782016-11-07 13:58:48 -0500637
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200638void TSymbolTable::addInvariantVarying(const std::string &originalName)
639{
640 ASSERT(atGlobalLevel());
641 table[currentLevel()]->addInvariantVarying(originalName);
642}
643
644bool TSymbolTable::isVaryingInvariant(const std::string &originalName) const
645{
646 ASSERT(atGlobalLevel());
647 return table[currentLevel()]->isVaryingInvariant(originalName);
648}
649
650void TSymbolTable::setGlobalInvariant(bool invariant)
651{
652 ASSERT(atGlobalLevel());
653 table[currentLevel()]->setGlobalInvariant(invariant);
654}
655
Martin Radevda6254b2016-12-14 17:00:36 +0200656void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
657{
658 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
Olli Etuaho5d69db12017-11-24 16:51:15 +0200659 ASSERT(mUserDefinedUniqueIdsStart == -1);
Olli Etuaho342b83d2018-01-10 13:24:01 +0200660 table[level]->insertUnmangledBuiltInName(name);
Martin Radevda6254b2016-12-14 17:00:36 +0200661}
662
663bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level)
664{
665 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
Olli Etuaho342b83d2018-01-10 13:24:01 +0200666 return table[level]->hasUnmangledBuiltIn(name);
Martin Radevda6254b2016-12-14 17:00:36 +0200667}
668
669bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion)
670{
671 ASSERT(static_cast<ESymbolLevel>(table.size()) > LAST_BUILTIN_LEVEL);
672
673 for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
674 {
675 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
676 {
677 --level;
678 }
679 if (level == ESSL3_BUILTINS && shaderVersion < 300)
680 {
681 --level;
682 }
683 if (level == ESSL1_BUILTINS && shaderVersion != 100)
684 {
685 --level;
686 }
687
688 if (table[level]->hasUnmangledBuiltIn(name))
689 {
690 return true;
691 }
692 }
693 return false;
694}
695
Olli Etuaho5d69db12017-11-24 16:51:15 +0200696void TSymbolTable::markBuiltInInitializationFinished()
697{
698 mUserDefinedUniqueIdsStart = mUniqueIdCounter;
699}
700
701void TSymbolTable::clearCompilationResults()
702{
703 mUniqueIdCounter = mUserDefinedUniqueIdsStart;
704
705 // User-defined scopes should have already been cleared when the compilation finished.
706 ASSERT(table.size() == LAST_BUILTIN_LEVEL + 1u);
707}
708
709int TSymbolTable::nextUniqueIdValue()
710{
711 ASSERT(mUniqueIdCounter < std::numeric_limits<int>::max());
712 return ++mUniqueIdCounter;
713}
714
Jamie Madill45bcc782016-11-07 13:58:48 -0500715} // namespace sh