1 // 2 // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved. 3 // Use of this source code is governed by a BSD-style license that can be 4 // found in the LICENSE file. 5 // 6 7 // 8 // Symbol table for parsing. Most functionaliy and main ideas 9 // are documented in the header file. 10 // 11 12 #if defined(_MSC_VER) 13 #pragma warning(disable: 4718) 14 #endif 15 16 #include "compiler/translator/SymbolTable.h" 17 18 #include <stdio.h> 19 #include <algorithm> 20 21 int TSymbolTable::uniqueIdCounter = 0; 22 23 // 24 // Functions have buried pointers to delete. 25 // 26 TFunction::~TFunction() 27 { 28 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i) 29 delete (*i).type; 30 } 31 32 // 33 // Symbol table levels are a map of pointers to symbols that have to be deleted. 34 // 35 TSymbolTableLevel::~TSymbolTableLevel() 36 { 37 for (tLevel::iterator it = level.begin(); it != level.end(); ++it) 38 delete (*it).second; 39 } 40 41 bool TSymbolTableLevel::insert(TSymbol *symbol) 42 { 43 symbol->setUniqueId(TSymbolTable::nextUniqueId()); 44 45 // returning true means symbol was added to the table 46 tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol)); 47 48 return result.second; 49 } 50 51 TSymbol *TSymbolTableLevel::find(const TString &name) const 52 { 53 tLevel::const_iterator it = level.find(name); 54 if (it == level.end()) 55 return 0; 56 else 57 return (*it).second; 58 } 59 60 // 61 // Change all function entries in the table with the non-mangled name 62 // to be related to the provided built-in operation. This is a low 63 // performance operation, and only intended for symbol tables that 64 // live across a large number of compiles. 65 // 66 void TSymbolTableLevel::relateToOperator(const char *name, TOperator op) 67 { 68 for (tLevel::iterator it = level.begin(); it != level.end(); ++it) 69 { 70 if ((*it).second->isFunction()) 71 { 72 TFunction *function = static_cast<TFunction*>((*it).second); 73 if (function->getName() == name) 74 function->relateToOperator(op); 75 } 76 } 77 } 78 79 // 80 // Change all function entries in the table with the non-mangled name 81 // to be related to the provided built-in extension. This is a low 82 // performance operation, and only intended for symbol tables that 83 // live across a large number of compiles. 84 // 85 void TSymbolTableLevel::relateToExtension(const char *name, const TString &ext) 86 { 87 for (tLevel::iterator it = level.begin(); it != level.end(); ++it) 88 { 89 TSymbol *symbol = it->second; 90 if (symbol->getName() == name) 91 symbol->relateToExtension(ext); 92 } 93 } 94 95 TSymbol::TSymbol(const TSymbol ©Of) 96 { 97 name = NewPoolTString(copyOf.name->c_str()); 98 uniqueId = copyOf.uniqueId; 99 } 100 101 TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, 102 bool *builtIn, bool *sameScope) const 103 { 104 int level = currentLevel(); 105 TSymbol *symbol; 106 107 do 108 { 109 if (level == ESSL3_BUILTINS && shaderVersion != 300) 110 level--; 111 if (level == ESSL1_BUILTINS && shaderVersion != 100) 112 level--; 113 114 symbol = table[level]->find(name); 115 } 116 while (symbol == 0 && --level >= 0); 117 118 if (builtIn) 119 *builtIn = (level <= LAST_BUILTIN_LEVEL); 120 if (sameScope) 121 *sameScope = (level == currentLevel()); 122 123 return symbol; 124 } 125 126 TSymbol *TSymbolTable::findBuiltIn( 127 const TString &name, int shaderVersion) const 128 { 129 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--) 130 { 131 if (level == ESSL3_BUILTINS && shaderVersion != 300) 132 level--; 133 if (level == ESSL1_BUILTINS && shaderVersion != 100) 134 level--; 135 136 TSymbol *symbol = table[level]->find(name); 137 138 if (symbol) 139 return symbol; 140 } 141 142 return 0; 143 } 144 145 TSymbolTable::~TSymbolTable() 146 { 147 while (table.size() > 0) 148 pop(); 149 } 150 151 void TSymbolTable::insertBuiltIn( 152 ESymbolLevel level, TType *rvalue, const char *name, 153 TType *ptype1, TType *ptype2, TType *ptype3, TType *ptype4, TType *ptype5) 154 { 155 if (ptype1->getBasicType() == EbtGSampler2D) 156 { 157 bool gvec4 = (rvalue->getBasicType() == EbtGVec4); 158 insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, 159 new TType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5); 160 insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, 161 new TType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5); 162 insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, 163 new TType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5); 164 return; 165 } 166 if (ptype1->getBasicType() == EbtGSampler3D) 167 { 168 bool gvec4 = (rvalue->getBasicType() == EbtGVec4); 169 insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, 170 new TType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5); 171 insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, 172 new TType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5); 173 insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, 174 new TType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5); 175 return; 176 } 177 if (ptype1->getBasicType() == EbtGSamplerCube) 178 { 179 bool gvec4 = (rvalue->getBasicType() == EbtGVec4); 180 insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, 181 new TType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5); 182 insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, 183 new TType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5); 184 insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, 185 new TType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5); 186 return; 187 } 188 if (ptype1->getBasicType() == EbtGSampler2DArray) 189 { 190 bool gvec4 = (rvalue->getBasicType() == EbtGVec4); 191 insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name, 192 new TType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5); 193 insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name, 194 new TType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5); 195 insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name, 196 new TType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5); 197 return; 198 } 199 200 TFunction *function = new TFunction(NewPoolTString(name), *rvalue); 201 202 TType *types[] = {ptype1, ptype2, ptype3, ptype4, ptype5}; 203 for (size_t ii = 0; ii < sizeof(types) / sizeof(types[0]); ++ii) 204 { 205 if (types[ii]) 206 { 207 TParameter param = {NULL, types[ii]}; 208 function->addParameter(param); 209 } 210 } 211 212 insert(level, function); 213 } 214 215 TPrecision TSymbolTable::getDefaultPrecision(TBasicType type) const 216 { 217 if (!SupportsPrecision(type)) 218 return EbpUndefined; 219 220 // unsigned integers use the same precision as signed 221 TBasicType baseType = (type == EbtUInt) ? EbtInt : type; 222 223 int level = static_cast<int>(precisionStack.size()) - 1; 224 assert(level >= 0); // Just to be safe. Should not happen. 225 // If we dont find anything we return this. Should we error check this? 226 TPrecision prec = EbpUndefined; 227 while (level >= 0) 228 { 229 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType); 230 if (it != precisionStack[level]->end()) 231 { 232 prec = (*it).second; 233 break; 234 } 235 level--; 236 } 237 return prec; 238 } 239