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 talloc-based new need not call delete. It's
30 * easier to just talloc_free 'ctx' (or any of its ancestors). */
31 static void* operator new(size_t size
, void *ctx
)
33 void *entry
= talloc_size(ctx
, size
);
34 assert(entry
!= NULL
);
38 /* If the user *does* call delete, that's OK, we will just
39 * talloc_free in that case. Here, C++ will have already called the
40 * destructor so tell talloc not to do that again. */
41 static void operator delete(void *table
)
43 talloc_set_destructor(table
, NULL
);
47 symbol_table_entry(ir_variable
*v
) : v(v
), f(0), t(0) {}
48 symbol_table_entry(ir_function
*f
) : v(0), f(f
), t(0) {}
49 symbol_table_entry(const glsl_type
*t
) : v(0), f(0), t(t
) {}
56 glsl_symbol_table::glsl_symbol_table()
58 this->language_version
= 120;
59 this->table
= _mesa_symbol_table_ctor();
60 this->mem_ctx
= talloc_init("symbol table entries");
63 glsl_symbol_table::~glsl_symbol_table()
65 _mesa_symbol_table_dtor(table
);
69 void glsl_symbol_table::push_scope()
71 _mesa_symbol_table_push_scope(table
);
74 void glsl_symbol_table::pop_scope()
76 _mesa_symbol_table_pop_scope(table
);
79 bool glsl_symbol_table::name_declared_this_scope(const char *name
)
81 return _mesa_symbol_table_symbol_scope(table
, -1, name
) == 0;
84 bool glsl_symbol_table::add_variable(const char *name
, ir_variable
*v
)
86 if (this->language_version
== 110) {
87 /* In 1.10, functions and variables have separate namespaces. */
88 symbol_table_entry
*existing
= get_entry(name
);
89 if (name_declared_this_scope(name
)) {
90 /* If there's already an existing function (not a constructor!) in
91 * the current scope, just update the existing entry to include 'v'.
93 if (existing
->v
== NULL
&& existing
->t
== NULL
) {
98 /* If not declared at this scope, add a new entry. But if an existing
99 * entry includes a function, propagate that to this block - otherwise
100 * the new variable declaration would shadow the function.
102 symbol_table_entry
*entry
= new(mem_ctx
) symbol_table_entry(v
);
103 if (existing
!= NULL
)
104 entry
->f
= existing
->f
;
105 int added
= _mesa_symbol_table_add_symbol(table
, -1, name
, entry
);
114 symbol_table_entry
*entry
= new(mem_ctx
) symbol_table_entry(v
);
115 return _mesa_symbol_table_add_symbol(table
, -1, name
, entry
) == 0;
118 bool glsl_symbol_table::add_type(const char *name
, const glsl_type
*t
)
120 symbol_table_entry
*entry
= new(mem_ctx
) symbol_table_entry(t
);
121 return _mesa_symbol_table_add_symbol(table
, -1, name
, entry
) == 0;
124 bool glsl_symbol_table::add_function(const char *name
, ir_function
*f
)
126 if (this->language_version
== 110 && name_declared_this_scope(name
)) {
127 /* In 1.10, functions and variables have separate namespaces. */
128 symbol_table_entry
*existing
= get_entry(name
);
129 if ((existing
->f
== NULL
) && (existing
->t
== NULL
)) {
134 symbol_table_entry
*entry
= new(mem_ctx
) symbol_table_entry(f
);
135 return _mesa_symbol_table_add_symbol(table
, -1, name
, entry
) == 0;
138 ir_variable
*glsl_symbol_table::get_variable(const char *name
)
140 symbol_table_entry
*entry
= get_entry(name
);
141 return entry
!= NULL
? entry
->v
: NULL
;
144 const glsl_type
*glsl_symbol_table::get_type(const char *name
)
146 symbol_table_entry
*entry
= get_entry(name
);
147 return entry
!= NULL
? entry
->t
: NULL
;
150 ir_function
*glsl_symbol_table::get_function(const char *name
)
152 symbol_table_entry
*entry
= get_entry(name
);
153 return entry
!= NULL
? entry
->f
: NULL
;
156 symbol_table_entry
*glsl_symbol_table::get_entry(const char *name
)
158 return (symbol_table_entry
*)
159 _mesa_symbol_table_find_symbol(table
, -1, name
);