Home | History | Annotate | Download | only in compiler
      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) && MSC_VER < 1900
     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),
     38 	primarySize(p.primarySize), secondarySize(p.secondarySize), array(p.array), arraySize(p.arraySize), maxArraySize(0),
     39 	arrayInformationType(0), interfaceBlock(0), layoutQualifier(p.layoutQualifier), structure(0), mangled(0)
     40 {
     41 	if (p.userDef)
     42 	{
     43 		structure = p.userDef->getStruct();
     44 	}
     45 }
     46 
     47 //
     48 // Recursively generate mangled names.
     49 //
     50 void TType::buildMangledName(TString& mangledName)
     51 {
     52 	if (isMatrix())
     53 		mangledName += 'm';
     54 	else if (isVector())
     55 		mangledName += 'v';
     56 
     57 	switch (type) {
     58 	case EbtFloat:              mangledName += 'f';      break;
     59 	case EbtInt:                mangledName += 'i';      break;
     60 	case EbtUInt:               mangledName += 'u';      break;
     61 	case EbtBool:               mangledName += 'b';      break;
     62 	case EbtSampler2D:          mangledName += "s2";     break;
     63 	case EbtSampler3D:          mangledName += "s3";     break;
     64 	case EbtSamplerCube:        mangledName += "sC";     break;
     65 	case EbtSampler2DArray:		mangledName += "s2a";    break;
     66 	case EbtSampler2DRect:      mangledName += "s2r";    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 bool TStructure::containsArrays() const
    109 {
    110 	for(const auto& field : *mFields)
    111 	{
    112 		const TType *fieldType = field->type();
    113 		if(fieldType->isArray() || fieldType->isStructureContainingArrays())
    114 			return true;
    115 	}
    116 	return false;
    117 }
    118 
    119 bool TStructure::containsType(TBasicType type) const
    120 {
    121 	for(const auto& field : *mFields)
    122 	{
    123 		const TType *fieldType = field->type();
    124 		if(fieldType->getBasicType() == type || fieldType->isStructureContainingType(type))
    125 			return true;
    126 	}
    127 	return false;
    128 }
    129 
    130 bool TStructure::containsSamplers() const
    131 {
    132 	for(const auto& field : *mFields)
    133 	{
    134 		const TType *fieldType = field->type();
    135 		if(IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
    136 			return true;
    137 	}
    138 	return false;
    139 }
    140 
    141 void TStructure::setMatrixPackingIfUnspecified(TLayoutMatrixPacking matrixPacking)
    142 {
    143 	for(auto& field : *mFields)
    144 	{
    145 		field->type()->setMatrixPackingIfUnspecified(matrixPacking);
    146 	}
    147 }
    148 
    149 TString TFieldListCollection::buildMangledName() const
    150 {
    151 	TString mangledName(mangledNamePrefix());
    152 	mangledName += *mName;
    153 	for(const auto& field : *mFields)
    154 	{
    155 		mangledName += '-';
    156 		mangledName += field->type()->getMangledName();
    157 	}
    158 	return mangledName;
    159 }
    160 
    161 size_t TFieldListCollection::calculateObjectSize() const
    162 {
    163 	size_t size = 0;
    164 	for(const auto& field : *mFields)
    165 	{
    166 		size_t fieldSize = field->type()->getObjectSize();
    167 		if(fieldSize > INT_MAX - size)
    168 			size = INT_MAX;
    169 		else
    170 			size += fieldSize;
    171 	}
    172 	return size;
    173 }
    174 
    175 int TStructure::calculateDeepestNesting() const
    176 {
    177 	int maxNesting = 0;
    178 	for(const auto& field : *mFields)
    179 		maxNesting = std::max(maxNesting, field->type()->getDeepestStructNesting());
    180 	return 1 + maxNesting;
    181 }
    182 
    183 //
    184 // Functions have buried pointers to delete.
    185 //
    186 TFunction::~TFunction()
    187 {
    188 	for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
    189 		delete (*i).type;
    190 }
    191 
    192 //
    193 // Symbol table levels are a map of pointers to symbols that have to be deleted.
    194 //
    195 TSymbolTableLevel::~TSymbolTableLevel()
    196 {
    197 	for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
    198 		delete (*it).second;
    199 }
    200 
    201 bool TSymbolTableLevel::insert(TSymbol *symbol)
    202 {
    203 	symbol->setUniqueId(nextUniqueId());
    204 
    205 	// returning true means symbol was added to the table
    206 	tInsertResult result = level.insert(tLevelPair(symbol->getMangledName(), symbol));
    207 
    208 	return result.second;
    209 }
    210 
    211 bool TSymbolTableLevel::insertUnmangled(TFunction *function)
    212 {
    213 	function->setUniqueId(nextUniqueId());
    214 
    215 	// returning true means symbol was added to the table
    216 	tInsertResult result = level.insert(tLevelPair(function->getName(), function));
    217 
    218 	return result.second;
    219 }
    220 
    221 TSymbol *TSymbolTableLevel::find(const TString &name) const
    222 {
    223 	tLevel::const_iterator it = level.find(name);
    224 	if (it == level.end())
    225 		return 0;
    226 	else
    227 		return (*it).second;
    228 }
    229 
    230 TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, bool *builtIn, bool *sameScope) const
    231 {
    232 	int level = currentLevel();
    233 	TSymbol *symbol = nullptr;
    234 
    235 	do
    236 	{
    237 		while((level == ESSL3_BUILTINS && shaderVersion != 300) ||
    238 		      (level == ESSL1_BUILTINS && shaderVersion != 100))   // Skip version specific levels
    239 		{
    240 			--level;
    241 		}
    242 
    243 		symbol = table[level]->find(name);
    244 	}
    245 	while(!symbol && --level >= 0);   // Doesn't decrement level when a symbol was found
    246 
    247 	if(builtIn)
    248 	{
    249 		*builtIn = (level <= LAST_BUILTIN_LEVEL);
    250 	}
    251 
    252 	if(sameScope)
    253 	{
    254 		*sameScope = (level == currentLevel());
    255 	}
    256 
    257 	return symbol;
    258 }
    259 
    260 TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
    261 {
    262 	for(int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
    263 	{
    264 		while((level == ESSL3_BUILTINS && shaderVersion != 300) ||
    265 		      (level == ESSL1_BUILTINS && shaderVersion != 100))   // Skip version specific levels
    266 		{
    267 			--level;
    268 		}
    269 
    270 		TSymbol *symbol = table[level]->find(name);
    271 
    272 		if(symbol)
    273 		{
    274 			return symbol;
    275 		}
    276 	}
    277 
    278 	return 0;
    279 }
    280 
    281 TSymbol::TSymbol(const TSymbol& copyOf)
    282 {
    283 	name = NewPoolTString(copyOf.name->c_str());
    284 }
    285