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