blob: fa54a9a597b825a9c9a4a6eb54ac10ab54946da5 [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
12#include "SymbolTable.h"
13
14//
15// TType helper function needs a place to live.
16//
17
18//
19// Recursively generate mangled names.
20//
21void TType::buildMangledName(TString& mangledName)
22{
23 if (isMatrix())
24 mangledName += 'm';
25 else if (isVector())
26 mangledName += 'v';
27
28 switch (type) {
29 case EbtFloat: mangledName += 'f'; break;
30 case EbtInt: mangledName += 'i'; break;
31 case EbtBool: mangledName += 'b'; break;
32 case EbtSampler2D: mangledName += "s2"; break;
33 case EbtSamplerCube: mangledName += "sC"; break;
34 case EbtStruct:
35 mangledName += "struct-";
36 if (typeName)
37 mangledName += *typeName;
38 {// support MSVC++6.0
39 for (unsigned int i = 0; i < structure->size(); ++i) {
40 mangledName += '-';
41 (*structure)[i].type->buildMangledName(mangledName);
42 }
43 }
44 default:
45 break;
46 }
47
48 mangledName += static_cast<char>('0' + getNominalSize());
49 if (isArray()) {
50 char buf[10];
51 sprintf(buf, "%d", arraySize);
52 mangledName += '[';
53 mangledName += buf;
54 mangledName += ']';
55 }
56}
57
58int TType::getStructSize() const
59{
60 if (!getStruct()) {
61 assert(false && "Not a struct");
62 return 0;
63 }
64
65 if (structureSize == 0)
66 for (TTypeList::iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
67 structureSize += ((*tl).type)->getObjectSize();
68
69 return structureSize;
70}
71
72//
73// Dump functions.
74//
75
76void TVariable::dump(TInfoSink& infoSink) const
77{
78 infoSink.debug << getName().c_str() << ": " << type.getQualifierString() << " " << type.getBasicString();
79 if (type.isArray()) {
80 infoSink.debug << "[0]";
81 }
82 infoSink.debug << "\n";
83}
84
85void TFunction::dump(TInfoSink &infoSink) const
86{
87 infoSink.debug << getName().c_str() << ": " << returnType.getBasicString() << " " << getMangledName().c_str() << "\n";
88}
89
90void TSymbolTableLevel::dump(TInfoSink &infoSink) const
91{
92 tLevel::const_iterator it;
93 for (it = level.begin(); it != level.end(); ++it)
94 (*it).second->dump(infoSink);
95}
96
97void TSymbolTable::dump(TInfoSink &infoSink) const
98{
99 for (int level = currentLevel(); level >= 0; --level) {
100 infoSink.debug << "LEVEL " << level << "\n";
101 table[level]->dump(infoSink);
102 }
103}
104
105//
106// Functions have buried pointers to delete.
107//
108TFunction::~TFunction()
109{
110 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
111 delete (*i).type;
112}
113
114//
115// Symbol table levels are a map of pointers to symbols that have to be deleted.
116//
117TSymbolTableLevel::~TSymbolTableLevel()
118{
119 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
120 delete (*it).second;
121}
122
123//
124// Change all function entries in the table with the non-mangled name
125// to be related to the provided built-in operation. This is a low
126// performance operation, and only intended for symbol tables that
127// live across a large number of compiles.
128//
129void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
130{
131 tLevel::iterator it;
132 for (it = level.begin(); it != level.end(); ++it) {
133 if ((*it).second->isFunction()) {
134 TFunction* function = static_cast<TFunction*>((*it).second);
135 if (function->getName() == name)
136 function->relateToOperator(op);
137 }
138 }
139}
140
141
142TSymbol::TSymbol(const TSymbol& copyOf)
143{
144 name = NewPoolTString(copyOf.name->c_str());
145 uniqueId = copyOf.uniqueId;
146}
147
148TVariable::TVariable(const TVariable& copyOf, TStructureMap& remapper) : TSymbol(copyOf)
149{
150 type.copyType(copyOf.type, remapper);
151 userType = copyOf.userType;
152 // for builtIn symbol table level, unionArray and arrayInformation pointers should be NULL
153 assert(copyOf.arrayInformationType == 0);
154 arrayInformationType = 0;
155
156 if (copyOf.unionArray) {
157 assert(!copyOf.type.getStruct());
158 assert(copyOf.type.getObjectSize() == 1);
159 unionArray = new constUnion[1];
160 unionArray[0] = copyOf.unionArray[0];
161 } else
162 unionArray = 0;
163}
164
165TVariable* TVariable::clone(TStructureMap& remapper)
166{
167 TVariable *variable = new TVariable(*this, remapper);
168
169 return variable;
170}
171
172TFunction::TFunction(const TFunction& copyOf, TStructureMap& remapper) : TSymbol(copyOf)
173{
174 for (unsigned int i = 0; i < copyOf.parameters.size(); ++i) {
175 TParameter param;
176 parameters.push_back(param);
177 parameters.back().copyParam(copyOf.parameters[i], remapper);
178 }
179
180 returnType.copyType(copyOf.returnType, remapper);
181 mangledName = copyOf.mangledName;
182 op = copyOf.op;
183 defined = copyOf.defined;
184}
185
186TFunction* TFunction::clone(TStructureMap& remapper)
187{
188 TFunction *function = new TFunction(*this, remapper);
189
190 return function;
191}
192
193TSymbolTableLevel* TSymbolTableLevel::clone(TStructureMap& remapper)
194{
195 TSymbolTableLevel *symTableLevel = new TSymbolTableLevel();
196 tLevel::iterator iter;
197 for (iter = level.begin(); iter != level.end(); ++iter) {
198 symTableLevel->insert(*iter->second->clone(remapper));
199 }
200
201 return symTableLevel;
202}
203
204void TSymbolTable::copyTable(const TSymbolTable& copyOf)
205{
206 TStructureMap remapper;
207 uniqueId = copyOf.uniqueId;
208 for (unsigned int i = 0; i < copyOf.table.size(); ++i) {
209 table.push_back(copyOf.table[i]->clone(remapper));
210 }
211}