blob: 01ec0db8c9b973f3a6947fcda9209c9af903dcc8 [file] [log] [blame]
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +00001//
2// Copyright (c) 2002-2010 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
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>
19
kbr@chromium.org476541f2011-10-27 21:14:51 +000020#include <algorithm>
21
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000022//
23// TType helper function needs a place to live.
24//
25
26//
27// Recursively generate mangled names.
28//
29void TType::buildMangledName(TString& mangledName)
30{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000031 if (isMatrix())
32 mangledName += 'm';
33 else if (isVector())
34 mangledName += 'v';
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000035
daniel@transgaming.com0578f812010-05-17 09:58:39 +000036 switch (type) {
37 case EbtFloat: mangledName += 'f'; break;
38 case EbtInt: mangledName += 'i'; break;
39 case EbtBool: mangledName += 'b'; break;
40 case EbtSampler2D: mangledName += "s2"; break;
41 case EbtSamplerCube: mangledName += "sC"; break;
42 case EbtStruct:
43 mangledName += "struct-";
44 if (typeName)
45 mangledName += *typeName;
46 {// support MSVC++6.0
47 for (unsigned int i = 0; i < structure->size(); ++i) {
48 mangledName += '-';
49 (*structure)[i].type->buildMangledName(mangledName);
50 }
51 }
52 default:
53 break;
54 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000055
daniel@transgaming.com0578f812010-05-17 09:58:39 +000056 mangledName += static_cast<char>('0' + getNominalSize());
57 if (isArray()) {
58 char buf[20];
kbr@chromium.orgddb6e8e2012-04-25 00:48:13 +000059 snprintf(buf, sizeof(buf), "%d", arraySize);
daniel@transgaming.com0578f812010-05-17 09:58:39 +000060 mangledName += '[';
61 mangledName += buf;
62 mangledName += ']';
63 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000064}
65
66int TType::getStructSize() const
67{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000068 if (!getStruct()) {
69 assert(false && "Not a struct");
70 return 0;
71 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000072
daniel@transgaming.com0578f812010-05-17 09:58:39 +000073 if (structureSize == 0)
alokp@chromium.org58e54292010-08-24 21:40:03 +000074 for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
daniel@transgaming.com0578f812010-05-17 09:58:39 +000075 structureSize += ((*tl).type)->getObjectSize();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000076
daniel@transgaming.com0578f812010-05-17 09:58:39 +000077 return structureSize;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000078}
79
kbr@chromium.org476541f2011-10-27 21:14:51 +000080void TType::computeDeepestStructNesting()
81{
82 if (!getStruct()) {
83 return;
84 }
85
86 int maxNesting = 0;
87 for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); ++tl) {
88 maxNesting = std::max(maxNesting, ((*tl).type)->getDeepestStructNesting());
89 }
90
91 deepestStructNesting = 1 + maxNesting;
92}
93
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000094//
95// Dump functions.
96//
97
98void TVariable::dump(TInfoSink& infoSink) const
99{
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000100 infoSink.debug << getName().c_str() << ": " << type.getQualifierString() << " " << type.getPrecisionString() << " " << type.getBasicString();
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000101 if (type.isArray()) {
102 infoSink.debug << "[0]";
103 }
104 infoSink.debug << "\n";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000105}
106
107void TFunction::dump(TInfoSink &infoSink) const
108{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000109 infoSink.debug << getName().c_str() << ": " << returnType.getBasicString() << " " << getMangledName().c_str() << "\n";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000110}
111
112void TSymbolTableLevel::dump(TInfoSink &infoSink) const
113{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000114 tLevel::const_iterator it;
115 for (it = level.begin(); it != level.end(); ++it)
116 (*it).second->dump(infoSink);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000117}
118
119void TSymbolTable::dump(TInfoSink &infoSink) const
120{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000121 for (int level = currentLevel(); level >= 0; --level) {
122 infoSink.debug << "LEVEL " << level << "\n";
123 table[level]->dump(infoSink);
124 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000125}
126
127//
128// Functions have buried pointers to delete.
129//
130TFunction::~TFunction()
131{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000132 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
133 delete (*i).type;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000134}
135
136//
137// Symbol table levels are a map of pointers to symbols that have to be deleted.
138//
139TSymbolTableLevel::~TSymbolTableLevel()
140{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000141 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
142 delete (*it).second;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000143}
144
145//
146// Change all function entries in the table with the non-mangled name
147// to be related to the provided built-in operation. This is a low
148// performance operation, and only intended for symbol tables that
149// live across a large number of compiles.
150//
151void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
152{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000153 tLevel::iterator it;
154 for (it = level.begin(); it != level.end(); ++it) {
155 if ((*it).second->isFunction()) {
156 TFunction* function = static_cast<TFunction*>((*it).second);
157 if (function->getName() == name)
158 function->relateToOperator(op);
159 }
160 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000161}
162
alokp@chromium.org8815d7f2010-09-09 17:30:03 +0000163//
164// Change all function entries in the table with the non-mangled name
165// to be related to the provided built-in extension. This is a low
166// performance operation, and only intended for symbol tables that
167// live across a large number of compiles.
168//
169void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext)
170{
171 for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
172 if (it->second->isFunction()) {
173 TFunction* function = static_cast<TFunction*>(it->second);
174 if (function->getName() == name)
175 function->relateToExtension(ext);
176 }
177 }
178}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000179
180TSymbol::TSymbol(const TSymbol& copyOf)
181{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000182 name = NewPoolTString(copyOf.name->c_str());
183 uniqueId = copyOf.uniqueId;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000184}
185
186TVariable::TVariable(const TVariable& copyOf, TStructureMap& remapper) : TSymbol(copyOf)
187{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000188 type.copyType(copyOf.type, remapper);
189 userType = copyOf.userType;
190 // for builtIn symbol table level, unionArray and arrayInformation pointers should be NULL
191 assert(copyOf.arrayInformationType == 0);
192 arrayInformationType = 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000193
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000194 if (copyOf.unionArray) {
195 assert(!copyOf.type.getStruct());
196 assert(copyOf.type.getObjectSize() == 1);
197 unionArray = new ConstantUnion[1];
198 unionArray[0] = copyOf.unionArray[0];
199 } else
200 unionArray = 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000201}
202
203TVariable* TVariable::clone(TStructureMap& remapper)
204{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000205 TVariable *variable = new TVariable(*this, remapper);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000206
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000207 return variable;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000208}
209
210TFunction::TFunction(const TFunction& copyOf, TStructureMap& remapper) : TSymbol(copyOf)
211{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000212 for (unsigned int i = 0; i < copyOf.parameters.size(); ++i) {
213 TParameter param;
214 parameters.push_back(param);
215 parameters.back().copyParam(copyOf.parameters[i], remapper);
216 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000217
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000218 returnType.copyType(copyOf.returnType, remapper);
219 mangledName = copyOf.mangledName;
220 op = copyOf.op;
221 defined = copyOf.defined;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000222}
223
224TFunction* TFunction::clone(TStructureMap& remapper)
225{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000226 TFunction *function = new TFunction(*this, remapper);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000227
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000228 return function;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000229}
230
231TSymbolTableLevel* TSymbolTableLevel::clone(TStructureMap& remapper)
232{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000233 TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
234 tLevel::iterator iter;
235 for (iter = level.begin(); iter != level.end(); ++iter) {
236 symTableLevel->insert(*iter->second->clone(remapper));
237 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000238
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000239 return symTableLevel;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000240}
241
242void TSymbolTable::copyTable(const TSymbolTable& copyOf)
243{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000244 TStructureMap remapper;
245 uniqueId = copyOf.uniqueId;
246 for (unsigned int i = 0; i < copyOf.table.size(); ++i) {
247 table.push_back(copyOf.table[i]->clone(remapper));
248 }
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000249 for( unsigned int i = 0; i < copyOf.precisionStack.size(); i++) {
250 precisionStack.push_back( copyOf.precisionStack[i] );
251 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000252}