blob: 5eb043480baa65e50c3e49c29300e8f21217804e [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +00002// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00003// 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
apatrick@chromium.orge057c5d2012-01-26 19:18:24 +000012#if defined(_MSC_VER)
13#pragma warning(disable: 4718)
14#endif
15
Geoff Lang17732822013-08-29 13:46:49 -040016#include "compiler/translator/SymbolTable.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000017
apatrick@chromium.org8187fa82010-06-15 22:09:28 +000018#include <stdio.h>
kbr@chromium.org476541f2011-10-27 21:14:51 +000019#include <algorithm>
20
Nicolas Capensbd10cf52013-06-20 09:51:51 -040021int TSymbolTableLevel::uniqueId = 0;
22
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000023//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000024// Functions have buried pointers to delete.
25//
26TFunction::~TFunction()
27{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000028 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
29 delete (*i).type;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000030}
31
32//
33// Symbol table levels are a map of pointers to symbols that have to be deleted.
34//
35TSymbolTableLevel::~TSymbolTableLevel()
36{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000037 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
38 delete (*it).second;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000039}
40
41//
42// Change all function entries in the table with the non-mangled name
43// to be related to the provided built-in operation. This is a low
44// performance operation, and only intended for symbol tables that
45// live across a large number of compiles.
46//
Zhenyao Mo9eedea02014-05-12 16:02:35 -070047void TSymbolTableLevel::relateToOperator(const char *name, TOperator op)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000048{
Zhenyao Mo9eedea02014-05-12 16:02:35 -070049 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
50 {
51 if ((*it).second->isFunction())
52 {
53 TFunction *function = static_cast<TFunction*>((*it).second);
daniel@transgaming.com0578f812010-05-17 09:58:39 +000054 if (function->getName() == name)
55 function->relateToOperator(op);
56 }
57 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000058}
59
alokp@chromium.org8815d7f2010-09-09 17:30:03 +000060//
61// Change all function entries in the table with the non-mangled name
62// to be related to the provided built-in extension. This is a low
63// performance operation, and only intended for symbol tables that
64// live across a large number of compiles.
65//
Zhenyao Mo9eedea02014-05-12 16:02:35 -070066void TSymbolTableLevel::relateToExtension(const char *name, const TString &ext)
alokp@chromium.org8815d7f2010-09-09 17:30:03 +000067{
Zhenyao Mo9eedea02014-05-12 16:02:35 -070068 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
69 {
70 TSymbol *symbol = it->second;
71 if (symbol->getName() == name)
Jamie Madill2aeb26a2013-07-08 14:02:55 -040072 symbol->relateToExtension(ext);
alokp@chromium.org8815d7f2010-09-09 17:30:03 +000073 }
74}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000075
Zhenyao Mo9eedea02014-05-12 16:02:35 -070076TSymbol::TSymbol(const TSymbol &copyOf)
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000077{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000078 name = NewPoolTString(copyOf.name->c_str());
79 uniqueId = copyOf.uniqueId;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000080}
81
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000082TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, bool *builtIn, bool *sameScope)
83{
84 int level = currentLevel();
85 TSymbol *symbol;
86
87 do
88 {
Zhenyao Mo9eedea02014-05-12 16:02:35 -070089 if (level == ESSL3_BUILTINS && shaderVersion != 300)
90 level--;
91 if (level == ESSL1_BUILTINS && shaderVersion != 100)
92 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +000093
94 symbol = table[level]->find(name);
95 }
96 while (symbol == 0 && --level >= 0);
97
98 if (builtIn)
99 *builtIn = (level <= LAST_BUILTIN_LEVEL);
100 if (sameScope)
101 *sameScope = (level == currentLevel());
102
103 return symbol;
104}
105
106TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion)
107{
108 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
109 {
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700110 if (level == ESSL3_BUILTINS && shaderVersion != 300)
111 level--;
112 if (level == ESSL1_BUILTINS && shaderVersion != 100)
113 level--;
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000114
115 TSymbol *symbol = table[level]->find(name);
116
117 if (symbol)
118 return symbol;
119 }
120
121 return 0;
122}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400123
124TSymbolTable::~TSymbolTable()
125{
126 while (table.size() > 0)
127 pop();
128}
Zhenyao Mo9eedea02014-05-12 16:02:35 -0700129
130void TSymbolTable::insertBuiltIn(
131 ESymbolLevel level, TType *rvalue, const char *name,
132 TType *ptype1, TType *ptype2, TType *ptype3, TType *ptype4, TType *ptype5)
133{
134 if (ptype1->getBasicType() == EbtGSampler2D)
135 {
136 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
137 insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name,
138 new TType(EbtSampler2D), ptype2, ptype3, ptype4, ptype5);
139 insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name,
140 new TType(EbtISampler2D), ptype2, ptype3, ptype4, ptype5);
141 insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name,
142 new TType(EbtUSampler2D), ptype2, ptype3, ptype4, ptype5);
143 return;
144 }
145 if (ptype1->getBasicType() == EbtGSampler3D)
146 {
147 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
148 insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name,
149 new TType(EbtSampler3D), ptype2, ptype3, ptype4, ptype5);
150 insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name,
151 new TType(EbtISampler3D), ptype2, ptype3, ptype4, ptype5);
152 insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name,
153 new TType(EbtUSampler3D), ptype2, ptype3, ptype4, ptype5);
154 return;
155 }
156 if (ptype1->getBasicType() == EbtGSamplerCube)
157 {
158 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
159 insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name,
160 new TType(EbtSamplerCube), ptype2, ptype3, ptype4, ptype5);
161 insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name,
162 new TType(EbtISamplerCube), ptype2, ptype3, ptype4, ptype5);
163 insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name,
164 new TType(EbtUSamplerCube), ptype2, ptype3, ptype4, ptype5);
165 return;
166 }
167 if (ptype1->getBasicType() == EbtGSampler2DArray)
168 {
169 bool gvec4 = (rvalue->getBasicType() == EbtGVec4);
170 insertBuiltIn(level, gvec4 ? new TType(EbtFloat, 4) : rvalue, name,
171 new TType(EbtSampler2DArray), ptype2, ptype3, ptype4, ptype5);
172 insertBuiltIn(level, gvec4 ? new TType(EbtInt, 4) : rvalue, name,
173 new TType(EbtISampler2DArray), ptype2, ptype3, ptype4, ptype5);
174 insertBuiltIn(level, gvec4 ? new TType(EbtUInt, 4) : rvalue, name,
175 new TType(EbtUSampler2DArray), ptype2, ptype3, ptype4, ptype5);
176 return;
177 }
178
179 TFunction *function = new TFunction(NewPoolTString(name), *rvalue);
180
181 TType *types[] = {ptype1, ptype2, ptype3, ptype4, ptype5};
182 for (size_t ii = 0; ii < sizeof(types) / sizeof(types[0]); ++ii)
183 {
184 if (types[ii])
185 {
186 TParameter param = {NULL, types[ii]};
187 function->addParameter(param);
188 }
189 }
190
191 insert(level, *function);
192}
193
194TPrecision TSymbolTable::getDefaultPrecision(TBasicType type)
195{
196 if (!SupportsPrecision(type))
197 return EbpUndefined;
198
199 // unsigned integers use the same precision as signed
200 TBasicType baseType = (type == EbtUInt) ? EbtInt : type;
201
202 int level = static_cast<int>(precisionStack.size()) - 1;
203 assert(level >= 0); // Just to be safe. Should not happen.
204 // If we dont find anything we return this. Should we error check this?
205 TPrecision prec = EbpUndefined;
206 while (level >= 0)
207 {
208 PrecisionStackLevel::iterator it = precisionStack[level]->find(baseType);
209 if (it != precisionStack[level]->end())
210 {
211 prec = (*it).second;
212 break;
213 }
214 level--;
215 }
216 return prec;
217}