blob: e6695d6b904f5df21107659fd339b5ff25b28edd [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
daniel@transgaming.combbf56f72010-04-20 18:52:13 +000012#include "compiler/SymbolTable.h"
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000013
apatrick@chromium.org8187fa82010-06-15 22:09:28 +000014#include <stdio.h>
15
kbr@chromium.org476541f2011-10-27 21:14:51 +000016#include <algorithm>
17
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000018//
19// TType helper function needs a place to live.
20//
21
22//
23// Recursively generate mangled names.
24//
25void TType::buildMangledName(TString& mangledName)
26{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000027 if (isMatrix())
28 mangledName += 'm';
29 else if (isVector())
30 mangledName += 'v';
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000031
daniel@transgaming.com0578f812010-05-17 09:58:39 +000032 switch (type) {
33 case EbtFloat: mangledName += 'f'; break;
34 case EbtInt: mangledName += 'i'; break;
35 case EbtBool: mangledName += 'b'; break;
36 case EbtSampler2D: mangledName += "s2"; break;
37 case EbtSamplerCube: mangledName += "sC"; break;
38 case EbtStruct:
39 mangledName += "struct-";
40 if (typeName)
41 mangledName += *typeName;
42 {// support MSVC++6.0
43 for (unsigned int i = 0; i < structure->size(); ++i) {
44 mangledName += '-';
45 (*structure)[i].type->buildMangledName(mangledName);
46 }
47 }
48 default:
49 break;
50 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000051
daniel@transgaming.com0578f812010-05-17 09:58:39 +000052 mangledName += static_cast<char>('0' + getNominalSize());
53 if (isArray()) {
54 char buf[20];
55 sprintf(buf, "%d", arraySize);
56 mangledName += '[';
57 mangledName += buf;
58 mangledName += ']';
59 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000060}
61
62int TType::getStructSize() const
63{
daniel@transgaming.com0578f812010-05-17 09:58:39 +000064 if (!getStruct()) {
65 assert(false && "Not a struct");
66 return 0;
67 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000068
daniel@transgaming.com0578f812010-05-17 09:58:39 +000069 if (structureSize == 0)
alokp@chromium.org58e54292010-08-24 21:40:03 +000070 for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
daniel@transgaming.com0578f812010-05-17 09:58:39 +000071 structureSize += ((*tl).type)->getObjectSize();
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000072
daniel@transgaming.com0578f812010-05-17 09:58:39 +000073 return structureSize;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000074}
75
kbr@chromium.org476541f2011-10-27 21:14:51 +000076void TType::computeDeepestStructNesting()
77{
78 if (!getStruct()) {
79 return;
80 }
81
82 int maxNesting = 0;
83 for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); ++tl) {
84 maxNesting = std::max(maxNesting, ((*tl).type)->getDeepestStructNesting());
85 }
86
87 deepestStructNesting = 1 + maxNesting;
88}
89
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +000090//
91// Dump functions.
92//
93
94void TVariable::dump(TInfoSink& infoSink) const
95{
daniel@transgaming.coma5d76232010-05-17 09:58:47 +000096 infoSink.debug << getName().c_str() << ": " << type.getQualifierString() << " " << type.getPrecisionString() << " " << type.getBasicString();
daniel@transgaming.com0578f812010-05-17 09:58:39 +000097 if (type.isArray()) {
98 infoSink.debug << "[0]";
99 }
100 infoSink.debug << "\n";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000101}
102
103void TFunction::dump(TInfoSink &infoSink) const
104{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000105 infoSink.debug << getName().c_str() << ": " << returnType.getBasicString() << " " << getMangledName().c_str() << "\n";
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000106}
107
108void TSymbolTableLevel::dump(TInfoSink &infoSink) const
109{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000110 tLevel::const_iterator it;
111 for (it = level.begin(); it != level.end(); ++it)
112 (*it).second->dump(infoSink);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000113}
114
115void TSymbolTable::dump(TInfoSink &infoSink) const
116{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000117 for (int level = currentLevel(); level >= 0; --level) {
118 infoSink.debug << "LEVEL " << level << "\n";
119 table[level]->dump(infoSink);
120 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000121}
122
123//
124// Functions have buried pointers to delete.
125//
126TFunction::~TFunction()
127{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000128 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
129 delete (*i).type;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000130}
131
132//
133// Symbol table levels are a map of pointers to symbols that have to be deleted.
134//
135TSymbolTableLevel::~TSymbolTableLevel()
136{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000137 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
138 delete (*it).second;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000139}
140
141//
142// Change all function entries in the table with the non-mangled name
143// to be related to the provided built-in operation. This is a low
144// performance operation, and only intended for symbol tables that
145// live across a large number of compiles.
146//
147void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
148{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000149 tLevel::iterator it;
150 for (it = level.begin(); it != level.end(); ++it) {
151 if ((*it).second->isFunction()) {
152 TFunction* function = static_cast<TFunction*>((*it).second);
153 if (function->getName() == name)
154 function->relateToOperator(op);
155 }
156 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000157}
158
alokp@chromium.org8815d7f2010-09-09 17:30:03 +0000159//
160// Change all function entries in the table with the non-mangled name
161// to be related to the provided built-in extension. This is a low
162// performance operation, and only intended for symbol tables that
163// live across a large number of compiles.
164//
165void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext)
166{
167 for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
168 if (it->second->isFunction()) {
169 TFunction* function = static_cast<TFunction*>(it->second);
170 if (function->getName() == name)
171 function->relateToExtension(ext);
172 }
173 }
174}
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000175
176TSymbol::TSymbol(const TSymbol& copyOf)
177{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000178 name = NewPoolTString(copyOf.name->c_str());
179 uniqueId = copyOf.uniqueId;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000180}
181
182TVariable::TVariable(const TVariable& copyOf, TStructureMap& remapper) : TSymbol(copyOf)
183{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000184 type.copyType(copyOf.type, remapper);
185 userType = copyOf.userType;
186 // for builtIn symbol table level, unionArray and arrayInformation pointers should be NULL
187 assert(copyOf.arrayInformationType == 0);
188 arrayInformationType = 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000189
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000190 if (copyOf.unionArray) {
191 assert(!copyOf.type.getStruct());
192 assert(copyOf.type.getObjectSize() == 1);
193 unionArray = new ConstantUnion[1];
194 unionArray[0] = copyOf.unionArray[0];
195 } else
196 unionArray = 0;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000197}
198
199TVariable* TVariable::clone(TStructureMap& remapper)
200{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000201 TVariable *variable = new TVariable(*this, remapper);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000202
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000203 return variable;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000204}
205
206TFunction::TFunction(const TFunction& copyOf, TStructureMap& remapper) : TSymbol(copyOf)
207{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000208 for (unsigned int i = 0; i < copyOf.parameters.size(); ++i) {
209 TParameter param;
210 parameters.push_back(param);
211 parameters.back().copyParam(copyOf.parameters[i], remapper);
212 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000213
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000214 returnType.copyType(copyOf.returnType, remapper);
215 mangledName = copyOf.mangledName;
216 op = copyOf.op;
217 defined = copyOf.defined;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000218}
219
220TFunction* TFunction::clone(TStructureMap& remapper)
221{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000222 TFunction *function = new TFunction(*this, remapper);
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000223
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000224 return function;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000225}
226
227TSymbolTableLevel* TSymbolTableLevel::clone(TStructureMap& remapper)
228{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000229 TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
230 tLevel::iterator iter;
231 for (iter = level.begin(); iter != level.end(); ++iter) {
232 symTableLevel->insert(*iter->second->clone(remapper));
233 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000234
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000235 return symTableLevel;
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000236}
237
238void TSymbolTable::copyTable(const TSymbolTable& copyOf)
239{
daniel@transgaming.com0578f812010-05-17 09:58:39 +0000240 TStructureMap remapper;
241 uniqueId = copyOf.uniqueId;
242 for (unsigned int i = 0; i < copyOf.table.size(); ++i) {
243 table.push_back(copyOf.table[i]->clone(remapper));
244 }
daniel@transgaming.coma5d76232010-05-17 09:58:47 +0000245 for( unsigned int i = 0; i < copyOf.precisionStack.size(); i++) {
246 precisionStack.push_back( copyOf.precisionStack[i] );
247 }
daniel@transgaming.com4f39fd92010-03-08 20:26:45 +0000248}