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 34int TSymbolTableLevel::uniqueId = 0; 35 36TType::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// 50void 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 98size_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 108bool 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 119bool 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 130bool 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 141void TStructure::setMatrixPackingIfUnspecified(TLayoutMatrixPacking matrixPacking) 142{ 143 for(auto& field : *mFields) 144 { 145 field->type()->setMatrixPackingIfUnspecified(matrixPacking); 146 } 147} 148 149TString 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 161size_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 175int 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// 186TFunction::~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// 195TSymbolTableLevel::~TSymbolTableLevel() 196{ 197 for (tLevel::iterator it = level.begin(); it != level.end(); ++it) 198 delete (*it).second; 199} 200 201bool 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 211bool 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 221TSymbol *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 230TSymbol *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 260TSymbol *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 281TSymbol::TSymbol(const TSymbol& copyOf) 282{ 283 name = NewPoolTString(copyOf.name->c_str()); 284} 285