3 * Copyright © 2010 Intel Corporation
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:
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
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.
25 #include "glsl_symbol_table.h"
27 class symbol_table_entry
{
29 /* Callers of this ralloc-based new need not call delete. It's
30 * easier to just ralloc_free 'ctx' (or any of its ancestors). */
31 static void* operator new(size_t size
, void *ctx
)
33 void *entry
= ralloc_size(ctx
, size
);
34 assert(entry
!= NULL
);
38 /* If the user *does* call delete, that's OK, we will just ralloc_free. */
39 static void operator delete(void *entry
)
44 bool add_interface(const glsl_type
*i
, enum ir_variable_mode mode
)
46 const glsl_type
**dest
;
52 case ir_var_shader_in
:
55 case ir_var_shader_out
:
59 assert(!"Unsupported interface variable mode!");
71 const glsl_type
*get_interface(enum ir_variable_mode mode
)
76 case ir_var_shader_in
:
78 case ir_var_shader_out
:
81 assert(!"Unsupported interface variable mode!");
86 symbol_table_entry(ir_variable
*v
) :
87 v(v
), f(0), t(0), ibu(0), ibi(0), ibo(0), a(0) {}
88 symbol_table_entry(ir_function
*f
) :
89 v(0), f(f
), t(0), ibu(0), ibi(0), ibo(0), a(0) {}
90 symbol_table_entry(const glsl_type
*t
) :
91 v(0), f(0), t(t
), ibu(0), ibi(0), ibo(0), a(0) {}
92 symbol_table_entry(const glsl_type
*t
, enum ir_variable_mode mode
) :
93 v(0), f(0), t(0), ibu(0), ibi(0), ibo(0), a(0)
95 assert(t
->is_interface());
96 add_interface(t
, mode
);
98 symbol_table_entry(const class ast_type_specifier
*a
):
99 v(0), f(0), t(0), ibu(0), ibi(0), ibo(0), a(a
) {}
104 const glsl_type
*ibu
;
105 const glsl_type
*ibi
;
106 const glsl_type
*ibo
;
107 const class ast_type_specifier
*a
;
110 glsl_symbol_table::glsl_symbol_table()
112 this->separate_function_namespace
= false;
113 this->table
= _mesa_symbol_table_ctor();
114 this->mem_ctx
= ralloc_context(NULL
);
117 glsl_symbol_table::~glsl_symbol_table()
119 _mesa_symbol_table_dtor(table
);
120 ralloc_free(mem_ctx
);
123 void glsl_symbol_table::push_scope()
125 _mesa_symbol_table_push_scope(table
);
128 void glsl_symbol_table::pop_scope()
130 _mesa_symbol_table_pop_scope(table
);
133 bool glsl_symbol_table::name_declared_this_scope(const char *name
)
135 return _mesa_symbol_table_symbol_scope(table
, -1, name
) == 0;
138 bool glsl_symbol_table::add_variable(ir_variable
*v
)
140 if (this->separate_function_namespace
) {
141 /* In 1.10, functions and variables have separate namespaces. */
142 symbol_table_entry
*existing
= get_entry(v
->name
);
143 if (name_declared_this_scope(v
->name
)) {
144 /* If there's already an existing function (not a constructor!) in
145 * the current scope, just update the existing entry to include 'v'.
147 if (existing
->v
== NULL
&& existing
->t
== NULL
) {
152 /* If not declared at this scope, add a new entry. But if an existing
153 * entry includes a function, propagate that to this block - otherwise
154 * the new variable declaration would shadow the function.
156 symbol_table_entry
*entry
= new(mem_ctx
) symbol_table_entry(v
);
157 if (existing
!= NULL
)
158 entry
->f
= existing
->f
;
159 int added
= _mesa_symbol_table_add_symbol(table
, -1, v
->name
, entry
);
168 symbol_table_entry
*entry
= new(mem_ctx
) symbol_table_entry(v
);
169 return _mesa_symbol_table_add_symbol(table
, -1, v
->name
, entry
) == 0;
172 bool glsl_symbol_table::add_type(const char *name
, const glsl_type
*t
)
174 symbol_table_entry
*entry
= new(mem_ctx
) symbol_table_entry(t
);
175 return _mesa_symbol_table_add_symbol(table
, -1, name
, entry
) == 0;
178 static char *make_ast_name(const char *name
)
180 char *ast_name
= new char[strlen("#ast.") + strlen(name
) + 1];
181 strcpy(ast_name
, "#ast.");
182 strcat(ast_name
+ strlen("#ast."), name
);
186 bool glsl_symbol_table::add_type_ast(const char *name
, const class ast_type_specifier
*a
)
188 symbol_table_entry
*entry
= new(mem_ctx
) symbol_table_entry(a
);
189 char *ast_name
= make_ast_name(name
);
190 bool ret
= _mesa_symbol_table_add_symbol(table
, -1, ast_name
, entry
) == 0;
195 bool glsl_symbol_table::add_interface(const char *name
, const glsl_type
*i
,
196 enum ir_variable_mode mode
)
198 assert(i
->is_interface());
199 symbol_table_entry
*entry
= get_entry(name
);
201 symbol_table_entry
*entry
=
202 new(mem_ctx
) symbol_table_entry(i
, mode
);
203 bool add_interface_symbol_result
=
204 _mesa_symbol_table_add_symbol(table
, -1, name
, entry
) == 0;
205 assert(add_interface_symbol_result
);
206 return add_interface_symbol_result
;
208 return entry
->add_interface(i
, mode
);
212 bool glsl_symbol_table::add_function(ir_function
*f
)
214 if (this->separate_function_namespace
&& name_declared_this_scope(f
->name
)) {
215 /* In 1.10, functions and variables have separate namespaces. */
216 symbol_table_entry
*existing
= get_entry(f
->name
);
217 if ((existing
->f
== NULL
) && (existing
->t
== NULL
)) {
222 symbol_table_entry
*entry
= new(mem_ctx
) symbol_table_entry(f
);
223 return _mesa_symbol_table_add_symbol(table
, -1, f
->name
, entry
) == 0;
226 void glsl_symbol_table::add_global_function(ir_function
*f
)
228 symbol_table_entry
*entry
= new(mem_ctx
) symbol_table_entry(f
);
229 int added
= _mesa_symbol_table_add_global_symbol(table
, -1, f
->name
, entry
);
234 ir_variable
*glsl_symbol_table::get_variable(const char *name
)
236 symbol_table_entry
*entry
= get_entry(name
);
237 return entry
!= NULL
? entry
->v
: NULL
;
240 const glsl_type
*glsl_symbol_table::get_type(const char *name
)
242 symbol_table_entry
*entry
= get_entry(name
);
243 return entry
!= NULL
? entry
->t
: NULL
;
246 const class ast_type_specifier
*glsl_symbol_table::get_type_ast(const char *name
)
248 char *ast_name
= make_ast_name(name
);
249 symbol_table_entry
*entry
= get_entry(ast_name
);
251 return entry
!= NULL
? entry
->a
: NULL
;
254 const glsl_type
*glsl_symbol_table::get_interface(const char *name
,
255 enum ir_variable_mode mode
)
257 symbol_table_entry
*entry
= get_entry(name
);
258 return entry
!= NULL
? entry
->get_interface(mode
) : NULL
;
261 ir_function
*glsl_symbol_table::get_function(const char *name
)
263 symbol_table_entry
*entry
= get_entry(name
);
264 return entry
!= NULL
? entry
->f
: NULL
;
267 symbol_table_entry
*glsl_symbol_table::get_entry(const char *name
)
269 return (symbol_table_entry
*)
270 _mesa_symbol_table_find_symbol(table
, -1, name
);