Home | History | Annotate | Download | only in translator
      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 &copyOf)
     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