blob: 4bc29a45c63389a06cc4bf82b13efb0a43ca5359 [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
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
Olli Etuaho2d8e4322018-01-22 14:12:46 +020058 std::set<ImmutableString> mUnmangledBuiltInNames;
Olli Etuahodd21ecf2018-01-10 12:42:09 +020059};
60
Olli Etuahodd21ecf2018-01-10 12:42:09 +020061bool TSymbolTable::TSymbolTableLevel::insert(TSymbol *symbol)
Jamie Madillbfa91f42014-06-05 15:45:18 -040062{
Jamie Madillbfa91f42014-06-05 15:45:18 -040063 // returning true means symbol was added to the table
Nicolas Capensadfffe42014-06-17 02:13:36 -040064 tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
Jamie Madillbfa91f42014-06-05 15:45:18 -040065
66 return result.second;
67}
68
Olli Etuahodd21ecf2018-01-10 12:42:09 +020069bool TSymbolTable::TSymbolTableLevel::insertUnmangled(TFunction *function)
Olli Etuahob2983c92015-03-18 14:02:46 +020070{
Olli Etuahob2983c92015-03-18 14:02:46 +020071 // returning true means symbol was added to the table
Olli Etuahobed35d72017-12-20 16:36:26 +020072 tInsertResult result = level.insert(tLevelPair(function->name(), function));
Olli Etuahob2983c92015-03-18 14:02:46 +020073
74 return result.second;
75}
76
Olli Etuahodd21ecf2018-01-10 12:42:09 +020077TSymbol *TSymbolTable::TSymbolTableLevel::find(const TString &name) const
Jamie Madillbfa91f42014-06-05 15:45:18 -040078{
79 tLevel::const_iterator it = level.find(name);
80 if (it == level.end())
81 return 0;
82 else
83 return (*it).second;
84}
85
Olli Etuahodd21ecf2018-01-10 12:42:09 +020086void TSymbolTable::TSymbolTableLevel::insertUnmangledBuiltInName(const char *name)
Olli Etuaho342b83d2018-01-10 13:24:01 +020087{
Olli Etuaho2d8e4322018-01-22 14:12:46 +020088 mUnmangledBuiltInNames.insert(ImmutableString(name));
Olli Etuaho342b83d2018-01-10 13:24:01 +020089}
90
Olli Etuahodd21ecf2018-01-10 12:42:09 +020091bool TSymbolTable::TSymbolTableLevel::hasUnmangledBuiltIn(const char *name) const
Olli Etuaho342b83d2018-01-10 13:24:01 +020092{
Olli Etuaho2d8e4322018-01-22 14:12:46 +020093 return mUnmangledBuiltInNames.count(ImmutableString(name)) > 0;
Olli Etuaho342b83d2018-01-10 13:24:01 +020094}
95
Olli Etuahodd21ecf2018-01-10 12:42:09 +020096void TSymbolTable::push()
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000097{
Olli Etuahodd21ecf2018-01-10 12:42:09 +020098 table.push_back(new TSymbolTableLevel);
99 precisionStack.push_back(new PrecisionStackLevel);
100}
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000101
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200102void TSymbolTable::pop()
103{
104 delete table.back();
105 table.pop_back();
106
107 delete precisionStack.back();
108 precisionStack.pop_back();
109}
110
111const TFunction *TSymbolTable::markUserDefinedFunctionHasPrototypeDeclaration(
112 const TString &mangledName,
113 bool *hadPrototypeDeclarationOut)
114{
115 TFunction *function = findUserDefinedFunction(mangledName);
116 *hadPrototypeDeclarationOut = function->hasPrototypeDeclaration();
117 function->setHasPrototypeDeclaration();
118 return function;
119}
120
121const TFunction *TSymbolTable::setUserDefinedFunctionParameterNamesFromDefinition(
122 const TFunction *function,
123 bool *wasDefinedOut)
124{
125 TFunction *firstDeclaration = findUserDefinedFunction(function->getMangledName());
126 ASSERT(firstDeclaration);
127 // Note: 'firstDeclaration' could be 'function' if this is the first time we've seen function as
128 // it would have just been put in the symbol table. Otherwise, we're looking up an earlier
129 // occurance.
130 if (function != firstDeclaration)
131 {
132 // Swap the parameters of the previous declaration to the parameters of the function
133 // definition (parameter names may differ).
134 firstDeclaration->swapParameters(*function);
135 }
136
137 *wasDefinedOut = firstDeclaration->isDefined();
138 firstDeclaration->setDefined();
139 return firstDeclaration;
140}
141
Olli Etuaho37b697e2018-01-29 12:19:27 +0200142const TSymbol *TSymbolTable::find(const TString &name, int shaderVersion) const
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200143{
144 int level = currentLevel();
145 TSymbol *symbol = nullptr;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000146 do
147 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300148 if (level == GLSL_BUILTINS)
149 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +0300150 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
151 level--;
152 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700153 level--;
154 if (level == ESSL1_BUILTINS && shaderVersion != 100)
155 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000156
157 symbol = table[level]->find(name);
Olli Etuaho37b697e2018-01-29 12:19:27 +0200158 level--;
159 } while (symbol == nullptr && level >= 0);
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000160
161 return symbol;
162}
163
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200164TFunction *TSymbolTable::findUserDefinedFunction(const TString &name) const
165{
166 // User-defined functions are always declared at the global level.
167 ASSERT(currentLevel() >= GLOBAL_LEVEL);
168 return static_cast<TFunction *>(table[GLOBAL_LEVEL]->find(name));
169}
170
171const TSymbol *TSymbolTable::findGlobal(const TString &name) const
Zhenyao Mod7490962016-11-09 15:49:51 -0800172{
173 ASSERT(table.size() > GLOBAL_LEVEL);
174 return table[GLOBAL_LEVEL]->find(name);
175}
176
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200177const TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000178{
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300179 return findBuiltIn(name, shaderVersion, false);
180}
181
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200182const TSymbol *TSymbolTable::findBuiltIn(const TString &name,
183 int shaderVersion,
184 bool includeGLSLBuiltins) const
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300185{
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000186 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
187 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300188 if (level == GLSL_BUILTINS && !includeGLSLBuiltins)
189 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +0300190 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
191 level--;
192 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700193 level--;
194 if (level == ESSL1_BUILTINS && shaderVersion != 100)
195 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000196
197 TSymbol *symbol = table[level]->find(name);
198
199 if (symbol)
200 return symbol;
201 }
202
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300203 return nullptr;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000204}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400205
206TSymbolTable::~TSymbolTable()
207{
208 while (table.size() > 0)
209 pop();
210}
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700211
Kai Ninomiya030017a2017-12-06 14:06:53 -0800212constexpr bool IsGenType(const TType *type)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500213{
214 if (type)
215 {
216 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500217 return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType ||
218 basicType == EbtGenBType;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500219 }
220
221 return false;
222}
223
Kai Ninomiya030017a2017-12-06 14:06:53 -0800224constexpr bool IsVecType(const TType *type)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500225{
226 if (type)
227 {
228 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500229 return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec ||
230 basicType == EbtBVec;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500231 }
232
233 return false;
234}
235
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800236constexpr const TType *SpecificType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500237{
238 ASSERT(size >= 1 && size <= 4);
239
240 if (!type)
241 {
242 return nullptr;
243 }
244
245 ASSERT(!IsVecType(type));
246
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500247 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500248 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500249 case EbtGenType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800250 return StaticType::GetForVec<EbtFloat>(type->getQualifier(),
251 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500252 case EbtGenIType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800253 return StaticType::GetForVec<EbtInt>(type->getQualifier(),
254 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500255 case EbtGenUType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800256 return StaticType::GetForVec<EbtUInt>(type->getQualifier(),
257 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500258 case EbtGenBType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800259 return StaticType::GetForVec<EbtBool>(type->getQualifier(),
260 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500261 default:
262 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500263 }
264}
265
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800266constexpr const TType *VectorType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500267{
268 ASSERT(size >= 2 && size <= 4);
269
270 if (!type)
271 {
272 return nullptr;
273 }
274
275 ASSERT(!IsGenType(type));
276
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500277 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500278 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500279 case EbtVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800280 return StaticType::GetForVecMat<EbtFloat>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500281 case EbtIVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800282 return StaticType::GetForVecMat<EbtInt>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500283 case EbtUVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800284 return StaticType::GetForVecMat<EbtUInt>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500285 case EbtBVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800286 return StaticType::GetForVecMat<EbtBool>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500287 default:
288 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500289 }
290}
291
Olli Etuaho195be942017-12-04 23:40:14 +0200292bool TSymbolTable::declareVariable(TVariable *variable)
Olli Etuaho0f684632017-07-13 12:42:15 +0300293{
Olli Etuaho195be942017-12-04 23:40:14 +0200294 ASSERT(variable->symbolType() == SymbolType::UserDefined);
295 return insertVariable(currentLevel(), variable);
Olli Etuaho0f684632017-07-13 12:42:15 +0300296}
297
Olli Etuaho035419f2017-11-28 14:27:15 +0200298bool TSymbolTable::declareStructType(TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300299{
300 return insertStructType(currentLevel(), str);
301}
302
Olli Etuaho378c3a52017-12-04 11:32:13 +0200303bool TSymbolTable::declareInterfaceBlock(TInterfaceBlock *interfaceBlock)
Olli Etuaho0f684632017-07-13 12:42:15 +0300304{
Olli Etuaho378c3a52017-12-04 11:32:13 +0200305 return insert(currentLevel(), interfaceBlock);
Jiawei Shaod8105a02017-08-08 09:54:36 +0800306}
307
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200308void TSymbolTable::declareUserDefinedFunction(TFunction *function, bool insertUnmangledName)
309{
310 ASSERT(currentLevel() >= GLOBAL_LEVEL);
311 if (insertUnmangledName)
312 {
313 // Insert the unmangled name to detect potential future redefinition as a variable.
314 table[GLOBAL_LEVEL]->insertUnmangled(function);
315 }
316 table[GLOBAL_LEVEL]->insert(function);
317}
318
Olli Etuahob60d30f2018-01-16 12:31:06 +0200319TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType *type)
Olli Etuaho0f684632017-07-13 12:42:15 +0300320{
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100321 ASSERT(level <= LAST_BUILTIN_LEVEL);
Olli Etuahob60d30f2018-01-16 12:31:06 +0200322 ASSERT(type->isRealized());
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100323 return insertVariable(level, NewPoolTString(name), type, SymbolType::BuiltIn);
Olli Etuaho0f684632017-07-13 12:42:15 +0300324}
325
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100326TVariable *TSymbolTable::insertVariable(ESymbolLevel level,
327 const TString *name,
Olli Etuahob60d30f2018-01-16 12:31:06 +0200328 const TType *type,
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100329 SymbolType symbolType)
Olli Etuaho0f684632017-07-13 12:42:15 +0300330{
Olli Etuahob60d30f2018-01-16 12:31:06 +0200331 ASSERT(level > LAST_BUILTIN_LEVEL || type->isRealized());
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100332 TVariable *var = new TVariable(this, name, type, symbolType);
Olli Etuaho0f684632017-07-13 12:42:15 +0300333 if (insert(level, var))
334 {
Olli Etuaho0f684632017-07-13 12:42:15 +0300335 return var;
336 }
337 return nullptr;
338}
339
340TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300341 TExtension ext,
Olli Etuaho0f684632017-07-13 12:42:15 +0300342 const char *name,
Olli Etuahob60d30f2018-01-16 12:31:06 +0200343 const TType *type)
Olli Etuaho0f684632017-07-13 12:42:15 +0300344{
Olli Etuahob60d30f2018-01-16 12:31:06 +0200345 ASSERT(level <= LAST_BUILTIN_LEVEL);
346 ASSERT(type->isRealized());
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100347 TVariable *var = new TVariable(this, NewPoolTString(name), type, SymbolType::BuiltIn, ext);
Olli Etuaho5d69db12017-11-24 16:51:15 +0200348 if (insert(level, var))
Olli Etuaho0f684632017-07-13 12:42:15 +0300349 {
Olli Etuaho0f684632017-07-13 12:42:15 +0300350 return var;
351 }
352 return nullptr;
353}
354
Olli Etuaho195be942017-12-04 23:40:14 +0200355bool TSymbolTable::insertVariable(ESymbolLevel level, TVariable *variable)
356{
357 ASSERT(variable);
Olli Etuahob60d30f2018-01-16 12:31:06 +0200358 ASSERT(level > LAST_BUILTIN_LEVEL || variable->getType().isRealized());
Olli Etuaho195be942017-12-04 23:40:14 +0200359 return insert(level, variable);
360}
361
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200362bool TSymbolTable::insert(ESymbolLevel level, TSymbol *symbol)
363{
364 ASSERT(level > LAST_BUILTIN_LEVEL || mUserDefinedUniqueIdsStart == -1);
365 return table[level]->insert(symbol);
366}
367
Olli Etuaho035419f2017-11-28 14:27:15 +0200368bool TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300369{
Olli Etuaho035419f2017-11-28 14:27:15 +0200370 ASSERT(str);
Olli Etuaho378c3a52017-12-04 11:32:13 +0200371 return insert(level, str);
372}
373
374bool TSymbolTable::insertInterfaceBlock(ESymbolLevel level, TInterfaceBlock *interfaceBlock)
375{
376 ASSERT(interfaceBlock);
377 return insert(level, interfaceBlock);
Olli Etuaho0f684632017-07-13 12:42:15 +0300378}
379
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500380void TSymbolTable::insertBuiltIn(ESymbolLevel level,
381 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300382 TExtension ext,
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500383 const TType *rvalue,
384 const char *name,
385 const TType *ptype1,
386 const TType *ptype2,
387 const TType *ptype3,
388 const TType *ptype4,
389 const TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700390{
391 if (ptype1->getBasicType() == EbtGSampler2D)
392 {
Martin Radevda6254b2016-12-14 17:00:36 +0200393 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700394 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800395 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
396 StaticType::GetBasic<EbtSampler2D>(), ptype2, ptype3, ptype4, ptype5);
397 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
398 StaticType::GetBasic<EbtISampler2D>(), ptype2, ptype3, ptype4, ptype5);
399 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
400 StaticType::GetBasic<EbtUSampler2D>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700401 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500402 else if (ptype1->getBasicType() == EbtGSampler3D)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700403 {
Martin Radevda6254b2016-12-14 17:00:36 +0200404 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700405 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800406 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
407 StaticType::GetBasic<EbtSampler3D>(), ptype2, ptype3, ptype4, ptype5);
408 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
409 StaticType::GetBasic<EbtISampler3D>(), ptype2, ptype3, ptype4, ptype5);
410 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
411 StaticType::GetBasic<EbtUSampler3D>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700412 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500413 else if (ptype1->getBasicType() == EbtGSamplerCube)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700414 {
Martin Radevda6254b2016-12-14 17:00:36 +0200415 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700416 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800417 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
418 StaticType::GetBasic<EbtSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
419 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
420 StaticType::GetBasic<EbtISamplerCube>(), ptype2, ptype3, ptype4, ptype5);
421 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
422 StaticType::GetBasic<EbtUSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700423 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500424 else if (ptype1->getBasicType() == EbtGSampler2DArray)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700425 {
Martin Radevda6254b2016-12-14 17:00:36 +0200426 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700427 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800428 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
429 StaticType::GetBasic<EbtSampler2DArray>(), ptype2, ptype3, ptype4,
430 ptype5);
431 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
432 StaticType::GetBasic<EbtISampler2DArray>(), ptype2, ptype3, ptype4,
433 ptype5);
434 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
435 StaticType::GetBasic<EbtUSampler2DArray>(), ptype2, ptype3, ptype4,
436 ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700437 }
JiangYizhou40219322016-12-09 09:50:51 +0800438 else if (ptype1->getBasicType() == EbtGSampler2DMS)
439 {
440 insertUnmangledBuiltInName(name, level);
441 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800442 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
443 StaticType::GetBasic<EbtSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
444 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
445 StaticType::GetBasic<EbtISampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
446 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
447 StaticType::GetBasic<EbtUSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
JiangYizhou40219322016-12-09 09:50:51 +0800448 }
Martin Radev2cc85b32016-08-05 16:22:53 +0300449 else if (IsGImage(ptype1->getBasicType()))
450 {
Martin Radevda6254b2016-12-14 17:00:36 +0200451 insertUnmangledBuiltInName(name, level);
Martin Radev2cc85b32016-08-05 16:22:53 +0300452
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800453 const TType *floatType = StaticType::GetBasic<EbtFloat, 4>();
454 const TType *intType = StaticType::GetBasic<EbtInt, 4>();
455 const TType *unsignedType = StaticType::GetBasic<EbtUInt, 4>();
Martin Radev2cc85b32016-08-05 16:22:53 +0300456
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800457 const TType *floatImage = StaticType::GetForFloatImage(ptype1->getBasicType());
458 const TType *intImage = StaticType::GetForIntImage(ptype1->getBasicType());
459 const TType *unsignedImage = StaticType::GetForUintImage(ptype1->getBasicType());
Martin Radev2cc85b32016-08-05 16:22:53 +0300460
461 // GLSL ES 3.10, Revision 4, 8.12 Image Functions
462 if (rvalue->getBasicType() == EbtGVec4)
463 {
464 // imageLoad
465 insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
466 insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
467 insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
468 }
469 else if (rvalue->getBasicType() == EbtVoid)
470 {
471 // imageStore
472 insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
473 insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
474 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
475 }
476 else
477 {
478 // imageSize
479 insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
480 insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
481 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
482 }
483 }
Olli Etuaho9250cb22017-01-21 10:51:27 +0000484 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3) ||
485 IsGenType(ptype4))
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500486 {
Olli Etuaho9250cb22017-01-21 10:51:27 +0000487 ASSERT(!ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200488 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500489 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000490 SpecificType(ptype2, 1), SpecificType(ptype3, 1), SpecificType(ptype4, 1));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500491 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000492 SpecificType(ptype2, 2), SpecificType(ptype3, 2), SpecificType(ptype4, 2));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500493 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000494 SpecificType(ptype2, 3), SpecificType(ptype3, 3), SpecificType(ptype4, 3));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500495 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000496 SpecificType(ptype2, 4), SpecificType(ptype3, 4), SpecificType(ptype4, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500497 }
498 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
499 {
500 ASSERT(!ptype4 && !ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200501 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500502 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2),
503 VectorType(ptype2, 2), VectorType(ptype3, 2));
504 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3),
505 VectorType(ptype2, 3), VectorType(ptype3, 3));
506 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4),
507 VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500508 }
509 else
510 {
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100511 TFunction *function =
Olli Etuaho0c371002017-12-13 17:00:25 +0400512 new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, false, op, ext);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700513
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700514 function->addParameter(TConstParameter(ptype1));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700515
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500516 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700517 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700518 function->addParameter(TConstParameter(ptype2));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700519 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700520
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500521 if (ptype3)
522 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700523 function->addParameter(TConstParameter(ptype3));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500524 }
525
526 if (ptype4)
527 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700528 function->addParameter(TConstParameter(ptype4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500529 }
530
531 if (ptype5)
532 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700533 function->addParameter(TConstParameter(ptype5));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500534 }
535
Martin Radevda6254b2016-12-14 17:00:36 +0200536 ASSERT(hasUnmangledBuiltInAtLevel(name, level));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500537 insert(level, function);
538 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700539}
540
Olli Etuaho492cfab2017-01-20 21:18:29 +0000541void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
542 TOperator op,
543 const TType *rvalue,
544 const TType *ptype1,
545 const TType *ptype2,
546 const TType *ptype3,
547 const TType *ptype4,
548 const TType *ptype5)
549{
550 const char *name = GetOperatorString(op);
551 ASSERT(strlen(name) > 0);
552 insertUnmangledBuiltInName(name, level);
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300553 insertBuiltIn(level, op, TExtension::UNDEFINED, rvalue, name, ptype1, ptype2, ptype3, ptype4,
554 ptype5);
Olli Etuaho492cfab2017-01-20 21:18:29 +0000555}
556
557void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
558 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300559 TExtension ext,
Olli Etuaho492cfab2017-01-20 21:18:29 +0000560 const TType *rvalue,
561 const TType *ptype1,
562 const TType *ptype2,
563 const TType *ptype3,
564 const TType *ptype4,
565 const TType *ptype5)
566{
567 const char *name = GetOperatorString(op);
568 insertUnmangledBuiltInName(name, level);
569 insertBuiltIn(level, op, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
570}
571
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300572void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
573 TOperator op,
574 const TType *rvalue,
575 const char *name)
576{
577 insertUnmangledBuiltInName(name, level);
Olli Etuaho0c371002017-12-13 17:00:25 +0400578 insert(level,
579 new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, false, op));
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300580}
581
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800582void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300583 TExtension ext,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800584 TOperator op,
585 const TType *rvalue,
586 const char *name)
587{
588 insertUnmangledBuiltInName(name, level);
Olli Etuaho0c371002017-12-13 17:00:25 +0400589 insert(level,
590 new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, false, op, ext));
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800591}
592
Zhenyao Moe740add2014-07-18 17:01:01 -0700593TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700594{
595 if (!SupportsPrecision(type))
596 return EbpUndefined;
597
598 // unsigned integers use the same precision as signed
599 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
600
601 int level = static_cast<int>(precisionStack.size()) - 1;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500602 assert(level >= 0); // Just to be safe. Should not happen.
Olli Etuaho183d7e22015-11-20 15:59:09 +0200603 // If we dont find anything we return this. Some types don't have predefined default precision.
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700604 TPrecision prec = EbpUndefined;
605 while (level >= 0)
606 {
607 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
608 if (it != precisionStack[level]->end())
609 {
610 prec = (*it).second;
611 break;
612 }
613 level--;
614 }
615 return prec;
616}
Jamie Madill45bcc782016-11-07 13:58:48 -0500617
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200618void TSymbolTable::addInvariantVarying(const std::string &originalName)
619{
620 ASSERT(atGlobalLevel());
621 table[currentLevel()]->addInvariantVarying(originalName);
622}
623
624bool TSymbolTable::isVaryingInvariant(const std::string &originalName) const
625{
626 ASSERT(atGlobalLevel());
627 return table[currentLevel()]->isVaryingInvariant(originalName);
628}
629
630void TSymbolTable::setGlobalInvariant(bool invariant)
631{
632 ASSERT(atGlobalLevel());
633 table[currentLevel()]->setGlobalInvariant(invariant);
634}
635
Martin Radevda6254b2016-12-14 17:00:36 +0200636void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
637{
638 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
Olli Etuaho5d69db12017-11-24 16:51:15 +0200639 ASSERT(mUserDefinedUniqueIdsStart == -1);
Olli Etuaho342b83d2018-01-10 13:24:01 +0200640 table[level]->insertUnmangledBuiltInName(name);
Martin Radevda6254b2016-12-14 17:00:36 +0200641}
642
643bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level)
644{
645 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
Olli Etuaho342b83d2018-01-10 13:24:01 +0200646 return table[level]->hasUnmangledBuiltIn(name);
Martin Radevda6254b2016-12-14 17:00:36 +0200647}
648
649bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion)
650{
651 ASSERT(static_cast<ESymbolLevel>(table.size()) > LAST_BUILTIN_LEVEL);
652
653 for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
654 {
655 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
656 {
657 --level;
658 }
659 if (level == ESSL3_BUILTINS && shaderVersion < 300)
660 {
661 --level;
662 }
663 if (level == ESSL1_BUILTINS && shaderVersion != 100)
664 {
665 --level;
666 }
667
668 if (table[level]->hasUnmangledBuiltIn(name))
669 {
670 return true;
671 }
672 }
673 return false;
674}
675
Olli Etuaho5d69db12017-11-24 16:51:15 +0200676void TSymbolTable::markBuiltInInitializationFinished()
677{
678 mUserDefinedUniqueIdsStart = mUniqueIdCounter;
679}
680
681void TSymbolTable::clearCompilationResults()
682{
683 mUniqueIdCounter = mUserDefinedUniqueIdsStart;
684
685 // User-defined scopes should have already been cleared when the compilation finished.
686 ASSERT(table.size() == LAST_BUILTIN_LEVEL + 1u);
687}
688
689int TSymbolTable::nextUniqueIdValue()
690{
691 ASSERT(mUniqueIdCounter < std::numeric_limits<int>::max());
692 return ++mUniqueIdCounter;
693}
694
Jamie Madill45bcc782016-11-07 13:58:48 -0500695} // namespace sh