blob: 7548880dcf0a584bb3f1679851a4f17af28816dd [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
142const TSymbol *TSymbolTable::find(const TString &name,
143 int shaderVersion,
144 bool *builtIn,
145 bool *sameScope) const
146{
147 int level = currentLevel();
148 TSymbol *symbol = nullptr;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000149 do
150 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300151 if (level == GLSL_BUILTINS)
152 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +0300153 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
154 level--;
155 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700156 level--;
157 if (level == ESSL1_BUILTINS && shaderVersion != 100)
158 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000159
160 symbol = table[level]->find(name);
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200161 } while (symbol == nullptr && --level >= 0);
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000162
163 if (builtIn)
164 *builtIn = (level <= LAST_BUILTIN_LEVEL);
165 if (sameScope)
166 *sameScope = (level == currentLevel());
167
168 return symbol;
169}
170
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200171TFunction *TSymbolTable::findUserDefinedFunction(const TString &name) const
172{
173 // User-defined functions are always declared at the global level.
174 ASSERT(currentLevel() >= GLOBAL_LEVEL);
175 return static_cast<TFunction *>(table[GLOBAL_LEVEL]->find(name));
176}
177
178const TSymbol *TSymbolTable::findGlobal(const TString &name) const
Zhenyao Mod7490962016-11-09 15:49:51 -0800179{
180 ASSERT(table.size() > GLOBAL_LEVEL);
181 return table[GLOBAL_LEVEL]->find(name);
182}
183
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200184const TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000185{
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300186 return findBuiltIn(name, shaderVersion, false);
187}
188
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200189const TSymbol *TSymbolTable::findBuiltIn(const TString &name,
190 int shaderVersion,
191 bool includeGLSLBuiltins) const
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300192{
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000193 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
194 {
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300195 if (level == GLSL_BUILTINS && !includeGLSLBuiltins)
196 level--;
Martin Radeve93d24e2016-07-28 12:06:05 +0300197 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
198 level--;
199 if (level == ESSL3_BUILTINS && shaderVersion < 300)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700200 level--;
201 if (level == ESSL1_BUILTINS && shaderVersion != 100)
202 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000203
204 TSymbol *symbol = table[level]->find(name);
205
206 if (symbol)
207 return symbol;
208 }
209
Olli Etuaho977ee7e2017-07-21 11:38:27 +0300210 return nullptr;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000211}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400212
213TSymbolTable::~TSymbolTable()
214{
215 while (table.size() > 0)
216 pop();
217}
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700218
Kai Ninomiya030017a2017-12-06 14:06:53 -0800219constexpr bool IsGenType(const TType *type)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500220{
221 if (type)
222 {
223 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500224 return basicType == EbtGenType || basicType == EbtGenIType || basicType == EbtGenUType ||
225 basicType == EbtGenBType;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500226 }
227
228 return false;
229}
230
Kai Ninomiya030017a2017-12-06 14:06:53 -0800231constexpr bool IsVecType(const TType *type)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500232{
233 if (type)
234 {
235 TBasicType basicType = type->getBasicType();
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500236 return basicType == EbtVec || basicType == EbtIVec || basicType == EbtUVec ||
237 basicType == EbtBVec;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500238 }
239
240 return false;
241}
242
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800243constexpr const TType *SpecificType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500244{
245 ASSERT(size >= 1 && size <= 4);
246
247 if (!type)
248 {
249 return nullptr;
250 }
251
252 ASSERT(!IsVecType(type));
253
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500254 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500255 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500256 case EbtGenType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800257 return StaticType::GetForVec<EbtFloat>(type->getQualifier(),
258 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500259 case EbtGenIType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800260 return StaticType::GetForVec<EbtInt>(type->getQualifier(),
261 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500262 case EbtGenUType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800263 return StaticType::GetForVec<EbtUInt>(type->getQualifier(),
264 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500265 case EbtGenBType:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800266 return StaticType::GetForVec<EbtBool>(type->getQualifier(),
267 static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500268 default:
269 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500270 }
271}
272
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800273constexpr const TType *VectorType(const TType *type, int size)
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500274{
275 ASSERT(size >= 2 && size <= 4);
276
277 if (!type)
278 {
279 return nullptr;
280 }
281
282 ASSERT(!IsGenType(type));
283
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500284 switch (type->getBasicType())
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500285 {
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500286 case EbtVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800287 return StaticType::GetForVecMat<EbtFloat>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500288 case EbtIVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800289 return StaticType::GetForVecMat<EbtInt>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500290 case EbtUVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800291 return StaticType::GetForVecMat<EbtUInt>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500292 case EbtBVec:
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800293 return StaticType::GetForVecMat<EbtBool>(static_cast<unsigned char>(size));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500294 default:
295 return type;
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500296 }
297}
298
Olli Etuaho195be942017-12-04 23:40:14 +0200299bool TSymbolTable::declareVariable(TVariable *variable)
Olli Etuaho0f684632017-07-13 12:42:15 +0300300{
Olli Etuaho195be942017-12-04 23:40:14 +0200301 ASSERT(variable->symbolType() == SymbolType::UserDefined);
302 return insertVariable(currentLevel(), variable);
Olli Etuaho0f684632017-07-13 12:42:15 +0300303}
304
Olli Etuaho035419f2017-11-28 14:27:15 +0200305bool TSymbolTable::declareStructType(TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300306{
307 return insertStructType(currentLevel(), str);
308}
309
Olli Etuaho378c3a52017-12-04 11:32:13 +0200310bool TSymbolTable::declareInterfaceBlock(TInterfaceBlock *interfaceBlock)
Olli Etuaho0f684632017-07-13 12:42:15 +0300311{
Olli Etuaho378c3a52017-12-04 11:32:13 +0200312 return insert(currentLevel(), interfaceBlock);
Jiawei Shaod8105a02017-08-08 09:54:36 +0800313}
314
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200315void TSymbolTable::declareUserDefinedFunction(TFunction *function, bool insertUnmangledName)
316{
317 ASSERT(currentLevel() >= GLOBAL_LEVEL);
318 if (insertUnmangledName)
319 {
320 // Insert the unmangled name to detect potential future redefinition as a variable.
321 table[GLOBAL_LEVEL]->insertUnmangled(function);
322 }
323 table[GLOBAL_LEVEL]->insert(function);
324}
325
Olli Etuahob60d30f2018-01-16 12:31:06 +0200326TVariable *TSymbolTable::insertVariable(ESymbolLevel level, const char *name, const TType *type)
Olli Etuaho0f684632017-07-13 12:42:15 +0300327{
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100328 ASSERT(level <= LAST_BUILTIN_LEVEL);
Olli Etuahob60d30f2018-01-16 12:31:06 +0200329 ASSERT(type->isRealized());
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100330 return insertVariable(level, NewPoolTString(name), type, SymbolType::BuiltIn);
Olli Etuaho0f684632017-07-13 12:42:15 +0300331}
332
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100333TVariable *TSymbolTable::insertVariable(ESymbolLevel level,
334 const TString *name,
Olli Etuahob60d30f2018-01-16 12:31:06 +0200335 const TType *type,
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100336 SymbolType symbolType)
Olli Etuaho0f684632017-07-13 12:42:15 +0300337{
Olli Etuahob60d30f2018-01-16 12:31:06 +0200338 ASSERT(level > LAST_BUILTIN_LEVEL || type->isRealized());
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100339 TVariable *var = new TVariable(this, name, type, symbolType);
Olli Etuaho0f684632017-07-13 12:42:15 +0300340 if (insert(level, var))
341 {
Olli Etuaho0f684632017-07-13 12:42:15 +0300342 return var;
343 }
344 return nullptr;
345}
346
347TVariable *TSymbolTable::insertVariableExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300348 TExtension ext,
Olli Etuaho0f684632017-07-13 12:42:15 +0300349 const char *name,
Olli Etuahob60d30f2018-01-16 12:31:06 +0200350 const TType *type)
Olli Etuaho0f684632017-07-13 12:42:15 +0300351{
Olli Etuahob60d30f2018-01-16 12:31:06 +0200352 ASSERT(level <= LAST_BUILTIN_LEVEL);
353 ASSERT(type->isRealized());
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100354 TVariable *var = new TVariable(this, NewPoolTString(name), type, SymbolType::BuiltIn, ext);
Olli Etuaho5d69db12017-11-24 16:51:15 +0200355 if (insert(level, var))
Olli Etuaho0f684632017-07-13 12:42:15 +0300356 {
Olli Etuaho0f684632017-07-13 12:42:15 +0300357 return var;
358 }
359 return nullptr;
360}
361
Olli Etuaho195be942017-12-04 23:40:14 +0200362bool TSymbolTable::insertVariable(ESymbolLevel level, TVariable *variable)
363{
364 ASSERT(variable);
Olli Etuahob60d30f2018-01-16 12:31:06 +0200365 ASSERT(level > LAST_BUILTIN_LEVEL || variable->getType().isRealized());
Olli Etuaho195be942017-12-04 23:40:14 +0200366 return insert(level, variable);
367}
368
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200369bool TSymbolTable::insert(ESymbolLevel level, TSymbol *symbol)
370{
371 ASSERT(level > LAST_BUILTIN_LEVEL || mUserDefinedUniqueIdsStart == -1);
372 return table[level]->insert(symbol);
373}
374
Olli Etuaho035419f2017-11-28 14:27:15 +0200375bool TSymbolTable::insertStructType(ESymbolLevel level, TStructure *str)
Olli Etuaho0f684632017-07-13 12:42:15 +0300376{
Olli Etuaho035419f2017-11-28 14:27:15 +0200377 ASSERT(str);
Olli Etuaho378c3a52017-12-04 11:32:13 +0200378 return insert(level, str);
379}
380
381bool TSymbolTable::insertInterfaceBlock(ESymbolLevel level, TInterfaceBlock *interfaceBlock)
382{
383 ASSERT(interfaceBlock);
384 return insert(level, interfaceBlock);
Olli Etuaho0f684632017-07-13 12:42:15 +0300385}
386
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500387void TSymbolTable::insertBuiltIn(ESymbolLevel level,
388 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300389 TExtension ext,
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500390 const TType *rvalue,
391 const char *name,
392 const TType *ptype1,
393 const TType *ptype2,
394 const TType *ptype3,
395 const TType *ptype4,
396 const TType *ptype5)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700397{
398 if (ptype1->getBasicType() == EbtGSampler2D)
399 {
Martin Radevda6254b2016-12-14 17:00:36 +0200400 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700401 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800402 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
403 StaticType::GetBasic<EbtSampler2D>(), ptype2, ptype3, ptype4, ptype5);
404 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
405 StaticType::GetBasic<EbtISampler2D>(), ptype2, ptype3, ptype4, ptype5);
406 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
407 StaticType::GetBasic<EbtUSampler2D>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700408 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500409 else if (ptype1->getBasicType() == EbtGSampler3D)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700410 {
Martin Radevda6254b2016-12-14 17:00:36 +0200411 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700412 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800413 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
414 StaticType::GetBasic<EbtSampler3D>(), ptype2, ptype3, ptype4, ptype5);
415 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
416 StaticType::GetBasic<EbtISampler3D>(), ptype2, ptype3, ptype4, ptype5);
417 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
418 StaticType::GetBasic<EbtUSampler3D>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700419 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500420 else if (ptype1->getBasicType() == EbtGSamplerCube)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700421 {
Martin Radevda6254b2016-12-14 17:00:36 +0200422 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700423 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800424 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
425 StaticType::GetBasic<EbtSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
426 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
427 StaticType::GetBasic<EbtISamplerCube>(), ptype2, ptype3, ptype4, ptype5);
428 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
429 StaticType::GetBasic<EbtUSamplerCube>(), ptype2, ptype3, ptype4, ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700430 }
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500431 else if (ptype1->getBasicType() == EbtGSampler2DArray)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700432 {
Martin Radevda6254b2016-12-14 17:00:36 +0200433 insertUnmangledBuiltInName(name, level);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700434 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800435 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
436 StaticType::GetBasic<EbtSampler2DArray>(), ptype2, ptype3, ptype4,
437 ptype5);
438 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
439 StaticType::GetBasic<EbtISampler2DArray>(), ptype2, ptype3, ptype4,
440 ptype5);
441 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
442 StaticType::GetBasic<EbtUSampler2DArray>(), ptype2, ptype3, ptype4,
443 ptype5);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700444 }
JiangYizhou40219322016-12-09 09:50:51 +0800445 else if (ptype1->getBasicType() == EbtGSampler2DMS)
446 {
447 insertUnmangledBuiltInName(name, level);
448 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800449 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtFloat, 4>() : rvalue, name,
450 StaticType::GetBasic<EbtSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
451 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtInt, 4>() : rvalue, name,
452 StaticType::GetBasic<EbtISampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
453 insertBuiltIn(level, gvec4 ? StaticType::GetBasic<EbtUInt, 4>() : rvalue, name,
454 StaticType::GetBasic<EbtUSampler2DMS>(), ptype2, ptype3, ptype4, ptype5);
JiangYizhou40219322016-12-09 09:50:51 +0800455 }
Martin Radev2cc85b32016-08-05 16:22:53 +0300456 else if (IsGImage(ptype1->getBasicType()))
457 {
Martin Radevda6254b2016-12-14 17:00:36 +0200458 insertUnmangledBuiltInName(name, level);
Martin Radev2cc85b32016-08-05 16:22:53 +0300459
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800460 const TType *floatType = StaticType::GetBasic<EbtFloat, 4>();
461 const TType *intType = StaticType::GetBasic<EbtInt, 4>();
462 const TType *unsignedType = StaticType::GetBasic<EbtUInt, 4>();
Martin Radev2cc85b32016-08-05 16:22:53 +0300463
Kai Ninomiya614dd0f2017-11-22 14:04:48 -0800464 const TType *floatImage = StaticType::GetForFloatImage(ptype1->getBasicType());
465 const TType *intImage = StaticType::GetForIntImage(ptype1->getBasicType());
466 const TType *unsignedImage = StaticType::GetForUintImage(ptype1->getBasicType());
Martin Radev2cc85b32016-08-05 16:22:53 +0300467
468 // GLSL ES 3.10, Revision 4, 8.12 Image Functions
469 if (rvalue->getBasicType() == EbtGVec4)
470 {
471 // imageLoad
472 insertBuiltIn(level, floatType, name, floatImage, ptype2, ptype3, ptype4, ptype5);
473 insertBuiltIn(level, intType, name, intImage, ptype2, ptype3, ptype4, ptype5);
474 insertBuiltIn(level, unsignedType, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
475 }
476 else if (rvalue->getBasicType() == EbtVoid)
477 {
478 // imageStore
479 insertBuiltIn(level, rvalue, name, floatImage, ptype2, floatType, ptype4, ptype5);
480 insertBuiltIn(level, rvalue, name, intImage, ptype2, intType, ptype4, ptype5);
481 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, unsignedType, ptype4, ptype5);
482 }
483 else
484 {
485 // imageSize
486 insertBuiltIn(level, rvalue, name, floatImage, ptype2, ptype3, ptype4, ptype5);
487 insertBuiltIn(level, rvalue, name, intImage, ptype2, ptype3, ptype4, ptype5);
488 insertBuiltIn(level, rvalue, name, unsignedImage, ptype2, ptype3, ptype4, ptype5);
489 }
490 }
Olli Etuaho9250cb22017-01-21 10:51:27 +0000491 else if (IsGenType(rvalue) || IsGenType(ptype1) || IsGenType(ptype2) || IsGenType(ptype3) ||
492 IsGenType(ptype4))
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500493 {
Olli Etuaho9250cb22017-01-21 10:51:27 +0000494 ASSERT(!ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200495 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500496 insertBuiltIn(level, op, ext, SpecificType(rvalue, 1), name, SpecificType(ptype1, 1),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000497 SpecificType(ptype2, 1), SpecificType(ptype3, 1), SpecificType(ptype4, 1));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500498 insertBuiltIn(level, op, ext, SpecificType(rvalue, 2), name, SpecificType(ptype1, 2),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000499 SpecificType(ptype2, 2), SpecificType(ptype3, 2), SpecificType(ptype4, 2));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500500 insertBuiltIn(level, op, ext, SpecificType(rvalue, 3), name, SpecificType(ptype1, 3),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000501 SpecificType(ptype2, 3), SpecificType(ptype3, 3), SpecificType(ptype4, 3));
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500502 insertBuiltIn(level, op, ext, SpecificType(rvalue, 4), name, SpecificType(ptype1, 4),
Olli Etuaho9250cb22017-01-21 10:51:27 +0000503 SpecificType(ptype2, 4), SpecificType(ptype3, 4), SpecificType(ptype4, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500504 }
505 else if (IsVecType(rvalue) || IsVecType(ptype1) || IsVecType(ptype2) || IsVecType(ptype3))
506 {
507 ASSERT(!ptype4 && !ptype5);
Martin Radevda6254b2016-12-14 17:00:36 +0200508 insertUnmangledBuiltInName(name, level);
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500509 insertBuiltIn(level, op, ext, VectorType(rvalue, 2), name, VectorType(ptype1, 2),
510 VectorType(ptype2, 2), VectorType(ptype3, 2));
511 insertBuiltIn(level, op, ext, VectorType(rvalue, 3), name, VectorType(ptype1, 3),
512 VectorType(ptype2, 3), VectorType(ptype3, 3));
513 insertBuiltIn(level, op, ext, VectorType(rvalue, 4), name, VectorType(ptype1, 4),
514 VectorType(ptype2, 4), VectorType(ptype3, 4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500515 }
516 else
517 {
Olli Etuaho9d4d7f02017-12-07 17:11:41 +0100518 TFunction *function =
Olli Etuaho0c371002017-12-13 17:00:25 +0400519 new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, false, op, ext);
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700520
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700521 function->addParameter(TConstParameter(ptype1));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700522
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500523 if (ptype2)
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700524 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700525 function->addParameter(TConstParameter(ptype2));
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700526 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700527
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500528 if (ptype3)
529 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700530 function->addParameter(TConstParameter(ptype3));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500531 }
532
533 if (ptype4)
534 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700535 function->addParameter(TConstParameter(ptype4));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500536 }
537
538 if (ptype5)
539 {
Dmitry Skibaefa3d8e2015-06-22 14:52:10 -0700540 function->addParameter(TConstParameter(ptype5));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500541 }
542
Martin Radevda6254b2016-12-14 17:00:36 +0200543 ASSERT(hasUnmangledBuiltInAtLevel(name, level));
Nicolas Capensf3cc4ae2015-02-23 13:51:25 -0500544 insert(level, function);
545 }
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700546}
547
Olli Etuaho492cfab2017-01-20 21:18:29 +0000548void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
549 TOperator op,
550 const TType *rvalue,
551 const TType *ptype1,
552 const TType *ptype2,
553 const TType *ptype3,
554 const TType *ptype4,
555 const TType *ptype5)
556{
557 const char *name = GetOperatorString(op);
558 ASSERT(strlen(name) > 0);
559 insertUnmangledBuiltInName(name, level);
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300560 insertBuiltIn(level, op, TExtension::UNDEFINED, rvalue, name, ptype1, ptype2, ptype3, ptype4,
561 ptype5);
Olli Etuaho492cfab2017-01-20 21:18:29 +0000562}
563
564void TSymbolTable::insertBuiltInOp(ESymbolLevel level,
565 TOperator op,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300566 TExtension ext,
Olli Etuaho492cfab2017-01-20 21:18:29 +0000567 const TType *rvalue,
568 const TType *ptype1,
569 const TType *ptype2,
570 const TType *ptype3,
571 const TType *ptype4,
572 const TType *ptype5)
573{
574 const char *name = GetOperatorString(op);
575 insertUnmangledBuiltInName(name, level);
576 insertBuiltIn(level, op, ext, rvalue, name, ptype1, ptype2, ptype3, ptype4, ptype5);
577}
578
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300579void TSymbolTable::insertBuiltInFunctionNoParameters(ESymbolLevel level,
580 TOperator op,
581 const TType *rvalue,
582 const char *name)
583{
584 insertUnmangledBuiltInName(name, level);
Olli Etuaho0c371002017-12-13 17:00:25 +0400585 insert(level,
586 new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, false, op));
Martin Radevd7c5b0a2016-07-27 14:04:43 +0300587}
588
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800589void TSymbolTable::insertBuiltInFunctionNoParametersExt(ESymbolLevel level,
Olli Etuaho2a1e8f92017-07-14 11:49:36 +0300590 TExtension ext,
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800591 TOperator op,
592 const TType *rvalue,
593 const char *name)
594{
595 insertUnmangledBuiltInName(name, level);
Olli Etuaho0c371002017-12-13 17:00:25 +0400596 insert(level,
597 new TFunction(this, NewPoolTString(name), rvalue, SymbolType::BuiltIn, false, op, ext));
Jiawei Shaod27f5c82017-08-23 09:38:08 +0800598}
599
Zhenyao Moe740add2014-07-18 17:01:01 -0700600TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700601{
602 if (!SupportsPrecision(type))
603 return EbpUndefined;
604
605 // unsigned integers use the same precision as signed
606 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
607
608 int level = static_cast<int>(precisionStack.size()) - 1;
Jamie Madilld7b1ab52016-12-12 14:42:19 -0500609 assert(level >= 0); // Just to be safe. Should not happen.
Olli Etuaho183d7e22015-11-20 15:59:09 +0200610 // If we dont find anything we return this. Some types don't have predefined default precision.
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700611 TPrecision prec = EbpUndefined;
612 while (level >= 0)
613 {
614 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
615 if (it != precisionStack[level]->end())
616 {
617 prec = (*it).second;
618 break;
619 }
620 level--;
621 }
622 return prec;
623}
Jamie Madill45bcc782016-11-07 13:58:48 -0500624
Olli Etuahodd21ecf2018-01-10 12:42:09 +0200625void TSymbolTable::addInvariantVarying(const std::string &originalName)
626{
627 ASSERT(atGlobalLevel());
628 table[currentLevel()]->addInvariantVarying(originalName);
629}
630
631bool TSymbolTable::isVaryingInvariant(const std::string &originalName) const
632{
633 ASSERT(atGlobalLevel());
634 return table[currentLevel()]->isVaryingInvariant(originalName);
635}
636
637void TSymbolTable::setGlobalInvariant(bool invariant)
638{
639 ASSERT(atGlobalLevel());
640 table[currentLevel()]->setGlobalInvariant(invariant);
641}
642
Martin Radevda6254b2016-12-14 17:00:36 +0200643void TSymbolTable::insertUnmangledBuiltInName(const char *name, ESymbolLevel level)
644{
645 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
Olli Etuaho5d69db12017-11-24 16:51:15 +0200646 ASSERT(mUserDefinedUniqueIdsStart == -1);
Olli Etuaho342b83d2018-01-10 13:24:01 +0200647 table[level]->insertUnmangledBuiltInName(name);
Martin Radevda6254b2016-12-14 17:00:36 +0200648}
649
650bool TSymbolTable::hasUnmangledBuiltInAtLevel(const char *name, ESymbolLevel level)
651{
652 ASSERT(level >= 0 && level < static_cast<ESymbolLevel>(table.size()));
Olli Etuaho342b83d2018-01-10 13:24:01 +0200653 return table[level]->hasUnmangledBuiltIn(name);
Martin Radevda6254b2016-12-14 17:00:36 +0200654}
655
656bool TSymbolTable::hasUnmangledBuiltInForShaderVersion(const char *name, int shaderVersion)
657{
658 ASSERT(static_cast<ESymbolLevel>(table.size()) > LAST_BUILTIN_LEVEL);
659
660 for (int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
661 {
662 if (level == ESSL3_1_BUILTINS && shaderVersion != 310)
663 {
664 --level;
665 }
666 if (level == ESSL3_BUILTINS && shaderVersion < 300)
667 {
668 --level;
669 }
670 if (level == ESSL1_BUILTINS && shaderVersion != 100)
671 {
672 --level;
673 }
674
675 if (table[level]->hasUnmangledBuiltIn(name))
676 {
677 return true;
678 }
679 }
680 return false;
681}
682
Olli Etuaho5d69db12017-11-24 16:51:15 +0200683void TSymbolTable::markBuiltInInitializationFinished()
684{
685 mUserDefinedUniqueIdsStart = mUniqueIdCounter;
686}
687
688void TSymbolTable::clearCompilationResults()
689{
690 mUniqueIdCounter = mUserDefinedUniqueIdsStart;
691
692 // User-defined scopes should have already been cleared when the compilation finished.
693 ASSERT(table.size() == LAST_BUILTIN_LEVEL + 1u);
694}
695
696int TSymbolTable::nextUniqueIdValue()
697{
698 ASSERT(mUniqueIdCounter < std::numeric_limits<int>::max());
699 return ++mUniqueIdCounter;
700}
701
Jamie Madill45bcc782016-11-07 13:58:48 -0500702} // namespace sh