blob: f183edb22a6ebb970787287db0c5f2d15e692d31 [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 Etuaho2d8e4322018-01-22 14:12:46 +020016#include "compiler/translator/ImmutableString.h"
Olli Etuaho01d0ad02017-01-22 14:51:23 -080017#include "compiler/translator/IntermNode.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
Olli Etuahodd21ecf2018-01-10 12:42:09 +020025class TSymbolTable::TSymbolTableLevel
26{
27 public:
28 TSymbolTableLevel() : mGlobalInvariant(false) {}
Olli Etuahodd21ecf2018-01-10 12:42:09 +020029
30 bool insert(TSymbol *symbol);
31
32 // Insert a function using its unmangled name as the key.
33 bool insertUnmangled(TFunction *function);
34
Olli Etuahofbb1c792018-01-19 16:26:59 +020035 TSymbol *find(const ImmutableString &name) const;
Olli Etuahodd21ecf2018-01-10 12:42:09 +020036
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:
Olli Etuahofbb1c792018-01-19 16:26:59 +020050 using tLevel = TUnorderedMap<ImmutableString,
51 TSymbol *,
52 ImmutableString::FowlerNollVoHash<sizeof(size_t)>>;
Olli Etuahodd21ecf2018-01-10 12:42:09 +020053 using tLevelPair = const tLevel::value_type;
54 using tInsertResult = std::pair<tLevel::iterator, bool>;
55
56 tLevel level;
57 std::set<std::string> mInvariantVaryings;
58 bool mGlobalInvariant;
59
Olli Etuaho2d8e4322018-01-22 14:12:46 +020060 std::set<ImmutableString> mUnmangledBuiltInNames;
Olli Etuahodd21ecf2018-01-10 12:42:09 +020061};
62
Olli Etuahodd21ecf2018-01-10 12:42:09 +020063bool TSymbolTable::TSymbolTableLevel::insert(TSymbol *symbol)
Jamie Madillbfa91f42014-06-05 15:45:18 -040064{
Jamie Madillbfa91f42014-06-05 15:45:18 -040065 // returning true means symbol was added to the table
Nicolas Capensadfffe42014-06-17 02:13:36 -040066 tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
Jamie Madillbfa91f42014-06-05 15:45:18 -040067
68 return result.second;
69}
70
Olli Etuahodd21ecf2018-01-10 12:42:09 +020071bool TSymbolTable::TSymbolTableLevel::insertUnmangled(TFunction *function)
Olli Etuahob2983c92015-03-18 14:02:46 +020072{
Olli Etuahob2983c92015-03-18 14:02:46 +020073 // returning true means symbol was added to the table
Olli Etuahobed35d72017-12-20 16:36:26 +020074 tInsertResult result = level.insert(tLevelPair(function->name(), function));
Olli Etuahob2983c92015-03-18 14:02:46 +020075
76 return result.second;
77}
78
Olli Etuahofbb1c792018-01-19 16:26:59 +020079TSymbol *TSymbolTable::TSymbolTableLevel::find(const ImmutableString &name) const
Jamie Madillbfa91f42014-06-05 15:45:18 -040080{
81 tLevel::const_iterator it = level.find(name);
82 if (it == level.end())
83 return 0;
84 else
85 return (*it).second;
86}
87
Olli Etuahodd21ecf2018-01-10 12:42:09 +020088void TSymbolTable::TSymbolTableLevel::insertUnmangledBuiltInName(const char *name)
Olli Etuaho342b83d2018-01-10 13:24:01 +020089{
Olli Etuaho2d8e4322018-01-22 14:12:46 +020090 mUnmangledBuiltInNames.insert(ImmutableString(name));
Olli Etuaho342b83d2018-01-10 13:24:01 +020091}
92
Olli Etuahodd21ecf2018-01-10 12:42:09 +020093bool TSymbolTable::TSymbolTableLevel::hasUnmangledBuiltIn(const char *name) const
Olli Etuaho342b83d2018-01-10 13:24:01 +020094{
Olli Etuaho2d8e4322018-01-22 14:12:46 +020095 return mUnmangledBuiltInNames.count(ImmutableString(name)) > 0;
Olli Etuaho342b83d2018-01-10 13:24:01 +020096}
97
Olli Etuahodd21ecf2018-01-10 12:42:09 +020098void TSymbolTable::push()
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000099{
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200100 table.push_back(new TSymbolTableLevel);
101 precisionStack.push_back(new PrecisionStackLevel);
102}
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000103
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200104void TSymbolTable::pop()
105{
106 delete table.back();
107 table.pop_back();
108
109 delete precisionStack.back();
110 precisionStack.pop_back();
111}
112
113const TFunction *TSymbolTable::markUserDefinedFunctionHasPrototypeDeclaration(
Olli Etuahofbb1c792018-01-19 16:26:59 +0200114 const ImmutableString &mangledName,
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200115 bool *hadPrototypeDeclarationOut)
116{
117 TFunction *function = findUserDefinedFunction(mangledName);
118 *hadPrototypeDeclarationOut = function->hasPrototypeDeclaration();
119 function->setHasPrototypeDeclaration();
120 return function;
121}
122
123const TFunction *TSymbolTable::setUserDefinedFunctionParameterNamesFromDefinition(
124 const TFunction *function,
125 bool *wasDefinedOut)
126{
127 TFunction *firstDeclaration = findUserDefinedFunction(function->getMangledName());
128 ASSERT(firstDeclaration);
129 // Note: 'firstDeclaration' could be 'function' if this is the first time we've seen function as
130 // it would have just been put in the symbol table. Otherwise, we're looking up an earlier
131 // occurance.
132 if (function != firstDeclaration)
133 {
134 // Swap the parameters of the previous declaration to the parameters of the function
135 // definition (parameter names may differ).
136 firstDeclaration->swapParameters(*function);
137 }
138
139 *wasDefinedOut = firstDeclaration->isDefined();
140 firstDeclaration->setDefined();
141 return firstDeclaration;
142}
143
Olli Etuahofbb1c792018-01-19 16:26:59 +0200144const TSymbol *TSymbolTable::find(const ImmutableString &name, int shaderVersion) const
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200145{
146 int level = currentLevel();
147 TSymbol *symbol = nullptr;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000148 do
149 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300150 if (level == GLSL_BUILTINS)
151 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +0300152 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
153 level--;
154 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700155 level--;
156 if (level == ESSL1_BUILTINS && shaderVersion != 100)
157 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000158
159 symbol = table[level]->find(name);
Olli Etuaho37b697e2018-01-29 12:19:27 +0200160 level--;
161 } while (symbol == nullptr && level >= 0);
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000162
163 return symbol;
164}
165
Olli Etuahofbb1c792018-01-19 16:26:59 +0200166TFunction *TSymbolTable::findUserDefinedFunction(const ImmutableString &name) const
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200167{
168 // User-defined functions are always declared at the global level.
169 ASSERT(currentLevel() >= GLOBAL_LEVEL);
170 return static_cast<TFunction *>(table[GLOBAL_LEVEL]->find(name));
171}
172
Olli Etuahofbb1c792018-01-19 16:26:59 +0200173const TSymbol *TSymbolTable::findGlobal(const ImmutableString &name) const
Zhenyao Mod7490962016-11-09 15:49:51 -0800174{
175 ASSERT(table.size() > GLOBAL_LEVEL);
176 return table[GLOBAL_LEVEL]->find(name);
177}
178
Olli Etuahofbb1c792018-01-19 16:26:59 +0200179const TSymbol *TSymbolTable::findBuiltIn(const ImmutableString &name, int shaderVersion) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000180{
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300181 return findBuiltIn(name, shaderVersion, false);
182}
183
Olli Etuahofbb1c792018-01-19 16:26:59 +0200184const TSymbol *TSymbolTable::findBuiltIn(const ImmutableString &name,
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200185 int shaderVersion,
186 bool includeGLSLBuiltins) const
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300187{
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000188 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
189 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300190 if (level == GLSL_BUILTINS && !includeGLSLBuiltins)
191 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +0300192 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
193 level--;
194 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700195 level--;
196 if (level == ESSL1_BUILTINS && shaderVersion != 100)
197 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000198
199 TSymbol *symbol = table[level]->find(name);
200
201 if (symbol)
202 return symbol;
203 }
204
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300205 return nullptr;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000206}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400207
208TSymbolTable::~TSymbolTable()
209{
210 while (table.size() > 0)
211 pop();
212}
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700213
Kai Ninomiya030017a2017-12-06 14:06:53 -0800214constexpr bool IsGenType(const TType *type)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500215{
216 if (type)
217 {
218 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500219 return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType ||
220 basicType == EbtGenBType;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500221 }
222
223 return false;
224}
225
Kai Ninomiya030017a2017-12-06 14:06:53 -0800226constexpr bool IsVecType(const TType *type)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500227{
228 if (type)
229 {
230 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500231 return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec ||
232 basicType == EbtBVec;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500233 }
234
235 return false;
236}
237
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800238constexpr const TType *SpecificType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500239{
240 ASSERT(size >= 1 && size <= 4);
241
242 if (!type)
243 {
244 return nullptr;
245 }
246
247 ASSERT(!IsVecType(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 EbtGenType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800252 return StaticType::GetForVec<EbtFloat>(type->getQualifier(),
253 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500254 case EbtGenIType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800255 return StaticType::GetForVec<EbtInt>(type->getQualifier(),
256 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500257 case EbtGenUType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800258 return StaticType::GetForVec<EbtUInt>(type->getQualifier(),
259 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500260 case EbtGenBType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800261 return StaticType::GetForVec<EbtBool>(type->getQualifier(),
262 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500263 default:
264 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500265 }
266}
267
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800268constexpr const TType *VectorType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500269{
270 ASSERT(size >= 2 && size <= 4);
271
272 if (!type)
273 {
274 return nullptr;
275 }
276
277 ASSERT(!IsGenType(type));
278
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500279 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500280 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500281 case EbtVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800282 return StaticType::GetForVecMat<EbtFloat>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500283 case EbtIVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800284 return StaticType::GetForVecMat<EbtInt>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500285 case EbtUVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800286 return StaticType::GetForVecMat<EbtUInt>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500287 case EbtBVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800288 return StaticType::GetForVecMat<EbtBool>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500289 default:
290 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500291 }
292}
293
Olli Etuaho195be942017-12-04 23:40:14 +0200294bool TSymbolTable::declareVariable(TVariable *variable)
Olli Etuaho0f684632017-07-13 12:42:15 +0300295{
Olli Etuaho195be942017-12-04 23:40:14 +0200296 ASSERT(variable->symbolType() == SymbolType::UserDefined);
297 return insertVariable(currentLevel(), variable);
Olli Etuaho0f684632017-07-13 12:42:15 +0300298}
299
Olli Etuaho035419f2017-11-28 14:27:15 +0200300bool TSymbolTable::declareStructType(TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300301{
302 return insertStructType(currentLevel(), str);
303}
304
Olli Etuaho378c3a52017-12-04 11:32:13 +0200305bool TSymbolTable::declareInterfaceBlock(TInterfaceBlock *interfaceBlock)
Olli Etuaho0f684632017-07-13 12:42:15 +0300306{
Olli Etuaho378c3a52017-12-04 11:32:13 +0200307 return insert(currentLevel(), interfaceBlock);
Jiawei Shaod8105a02017-08-08 09:54:36 +0800308}
309
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200310void TSymbolTable::declareUserDefinedFunction(TFunction *function, bool insertUnmangledName)
311{
312 ASSERT(currentLevel() >= GLOBAL_LEVEL);
313 if (insertUnmangledName)
314 {
315 // Insert the unmangled name to detect potential future redefinition as a variable.
316 table[GLOBAL_LEVEL]->insertUnmangled(function);
317 }
318 table[GLOBAL_LEVEL]->insert(function);
319}
320
Olli Etuahofbb1c792018-01-19 16:26:59 +0200321TVariable *TSymbolTable::insertVariable(ESymbolLevel level,
322 const ImmutableString &name,
323 const TType *type)
Olli Etuaho0f684632017-07-13 12:42:15 +0300324{
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100325 ASSERT(level <= LAST_BUILTIN_LEVEL);
Olli Etuahob60d30f2018-01-16 12:31:06 +0200326 ASSERT(type->isRealized());
Olli Etuahofbb1c792018-01-19 16:26:59 +0200327 return insertVariable(level, name, type, SymbolType::BuiltIn);
Olli Etuaho0f684632017-07-13 12:42:15 +0300328}
329
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100330TVariable *TSymbolTable::insertVariable(ESymbolLevel level,
Olli Etuahofbb1c792018-01-19 16:26:59 +0200331 const ImmutableString &name,
Olli Etuahob60d30f2018-01-16 12:31:06 +0200332 const TType *type,
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100333 SymbolType symbolType)
Olli Etuaho0f684632017-07-13 12:42:15 +0300334{
Olli Etuahob60d30f2018-01-16 12:31:06 +0200335 ASSERT(level > LAST_BUILTIN_LEVEL || type->isRealized());
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100336 TVariable *var = new TVariable(this, name, type, symbolType);
Olli Etuaho0f684632017-07-13 12:42:15 +0300337 if (insert(level, var))
338 {
Olli Etuaho0f684632017-07-13 12:42:15 +0300339 return var;
340 }
341 return nullptr;
342}
343
344TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300345 TExtension ext,
Olli Etuahofbb1c792018-01-19 16:26:59 +0200346 const ImmutableString &name,
Olli Etuahob60d30f2018-01-16 12:31:06 +0200347 const TType *type)
Olli Etuaho0f684632017-07-13 12:42:15 +0300348{
Olli Etuahob60d30f2018-01-16 12:31:06 +0200349 ASSERT(level <= LAST_BUILTIN_LEVEL);
350 ASSERT(type->isRealized());
Olli Etuahofbb1c792018-01-19 16:26:59 +0200351 TVariable *var = new TVariable(this, name, type, SymbolType::BuiltIn, ext);
Olli Etuaho5d69db12017-11-24 16:51:15 +0200352 if (insert(level, var))
Olli Etuaho0f684632017-07-13 12:42:15 +0300353 {
Olli Etuaho0f684632017-07-13 12:42:15 +0300354 return var;
355 }
356 return nullptr;
357}
358
Olli Etuaho195be942017-12-04 23:40:14 +0200359bool TSymbolTable::insertVariable(ESymbolLevel level, TVariable *variable)
360{
361 ASSERT(variable);
Olli Etuahob60d30f2018-01-16 12:31:06 +0200362 ASSERT(level > LAST_BUILTIN_LEVEL || variable->getType().isRealized());
Olli Etuaho195be942017-12-04 23:40:14 +0200363 return insert(level, variable);
364}
365
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200366bool TSymbolTable::insert(ESymbolLevel level, TSymbol *symbol)
367{
368 ASSERT(level > LAST_BUILTIN_LEVEL || mUserDefinedUniqueIdsStart == -1);
369 return table[level]->insert(symbol);
370}
371
Olli Etuaho035419f2017-11-28 14:27:15 +0200372bool TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300373{
Olli Etuaho035419f2017-11-28 14:27:15 +0200374 ASSERT(str);
Olli Etuaho378c3a52017-12-04 11:32:13 +0200375 return insert(level, str);
376}
377
378bool TSymbolTable::insertInterfaceBlock(ESymbolLevel level, TInterfaceBlock *interfaceBlock)
379{
380 ASSERT(interfaceBlock);
381 return insert(level, interfaceBlock);
Olli Etuaho0f684632017-07-13 12:42:15 +0300382}
383
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500384void TSymbolTable::insertBuiltIn(ESymbolLevel level,
385 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300386 TExtension ext,
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500387 const TType *rvalue,
388 const char *name,
389 const TType *ptype1,
390 const TType *ptype2,
391 const TType *ptype3,
392 const TType *ptype4,
393 const TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700394{
395 if (ptype1->getBasicType() == EbtGSampler2D)
396 {
Martin Radevda6254b2016-12-14 17:00:36 +0200397 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700398 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800399 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
400 StaticType::GetBasic<EbtSampler2D>(), ptype2, ptype3, ptype4, ptype5);
401 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
402 StaticType::GetBasic<EbtISampler2D>(), ptype2, ptype3, ptype4, ptype5);
403 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
404 StaticType::GetBasic<EbtUSampler2D>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700405 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500406 else if (ptype1->getBasicType() == EbtGSampler3D)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700407 {
Martin Radevda6254b2016-12-14 17:00:36 +0200408 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700409 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800410 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
411 StaticType::GetBasic<EbtSampler3D>(), ptype2, ptype3, ptype4, ptype5);
412 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
413 StaticType::GetBasic<EbtISampler3D>(), ptype2, ptype3, ptype4, ptype5);
414 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
415 StaticType::GetBasic<EbtUSampler3D>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700416 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500417 else if (ptype1->getBasicType() == EbtGSamplerCube)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700418 {
Martin Radevda6254b2016-12-14 17:00:36 +0200419 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700420 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800421 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
422 StaticType::GetBasic<EbtSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
423 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
424 StaticType::GetBasic<EbtISamplerCube>(), ptype2, ptype3, ptype4, ptype5);
425 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
426 StaticType::GetBasic<EbtUSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700427 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500428 else if (ptype1->getBasicType() == EbtGSampler2DArray)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700429 {
Martin Radevda6254b2016-12-14 17:00:36 +0200430 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700431 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800432 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
433 StaticType::GetBasic<EbtSampler2DArray>(), ptype2, ptype3, ptype4,
434 ptype5);
435 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
436 StaticType::GetBasic<EbtISampler2DArray>(), ptype2, ptype3, ptype4,
437 ptype5);
438 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
439 StaticType::GetBasic<EbtUSampler2DArray>(), ptype2, ptype3, ptype4,
440 ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700441 }
JiangYizhou40219322016-12-09 09:50:51 +0800442 else if (ptype1->getBasicType() == EbtGSampler2DMS)
443 {
444 insertUnmangledBuiltInName(name, level);
445 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800446 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
447 StaticType::GetBasic<EbtSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
448 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
449 StaticType::GetBasic<EbtISampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
450 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
451 StaticType::GetBasic<EbtUSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
JiangYizhou40219322016-12-09 09:50:51 +0800452 }
Martin Radev2cc85b32016-08-05 16:22:53 +0300453 else if (IsGImage(ptype1->getBasicType()))
454 {
Martin Radevda6254b2016-12-14 17:00:36 +0200455 insertUnmangledBuiltInName(name, level);
Martin Radev2cc85b32016-08-05 16:22:53 +0300456
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800457 const TType *floatType = StaticType::GetBasic<EbtFloat, 4>();
458 const TType *intType = StaticType::GetBasic<EbtInt, 4>();
459 const TType *unsignedType = StaticType::GetBasic<EbtUInt, 4>();
Martin Radev2cc85b32016-08-05 16:22:53 +0300460
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800461 const TType *floatImage = StaticType::GetForFloatImage(ptype1->getBasicType());
462 const TType *intImage = StaticType::GetForIntImage(ptype1->getBasicType());
463 const TType *unsignedImage = StaticType::GetForUintImage(ptype1->getBasicType());
Martin Radev2cc85b32016-08-05 16:22:53 +0300464
465 // GLSL ES 3.10, Revision 4, 8.12 Image Functions
466 if (rvalue->getBasicType() == EbtGVec4)
467 {
468 // imageLoad
469 insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
470 insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
471 insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
472 }
473 else if (rvalue->getBasicType() == EbtVoid)
474 {
475 // imageStore
476 insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
477 insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
478 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
479 }
480 else
481 {
482 // imageSize
483 insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
484 insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
485 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
486 }
487 }
Olli Etuaho9250cb22017-01-21 10:51:27 +0000488 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3) ||
489 IsGenType(ptype4))
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500490 {
Olli Etuaho9250cb22017-01-21 10:51:27 +0000491 ASSERT(!ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200492 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500493 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000494 SpecificType(ptype2, 1), SpecificType(ptype3, 1), SpecificType(ptype4, 1));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500495 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000496 SpecificType(ptype2, 2), SpecificType(ptype3, 2), SpecificType(ptype4, 2));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500497 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000498 SpecificType(ptype2, 3), SpecificType(ptype3, 3), SpecificType(ptype4, 3));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500499 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000500 SpecificType(ptype2, 4), SpecificType(ptype3, 4), SpecificType(ptype4, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500501 }
502 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
503 {
504 ASSERT(!ptype4 && !ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200505 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500506 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2),
507 VectorType(ptype2, 2), VectorType(ptype3, 2));
508 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3),
509 VectorType(ptype2, 3), VectorType(ptype3, 3));
510 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4),
511 VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500512 }
513 else
514 {
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100515 TFunction *function =
Olli Etuahofbb1c792018-01-19 16:26:59 +0200516 new TFunction(this, ImmutableString(name), rvalue, SymbolType::BuiltIn, false, op, ext);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700517
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700518 function->addParameter(TConstParameter(ptype1));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700519
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500520 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700521 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700522 function->addParameter(TConstParameter(ptype2));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700523 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700524
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500525 if (ptype3)
526 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700527 function->addParameter(TConstParameter(ptype3));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500528 }
529
530 if (ptype4)
531 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700532 function->addParameter(TConstParameter(ptype4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500533 }
534
535 if (ptype5)
536 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700537 function->addParameter(TConstParameter(ptype5));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500538 }
539
Martin Radevda6254b2016-12-14 17:00:36 +0200540 ASSERT(hasUnmangledBuiltInAtLevel(name, level));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500541 insert(level, function);
542 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700543}
544
Olli Etuaho492cfab2017-01-20 21:18:29 +0000545void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
546 TOperator op,
547 const TType *rvalue,
548 const TType *ptype1,
549 const TType *ptype2,
550 const TType *ptype3,
551 const TType *ptype4,
552 const TType *ptype5)
553{
554 const char *name = GetOperatorString(op);
555 ASSERT(strlen(name) > 0);
556 insertUnmangledBuiltInName(name, level);
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300557 insertBuiltIn(level, op, TExtension::UNDEFINED, rvalue, name, ptype1, ptype2, ptype3, ptype4,
558 ptype5);
Olli Etuaho492cfab2017-01-20 21:18:29 +0000559}
560
561void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
562 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300563 TExtension ext,
Olli Etuaho492cfab2017-01-20 21:18:29 +0000564 const TType *rvalue,
565 const TType *ptype1,
566 const TType *ptype2,
567 const TType *ptype3,
568 const TType *ptype4,
569 const TType *ptype5)
570{
571 const char *name = GetOperatorString(op);
572 insertUnmangledBuiltInName(name, level);
573 insertBuiltIn(level, op, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
574}
575
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300576void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
577 TOperator op,
578 const TType *rvalue,
579 const char *name)
580{
581 insertUnmangledBuiltInName(name, level);
Olli Etuaho0c371002017-12-13 17:00:25 +0400582 insert(level,
Olli Etuahofbb1c792018-01-19 16:26:59 +0200583 new TFunction(this, ImmutableString(name), rvalue, SymbolType::BuiltIn, false, op));
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300584}
585
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800586void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300587 TExtension ext,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800588 TOperator op,
589 const TType *rvalue,
590 const char *name)
591{
592 insertUnmangledBuiltInName(name, level);
Olli Etuaho0c371002017-12-13 17:00:25 +0400593 insert(level,
Olli Etuahofbb1c792018-01-19 16:26:59 +0200594 new TFunction(this, ImmutableString(name), rvalue, SymbolType::BuiltIn, false, op, ext));
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800595}
596
Zhenyao Moe740add2014-07-18 17:01:01 -0700597TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700598{
599 if (!SupportsPrecision(type))
600 return EbpUndefined;
601
602 // unsigned integers use the same precision as signed
603 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
604
605 int level = static_cast<int>(precisionStack.size()) - 1;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500606 assert(level >= 0); // Just to be safe. Should not happen.
Olli Etuaho183d7e22015-11-20 15:59:09 +0200607 // If we dont find anything we return this. Some types don't have predefined default precision.
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700608 TPrecision prec = EbpUndefined;
609 while (level >= 0)
610 {
611 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
612 if (it != precisionStack[level]->end())
613 {
614 prec = (*it).second;
615 break;
616 }
617 level--;
618 }
619 return prec;
620}
Jamie Madill45bcc782016-11-07 13:58:48 -0500621
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200622void TSymbolTable::addInvariantVarying(const std::string &originalName)
623{
624 ASSERT(atGlobalLevel());
625 table[currentLevel()]->addInvariantVarying(originalName);
626}
627
628bool TSymbolTable::isVaryingInvariant(const std::string &originalName) const
629{
630 ASSERT(atGlobalLevel());
631 return table[currentLevel()]->isVaryingInvariant(originalName);
632}
633
634void TSymbolTable::setGlobalInvariant(bool invariant)
635{
636 ASSERT(atGlobalLevel());
637 table[currentLevel()]->setGlobalInvariant(invariant);
638}
639
Martin Radevda6254b2016-12-14 17:00:36 +0200640void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
641{
642 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
Olli Etuaho5d69db12017-11-24 16:51:15 +0200643 ASSERT(mUserDefinedUniqueIdsStart == -1);
Olli Etuaho342b83d2018-01-10 13:24:01 +0200644 table[level]->insertUnmangledBuiltInName(name);
Martin Radevda6254b2016-12-14 17:00:36 +0200645}
646
647bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level)
648{
649 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
Olli Etuaho342b83d2018-01-10 13:24:01 +0200650 return table[level]->hasUnmangledBuiltIn(name);
Martin Radevda6254b2016-12-14 17:00:36 +0200651}
652
653bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion)
654{
655 ASSERT(static_cast<ESymbolLevel>(table.size()) > LAST_BUILTIN_LEVEL);
656
657 for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
658 {
659 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
660 {
661 --level;
662 }
663 if (level == ESSL3_BUILTINS && shaderVersion < 300)
664 {
665 --level;
666 }
667 if (level == ESSL1_BUILTINS && shaderVersion != 100)
668 {
669 --level;
670 }
671
672 if (table[level]->hasUnmangledBuiltIn(name))
673 {
674 return true;
675 }
676 }
677 return false;
678}
679
Olli Etuaho5d69db12017-11-24 16:51:15 +0200680void TSymbolTable::markBuiltInInitializationFinished()
681{
682 mUserDefinedUniqueIdsStart = mUniqueIdCounter;
683}
684
685void TSymbolTable::clearCompilationResults()
686{
687 mUniqueIdCounter = mUserDefinedUniqueIdsStart;
688
689 // User-defined scopes should have already been cleared when the compilation finished.
690 ASSERT(table.size() == LAST_BUILTIN_LEVEL + 1u);
691}
692
693int TSymbolTable::nextUniqueIdValue()
694{
695 ASSERT(mUniqueIdCounter < std::numeric_limits<int>::max());
696 return ++mUniqueIdCounter;
697}
698
Jamie Madill45bcc782016-11-07 13:58:48 -0500699} // namespace sh