1 //
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 #include <climits>
21
TType(const TPublicType & p)22 TType::TType(const TPublicType &p) :
23 type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize), structure(0)
24 {
25 if (p.userDef)
26 structure = p.userDef->getStruct();
27 }
28
29 //
30 // Recursively generate mangled names.
31 //
buildMangledName() const32 TString TType::buildMangledName() const
33 {
34 TString mangledName;
35 if (isMatrix())
36 mangledName += 'm';
37 else if (isVector())
38 mangledName += 'v';
39
40 switch (type) {
41 case EbtFloat: mangledName += 'f'; break;
42 case EbtInt: mangledName += 'i'; break;
43 case EbtBool: mangledName += 'b'; break;
44 case EbtSampler2D: mangledName += "s2"; break;
45 case EbtSamplerCube: mangledName += "sC"; break;
46 case EbtStruct: mangledName += structure->mangledName(); break;
47 default: break;
48 }
49
50 mangledName += static_cast<char>('0' + getNominalSize());
51 if (isArray()) {
52 char buf[20];
53 snprintf(buf, sizeof(buf), "%d", arraySize);
54 mangledName += '[';
55 mangledName += buf;
56 mangledName += ']';
57 }
58 return mangledName;
59 }
60
getObjectSize() const61 size_t TType::getObjectSize() const
62 {
63 size_t totalSize = 0;
64
65 if (getBasicType() == EbtStruct)
66 totalSize = structure->objectSize();
67 else if (matrix)
68 totalSize = size * size;
69 else
70 totalSize = size;
71
72 if (isArray()) {
73 size_t arraySize = getArraySize();
74 if (arraySize > INT_MAX / totalSize)
75 totalSize = INT_MAX;
76 else
77 totalSize *= arraySize;
78 }
79
80 return totalSize;
81 }
82
containsArrays() const83 bool TStructure::containsArrays() const
84 {
85 for (size_t i = 0; i < mFields->size(); ++i) {
86 const TType* fieldType = (*mFields)[i]->type();
87 if (fieldType->isArray() || fieldType->isStructureContainingArrays())
88 return true;
89 }
90 return false;
91 }
92
buildMangledName() const93 TString TStructure::buildMangledName() const
94 {
95 TString mangledName("struct-");
96 mangledName += *mName;
97 for (size_t i = 0; i < mFields->size(); ++i) {
98 mangledName += '-';
99 mangledName += (*mFields)[i]->type()->getMangledName();
100 }
101 return mangledName;
102 }
103
calculateObjectSize() const104 size_t TStructure::calculateObjectSize() const
105 {
106 size_t size = 0;
107 for (size_t i = 0; i < mFields->size(); ++i) {
108 size_t fieldSize = (*mFields)[i]->type()->getObjectSize();
109 if (fieldSize > INT_MAX - size)
110 size = INT_MAX;
111 else
112 size += fieldSize;
113 }
114 return size;
115 }
116
calculateDeepestNesting() const117 int TStructure::calculateDeepestNesting() const
118 {
119 int maxNesting = 0;
120 for (size_t i = 0; i < mFields->size(); ++i) {
121 maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
122 }
123 return 1 + maxNesting;
124 }
125
126 //
127 // Dump functions.
128 //
129
dump(TInfoSink & infoSink) const130 void 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
dump(TInfoSink & infoSink) const139 void TFunction::dump(TInfoSink &infoSink) const
140 {
141 infoSink.debug << getName().c_str() << ": " << returnType.getBasicString() << " " << getMangledName().c_str() << "\n";
142 }
143
dump(TInfoSink & infoSink) const144 void 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
dump(TInfoSink & infoSink) const151 void 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 //
~TFunction()162 TFunction::~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 //
~TSymbolTableLevel()171 TSymbolTableLevel::~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 //
relateToOperator(const char * name,TOperator op)183 void 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 //
relateToExtension(const char * name,const TString & ext)201 void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext)
202 {
203 for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
204 TSymbol* symbol = it->second;
205 if (symbol->getName() == name)
206 symbol->relateToExtension(ext);
207 }
208 }
209
~TSymbolTable()210 TSymbolTable::~TSymbolTable()
211 {
212 for (size_t i = 0; i < table.size(); ++i)
213 delete table[i];
214 for (size_t i = 0; i < precisionStack.size(); ++i)
215 delete precisionStack[i];
216 }
217