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) 31 #define snprintf _snprintf 32 #endif 33 34 int TSymbolTableLevel::uniqueId = 0; 35 36 TType::TType(const TPublicType &p) : 37 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) 40 { 41 if (p.userDef) 42 { 43 structure = p.userDef->getStruct(); 44 computeDeepestStructNesting(); 45 } 46 } 47 48 // 49 // Recursively generate mangled names. 50 // 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 98 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 108 void TType::computeDeepestStructNesting() 109 { 110 deepestStructNesting = structure ? structure->deepestNesting() : 0; 111 } 112 113 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 124 bool 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 } 134 135 TString 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 147 size_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 161 int 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; 167 } 168 169 // 170 // Functions have buried pointers to delete. 171 // 172 TFunction::~TFunction() 173 { 174 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i) 175 delete (*i).type; 176 } 177 178 // 179 // Symbol table levels are a map of pointers to symbols that have to be deleted. 180 // 181 TSymbolTableLevel::~TSymbolTableLevel() 182 { 183 for (tLevel::iterator it = level.begin(); it != level.end(); ++it) 184 delete (*it).second; 185 } 186 187 TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, bool *builtIn, bool *sameScope) const 188 { 189 int level = currentLevel(); 190 TSymbol *symbol = nullptr; 191 192 do 193 { 194 while((level == ESSL3_BUILTINS && shaderVersion != 300) || 195 (level == ESSL1_BUILTINS && shaderVersion != 100)) // Skip version specific levels 196 { 197 --level; 198 } 199 200 symbol = table[level]->find(name); 201 } 202 while(!symbol && --level >= 0); // Doesn't decrement level when a symbol was found 203 204 if(builtIn) 205 { 206 *builtIn = (level <= LAST_BUILTIN_LEVEL); 207 } 208 209 if(sameScope) 210 { 211 *sameScope = (level == currentLevel()); 212 } 213 214 return symbol; 215 } 216 217 TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const 218 { 219 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 } 226 227 TSymbol *symbol = table[level]->find(name); 228 229 if(symbol) 230 { 231 return symbol; 232 } 233 } 234 235 return 0; 236 } 237 238 TSymbol::TSymbol(const TSymbol& copyOf) 239 { 240 name = NewPoolTString(copyOf.name->c_str()); 241 } 242