blob: d8f58c7825c97f82c76121de4a20524b77a8bce4 [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>
Jamie Madill94bf7f22013-07-08 13:31:15 -040020#include <climits>
kbr@chromium.org476541f2011-10-27 21:14:51 +000021
Nicolas Capensbd10cf52013-06-20 09:51:51 -040022int TSymbolTableLevel::uniqueId = 0;
23
daniel@transgaming.com8abd0b72012-09-27 17:46:07 +000024TType::TType(const TPublicType &p) :
Jamie Madilla5efff92013-06-06 11:56:47 -040025 type(p.type), precision(p.precision), qualifier(p.qualifier), primarySize(p.primarySize), secondarySize(p.secondarySize), array(p.array), layoutQualifier(p.layoutQualifier), arraySize(p.arraySize),
Jamie Madill98493dd2013-07-08 14:39:03 -040026 interfaceBlock(0), structure(0)
daniel@transgaming.com8abd0b72012-09-27 17:46:07 +000027{
28 if (p.userDef) {
29 structure = p.userDef->getStruct();
daniel@transgaming.com8abd0b72012-09-27 17:46:07 +000030 }
31}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000032
33//
34// Recursively generate mangled names.
35//
Jamie Madill98493dd2013-07-08 14:39:03 -040036TString TType::buildMangledName() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000037{
Jamie Madill98493dd2013-07-08 14:39:03 -040038 TString mangledName;
daniel@transgaming.com0578f812010-05-17 09:58:39 +000039 if (isMatrix())
40 mangledName += 'm';
41 else if (isVector())
42 mangledName += 'v';
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000043
Nicolas Capens2a1d8a32013-07-18 11:49:40 -040044 switch (type)
45 {
46 case EbtFloat: mangledName += 'f'; break;
47 case EbtInt: mangledName += 'i'; break;
Jamie Madill5ccc6242013-07-26 13:14:54 -040048 case EbtUInt: mangledName += 'u'; break;
Nicolas Capens2a1d8a32013-07-18 11:49:40 -040049 case EbtBool: mangledName += 'b'; break;
50 case EbtSampler2D: mangledName += "s2"; break;
51 case EbtSampler3D: mangledName += "s3"; break;
52 case EbtSamplerCube: mangledName += "sC"; break;
53 case EbtSampler2DArray: mangledName += "s2a"; break;
54 case EbtISampler2D: mangledName += "is2"; break;
55 case EbtISampler3D: mangledName += "is3"; break;
56 case EbtISamplerCube: mangledName += "isC"; break;
57 case EbtISampler2DArray: mangledName += "is2a"; break;
58 case EbtUSampler2D: mangledName += "us2"; break;
59 case EbtUSampler3D: mangledName += "us3"; break;
60 case EbtUSamplerCube: mangledName += "usC"; break;
61 case EbtUSampler2DArray: mangledName += "us2a"; break;
62 case EbtSampler2DShadow: mangledName += "s2s"; break;
63 case EbtSamplerCubeShadow: mangledName += "sCs"; break;
64 case EbtSampler2DArrayShadow: mangledName += "s2as"; break;
65 case EbtStruct: mangledName += structure->mangledName(); break;
66 case EbtInterfaceBlock: mangledName += interfaceBlock->mangledName(); break;
67 default: UNREACHABLE();
daniel@transgaming.com0578f812010-05-17 09:58:39 +000068 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000069
shannonwoods@chromium.org09e09882013-05-30 00:18:25 +000070 if (isMatrix())
71 {
72 mangledName += static_cast<char>('0' + getCols());
73 mangledName += static_cast<char>('x');
74 mangledName += static_cast<char>('0' + getRows());
75 }
76 else
77 {
78 mangledName += static_cast<char>('0' + getNominalSize());
79 }
Jamie Madill98493dd2013-07-08 14:39:03 -040080
daniel@transgaming.com0578f812010-05-17 09:58:39 +000081 if (isArray()) {
82 char buf[20];
kbr@chromium.orgddb6e8e2012-04-25 00:48:13 +000083 snprintf(buf, sizeof(buf), "%d", arraySize);
daniel@transgaming.com0578f812010-05-17 09:58:39 +000084 mangledName += '[';
85 mangledName += buf;
86 mangledName += ']';
87 }
Jamie Madill98493dd2013-07-08 14:39:03 -040088 return mangledName;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000089}
90
Jamie Madill94bf7f22013-07-08 13:31:15 -040091size_t TType::getObjectSize() const
92{
93 size_t totalSize;
94
95 if (getBasicType() == EbtStruct)
Jamie Madill98493dd2013-07-08 14:39:03 -040096 totalSize = structure->objectSize();
Jamie Madill94bf7f22013-07-08 13:31:15 -040097 else
98 totalSize = primarySize * secondarySize;
99
100 if (isArray()) {
Jamie Madill18464b52013-07-08 14:01:55 -0400101 size_t arraySize = getArraySize();
Jamie Madill94bf7f22013-07-08 13:31:15 -0400102 if (arraySize > INT_MAX / totalSize)
103 totalSize = INT_MAX;
104 else
105 totalSize *= arraySize;
106 }
107
108 return totalSize;
109}
110
Jamie Madill98493dd2013-07-08 14:39:03 -0400111bool TStructure::containsArrays() const
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000112{
Jamie Madill98493dd2013-07-08 14:39:03 -0400113 for (size_t i = 0; i < mFields->size(); ++i) {
114 const TType* fieldType = (*mFields)[i]->type();
115 if (fieldType->isArray() || fieldType->isStructureContainingArrays())
daniel@transgaming.com8abd0b72012-09-27 17:46:07 +0000116 return true;
daniel@transgaming.com8abd0b72012-09-27 17:46:07 +0000117 }
daniel@transgaming.com8abd0b72012-09-27 17:46:07 +0000118 return false;
119}
120
Jamie Madill98493dd2013-07-08 14:39:03 -0400121TString TFieldListCollection::buildMangledName() const
122{
123 TString mangledName(mangledNamePrefix());
124 mangledName += *mName;
125 for (size_t i = 0; i < mFields->size(); ++i) {
126 mangledName += '-';
127 mangledName += (*mFields)[i]->type()->getMangledName();
128 }
129 return mangledName;
130}
131
132size_t TFieldListCollection::calculateObjectSize() const
133{
134 size_t size = 0;
135 for (size_t i = 0; i < mFields->size(); ++i) {
136 size_t fieldSize = (*mFields)[i]->type()->getObjectSize();
137 if (fieldSize > INT_MAX - size)
138 size = INT_MAX;
139 else
140 size += fieldSize;
141 }
142 return size;
143}
144
145int TStructure::calculateDeepestNesting() const
146{
147 int maxNesting = 0;
148 for (size_t i = 0; i < mFields->size(); ++i) {
149 maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
150 }
151 return 1 + maxNesting;
152}
153
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000154//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000155// Functions have buried pointers to delete.
156//
157TFunction::~TFunction()
158{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000159 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
160 delete (*i).type;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000161}
162
163//
164// Symbol table levels are a map of pointers to symbols that have to be deleted.
165//
166TSymbolTableLevel::~TSymbolTableLevel()
167{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000168 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
169 delete (*it).second;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000170}
171
172//
173// Change all function entries in the table with the non-mangled name
174// to be related to the provided built-in operation. This is a low
175// performance operation, and only intended for symbol tables that
176// live across a large number of compiles.
177//
178void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
179{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000180 tLevel::iterator it;
181 for (it = level.begin(); it != level.end(); ++it) {
182 if ((*it).second->isFunction()) {
183 TFunction* function = static_cast<TFunction*>((*it).second);
184 if (function->getName() == name)
185 function->relateToOperator(op);
186 }
187 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000188}
189
alokp@chromium.org8815d7f2010-09-09 17:30:03 +0000190//
191// Change all function entries in the table with the non-mangled name
192// to be related to the provided built-in extension. This is a low
193// performance operation, and only intended for symbol tables that
194// live across a large number of compiles.
195//
196void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext)
197{
198 for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
Jamie Madill2aeb26a2013-07-08 14:02:55 -0400199 TSymbol* symbol = it->second;
200 if (symbol->getName() == name) {
201 symbol->relateToExtension(ext);
alokp@chromium.org8815d7f2010-09-09 17:30:03 +0000202 }
203 }
204}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000205
206TSymbol::TSymbol(const TSymbol& copyOf)
207{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000208 name = NewPoolTString(copyOf.name->c_str());
209 uniqueId = copyOf.uniqueId;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000210}
211
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000212TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, bool *builtIn, bool *sameScope)
213{
214 int level = currentLevel();
215 TSymbol *symbol;
216
217 do
218 {
219 if (level == ESSL3_BUILTINS && shaderVersion != 300) level--;
220 if (level == ESSL1_BUILTINS && shaderVersion != 100) level--;
221
222 symbol = table[level]->find(name);
223 }
224 while (symbol == 0 && --level >= 0);
225
226 if (builtIn)
227 *builtIn = (level <= LAST_BUILTIN_LEVEL);
228 if (sameScope)
229 *sameScope = (level == currentLevel());
230
231 return symbol;
232}
233
234TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion)
235{
236 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
237 {
238 if (level == ESSL3_BUILTINS && shaderVersion != 300) level--;
239 if (level == ESSL1_BUILTINS && shaderVersion != 100) level--;
240
241 TSymbol *symbol = table[level]->find(name);
242
243 if (symbol)
244 return symbol;
245 }
246
247 return 0;
248}
Alok Priyadarshibc3f1ac2013-09-23 14:57:02 -0400249
250TSymbolTable::~TSymbolTable()
251{
252 while (table.size() > 0)
253 pop();
254}