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
21int TSymbolTable::uniqueIdCounter = 0;
22
23//
24// Functions have buried pointers to delete.
25//
26TFunction::~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//
35TSymbolTableLevel::~TSymbolTableLevel()
36{
37    for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
38        delete (*it).second;
39}
40
41bool 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
51TSymbol *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//
66void 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//
85void 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
95TSymbol::TSymbol(const TSymbol &copyOf)
96{
97    name = NewPoolTString(copyOf.name->c_str());
98    uniqueId = copyOf.uniqueId;
99}
100
101TSymbol *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
126TSymbol *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
145TSymbolTable::~TSymbolTable()
146{
147    while (table.size() > 0)
148        pop();
149}
150
151void 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
215TPrecision 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