blob: 4a384471c793d9b4ac6b7a3307265d4641123064 [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
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000016#include "compiler/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
alokp@chromium.org79fb1012012-04-26 21:07:39 +000021#include "common/angleutils.h"
22
Nicolas Capensbd10cf52013-06-20 09:51:51 -040023int TSymbolTableLevel::uniqueId = 0;
24
daniel@transgaming.com8abd0b72012-09-27 17:46:07 +000025TType::TType(const TPublicType &p) :
Jamie Madilla5efff92013-06-06 11:56:47 -040026 type(p.type), precision(p.precision), qualifier(p.qualifier), primarySize(p.primarySize), secondarySize(p.secondarySize), array(p.array), layoutQualifier(p.layoutQualifier), arraySize(p.arraySize),
shannonwoods@chromium.org5668c5d2013-05-30 00:11:48 +000027 maxArraySize(0), arrayInformationType(0), interfaceBlockType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0)
daniel@transgaming.com8abd0b72012-09-27 17:46:07 +000028{
29 if (p.userDef) {
30 structure = p.userDef->getStruct();
31 typeName = NewPoolTString(p.userDef->getTypeName().c_str());
32 computeDeepestStructNesting();
33 }
34}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000035
36//
37// Recursively generate mangled names.
38//
39void TType::buildMangledName(TString& mangledName)
40{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000041 if (isMatrix())
42 mangledName += 'm';
43 else if (isVector())
44 mangledName += 'v';
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000045
daniel@transgaming.com0578f812010-05-17 09:58:39 +000046 switch (type) {
47 case EbtFloat: mangledName += 'f'; break;
48 case EbtInt: mangledName += 'i'; break;
shannonwoods@chromium.org6b709912013-05-30 00:20:04 +000049 case EbtUInt: mangledName += 'u'; break;
daniel@transgaming.com0578f812010-05-17 09:58:39 +000050 case EbtBool: mangledName += 'b'; break;
51 case EbtSampler2D: mangledName += "s2"; break;
52 case EbtSamplerCube: mangledName += "sC"; break;
Nicolas Capens344e7142013-06-24 15:39:21 -040053 case EbtISampler2D: mangledName += "is2"; break;
54 case EbtISamplerCube: mangledName += "isC"; break;
Nicolas Capens2ffe0bb2013-06-24 15:56:19 -040055 case EbtUSampler2D: mangledName += "us2"; break;
56 case EbtUSamplerCube: mangledName += "usC"; break;
daniel@transgaming.com0578f812010-05-17 09:58:39 +000057 case EbtStruct:
58 mangledName += "struct-";
59 if (typeName)
60 mangledName += *typeName;
61 {// support MSVC++6.0
62 for (unsigned int i = 0; i < structure->size(); ++i) {
63 mangledName += '-';
64 (*structure)[i].type->buildMangledName(mangledName);
65 }
66 }
shannonwoods@chromium.org5668c5d2013-05-30 00:11:48 +000067 break;
68 case EbtInterfaceBlock:
69 {
70 mangledName += "interface-block-";
71 if (typeName)
72 {
73 mangledName += *typeName;
74 }
75 for (unsigned int i = 0; i < structure->size(); ++i)
76 {
77 mangledName += '-';
78 (*structure)[i].type->buildMangledName(mangledName);
79 }
80 }
81 break;
daniel@transgaming.com0578f812010-05-17 09:58:39 +000082 default:
83 break;
84 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000085
shannonwoods@chromium.org09e09882013-05-30 00:18:25 +000086 if (isMatrix())
87 {
88 mangledName += static_cast<char>('0' + getCols());
89 mangledName += static_cast<char>('x');
90 mangledName += static_cast<char>('0' + getRows());
91 }
92 else
93 {
94 mangledName += static_cast<char>('0' + getNominalSize());
95 }
daniel@transgaming.com0578f812010-05-17 09:58:39 +000096 if (isArray()) {
97 char buf[20];
kbr@chromium.orgddb6e8e2012-04-25 00:48:13 +000098 snprintf(buf, sizeof(buf), "%d", arraySize);
daniel@transgaming.com0578f812010-05-17 09:58:39 +000099 mangledName += '[';
100 mangledName += buf;
101 mangledName += ']';
102 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000103}
104
105int TType::getStructSize() const
106{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000107 if (!getStruct()) {
108 assert(false && "Not a struct");
109 return 0;
110 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000111
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000112 if (structureSize == 0)
alokp@chromium.org58e54292010-08-24 21:40:03 +0000113 for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000114 structureSize += ((*tl).type)->getObjectSize();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000115
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000116 return structureSize;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000117}
118
kbr@chromium.org476541f2011-10-27 21:14:51 +0000119void TType::computeDeepestStructNesting()
120{
121 if (!getStruct()) {
122 return;
123 }
124
125 int maxNesting = 0;
126 for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); ++tl) {
127 maxNesting = std::max(maxNesting, ((*tl).type)->getDeepestStructNesting());
128 }
129
130 deepestStructNesting = 1 + maxNesting;
131}
132
daniel@transgaming.com8abd0b72012-09-27 17:46:07 +0000133bool TType::isStructureContainingArrays() const
134{
135 if (!structure)
136 {
137 return false;
138 }
139
140 for (TTypeList::const_iterator member = structure->begin(); member != structure->end(); member++)
141 {
142 if (member->type->isArray() ||
143 member->type->isStructureContainingArrays())
144 {
145 return true;
146 }
147 }
148
149 return false;
150}
151
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000152//
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000153// Functions have buried pointers to delete.
154//
155TFunction::~TFunction()
156{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000157 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
158 delete (*i).type;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000159}
160
161//
162// Symbol table levels are a map of pointers to symbols that have to be deleted.
163//
164TSymbolTableLevel::~TSymbolTableLevel()
165{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000166 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
167 delete (*it).second;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000168}
169
170//
171// Change all function entries in the table with the non-mangled name
172// to be related to the provided built-in operation. This is a low
173// performance operation, and only intended for symbol tables that
174// live across a large number of compiles.
175//
176void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
177{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000178 tLevel::iterator it;
179 for (it = level.begin(); it != level.end(); ++it) {
180 if ((*it).second->isFunction()) {
181 TFunction* function = static_cast<TFunction*>((*it).second);
182 if (function->getName() == name)
183 function->relateToOperator(op);
184 }
185 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000186}
187
alokp@chromium.org8815d7f2010-09-09 17:30:03 +0000188//
189// Change all function entries in the table with the non-mangled name
190// to be related to the provided built-in extension. This is a low
191// performance operation, and only intended for symbol tables that
192// live across a large number of compiles.
193//
194void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext)
195{
196 for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
197 if (it->second->isFunction()) {
198 TFunction* function = static_cast<TFunction*>(it->second);
199 if (function->getName() == name)
200 function->relateToExtension(ext);
201 }
202 }
203}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000204
205TSymbol::TSymbol(const TSymbol& copyOf)
206{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000207 name = NewPoolTString(copyOf.name->c_str());
208 uniqueId = copyOf.uniqueId;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000209}
210
shannonwoods@chromium.org96e7ba12013-05-30 00:02:41 +0000211TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, bool *builtIn, bool *sameScope)
212{
213 int level = currentLevel();
214 TSymbol *symbol;
215
216 do
217 {
218 if (level == ESSL3_BUILTINS && shaderVersion != 300) level--;
219 if (level == ESSL1_BUILTINS && shaderVersion != 100) level--;
220
221 symbol = table[level]->find(name);
222 }
223 while (symbol == 0 && --level >= 0);
224
225 if (builtIn)
226 *builtIn = (level <= LAST_BUILTIN_LEVEL);
227 if (sameScope)
228 *sameScope = (level == currentLevel());
229
230 return symbol;
231}
232
233TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion)
234{
235 for (int level = LAST_BUILTIN_LEVEL; level >= 0; level--)
236 {
237 if (level == ESSL3_BUILTINS && shaderVersion != 300) level--;
238 if (level == ESSL1_BUILTINS && shaderVersion != 100) level--;
239
240 TSymbol *symbol = table[level]->find(name);
241
242 if (symbol)
243 return symbol;
244 }
245
246 return 0;
247}