1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/angle/src/compiler/SymbolTable.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,209 @@ 1.4 +// 1.5 +// Copyright (c) 2002-2012 The ANGLE Project Authors. All rights reserved. 1.6 +// Use of this source code is governed by a BSD-style license that can be 1.7 +// found in the LICENSE file. 1.8 +// 1.9 + 1.10 +// 1.11 +// Symbol table for parsing. Most functionaliy and main ideas 1.12 +// are documented in the header file. 1.13 +// 1.14 + 1.15 +#if defined(_MSC_VER) 1.16 +#pragma warning(disable: 4718) 1.17 +#endif 1.18 + 1.19 +#include "compiler/SymbolTable.h" 1.20 + 1.21 +#include <stdio.h> 1.22 +#include <algorithm> 1.23 +#include <climits> 1.24 + 1.25 +TType::TType(const TPublicType &p) : 1.26 + type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize), structure(0) 1.27 +{ 1.28 + if (p.userDef) 1.29 + structure = p.userDef->getStruct(); 1.30 +} 1.31 + 1.32 +// 1.33 +// Recursively generate mangled names. 1.34 +// 1.35 +TString TType::buildMangledName() const 1.36 +{ 1.37 + TString mangledName; 1.38 + if (isMatrix()) 1.39 + mangledName += 'm'; 1.40 + else if (isVector()) 1.41 + mangledName += 'v'; 1.42 + 1.43 + switch (type) { 1.44 + case EbtFloat: mangledName += 'f'; break; 1.45 + case EbtInt: mangledName += 'i'; break; 1.46 + case EbtBool: mangledName += 'b'; break; 1.47 + case EbtSampler2D: mangledName += "s2"; break; 1.48 + case EbtSamplerCube: mangledName += "sC"; break; 1.49 + case EbtStruct: mangledName += structure->mangledName(); break; 1.50 + default: break; 1.51 + } 1.52 + 1.53 + mangledName += static_cast<char>('0' + getNominalSize()); 1.54 + if (isArray()) { 1.55 + char buf[20]; 1.56 + snprintf(buf, sizeof(buf), "%d", arraySize); 1.57 + mangledName += '['; 1.58 + mangledName += buf; 1.59 + mangledName += ']'; 1.60 + } 1.61 + return mangledName; 1.62 +} 1.63 + 1.64 +size_t TType::getObjectSize() const 1.65 +{ 1.66 + size_t totalSize = 0; 1.67 + 1.68 + if (getBasicType() == EbtStruct) 1.69 + totalSize = structure->objectSize(); 1.70 + else if (matrix) 1.71 + totalSize = size * size; 1.72 + else 1.73 + totalSize = size; 1.74 + 1.75 + if (isArray()) { 1.76 + size_t arraySize = getArraySize(); 1.77 + if (arraySize > INT_MAX / totalSize) 1.78 + totalSize = INT_MAX; 1.79 + else 1.80 + totalSize *= arraySize; 1.81 + } 1.82 + 1.83 + return totalSize; 1.84 +} 1.85 + 1.86 +bool TStructure::containsArrays() const 1.87 +{ 1.88 + for (size_t i = 0; i < mFields->size(); ++i) { 1.89 + const TType* fieldType = (*mFields)[i]->type(); 1.90 + if (fieldType->isArray() || fieldType->isStructureContainingArrays()) 1.91 + return true; 1.92 + } 1.93 + return false; 1.94 +} 1.95 + 1.96 +TString TStructure::buildMangledName() const 1.97 +{ 1.98 + TString mangledName("struct-"); 1.99 + mangledName += *mName; 1.100 + for (size_t i = 0; i < mFields->size(); ++i) { 1.101 + mangledName += '-'; 1.102 + mangledName += (*mFields)[i]->type()->getMangledName(); 1.103 + } 1.104 + return mangledName; 1.105 +} 1.106 + 1.107 +size_t TStructure::calculateObjectSize() const 1.108 +{ 1.109 + size_t size = 0; 1.110 + for (size_t i = 0; i < mFields->size(); ++i) { 1.111 + size_t fieldSize = (*mFields)[i]->type()->getObjectSize(); 1.112 + if (fieldSize > INT_MAX - size) 1.113 + size = INT_MAX; 1.114 + else 1.115 + size += fieldSize; 1.116 + } 1.117 + return size; 1.118 +} 1.119 + 1.120 +int TStructure::calculateDeepestNesting() const 1.121 +{ 1.122 + int maxNesting = 0; 1.123 + for (size_t i = 0; i < mFields->size(); ++i) { 1.124 + maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting()); 1.125 + } 1.126 + return 1 + maxNesting; 1.127 +} 1.128 + 1.129 +// 1.130 +// Dump functions. 1.131 +// 1.132 + 1.133 +void TVariable::dump(TInfoSink& infoSink) const 1.134 +{ 1.135 + infoSink.debug << getName().c_str() << ": " << type.getQualifierString() << " " << type.getPrecisionString() << " " << type.getBasicString(); 1.136 + if (type.isArray()) { 1.137 + infoSink.debug << "[0]"; 1.138 + } 1.139 + infoSink.debug << "\n"; 1.140 +} 1.141 + 1.142 +void TFunction::dump(TInfoSink &infoSink) const 1.143 +{ 1.144 + infoSink.debug << getName().c_str() << ": " << returnType.getBasicString() << " " << getMangledName().c_str() << "\n"; 1.145 +} 1.146 + 1.147 +void TSymbolTableLevel::dump(TInfoSink &infoSink) const 1.148 +{ 1.149 + tLevel::const_iterator it; 1.150 + for (it = level.begin(); it != level.end(); ++it) 1.151 + (*it).second->dump(infoSink); 1.152 +} 1.153 + 1.154 +void TSymbolTable::dump(TInfoSink &infoSink) const 1.155 +{ 1.156 + for (int level = currentLevel(); level >= 0; --level) { 1.157 + infoSink.debug << "LEVEL " << level << "\n"; 1.158 + table[level]->dump(infoSink); 1.159 + } 1.160 +} 1.161 + 1.162 +// 1.163 +// Functions have buried pointers to delete. 1.164 +// 1.165 +TFunction::~TFunction() 1.166 +{ 1.167 + for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i) 1.168 + delete (*i).type; 1.169 +} 1.170 + 1.171 +// 1.172 +// Symbol table levels are a map of pointers to symbols that have to be deleted. 1.173 +// 1.174 +TSymbolTableLevel::~TSymbolTableLevel() 1.175 +{ 1.176 + for (tLevel::iterator it = level.begin(); it != level.end(); ++it) 1.177 + if ((*it).first == (*it).second->getMangledName()) 1.178 + delete (*it).second; 1.179 +} 1.180 + 1.181 +// 1.182 +// Change all function entries in the table with the non-mangled name 1.183 +// to be related to the provided built-in operation. This is a low 1.184 +// performance operation, and only intended for symbol tables that 1.185 +// live across a large number of compiles. 1.186 +// 1.187 +void TSymbolTableLevel::relateToOperator(const char* name, TOperator op) 1.188 +{ 1.189 + tLevel::iterator it; 1.190 + for (it = level.begin(); it != level.end(); ++it) { 1.191 + if ((*it).second->isFunction()) { 1.192 + TFunction* function = static_cast<TFunction*>((*it).second); 1.193 + if (function->getName() == name) 1.194 + function->relateToOperator(op); 1.195 + } 1.196 + } 1.197 +} 1.198 + 1.199 +// 1.200 +// Change all function entries in the table with the non-mangled name 1.201 +// to be related to the provided built-in extension. This is a low 1.202 +// performance operation, and only intended for symbol tables that 1.203 +// live across a large number of compiles. 1.204 +// 1.205 +void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext) 1.206 +{ 1.207 + for (tLevel::iterator it = level.begin(); it != level.end(); ++it) { 1.208 + TSymbol* symbol = it->second; 1.209 + if (symbol->getName() == name) 1.210 + symbol->relateToExtension(ext); 1.211 + } 1.212 +}