1 // 2 // Copyright (c) 2002-2012 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/SymbolTable.h" 17 18 #include <stdio.h> 19 #include <algorithm> 20 #include <climits> 21 22 TType::TType(const TPublicType &p) : 23 type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize), structure(0) 24 { 25 if (p.userDef) 26 structure = p.userDef->getStruct(); 27 } 28 29 // 30 // Recursively generate mangled names. 31 // 32 TString TType::buildMangledName() const 33 { 34 TString mangledName; 35 if (isMatrix()) 36 mangledName += 'm'; 37 else if (isVector()) 38 mangledName += 'v'; 39 40 switch (type) { 41 case EbtFloat: mangledName += 'f'; break; 42 case EbtInt: mangledName += 'i'; break; 43 case EbtBool: mangledName += 'b'; break; 44 case EbtSampler2D: mangledName += "s2"; break; 45 case EbtSamplerCube: mangledName += "sC"; break; 46 case EbtStruct: mangledName += structure->mangledName(); break; 47 default: break; 48 } 49 50 mangledName += static_cast<char>('0' + getNominalSize()); 51 if (isArray()) { 52 char buf[20]; 53 snprintf(buf, sizeof(buf), "%d", arraySize); 54 mangledName += '['; 55 mangledName += buf; 56 mangledName += ']'; 57 } 58 return mangledName; 59 } 60 61 size_t TType::getObjectSize() const 62 { 63 size_t totalSize = 0; 64 65 if (getBasicType() == EbtStruct) 66 totalSize = structure->objectSize(); 67 else if (matrix) 68 totalSize = size * size; 69 else 70 totalSize = size; 71 72 if (isArray()) { 73 size_t arraySize = getArraySize(); 74 if (arraySize > INT_MAX / totalSize) 75 totalSize = INT_MAX; 76 else 77 totalSize *= arraySize; 78 } 79 80 return totalSize; 81 } 82 83 bool TStructure::containsArrays() const 84 { 85 for (size_t i = 0; i < mFields->size(); ++i) { 86 const TType* fieldType = (*mFields)[i]->type(); 87 if (fieldType->isArray() || fieldType->isStructureContainingArrays()) 88 return true; 89 } 90 return false; 91 } 92 93 TString TStructure::buildMangledName() const 94 { 95 TString mangledName("struct-"); 96 mangledName += *mName; 97 for (size_t i = 0; i < mFields->size(); ++i) { 98 mangledName += '-'; 99 mangledName += (*mFields)[i]->type()->getMangledName(); 100 } 101 return mangledName; 102 } 103 104 size_t TStructure::calculateObjectSize() const 105 { 106 size_t size = 0; 107 for (size_t i = 0; i < mFields->size(); ++i) { 108 size_t fieldSize = (*mFields)[i]->type()->getObjectSize(); 109 if (fieldSize > INT_MAX - size) 110 size = INT_MAX; 111 else 112 size += fieldSize; 113 } 114 return size; 115 } 116 117 int TStructure::calculateDeepestNesting() const 118 { 119 int maxNesting = 0; 120 for (size_t i = 0; i < mFields->size(); ++i) { 121 maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting()); 122 } 123 return 1 + maxNesting; 124 } 125 126 // 127 // Dump functions. 128 // 129 130 void TVariable::dump(TInfoSink& infoSink) const 131 { 132 infoSink.debug << getName().c_str() << ": " << type.getQualifierString() << " " << type.getPrecisionString() << " " << type.getBasicString(); 133 if (type.isArray()) { 134 infoSink.debug << "[0]"; 135 } 136 infoSink.debug << "\n"; 137 } 138 139 void TFunction::dump(TInfoSink &infoSink) const 140 { 141 infoSink.debug << getName().c_str() << ": " << returnType.getBasicString() << " " << getMangledName().c_str() << "\n"; 142 } 143 144 void TSymbolTableLevel::dump(TInfoSink &infoSink) const 145 { 146 tLevel::const_iterator it; 147 for (it = level.begin(); it != level.end(); ++it) 148 (*it).second->dump(infoSink); 149 } 150 151 void TSymbolTable::dump(TInfoSink &infoSink) const 152 { 153 for (int level = currentLevel(); level >= 0; --level) { 154 infoSink.debug << "LEVEL " << level << "\n"; 155 table[level]->dump(infoSink); 156 } 157 } 158 159 // 160 // Functions have buried pointers to delete. 161 // 162 TFunction::~TFunction() 163 { 164 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i) 165 delete (*i).type; 166 } 167 168 // 169 // Symbol table levels are a map of pointers to symbols that have to be deleted. 170 // 171 TSymbolTableLevel::~TSymbolTableLevel() 172 { 173 for (tLevel::iterator it = level.begin(); it != level.end(); ++it) 174 delete (*it).second; 175 } 176 177 // 178 // Change all function entries in the table with the non-mangled name 179 // to be related to the provided built-in operation. This is a low 180 // performance operation, and only intended for symbol tables that 181 // live across a large number of compiles. 182 // 183 void TSymbolTableLevel::relateToOperator(const char* name, TOperator op) 184 { 185 tLevel::iterator it; 186 for (it = level.begin(); it != level.end(); ++it) { 187 if ((*it).second->isFunction()) { 188 TFunction* function = static_cast<TFunction*>((*it).second); 189 if (function->getName() == name) 190 function->relateToOperator(op); 191 } 192 } 193 } 194 195 // 196 // Change all function entries in the table with the non-mangled name 197 // to be related to the provided built-in extension. This is a low 198 // performance operation, and only intended for symbol tables that 199 // live across a large number of compiles. 200 // 201 void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext) 202 { 203 for (tLevel::iterator it = level.begin(); it != level.end(); ++it) { 204 TSymbol* symbol = it->second; 205 if (symbol->getName() == name) 206 symbol->relateToExtension(ext); 207 } 208 } 209 210 TSymbolTable::~TSymbolTable() 211 { 212 for (size_t i = 0; i < table.size(); ++i) 213 delete table[i]; 214 for (size_t i = 0; i < precisionStack.size(); ++i) 215 delete precisionStack[i]; 216 } 217