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