1 // Copyright 2016 The SwiftShader Authors. All Rights Reserved.
2 //
3 // 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
6 //
7 // 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.
14
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
24 #include "SymbolTable.h"
25
26 #include <stdio.h>
27 #include <limits.h>
28 #include <algorithm>
29
30 #if defined(_MSC_VER) && MSC_VER < 1900
31 #define snprintf _snprintf
32 #endif
33
34 int TSymbolTableLevel::uniqueId = 0;
35
TType(const TPublicType & p)36 TType::TType(const TPublicType &p) :
37 type(p.type), precision(p.precision), qualifier(p.qualifier), invariant(p.invariant), layoutQualifier(p.layoutQualifier),
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)
40 {
41 if (p.userDef)
42 {
43 structure = p.userDef->getStruct();
44 computeDeepestStructNesting();
45 }
46 }
47
48 //
49 // Recursively generate mangled names.
50 //
buildMangledName(TString & mangledName)51 void TType::buildMangledName(TString& mangledName)
52 {
53 if (isMatrix())
54 mangledName += 'm';
55 else if (isVector())
56 mangledName += 'v';
57
58 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;
64 case EbtSampler3D: mangledName += "s3"; break;
65 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;
81 default:
82 break;
83 }
84
85 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 }
96 }
97
getStructSize() const98 size_t TType::getStructSize() const
99 {
100 if (!getStruct()) {
101 assert(false && "Not a struct");
102 return 0;
103 }
104
105 return getStruct()->objectSize();
106 }
107
computeDeepestStructNesting()108 void TType::computeDeepestStructNesting()
109 {
110 deepestStructNesting = structure ? structure->deepestNesting() : 0;
111 }
112
containsArrays() const113 bool TStructure::containsArrays() const
114 {
115 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 }
123
containsType(TBasicType type) const124 bool TStructure::containsType(TBasicType type) const
125 {
126 for(size_t i = 0; i < mFields->size(); ++i)
127 {
128 const TType *fieldType = (*mFields)[i]->type();
129 if(fieldType->getBasicType() == type || fieldType->isStructureContainingType(type))
130 return true;
131 }
132 return false;
133 }
134
containsSamplers() const135 bool TStructure::containsSamplers() const
136 {
137 for(size_t i = 0; i < mFields->size(); ++i)
138 {
139 const TType *fieldType = (*mFields)[i]->type();
140 if(IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
141 return true;
142 }
143 return false;
144 }
145
buildMangledName() const146 TString TFieldListCollection::buildMangledName() const
147 {
148 TString mangledName(mangledNamePrefix());
149 mangledName += *mName;
150 for(size_t i = 0; i < mFields->size(); ++i)
151 {
152 mangledName += '-';
153 mangledName += (*mFields)[i]->type()->getMangledName();
154 }
155 return mangledName;
156 }
157
calculateObjectSize() const158 size_t TFieldListCollection::calculateObjectSize() const
159 {
160 size_t size = 0;
161 for(size_t i = 0; i < mFields->size(); ++i)
162 {
163 size_t fieldSize = (*mFields)[i]->type()->getObjectSize();
164 if(fieldSize > INT_MAX - size)
165 size = INT_MAX;
166 else
167 size += fieldSize;
168 }
169 return size;
170 }
171
calculateDeepestNesting() const172 int TStructure::calculateDeepestNesting() const
173 {
174 int maxNesting = 0;
175 for(size_t i = 0; i < mFields->size(); ++i)
176 maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
177 return 1 + maxNesting;
178 }
179
180 //
181 // Functions have buried pointers to delete.
182 //
~TFunction()183 TFunction::~TFunction()
184 {
185 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
186 delete (*i).type;
187 }
188
189 //
190 // Symbol table levels are a map of pointers to symbols that have to be deleted.
191 //
~TSymbolTableLevel()192 TSymbolTableLevel::~TSymbolTableLevel()
193 {
194 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
195 delete (*it).second;
196 }
197
find(const TString & name,int shaderVersion,bool * builtIn,bool * sameScope) const198 TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, bool *builtIn, bool *sameScope) const
199 {
200 int level = currentLevel();
201 TSymbol *symbol = nullptr;
202
203 do
204 {
205 while((level == ESSL3_BUILTINS && shaderVersion != 300) ||
206 (level == ESSL1_BUILTINS && shaderVersion != 100)) // Skip version specific levels
207 {
208 --level;
209 }
210
211 symbol = table[level]->find(name);
212 }
213 while(!symbol && --level >= 0); // Doesn't decrement level when a symbol was found
214
215 if(builtIn)
216 {
217 *builtIn = (level <= LAST_BUILTIN_LEVEL);
218 }
219
220 if(sameScope)
221 {
222 *sameScope = (level == currentLevel());
223 }
224
225 return symbol;
226 }
227
findBuiltIn(const TString & name,int shaderVersion) const228 TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
229 {
230 for(int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
231 {
232 while((level == ESSL3_BUILTINS && shaderVersion != 300) ||
233 (level == ESSL1_BUILTINS && shaderVersion != 100)) // Skip version specific levels
234 {
235 --level;
236 }
237
238 TSymbol *symbol = table[level]->find(name);
239
240 if(symbol)
241 {
242 return symbol;
243 }
244 }
245
246 return 0;
247 }
248
TSymbol(const TSymbol & copyOf)249 TSymbol::TSymbol(const TSymbol& copyOf)
250 {
251 name = NewPoolTString(copyOf.name->c_str());
252 }
253