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