blob: adf56a8a300f50de532f077314f27579f88f2bc2 [file] [log] [blame]
John Bauman66b8ab22014-05-06 15:57:45 -04001//
2// Copyright (c) 2002-2012 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/SymbolTable.h"
17
18#include <stdio.h>
19#include <algorithm>
20
21#if defined(_MSC_VER)
22#define snprintf _snprintf
23#endif
24
25TType::TType(const TPublicType &p) :
26 type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize),
27 maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0)
28{
29 if (p.userDef)
30 {
31 structure = p.userDef->getStruct();
32 typeName = NewPoolTString(p.userDef->getTypeName().c_str());
33 computeDeepestStructNesting();
34 }
35}
36
37//
38// Recursively generate mangled names.
39//
40void TType::buildMangledName(TString& mangledName)
41{
42 if (isMatrix())
43 mangledName += 'm';
44 else if (isVector())
45 mangledName += 'v';
46
47 switch (type) {
48 case EbtFloat: mangledName += 'f'; break;
49 case EbtInt: mangledName += 'i'; break;
50 case EbtBool: mangledName += 'b'; break;
51 case EbtSampler2D: mangledName += "s2"; break;
52 case EbtSamplerCube: mangledName += "sC"; break;
53 case EbtStruct:
54 mangledName += "struct-";
55 if (typeName)
56 mangledName += *typeName;
57 {// support MSVC++6.0
58 for (unsigned int i = 0; i < structure->size(); ++i) {
59 mangledName += '-';
60 (*structure)[i].type->buildMangledName(mangledName);
61 }
62 }
63 default:
64 break;
65 }
66
67 mangledName += static_cast<char>('0' + getNominalSize());
68 if (isArray()) {
69 char buf[20];
70 snprintf(buf, sizeof(buf), "%d", arraySize);
71 mangledName += '[';
72 mangledName += buf;
73 mangledName += ']';
74 }
75}
76
77int TType::getStructSize() const
78{
79 if (!getStruct()) {
80 assert(false && "Not a struct");
81 return 0;
82 }
83
84 if (structureSize == 0)
85 for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
86 structureSize += ((*tl).type)->getObjectSize();
87
88 return structureSize;
89}
90
91void TType::computeDeepestStructNesting()
92{
93 if (!structure)
94 {
95 return;
96 }
97
98 int maxNesting = 0;
99 for (TTypeList::const_iterator tl = structure->begin(); tl != structure->end(); tl++)
100 {
101 maxNesting = std::max(maxNesting, ((*tl).type)->getDeepestStructNesting());
102 }
103
104 deepestStructNesting = 1 + maxNesting;
105}
106
107bool TType::isStructureContainingArrays() const
108{
109 if (!structure)
110 {
111 return false;
112 }
113
114 for (TTypeList::const_iterator member = structure->begin(); member != structure->end(); member++)
115 {
116 if (member->type->isArray() ||
117 member->type->isStructureContainingArrays())
118 {
119 return true;
120 }
121 }
122
123 return false;
124}
125
126//
127// Dump functions.
128//
129
130void TVariable::dump(TInfoSink& infoSink) const
131{
132 infoSink.debug << getName().c_str() << ": " << type.getQualifierString() << " " << type.getPrecisionString() << " " << type.getBasicString();
133 if (type.isArray()) {
134 infoSink.debug << "[0]";
135 }
136 infoSink.debug << "\n";
137}
138
139void TFunction::dump(TInfoSink &infoSink) const
140{
141 infoSink.debug << getName().c_str() << ": " << returnType.getBasicString() << " " << getMangledName().c_str() << "\n";
142}
143
144void TSymbolTableLevel::dump(TInfoSink &infoSink) const
145{
146 tLevel::const_iterator it;
147 for (it = level.begin(); it != level.end(); ++it)
148 (*it).second->dump(infoSink);
149}
150
151void TSymbolTable::dump(TInfoSink &infoSink) const
152{
153 for (int level = currentLevel(); level >= 0; --level) {
154 infoSink.debug << "LEVEL " << level << "\n";
155 table[level]->dump(infoSink);
156 }
157}
158
159//
160// Functions have buried pointers to delete.
161//
162TFunction::~TFunction()
163{
164 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
165 delete (*i).type;
166}
167
168//
169// Symbol table levels are a map of pointers to symbols that have to be deleted.
170//
171TSymbolTableLevel::~TSymbolTableLevel()
172{
173 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
174 delete (*it).second;
175}
176
177//
178// Change all function entries in the table with the non-mangled name
179// to be related to the provided built-in operation. This is a low
180// performance operation, and only intended for symbol tables that
181// live across a large number of compiles.
182//
183void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
184{
185 tLevel::iterator it;
186 for (it = level.begin(); it != level.end(); ++it) {
187 if ((*it).second->isFunction()) {
188 TFunction* function = static_cast<TFunction*>((*it).second);
189 if (function->getName() == name)
190 function->relateToOperator(op);
191 }
192 }
193}
194
195//
196// Change all function entries in the table with the non-mangled name
197// to be related to the provided built-in extension. This is a low
198// performance operation, and only intended for symbol tables that
199// live across a large number of compiles.
200//
201void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext)
202{
203 for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
204 if (it->second->isFunction()) {
205 TFunction* function = static_cast<TFunction*>(it->second);
206 if (function->getName() == name)
207 function->relateToExtension(ext);
208 }
209 }
210}
211
212TSymbol::TSymbol(const TSymbol& copyOf)
213{
214 name = NewPoolTString(copyOf.name->c_str());
215 uniqueId = copyOf.uniqueId;
216}
217
218TVariable::TVariable(const TVariable& copyOf, TStructureMap& remapper) : TSymbol(copyOf)
219{
220 type.copyType(copyOf.type, remapper);
221 userType = copyOf.userType;
222 // for builtIn symbol table level, unionArray and arrayInformation pointers should be NULL
223 assert(copyOf.arrayInformationType == 0);
224 arrayInformationType = 0;
225
226 if (copyOf.unionArray) {
227 assert(!copyOf.type.getStruct());
228 assert(copyOf.type.getObjectSize() == 1);
229 unionArray = new ConstantUnion[1];
230 unionArray[0] = copyOf.unionArray[0];
231 } else
232 unionArray = 0;
233}
234
235TVariable* TVariable::clone(TStructureMap& remapper)
236{
237 TVariable *variable = new TVariable(*this, remapper);
238
239 return variable;
240}
241
242TFunction::TFunction(const TFunction& copyOf, TStructureMap& remapper) : TSymbol(copyOf)
243{
244 for (unsigned int i = 0; i < copyOf.parameters.size(); ++i) {
245 TParameter param;
246 parameters.push_back(param);
247 parameters.back().copyParam(copyOf.parameters[i], remapper);
248 }
249
250 returnType.copyType(copyOf.returnType, remapper);
251 mangledName = copyOf.mangledName;
252 op = copyOf.op;
253 defined = copyOf.defined;
254}
255
256TFunction* TFunction::clone(TStructureMap& remapper)
257{
258 TFunction *function = new TFunction(*this, remapper);
259
260 return function;
261}
262
263TSymbolTableLevel* TSymbolTableLevel::clone(TStructureMap& remapper)
264{
265 TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
266 tLevel::iterator iter;
267 for (iter = level.begin(); iter != level.end(); ++iter) {
268 symTableLevel->insert(*iter->second->clone(remapper));
269 }
270
271 return symTableLevel;
272}
273
274void TSymbolTable::copyTable(const TSymbolTable& copyOf)
275{
276 TStructureMap remapper;
277 uniqueId = copyOf.uniqueId;
278 for (unsigned int i = 0; i < copyOf.table.size(); ++i) {
279 table.push_back(copyOf.table[i]->clone(remapper));
280 }
281 for( unsigned int i = 0; i < copyOf.precisionStack.size(); i++) {
282 precisionStack.push_back( copyOf.precisionStack[i] );
283 }
284}