1// 2// Copyright (c) 2002-2010 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#include "compiler/SymbolTable.h" 13 14#include <stdio.h> 15 16// 17// TType helper function needs a place to live. 18// 19 20// 21// Recursively generate mangled names. 22// 23void TType::buildMangledName(TString& mangledName) 24{ 25 if (isMatrix()) 26 mangledName += 'm'; 27 else if (isVector()) 28 mangledName += 'v'; 29 30 switch (type) { 31 case EbtFloat: mangledName += 'f'; break; 32 case EbtInt: mangledName += 'i'; break; 33 case EbtBool: mangledName += 'b'; break; 34 case EbtSampler2D: mangledName += "s2"; break; 35 case EbtSamplerCube: mangledName += "sC"; break; 36 case EbtStruct: 37 mangledName += "struct-"; 38 if (typeName) 39 mangledName += *typeName; 40 {// support MSVC++6.0 41 for (unsigned int i = 0; i < structure->size(); ++i) { 42 mangledName += '-'; 43 (*structure)[i].type->buildMangledName(mangledName); 44 } 45 } 46 default: 47 break; 48 } 49 50 mangledName += static_cast<char>('0' + getNominalSize()); 51 if (isArray()) { 52 char buf[20]; 53 sprintf(buf, "%d", arraySize); 54 mangledName += '['; 55 mangledName += buf; 56 mangledName += ']'; 57 } 58} 59 60int TType::getStructSize() const 61{ 62 if (!getStruct()) { 63 assert(false && "Not a struct"); 64 return 0; 65 } 66 67 if (structureSize == 0) 68 for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++) 69 structureSize += ((*tl).type)->getObjectSize(); 70 71 return structureSize; 72} 73 74// 75// Dump functions. 76// 77 78void TVariable::dump(TInfoSink& infoSink) const 79{ 80 infoSink.debug << getName().c_str() << ": " << type.getQualifierString() << " " << type.getPrecisionString() << " " << type.getBasicString(); 81 if (type.isArray()) { 82 infoSink.debug << "[0]"; 83 } 84 infoSink.debug << "\n"; 85} 86 87void TFunction::dump(TInfoSink &infoSink) const 88{ 89 infoSink.debug << getName().c_str() << ": " << returnType.getBasicString() << " " << getMangledName().c_str() << "\n"; 90} 91 92void TSymbolTableLevel::dump(TInfoSink &infoSink) const 93{ 94 tLevel::const_iterator it; 95 for (it = level.begin(); it != level.end(); ++it) 96 (*it).second->dump(infoSink); 97} 98 99void TSymbolTable::dump(TInfoSink &infoSink) const 100{ 101 for (int level = currentLevel(); level >= 0; --level) { 102 infoSink.debug << "LEVEL " << level << "\n"; 103 table[level]->dump(infoSink); 104 } 105} 106 107// 108// Functions have buried pointers to delete. 109// 110TFunction::~TFunction() 111{ 112 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i) 113 delete (*i).type; 114} 115 116// 117// Symbol table levels are a map of pointers to symbols that have to be deleted. 118// 119TSymbolTableLevel::~TSymbolTableLevel() 120{ 121 for (tLevel::iterator it = level.begin(); it != level.end(); ++it) 122 delete (*it).second; 123} 124 125// 126// Change all function entries in the table with the non-mangled name 127// to be related to the provided built-in operation. This is a low 128// performance operation, and only intended for symbol tables that 129// live across a large number of compiles. 130// 131void TSymbolTableLevel::relateToOperator(const char* name, TOperator op) 132{ 133 tLevel::iterator it; 134 for (it = level.begin(); it != level.end(); ++it) { 135 if ((*it).second->isFunction()) { 136 TFunction* function = static_cast<TFunction*>((*it).second); 137 if (function->getName() == name) 138 function->relateToOperator(op); 139 } 140 } 141} 142 143// 144// Change all function entries in the table with the non-mangled name 145// to be related to the provided built-in extension. This is a low 146// performance operation, and only intended for symbol tables that 147// live across a large number of compiles. 148// 149void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext) 150{ 151 for (tLevel::iterator it = level.begin(); it != level.end(); ++it) { 152 if (it->second->isFunction()) { 153 TFunction* function = static_cast<TFunction*>(it->second); 154 if (function->getName() == name) 155 function->relateToExtension(ext); 156 } 157 } 158} 159 160TSymbol::TSymbol(const TSymbol& copyOf) 161{ 162 name = NewPoolTString(copyOf.name->c_str()); 163 uniqueId = copyOf.uniqueId; 164} 165 166TVariable::TVariable(const TVariable& copyOf, TStructureMap& remapper) : TSymbol(copyOf) 167{ 168 type.copyType(copyOf.type, remapper); 169 userType = copyOf.userType; 170 // for builtIn symbol table level, unionArray and arrayInformation pointers should be NULL 171 assert(copyOf.arrayInformationType == 0); 172 arrayInformationType = 0; 173 174 if (copyOf.unionArray) { 175 assert(!copyOf.type.getStruct()); 176 assert(copyOf.type.getObjectSize() == 1); 177 unionArray = new ConstantUnion[1]; 178 unionArray[0] = copyOf.unionArray[0]; 179 } else 180 unionArray = 0; 181} 182 183TVariable* TVariable::clone(TStructureMap& remapper) 184{ 185 TVariable *variable = new TVariable(*this, remapper); 186 187 return variable; 188} 189 190TFunction::TFunction(const TFunction& copyOf, TStructureMap& remapper) : TSymbol(copyOf) 191{ 192 for (unsigned int i = 0; i < copyOf.parameters.size(); ++i) { 193 TParameter param; 194 parameters.push_back(param); 195 parameters.back().copyParam(copyOf.parameters[i], remapper); 196 } 197 198 returnType.copyType(copyOf.returnType, remapper); 199 mangledName = copyOf.mangledName; 200 op = copyOf.op; 201 defined = copyOf.defined; 202} 203 204TFunction* TFunction::clone(TStructureMap& remapper) 205{ 206 TFunction *function = new TFunction(*this, remapper); 207 208 return function; 209} 210 211TSymbolTableLevel* TSymbolTableLevel::clone(TStructureMap& remapper) 212{ 213 TSymbolTableLevel *symTableLevel = new TSymbolTableLevel(); 214 tLevel::iterator iter; 215 for (iter = level.begin(); iter != level.end(); ++iter) { 216 symTableLevel->insert(*iter->second->clone(remapper)); 217 } 218 219 return symTableLevel; 220} 221 222void TSymbolTable::copyTable(const TSymbolTable& copyOf) 223{ 224 TStructureMap remapper; 225 uniqueId = copyOf.uniqueId; 226 for (unsigned int i = 0; i < copyOf.table.size(); ++i) { 227 table.push_back(copyOf.table[i]->clone(remapper)); 228 } 229 for( unsigned int i = 0; i < copyOf.precisionStack.size(); i++) { 230 precisionStack.push_back( copyOf.precisionStack[i] ); 231 } 232} 233