Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mesa
Path: blob/21.2-virgl/src/compiler/glsl/glsl_symbol_table.cpp
4545 views
1
/* -*- c++ -*- */
2
/*
3
* Copyright © 2010 Intel Corporation
4
*
5
* Permission is hereby granted, free of charge, to any person obtaining a
6
* copy of this software and associated documentation files (the "Software"),
7
* to deal in the Software without restriction, including without limitation
8
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
9
* and/or sell copies of the Software, and to permit persons to whom the
10
* Software is furnished to do so, subject to the following conditions:
11
*
12
* The above copyright notice and this permission notice (including the next
13
* paragraph) shall be included in all copies or substantial portions of the
14
* Software.
15
*
16
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
* DEALINGS IN THE SOFTWARE.
23
*/
24
25
#include "glsl_symbol_table.h"
26
#include "ast.h"
27
28
class symbol_table_entry {
29
public:
30
DECLARE_LINEAR_ALLOC_CXX_OPERATORS(symbol_table_entry);
31
32
bool add_interface(const glsl_type *i, enum ir_variable_mode mode)
33
{
34
const glsl_type **dest;
35
36
switch (mode) {
37
case ir_var_uniform:
38
dest = &ibu;
39
break;
40
case ir_var_shader_storage:
41
dest = &iss;
42
break;
43
case ir_var_shader_in:
44
dest = &ibi;
45
break;
46
case ir_var_shader_out:
47
dest = &ibo;
48
break;
49
default:
50
assert(!"Unsupported interface variable mode!");
51
return false;
52
}
53
54
if (*dest != NULL) {
55
return false;
56
} else {
57
*dest = i;
58
return true;
59
}
60
}
61
62
const glsl_type *get_interface(enum ir_variable_mode mode)
63
{
64
switch (mode) {
65
case ir_var_uniform:
66
return ibu;
67
case ir_var_shader_storage:
68
return iss;
69
case ir_var_shader_in:
70
return ibi;
71
case ir_var_shader_out:
72
return ibo;
73
default:
74
assert(!"Unsupported interface variable mode!");
75
return NULL;
76
}
77
}
78
79
symbol_table_entry(ir_variable *v) :
80
v(v), f(0), t(0), ibu(0), iss(0), ibi(0), ibo(0), a(0) {}
81
symbol_table_entry(ir_function *f) :
82
v(0), f(f), t(0), ibu(0), iss(0), ibi(0), ibo(0), a(0) {}
83
symbol_table_entry(const glsl_type *t) :
84
v(0), f(0), t(t), ibu(0), iss(0), ibi(0), ibo(0), a(0) {}
85
symbol_table_entry(const glsl_type *t, enum ir_variable_mode mode) :
86
v(0), f(0), t(0), ibu(0), iss(0), ibi(0), ibo(0), a(0)
87
{
88
assert(t->is_interface());
89
add_interface(t, mode);
90
}
91
symbol_table_entry(const class ast_type_specifier *a):
92
v(0), f(0), t(0), ibu(0), iss(0), ibi(0), ibo(0), a(a) {}
93
94
ir_variable *v;
95
ir_function *f;
96
const glsl_type *t;
97
const glsl_type *ibu;
98
const glsl_type *iss;
99
const glsl_type *ibi;
100
const glsl_type *ibo;
101
const class ast_type_specifier *a;
102
};
103
104
glsl_symbol_table::glsl_symbol_table()
105
{
106
this->separate_function_namespace = false;
107
this->table = _mesa_symbol_table_ctor();
108
this->mem_ctx = ralloc_context(NULL);
109
this->linalloc = linear_alloc_parent(this->mem_ctx, 0);
110
}
111
112
glsl_symbol_table::~glsl_symbol_table()
113
{
114
_mesa_symbol_table_dtor(table);
115
ralloc_free(mem_ctx);
116
}
117
118
void glsl_symbol_table::push_scope()
119
{
120
_mesa_symbol_table_push_scope(table);
121
}
122
123
void glsl_symbol_table::pop_scope()
124
{
125
_mesa_symbol_table_pop_scope(table);
126
}
127
128
bool glsl_symbol_table::name_declared_this_scope(const char *name)
129
{
130
return _mesa_symbol_table_symbol_scope(table, name) == 0;
131
}
132
133
bool glsl_symbol_table::add_variable(ir_variable *v)
134
{
135
assert(v->data.mode != ir_var_temporary);
136
137
if (this->separate_function_namespace) {
138
/* In 1.10, functions and variables have separate namespaces. */
139
symbol_table_entry *existing = get_entry(v->name);
140
if (name_declared_this_scope(v->name)) {
141
/* If there's already an existing function (not a constructor!) in
142
* the current scope, just update the existing entry to include 'v'.
143
*/
144
if (existing->v == NULL && existing->t == NULL) {
145
existing->v = v;
146
return true;
147
}
148
} else {
149
/* If not declared at this scope, add a new entry. But if an existing
150
* entry includes a function, propagate that to this block - otherwise
151
* the new variable declaration would shadow the function.
152
*/
153
symbol_table_entry *entry = new(linalloc) symbol_table_entry(v);
154
if (existing != NULL)
155
entry->f = existing->f;
156
int added = _mesa_symbol_table_add_symbol(table, v->name, entry);
157
assert(added == 0);
158
(void)added;
159
return true;
160
}
161
return false;
162
}
163
164
/* 1.20+ rules: */
165
symbol_table_entry *entry = new(linalloc) symbol_table_entry(v);
166
return _mesa_symbol_table_add_symbol(table, v->name, entry) == 0;
167
}
168
169
bool glsl_symbol_table::add_type(const char *name, const glsl_type *t)
170
{
171
symbol_table_entry *entry = new(linalloc) symbol_table_entry(t);
172
return _mesa_symbol_table_add_symbol(table, name, entry) == 0;
173
}
174
175
bool glsl_symbol_table::add_interface(const char *name, const glsl_type *i,
176
enum ir_variable_mode mode)
177
{
178
assert(i->is_interface());
179
symbol_table_entry *entry = get_entry(name);
180
if (entry == NULL) {
181
symbol_table_entry *entry =
182
new(linalloc) symbol_table_entry(i, mode);
183
bool add_interface_symbol_result =
184
_mesa_symbol_table_add_symbol(table, name, entry) == 0;
185
assert(add_interface_symbol_result);
186
return add_interface_symbol_result;
187
} else {
188
return entry->add_interface(i, mode);
189
}
190
}
191
192
bool glsl_symbol_table::add_function(ir_function *f)
193
{
194
if (this->separate_function_namespace && name_declared_this_scope(f->name)) {
195
/* In 1.10, functions and variables have separate namespaces. */
196
symbol_table_entry *existing = get_entry(f->name);
197
if ((existing->f == NULL) && (existing->t == NULL)) {
198
existing->f = f;
199
return true;
200
}
201
}
202
symbol_table_entry *entry = new(linalloc) symbol_table_entry(f);
203
return _mesa_symbol_table_add_symbol(table, f->name, entry) == 0;
204
}
205
206
bool glsl_symbol_table::add_default_precision_qualifier(const char *type_name,
207
int precision)
208
{
209
char *name = ralloc_asprintf(mem_ctx, "#default_precision_%s", type_name);
210
211
ast_type_specifier *default_specifier = new(linalloc) ast_type_specifier(name);
212
default_specifier->default_precision = precision;
213
214
symbol_table_entry *entry =
215
new(linalloc) symbol_table_entry(default_specifier);
216
217
if (!get_entry(name))
218
return _mesa_symbol_table_add_symbol(table, name, entry) == 0;
219
220
return _mesa_symbol_table_replace_symbol(table, name, entry) == 0;
221
}
222
223
void glsl_symbol_table::add_global_function(ir_function *f)
224
{
225
symbol_table_entry *entry = new(linalloc) symbol_table_entry(f);
226
int added = _mesa_symbol_table_add_global_symbol(table, f->name, entry);
227
assert(added == 0);
228
(void)added;
229
}
230
231
ir_variable *glsl_symbol_table::get_variable(const char *name)
232
{
233
symbol_table_entry *entry = get_entry(name);
234
return entry != NULL ? entry->v : NULL;
235
}
236
237
const glsl_type *glsl_symbol_table::get_type(const char *name)
238
{
239
symbol_table_entry *entry = get_entry(name);
240
return entry != NULL ? entry->t : NULL;
241
}
242
243
const glsl_type *glsl_symbol_table::get_interface(const char *name,
244
enum ir_variable_mode mode)
245
{
246
symbol_table_entry *entry = get_entry(name);
247
return entry != NULL ? entry->get_interface(mode) : NULL;
248
}
249
250
ir_function *glsl_symbol_table::get_function(const char *name)
251
{
252
symbol_table_entry *entry = get_entry(name);
253
return entry != NULL ? entry->f : NULL;
254
}
255
256
int glsl_symbol_table::get_default_precision_qualifier(const char *type_name)
257
{
258
char *name = ralloc_asprintf(mem_ctx, "#default_precision_%s", type_name);
259
symbol_table_entry *entry = get_entry(name);
260
if (!entry)
261
return ast_precision_none;
262
return entry->a->default_precision;
263
}
264
265
symbol_table_entry *glsl_symbol_table::get_entry(const char *name)
266
{
267
return (symbol_table_entry *)
268
_mesa_symbol_table_find_symbol(table, name);
269
}
270
271
void
272
glsl_symbol_table::disable_variable(const char *name)
273
{
274
/* Ideally we would remove the variable's entry from the symbol table, but
275
* that would be difficult. Fortunately, since this is only used for
276
* built-in variables, it won't be possible for the shader to re-introduce
277
* the variable later, so all we really need to do is to make sure that
278
* further attempts to access it using get_variable() will return NULL.
279
*/
280
symbol_table_entry *entry = get_entry(name);
281
if (entry != NULL) {
282
entry->v = NULL;
283
}
284
}
285
286
void
287
glsl_symbol_table::replace_variable(const char *name,
288
ir_variable *v)
289
{
290
symbol_table_entry *entry = get_entry(name);
291
if (entry != NULL) {
292
entry->v = v;
293
}
294
}
295
296