blob: 39023aebe93ad60bbba0604b65d101d07fed2f39 [file] [log] [blame]
Nicolas Capens0bac2852016-05-07 06:09:58 -04001// Copyright 2016 The SwiftShader Authors. All Rights Reserved.
John Bauman66b8ab22014-05-06 15:57:45 -04002//
Nicolas Capens0bac2852016-05-07 06:09:58 -04003// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
John Bauman66b8ab22014-05-06 15:57:45 -04006//
Nicolas Capens0bac2852016-05-07 06:09:58 -04007// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
John Bauman66b8ab22014-05-06 15:57:45 -040014
15//
16// Symbol table for parsing. Most functionaliy and main ideas
17// are documented in the header file.
18//
19
20#if defined(_MSC_VER)
21#pragma warning(disable: 4718)
22#endif
23
Nicolas Capenscc863da2015-01-21 15:50:55 -050024#include "SymbolTable.h"
John Bauman66b8ab22014-05-06 15:57:45 -040025
26#include <stdio.h>
Nicolas Capens94352d92015-06-11 08:53:40 -050027#include <limits.h>
John Bauman66b8ab22014-05-06 15:57:45 -040028#include <algorithm>
29
30#if defined(_MSC_VER)
31#define snprintf _snprintf
32#endif
33
John Baumand4ae8632014-05-06 16:18:33 -040034int TSymbolTableLevel::uniqueId = 0;
35
John Bauman66b8ab22014-05-06 15:57:45 -040036TType::TType(const TPublicType &p) :
Nicolas Capens0bac2852016-05-07 06:09:58 -040037 type(p.type), precision(p.precision), qualifier(p.qualifier), invariant(false), layoutQualifier(TLayoutQualifier::create()),
38 primarySize(p.primarySize), secondarySize(p.secondarySize), array(p.array), arraySize(p.arraySize), maxArraySize(0),
39 arrayInformationType(0), interfaceBlock(0), structure(0), deepestStructNesting(0), mangled(0)
John Bauman66b8ab22014-05-06 15:57:45 -040040{
Nicolas Capens0bac2852016-05-07 06:09:58 -040041 if (p.userDef)
42 {
43 structure = p.userDef->getStruct();
44 computeDeepestStructNesting();
45 }
John Bauman66b8ab22014-05-06 15:57:45 -040046}
47
48//
49// Recursively generate mangled names.
50//
51void TType::buildMangledName(TString& mangledName)
52{
Nicolas Capens0bac2852016-05-07 06:09:58 -040053 if (isMatrix())
54 mangledName += 'm';
55 else if (isVector())
56 mangledName += 'v';
John Bauman66b8ab22014-05-06 15:57:45 -040057
Nicolas Capens0bac2852016-05-07 06:09:58 -040058 switch (type) {
59 case EbtFloat: mangledName += 'f'; break;
60 case EbtInt: mangledName += 'i'; break;
61 case EbtUInt: mangledName += 'u'; break;
62 case EbtBool: mangledName += 'b'; break;
63 case EbtSampler2D: mangledName += "s2"; break;
Alexis Hetub027aa92015-01-19 15:56:12 -050064 case EbtSampler3D: mangledName += "s3"; break;
Alexis Hetua8b364b2015-06-10 11:48:40 -040065 case EbtSamplerCube: mangledName += "sC"; break;
66 case EbtSampler2DArray: mangledName += "s2a"; break;
67 case EbtSamplerExternalOES: mangledName += "sext"; break;
68 case EbtISampler2D: mangledName += "is2"; break;
69 case EbtISampler3D: mangledName += "is3"; break;
70 case EbtISamplerCube: mangledName += "isC"; break;
71 case EbtISampler2DArray: mangledName += "is2a"; break;
72 case EbtUSampler2D: mangledName += "us2"; break;
73 case EbtUSampler3D: mangledName += "us3"; break;
74 case EbtUSamplerCube: mangledName += "usC"; break;
75 case EbtUSampler2DArray: mangledName += "us2a"; break;
76 case EbtSampler2DShadow: mangledName += "s2s"; break;
77 case EbtSamplerCubeShadow: mangledName += "sCs"; break;
78 case EbtSampler2DArrayShadow: mangledName += "s2as"; break;
79 case EbtStruct: mangledName += structure->mangledName(); break;
80 case EbtInterfaceBlock: mangledName += interfaceBlock->mangledName(); break;
Nicolas Capens0bac2852016-05-07 06:09:58 -040081 default:
82 break;
83 }
John Bauman66b8ab22014-05-06 15:57:45 -040084
Nicolas Capens0bac2852016-05-07 06:09:58 -040085 mangledName += static_cast<char>('0' + getNominalSize());
86 if(isMatrix()) {
87 mangledName += static_cast<char>('0' + getSecondarySize());
88 }
89 if (isArray()) {
90 char buf[20];
91 snprintf(buf, sizeof(buf), "%d", arraySize);
92 mangledName += '[';
93 mangledName += buf;
94 mangledName += ']';
95 }
John Bauman66b8ab22014-05-06 15:57:45 -040096}
97
Alexis Hetuab752792016-04-21 16:11:31 -040098size_t TType::getStructSize() const
John Bauman66b8ab22014-05-06 15:57:45 -040099{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400100 if (!getStruct()) {
101 assert(false && "Not a struct");
102 return 0;
103 }
John Bauman66b8ab22014-05-06 15:57:45 -0400104
Nicolas Capens0bac2852016-05-07 06:09:58 -0400105 return getStruct()->objectSize();
John Bauman66b8ab22014-05-06 15:57:45 -0400106}
107
108void TType::computeDeepestStructNesting()
109{
Alexis Hetua8b364b2015-06-10 11:48:40 -0400110 deepestStructNesting = structure ? structure->deepestNesting() : 0;
John Bauman66b8ab22014-05-06 15:57:45 -0400111}
112
Alexis Hetua8b364b2015-06-10 11:48:40 -0400113bool TStructure::containsArrays() const
John Bauman66b8ab22014-05-06 15:57:45 -0400114{
Alexis Hetua8b364b2015-06-10 11:48:40 -0400115 for(size_t i = 0; i < mFields->size(); ++i)
116 {
117 const TType *fieldType = (*mFields)[i]->type();
118 if(fieldType->isArray() || fieldType->isStructureContainingArrays())
119 return true;
120 }
121 return false;
122}
John Bauman66b8ab22014-05-06 15:57:45 -0400123
Alexis Hetua8b364b2015-06-10 11:48:40 -0400124bool TStructure::containsSamplers() const
125{
126 for(size_t i = 0; i < mFields->size(); ++i)
127 {
128 const TType *fieldType = (*mFields)[i]->type();
129 if(IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
130 return true;
131 }
132 return false;
133}
John Bauman66b8ab22014-05-06 15:57:45 -0400134
Alexis Hetua8b364b2015-06-10 11:48:40 -0400135TString TFieldListCollection::buildMangledName() const
136{
137 TString mangledName(mangledNamePrefix());
138 mangledName += *mName;
139 for(size_t i = 0; i < mFields->size(); ++i)
140 {
141 mangledName += '-';
142 mangledName += (*mFields)[i]->type()->getMangledName();
143 }
144 return mangledName;
145}
146
147size_t TFieldListCollection::calculateObjectSize() const
148{
149 size_t size = 0;
150 for(size_t i = 0; i < mFields->size(); ++i)
151 {
152 size_t fieldSize = (*mFields)[i]->type()->getObjectSize();
153 if(fieldSize > INT_MAX - size)
154 size = INT_MAX;
155 else
156 size += fieldSize;
157 }
158 return size;
159}
160
161int TStructure::calculateDeepestNesting() const
162{
163 int maxNesting = 0;
164 for(size_t i = 0; i < mFields->size(); ++i)
165 maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
166 return 1 + maxNesting;
John Bauman66b8ab22014-05-06 15:57:45 -0400167}
168
169//
John Bauman66b8ab22014-05-06 15:57:45 -0400170// Functions have buried pointers to delete.
171//
172TFunction::~TFunction()
173{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400174 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
175 delete (*i).type;
John Bauman66b8ab22014-05-06 15:57:45 -0400176}
177
178//
179// Symbol table levels are a map of pointers to symbols that have to be deleted.
180//
181TSymbolTableLevel::~TSymbolTableLevel()
182{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400183 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
184 delete (*it).second;
John Bauman66b8ab22014-05-06 15:57:45 -0400185}
186
Nicolas Capense2858652015-02-18 15:30:51 -0500187TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, bool *builtIn, bool *sameScope) const
188{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400189 int level = currentLevel();
190 TSymbol *symbol = nullptr;
Nicolas Capense2858652015-02-18 15:30:51 -0500191
Nicolas Capens0bac2852016-05-07 06:09:58 -0400192 do
193 {
194 while((level == ESSL3_BUILTINS && shaderVersion != 300) ||
195 (level == ESSL1_BUILTINS && shaderVersion != 100)) // Skip version specific levels
196 {
197 --level;
198 }
Nicolas Capense2858652015-02-18 15:30:51 -0500199
Nicolas Capens0bac2852016-05-07 06:09:58 -0400200 symbol = table[level]->find(name);
201 }
202 while(!symbol && --level >= 0); // Doesn't decrement level when a symbol was found
Nicolas Capense2858652015-02-18 15:30:51 -0500203
Nicolas Capens0bac2852016-05-07 06:09:58 -0400204 if(builtIn)
205 {
206 *builtIn = (level <= LAST_BUILTIN_LEVEL);
207 }
Nicolas Capense2858652015-02-18 15:30:51 -0500208
Nicolas Capens0bac2852016-05-07 06:09:58 -0400209 if(sameScope)
210 {
211 *sameScope = (level == currentLevel());
212 }
Nicolas Capense2858652015-02-18 15:30:51 -0500213
Nicolas Capens0bac2852016-05-07 06:09:58 -0400214 return symbol;
Nicolas Capense2858652015-02-18 15:30:51 -0500215}
216
217TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
218{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400219 for(int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
220 {
221 while((level == ESSL3_BUILTINS && shaderVersion != 300) ||
222 (level == ESSL1_BUILTINS && shaderVersion != 100)) // Skip version specific levels
223 {
224 --level;
225 }
Nicolas Capens3d7f6ed2015-02-18 16:34:50 -0500226
Nicolas Capens0bac2852016-05-07 06:09:58 -0400227 TSymbol *symbol = table[level]->find(name);
Nicolas Capens3d7f6ed2015-02-18 16:34:50 -0500228
Nicolas Capens0bac2852016-05-07 06:09:58 -0400229 if(symbol)
230 {
231 return symbol;
232 }
233 }
Nicolas Capens3d7f6ed2015-02-18 16:34:50 -0500234
Nicolas Capens0bac2852016-05-07 06:09:58 -0400235 return 0;
Nicolas Capense2858652015-02-18 15:30:51 -0500236}
237
John Bauman66b8ab22014-05-06 15:57:45 -0400238TSymbol::TSymbol(const TSymbol& copyOf)
239{
Nicolas Capens0bac2852016-05-07 06:09:58 -0400240 name = NewPoolTString(copyOf.name->c_str());
John Bauman66b8ab22014-05-06 15:57:45 -0400241}