• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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),
38 	primarySize(p.primarySize), secondarySize(p.secondarySize), array(p.array), arraySize(p.arraySize), maxArraySize(0),
39 	arrayInformationType(0), interfaceBlock(0), layoutQualifier(p.layoutQualifier), structure(0), mangled(0)
40 {
41 	if (p.userDef)
42 	{
43 		structure = p.userDef->getStruct();
44 	}
45 }
46 
47 //
48 // Recursively generate mangled names.
49 //
buildMangledName(TString & mangledName)50 void TType::buildMangledName(TString& mangledName)
51 {
52 	if (isMatrix())
53 		mangledName += 'm';
54 	else if (isVector())
55 		mangledName += 'v';
56 
57 	switch (type) {
58 	case EbtFloat:              mangledName += 'f';      break;
59 	case EbtInt:                mangledName += 'i';      break;
60 	case EbtUInt:               mangledName += 'u';      break;
61 	case EbtBool:               mangledName += 'b';      break;
62 	case EbtSampler2D:          mangledName += "s2";     break;
63 	case EbtSampler3D:          mangledName += "s3";     break;
64 	case EbtSamplerCube:        mangledName += "sC";     break;
65 	case EbtSampler2DArray:		mangledName += "s2a";    break;
66 	case EbtSampler2DRect:      mangledName += "s2r";    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 
containsArrays() const108 bool TStructure::containsArrays() const
109 {
110 	for(const auto& field : *mFields)
111 	{
112 		const TType *fieldType = field->type();
113 		if(fieldType->isArray() || fieldType->isStructureContainingArrays())
114 			return true;
115 	}
116 	return false;
117 }
118 
containsType(TBasicType type) const119 bool TStructure::containsType(TBasicType type) const
120 {
121 	for(const auto& field : *mFields)
122 	{
123 		const TType *fieldType = field->type();
124 		if(fieldType->getBasicType() == type || fieldType->isStructureContainingType(type))
125 			return true;
126 	}
127 	return false;
128 }
129 
containsSamplers() const130 bool TStructure::containsSamplers() const
131 {
132 	for(const auto& field : *mFields)
133 	{
134 		const TType *fieldType = field->type();
135 		if(IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
136 			return true;
137 	}
138 	return false;
139 }
140 
setMatrixPackingIfUnspecified(TLayoutMatrixPacking matrixPacking)141 void TStructure::setMatrixPackingIfUnspecified(TLayoutMatrixPacking matrixPacking)
142 {
143 	for(auto& field : *mFields)
144 	{
145 		field->type()->setMatrixPackingIfUnspecified(matrixPacking);
146 	}
147 }
148 
buildMangledName() const149 TString TFieldListCollection::buildMangledName() const
150 {
151 	TString mangledName(mangledNamePrefix());
152 	mangledName += *mName;
153 	for(const auto& field : *mFields)
154 	{
155 		mangledName += '-';
156 		mangledName += field->type()->getMangledName();
157 	}
158 	return mangledName;
159 }
160 
calculateObjectSize() const161 size_t TFieldListCollection::calculateObjectSize() const
162 {
163 	size_t size = 0;
164 	for(const auto& field : *mFields)
165 	{
166 		size_t fieldSize = field->type()->getObjectSize();
167 		if(fieldSize > INT_MAX - size)
168 			size = INT_MAX;
169 		else
170 			size += fieldSize;
171 	}
172 	return size;
173 }
174 
calculateDeepestNesting() const175 int TStructure::calculateDeepestNesting() const
176 {
177 	int maxNesting = 0;
178 	for(const auto& field : *mFields)
179 		maxNesting = std::max(maxNesting, field->type()->getDeepestStructNesting());
180 	return 1 + maxNesting;
181 }
182 
183 //
184 // Functions have buried pointers to delete.
185 //
~TFunction()186 TFunction::~TFunction()
187 {
188 	for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
189 		delete (*i).type;
190 }
191 
192 //
193 // Symbol table levels are a map of pointers to symbols that have to be deleted.
194 //
~TSymbolTableLevel()195 TSymbolTableLevel::~TSymbolTableLevel()
196 {
197 	for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
198 		delete (*it).second;
199 }
200 
insert(TSymbol * symbol)201 bool TSymbolTableLevel::insert(TSymbol *symbol)
202 {
203 	symbol->setUniqueId(nextUniqueId());
204 
205 	// returning true means symbol was added to the table
206 	tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
207 
208 	return result.second;
209 }
210 
insertUnmangled(TFunction * function)211 bool TSymbolTableLevel::insertUnmangled(TFunction *function)
212 {
213 	function->setUniqueId(nextUniqueId());
214 
215 	// returning true means symbol was added to the table
216 	tInsertResult result = level.insert(tLevelPair(function->getName(), function));
217 
218 	return result.second;
219 }
220 
find(const TString & name) const221 TSymbol *TSymbolTableLevel::find(const TString &name) const
222 {
223 	tLevel::const_iterator it = level.find(name);
224 	if (it == level.end())
225 		return 0;
226 	else
227 		return (*it).second;
228 }
229 
find(const TString & name,int shaderVersion,bool * builtIn,bool * sameScope) const230 TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, bool *builtIn, bool *sameScope) const
231 {
232 	int level = currentLevel();
233 	TSymbol *symbol = nullptr;
234 
235 	do
236 	{
237 		while((level == ESSL3_BUILTINS && shaderVersion != 300) ||
238 		      (level == ESSL1_BUILTINS && shaderVersion != 100))   // Skip version specific levels
239 		{
240 			--level;
241 		}
242 
243 		symbol = table[level]->find(name);
244 	}
245 	while(!symbol && --level >= 0);   // Doesn't decrement level when a symbol was found
246 
247 	if(builtIn)
248 	{
249 		*builtIn = (level <= LAST_BUILTIN_LEVEL);
250 	}
251 
252 	if(sameScope)
253 	{
254 		*sameScope = (level == currentLevel());
255 	}
256 
257 	return symbol;
258 }
259 
findBuiltIn(const TString & name,int shaderVersion) const260 TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
261 {
262 	for(int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
263 	{
264 		while((level == ESSL3_BUILTINS && shaderVersion != 300) ||
265 		      (level == ESSL1_BUILTINS && shaderVersion != 100))   // Skip version specific levels
266 		{
267 			--level;
268 		}
269 
270 		TSymbol *symbol = table[level]->find(name);
271 
272 		if(symbol)
273 		{
274 			return symbol;
275 		}
276 	}
277 
278 	return 0;
279 }
280 
TSymbol(const TSymbol & copyOf)281 TSymbol::TSymbol(const TSymbol& copyOf)
282 {
283 	name = NewPoolTString(copyOf.name->c_str());
284 }
285