blob: d0cd43d71475e9e37f256325bcac88af59815659 [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) :
28 type(p.type), precision(p.precision), qualifier(p.qualifier), size(p.size), matrix(p.matrix), array(p.array), arraySize(p.arraySize),
29 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());
73 if (isArray()) {
74 char buf[20];
75 snprintf(buf, sizeof(buf), "%d", arraySize);
76 mangledName += '[';
77 mangledName += buf;
78 mangledName += ']';
79 }
80}
81
82int TType::getStructSize() const
83{
84 if (!getStruct()) {
85 assert(false && "Not a struct");
86 return 0;
87 }
88
89 if (structureSize == 0)
90 for (TTypeList::const_iterator tl = getStruct()->begin(); tl != getStruct()->end(); tl++)
91 structureSize += ((*tl).type)->getObjectSize();
92
93 return structureSize;
94}
95
96void TType::computeDeepestStructNesting()
97{
98 if (!structure)
99 {
100 return;
101 }
102
103 int maxNesting = 0;
104 for (TTypeList::const_iterator tl = structure->begin(); tl != structure->end(); tl++)
105 {
106 maxNesting = std::max(maxNesting, ((*tl).type)->getDeepestStructNesting());
107 }
108
109 deepestStructNesting = 1 + maxNesting;
110}
111
112bool TType::isStructureContainingArrays() const
113{
114 if (!structure)
115 {
116 return false;
117 }
118
119 for (TTypeList::const_iterator member = structure->begin(); member != structure->end(); member++)
120 {
121 if (member->type->isArray() ||
122 member->type->isStructureContainingArrays())
123 {
124 return true;
125 }
126 }
127
128 return false;
129}
130
131//
John Bauman66b8ab22014-05-06 15:57:45 -0400132// Functions have buried pointers to delete.
133//
134TFunction::~TFunction()
135{
136 for (TParamList::iterator i = parameters.begin(); i != parameters.end(); ++i)
137 delete (*i).type;
138}
139
140//
141// Symbol table levels are a map of pointers to symbols that have to be deleted.
142//
143TSymbolTableLevel::~TSymbolTableLevel()
144{
145 for (tLevel::iterator it = level.begin(); it != level.end(); ++it)
146 delete (*it).second;
147}
148
149//
150// Change all function entries in the table with the non-mangled name
151// to be related to the provided built-in operation. This is a low
152// performance operation, and only intended for symbol tables that
153// live across a large number of compiles.
154//
155void TSymbolTableLevel::relateToOperator(const char* name, TOperator op)
156{
157 tLevel::iterator it;
158 for (it = level.begin(); it != level.end(); ++it) {
159 if ((*it).second->isFunction()) {
160 TFunction* function = static_cast<TFunction*>((*it).second);
161 if (function->getName() == name)
162 function->relateToOperator(op);
163 }
164 }
165}
166
167//
168// Change all function entries in the table with the non-mangled name
169// to be related to the provided built-in extension. This is a low
170// performance operation, and only intended for symbol tables that
171// live across a large number of compiles.
172//
173void TSymbolTableLevel::relateToExtension(const char* name, const TString& ext)
174{
175 for (tLevel::iterator it = level.begin(); it != level.end(); ++it) {
176 if (it->second->isFunction()) {
177 TFunction* function = static_cast<TFunction*>(it->second);
178 if (function->getName() == name)
179 function->relateToExtension(ext);
180 }
181 }
182}
183
184TSymbol::TSymbol(const TSymbol& copyOf)
185{
186 name = NewPoolTString(copyOf.name->c_str());
John Bauman66b8ab22014-05-06 15:57:45 -0400187}