blob: 2881977f5999cd56fa19c4e03225149844209e2e [file] [log] [blame]
John Bauman66b8ab22014-05-06 15:57:45 -04001//
John Baumand4ae8632014-05-06 16:18:33 -04002// Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
John Bauman66b8ab22014-05-06 15:57:45 -04003// 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
Nicolas Capenscc863da2015-01-21 15:50:55 -050016#include "SymbolTable.h"
John Bauman66b8ab22014-05-06 15:57:45 -040017
18#include <stdio.h>
19#include <algorithm>
20
21#if defined(_MSC_VER)
22#define snprintf _snprintf
23#endif
24
John Baumand4ae8632014-05-06 16:18:33 -040025int TSymbolTableLevel::uniqueId = 0;
26
John Bauman66b8ab22014-05-06 15:57:45 -040027TType::TType(const TPublicType &p) :
Alexis Hetub14178b2015-04-13 13:23:20 -040028 type(p.type), precision(p.precision), primarySize(p.primarySize), secondarySize(p.secondarySize), qualifier(p.qualifier), array(p.array), arraySize(p.arraySize),
Alexis Hetua8b364b2015-06-10 11:48:40 -040029 maxArraySize(0), arrayInformationType(0), structure(0), deepestStructNesting(0), mangled(0)
John Bauman66b8ab22014-05-06 15:57:45 -040030{
31 if (p.userDef)
32 {
33 structure = p.userDef->getStruct();
John Bauman66b8ab22014-05-06 15:57:45 -040034 computeDeepestStructNesting();
35 }
36}
37
38//
39// Recursively generate mangled names.
40//
41void TType::buildMangledName(TString& mangledName)
42{
43 if (isMatrix())
44 mangledName += 'm';
45 else if (isVector())
46 mangledName += 'v';
47
48 switch (type) {
49 case EbtFloat: mangledName += 'f'; break;
50 case EbtInt: mangledName += 'i'; break;
Nicolas Capens3c20f802015-02-17 17:17:20 -050051 case EbtUInt: mangledName += 'u'; break;
John Bauman66b8ab22014-05-06 15:57:45 -040052 case EbtBool: mangledName += 'b'; break;
53 case EbtSampler2D: mangledName += "s2"; break;
Alexis Hetub027aa92015-01-19 15:56:12 -050054 case EbtSampler3D: mangledName += "s3"; break;
Alexis Hetua8b364b2015-06-10 11:48:40 -040055 case EbtSamplerCube: mangledName += "sC"; break;
56 case EbtSampler2DArray: mangledName += "s2a"; break;
57 case EbtSamplerExternalOES: mangledName += "sext"; break;
58 case EbtISampler2D: mangledName += "is2"; break;
59 case EbtISampler3D: mangledName += "is3"; break;
60 case EbtISamplerCube: mangledName += "isC"; break;
61 case EbtISampler2DArray: mangledName += "is2a"; break;
62 case EbtUSampler2D: mangledName += "us2"; break;
63 case EbtUSampler3D: mangledName += "us3"; break;
64 case EbtUSamplerCube: mangledName += "usC"; break;
65 case EbtUSampler2DArray: mangledName += "us2a"; break;
66 case EbtSampler2DShadow: mangledName += "s2s"; break;
67 case EbtSamplerCubeShadow: mangledName += "sCs"; break;
68 case EbtSampler2DArrayShadow: mangledName += "s2as"; break;
69 case EbtStruct: mangledName += structure->mangledName(); break;
70 case EbtInterfaceBlock: mangledName += interfaceBlock->mangledName(); break;
John Bauman66b8ab22014-05-06 15:57:45 -040071 default:
72 break;
73 }
74
75 mangledName += static_cast<char>('0' + getNominalSize());
Alexis Hetu39358652015-05-26 14:34:54 -040076 if(isMatrix()) {
77 mangledName += static_cast<char>('0' + getSecondarySize());
78 }
John Bauman66b8ab22014-05-06 15:57:45 -040079 if (isArray()) {
80 char buf[20];
81 snprintf(buf, sizeof(buf), "%d", arraySize);
82 mangledName += '[';
83 mangledName += buf;
84 mangledName += ']';
85 }
86}
87
88int TType::getStructSize() const
89{
90 if (!getStruct()) {
91 assert(false && "Not a struct");
92 return 0;
93 }
94
Alexis Hetua8b364b2015-06-10 11:48:40 -040095 return getStruct()->objectSize();
John Bauman66b8ab22014-05-06 15:57:45 -040096}
97
98void TType::computeDeepestStructNesting()
99{
Alexis Hetua8b364b2015-06-10 11:48:40 -0400100 deepestStructNesting = structure ? structure->deepestNesting() : 0;
John Bauman66b8ab22014-05-06 15:57:45 -0400101}
102
Alexis Hetua8b364b2015-06-10 11:48:40 -0400103bool TStructure::containsArrays() const
John Bauman66b8ab22014-05-06 15:57:45 -0400104{
Alexis Hetua8b364b2015-06-10 11:48:40 -0400105 for(size_t i = 0; i < mFields->size(); ++i)
106 {
107 const TType *fieldType = (*mFields)[i]->type();
108 if(fieldType->isArray() || fieldType->isStructureContainingArrays())
109 return true;
110 }
111 return false;
112}
John Bauman66b8ab22014-05-06 15:57:45 -0400113
Alexis Hetua8b364b2015-06-10 11:48:40 -0400114bool TStructure::containsSamplers() const
115{
116 for(size_t i = 0; i < mFields->size(); ++i)
117 {
118 const TType *fieldType = (*mFields)[i]->type();
119 if(IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
120 return true;
121 }
122 return false;
123}
John Bauman66b8ab22014-05-06 15:57:45 -0400124
Alexis Hetua8b364b2015-06-10 11:48:40 -0400125TString TFieldListCollection::buildMangledName() const
126{
127 TString mangledName(mangledNamePrefix());
128 mangledName += *mName;
129 for(size_t i = 0; i < mFields->size(); ++i)
130 {
131 mangledName += '-';
132 mangledName += (*mFields)[i]->type()->getMangledName();
133 }
134 return mangledName;
135}
136
137size_t TFieldListCollection::calculateObjectSize() const
138{
139 size_t size = 0;
140 for(size_t i = 0; i < mFields->size(); ++i)
141 {
142 size_t fieldSize = (*mFields)[i]->type()->getObjectSize();
143 if(fieldSize > INT_MAX - size)
144 size = INT_MAX;
145 else
146 size += fieldSize;
147 }
148 return size;
149}
150
151int TStructure::calculateDeepestNesting() const
152{
153 int maxNesting = 0;
154 for(size_t i = 0; i < mFields->size(); ++i)
155 maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
156 return 1 + maxNesting;
John Bauman66b8ab22014-05-06 15:57:45 -0400157}
158
159//
John Bauman66b8ab22014-05-06 15:57:45 -0400160// Functions have buried pointers to delete.
161//
162TFunction::~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//
171TSymbolTableLevel::~TSymbolTableLevel()
172{
173 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
174 delete (*it).second;
175}
176
Nicolas Capense2858652015-02-18 15:30:51 -0500177TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, bool *builtIn, bool *sameScope) const
178{
179 int level = currentLevel();
180 TSymbol *symbol = nullptr;
181
182 do
183 {
Nicolas Capens3d7f6ed2015-02-18 16:34:50 -0500184 while((level == ESSL3_BUILTINS && shaderVersion != 300) ||
185 (level == ESSL1_BUILTINS && shaderVersion != 100)) // Skip version specific levels
186 {
187 --level;
188 }
Nicolas Capense2858652015-02-18 15:30:51 -0500189
Nicolas Capens3d7f6ed2015-02-18 16:34:50 -0500190 symbol = table[level]->find(name);
191 }
192 while(!symbol && --level >= 0); // Doesn't decrement level when a symbol was found
Nicolas Capense2858652015-02-18 15:30:51 -0500193
194 if(builtIn)
195 {
Nicolas Capens3d7f6ed2015-02-18 16:34:50 -0500196 *builtIn = (level <= LAST_BUILTIN_LEVEL);
Nicolas Capense2858652015-02-18 15:30:51 -0500197 }
198
199 if(sameScope)
200 {
201 *sameScope = (level == currentLevel());
202 }
203
204 return symbol;
205}
206
207TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
208{
Nicolas Capens3d7f6ed2015-02-18 16:34:50 -0500209 for(int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
210 {
211 while((level == ESSL3_BUILTINS && shaderVersion != 300) ||
212 (level == ESSL1_BUILTINS && shaderVersion != 100)) // Skip version specific levels
213 {
214 --level;
215 }
216
217 TSymbol *symbol = table[level]->find(name);
218
219 if(symbol)
220 {
221 return symbol;
222 }
223 }
224
225 return 0;
Nicolas Capense2858652015-02-18 15:30:51 -0500226}
227
John Bauman66b8ab22014-05-06 15:57:45 -0400228TSymbol::TSymbol(const TSymbol& copyOf)
229{
230 name = NewPoolTString(copyOf.name->c_str());
John Bauman66b8ab22014-05-06 15:57:45 -0400231}