blob: 0d449d9df884e76e14ecef63569c3162c914f4e1 [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>
Nicolas Capens94352d92015-06-11 08:53:40 -050019#include <limits.h>
John Bauman66b8ab22014-05-06 15:57:45 -040020#include <algorithm>
21
22#if defined(_MSC_VER)
23#define snprintf _snprintf
24#endif
25
John Baumand4ae8632014-05-06 16:18:33 -040026int TSymbolTableLevel::uniqueId = 0;
27
John Bauman66b8ab22014-05-06 15:57:45 -040028TType::TType(const TPublicType &p) :
Alexis Hetu909b8bc2015-07-15 16:55:56 -040029 type(p.type), precision(p.precision), qualifier(p.qualifier), invariant(false), layoutQualifier(TLayoutQualifier::create()),
30 primarySize(p.primarySize), secondarySize(p.secondarySize), array(p.array), arraySize(p.arraySize), maxArraySize(0),
31 arrayInformationType(0), interfaceBlock(0), structure(0), deepestStructNesting(0), mangled(0)
John Bauman66b8ab22014-05-06 15:57:45 -040032{
33 if (p.userDef)
34 {
35 structure = p.userDef->getStruct();
John Bauman66b8ab22014-05-06 15:57:45 -040036 computeDeepestStructNesting();
37 }
38}
39
40//
41// Recursively generate mangled names.
42//
43void TType::buildMangledName(TString& mangledName)
44{
45 if (isMatrix())
46 mangledName += 'm';
47 else if (isVector())
48 mangledName += 'v';
49
50 switch (type) {
51 case EbtFloat: mangledName += 'f'; break;
52 case EbtInt: mangledName += 'i'; break;
Nicolas Capens3c20f802015-02-17 17:17:20 -050053 case EbtUInt: mangledName += 'u'; break;
John Bauman66b8ab22014-05-06 15:57:45 -040054 case EbtBool: mangledName += 'b'; break;
55 case EbtSampler2D: mangledName += "s2"; break;
Alexis Hetub027aa92015-01-19 15:56:12 -050056 case EbtSampler3D: mangledName += "s3"; break;
Alexis Hetua8b364b2015-06-10 11:48:40 -040057 case EbtSamplerCube: mangledName += "sC"; break;
58 case EbtSampler2DArray: mangledName += "s2a"; break;
59 case EbtSamplerExternalOES: mangledName += "sext"; break;
60 case EbtISampler2D: mangledName += "is2"; break;
61 case EbtISampler3D: mangledName += "is3"; break;
62 case EbtISamplerCube: mangledName += "isC"; break;
63 case EbtISampler2DArray: mangledName += "is2a"; break;
64 case EbtUSampler2D: mangledName += "us2"; break;
65 case EbtUSampler3D: mangledName += "us3"; break;
66 case EbtUSamplerCube: mangledName += "usC"; break;
67 case EbtUSampler2DArray: mangledName += "us2a"; break;
68 case EbtSampler2DShadow: mangledName += "s2s"; break;
69 case EbtSamplerCubeShadow: mangledName += "sCs"; break;
70 case EbtSampler2DArrayShadow: mangledName += "s2as"; break;
71 case EbtStruct: mangledName += structure->mangledName(); break;
72 case EbtInterfaceBlock: mangledName += interfaceBlock->mangledName(); break;
John Bauman66b8ab22014-05-06 15:57:45 -040073 default:
74 break;
75 }
76
77 mangledName += static_cast<char>('0' + getNominalSize());
Alexis Hetu39358652015-05-26 14:34:54 -040078 if(isMatrix()) {
79 mangledName += static_cast<char>('0' + getSecondarySize());
80 }
John Bauman66b8ab22014-05-06 15:57:45 -040081 if (isArray()) {
82 char buf[20];
83 snprintf(buf, sizeof(buf), "%d", arraySize);
84 mangledName += '[';
85 mangledName += buf;
86 mangledName += ']';
87 }
88}
89
Alexis Hetuab752792016-04-21 16:11:31 -040090size_t TType::getStructSize() const
John Bauman66b8ab22014-05-06 15:57:45 -040091{
92 if (!getStruct()) {
93 assert(false && "Not a struct");
94 return 0;
95 }
96
Alexis Hetua8b364b2015-06-10 11:48:40 -040097 return getStruct()->objectSize();
John Bauman66b8ab22014-05-06 15:57:45 -040098}
99
100void TType::computeDeepestStructNesting()
101{
Alexis Hetua8b364b2015-06-10 11:48:40 -0400102 deepestStructNesting = structure ? structure->deepestNesting() : 0;
John Bauman66b8ab22014-05-06 15:57:45 -0400103}
104
Alexis Hetua8b364b2015-06-10 11:48:40 -0400105bool TStructure::containsArrays() const
John Bauman66b8ab22014-05-06 15:57:45 -0400106{
Alexis Hetua8b364b2015-06-10 11:48:40 -0400107 for(size_t i = 0; i < mFields->size(); ++i)
108 {
109 const TType *fieldType = (*mFields)[i]->type();
110 if(fieldType->isArray() || fieldType->isStructureContainingArrays())
111 return true;
112 }
113 return false;
114}
John Bauman66b8ab22014-05-06 15:57:45 -0400115
Alexis Hetua8b364b2015-06-10 11:48:40 -0400116bool TStructure::containsSamplers() const
117{
118 for(size_t i = 0; i < mFields->size(); ++i)
119 {
120 const TType *fieldType = (*mFields)[i]->type();
121 if(IsSampler(fieldType->getBasicType()) || fieldType->isStructureContainingSamplers())
122 return true;
123 }
124 return false;
125}
John Bauman66b8ab22014-05-06 15:57:45 -0400126
Alexis Hetua8b364b2015-06-10 11:48:40 -0400127TString TFieldListCollection::buildMangledName() const
128{
129 TString mangledName(mangledNamePrefix());
130 mangledName += *mName;
131 for(size_t i = 0; i < mFields->size(); ++i)
132 {
133 mangledName += '-';
134 mangledName += (*mFields)[i]->type()->getMangledName();
135 }
136 return mangledName;
137}
138
139size_t TFieldListCollection::calculateObjectSize() const
140{
141 size_t size = 0;
142 for(size_t i = 0; i < mFields->size(); ++i)
143 {
144 size_t fieldSize = (*mFields)[i]->type()->getObjectSize();
145 if(fieldSize > INT_MAX - size)
146 size = INT_MAX;
147 else
148 size += fieldSize;
149 }
150 return size;
151}
152
153int TStructure::calculateDeepestNesting() const
154{
155 int maxNesting = 0;
156 for(size_t i = 0; i < mFields->size(); ++i)
157 maxNesting = std::max(maxNesting, (*mFields)[i]->type()->getDeepestStructNesting());
158 return 1 + maxNesting;
John Bauman66b8ab22014-05-06 15:57:45 -0400159}
160
161//
John Bauman66b8ab22014-05-06 15:57:45 -0400162// Functions have buried pointers to delete.
163//
164TFunction::~TFunction()
165{
166 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
167 delete (*i).type;
168}
169
170//
171// Symbol table levels are a map of pointers to symbols that have to be deleted.
172//
173TSymbolTableLevel::~TSymbolTableLevel()
174{
175 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
176 delete (*it).second;
177}
178
Nicolas Capense2858652015-02-18 15:30:51 -0500179TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, bool *builtIn, bool *sameScope) const
180{
181 int level = currentLevel();
182 TSymbol *symbol = nullptr;
183
184 do
185 {
Nicolas Capens3d7f6ed2015-02-18 16:34:50 -0500186 while((level == ESSL3_BUILTINS && shaderVersion != 300) ||
187 (level == ESSL1_BUILTINS && shaderVersion != 100)) // Skip version specific levels
188 {
189 --level;
190 }
Nicolas Capense2858652015-02-18 15:30:51 -0500191
Nicolas Capens3d7f6ed2015-02-18 16:34:50 -0500192 symbol = table[level]->find(name);
193 }
194 while(!symbol && --level >= 0); // Doesn't decrement level when a symbol was found
Nicolas Capense2858652015-02-18 15:30:51 -0500195
196 if(builtIn)
197 {
Nicolas Capens3d7f6ed2015-02-18 16:34:50 -0500198 *builtIn = (level <= LAST_BUILTIN_LEVEL);
Nicolas Capense2858652015-02-18 15:30:51 -0500199 }
200
201 if(sameScope)
202 {
203 *sameScope = (level == currentLevel());
204 }
205
206 return symbol;
207}
208
209TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
210{
Nicolas Capens3d7f6ed2015-02-18 16:34:50 -0500211 for(int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
212 {
213 while((level == ESSL3_BUILTINS && shaderVersion != 300) ||
214 (level == ESSL1_BUILTINS && shaderVersion != 100)) // Skip version specific levels
215 {
216 --level;
217 }
218
219 TSymbol *symbol = table[level]->find(name);
220
221 if(symbol)
222 {
223 return symbol;
224 }
225 }
226
227 return 0;
Nicolas Capense2858652015-02-18 15:30:51 -0500228}
229
John Bauman66b8ab22014-05-06 15:57:45 -0400230TSymbol::TSymbol(const TSymbol& copyOf)
231{
232 name = NewPoolTString(copyOf.name->c_str());
John Bauman66b8ab22014-05-06 15:57:45 -0400233}