blob: 19354786fc7e6b49b27e62b73c0b15671e1e325a [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),
John Bauman66b8ab22014-05-06 15:57:45 -040029 maxArraySize(0), arrayInformationType(0), structure(0), structureSize(0), deepestStructNesting(0), fieldName(0), mangled(0), typeName(0)
30{
31 if (p.userDef)
32 {
33 structure = p.userDef->getStruct();
34 typeName = NewPoolTString(p.userDef->getTypeName().c_str());
35 computeDeepestStructNesting();
36 }
37}
38
39//
40// Recursively generate mangled names.
41//
42void TType::buildMangledName(TString& mangledName)
43{
44 if (isMatrix())
45 mangledName += 'm';
46 else if (isVector())
47 mangledName += 'v';
48
49 switch (type) {
50 case EbtFloat: mangledName += 'f'; break;
51 case EbtInt: mangledName += 'i'; break;
Nicolas Capens3c20f802015-02-17 17:17:20 -050052 case EbtUInt: mangledName += 'u'; break;
John Bauman66b8ab22014-05-06 15:57:45 -040053 case EbtBool: mangledName += 'b'; break;
54 case EbtSampler2D: mangledName += "s2"; break;
55 case EbtSamplerCube: mangledName += "sC"; break;
Nicolas Capense9c5e4f2014-05-28 22:46:43 -040056 case EbtSamplerExternalOES: mangledName += "sE"; break;
Alexis Hetub027aa92015-01-19 15:56:12 -050057 case EbtSampler3D: mangledName += "s3"; break;
58 case EbtStruct:
John Bauman66b8ab22014-05-06 15:57:45 -040059 mangledName += "struct-";
60 if (typeName)
61 mangledName += *typeName;
62 {// support MSVC++6.0
63 for (unsigned int i = 0; i < structure->size(); ++i) {
64 mangledName += '-';
65 (*structure)[i].type->buildMangledName(mangledName);
66 }
67 }
68 default:
69 break;
70 }
71
72 mangledName += static_cast<char>('0' + getNominalSize());
Alexis Hetu39358652015-05-26 14:34:54 -040073 if(isMatrix()) {
74 mangledName += static_cast<char>('0' + getSecondarySize());
75 }
John Bauman66b8ab22014-05-06 15:57:45 -040076 if (isArray()) {
77 char buf[20];
78 snprintf(buf, sizeof(buf), "%d", arraySize);
79 mangledName += '[';
80 mangledName += buf;
81 mangledName += ']';
82 }
83}
84
85int TType::getStructSize() const
86{
87 if (!getStruct()) {
88 assert(false && "Not a struct");
89 return 0;
90 }
91
92 if (structureSize == 0)
93 for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
94 structureSize += ((*tl).type)->getObjectSize();
95
96 return structureSize;
97}
98
99void TType::computeDeepestStructNesting()
100{
101 if (!structure)
102 {
103 return;
104 }
105
106 int maxNesting = 0;
107 for (TTypeList::const_iterator tl = structure->begin(); tl != structure->end(); tl++)
108 {
109 maxNesting = std::max(maxNesting, ((*tl).type)->getDeepestStructNesting());
110 }
111
112 deepestStructNesting = 1 + maxNesting;
113}
114
115bool TType::isStructureContainingArrays() const
116{
117 if (!structure)
118 {
119 return false;
120 }
121
122 for (TTypeList::const_iterator member = structure->begin(); member != structure->end(); member++)
123 {
124 if (member->type->isArray() ||
125 member->type->isStructureContainingArrays())
126 {
127 return true;
128 }
129 }
130
131 return false;
132}
133
134//
John Bauman66b8ab22014-05-06 15:57:45 -0400135// Functions have buried pointers to delete.
136//
137TFunction::~TFunction()
138{
139 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
140 delete (*i).type;
141}
142
143//
144// Symbol table levels are a map of pointers to symbols that have to be deleted.
145//
146TSymbolTableLevel::~TSymbolTableLevel()
147{
148 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
149 delete (*it).second;
150}
151
Nicolas Capense2858652015-02-18 15:30:51 -0500152TSymbol *TSymbolTable::find(const TString &name, int shaderVersion, bool *builtIn, bool *sameScope) const
153{
154 int level = currentLevel();
155 TSymbol *symbol = nullptr;
156
157 do
158 {
Nicolas Capens3d7f6ed2015-02-18 16:34:50 -0500159 while((level == ESSL3_BUILTINS && shaderVersion != 300) ||
160 (level == ESSL1_BUILTINS && shaderVersion != 100)) // Skip version specific levels
161 {
162 --level;
163 }
Nicolas Capense2858652015-02-18 15:30:51 -0500164
Nicolas Capens3d7f6ed2015-02-18 16:34:50 -0500165 symbol = table[level]->find(name);
166 }
167 while(!symbol && --level >= 0); // Doesn't decrement level when a symbol was found
Nicolas Capense2858652015-02-18 15:30:51 -0500168
169 if(builtIn)
170 {
Nicolas Capens3d7f6ed2015-02-18 16:34:50 -0500171 *builtIn = (level <= LAST_BUILTIN_LEVEL);
Nicolas Capense2858652015-02-18 15:30:51 -0500172 }
173
174 if(sameScope)
175 {
176 *sameScope = (level == currentLevel());
177 }
178
179 return symbol;
180}
181
182TSymbol *TSymbolTable::findBuiltIn(const TString &name, int shaderVersion) const
183{
Nicolas Capens3d7f6ed2015-02-18 16:34:50 -0500184 for(int level = LAST_BUILTIN_LEVEL; level >= 0; --level)
185 {
186 while((level == ESSL3_BUILTINS && shaderVersion != 300) ||
187 (level == ESSL1_BUILTINS && shaderVersion != 100)) // Skip version specific levels
188 {
189 --level;
190 }
191
192 TSymbol *symbol = table[level]->find(name);
193
194 if(symbol)
195 {
196 return symbol;
197 }
198 }
199
200 return 0;
Nicolas Capense2858652015-02-18 15:30:51 -0500201}
202
John Bauman66b8ab22014-05-06 15:57:45 -0400203TSymbol::TSymbol(const TSymbol& copyOf)
204{
205 name = NewPoolTString(copyOf.name->c_str());
John Bauman66b8ab22014-05-06 15:57:45 -0400206}