Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4358 Serge 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
 
27
class symbol_table_entry {
28
public:
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)
32
   {
33
      void *entry = ralloc_size(ctx, size);
34
      assert(entry != NULL);
35
      return entry;
36
   }
37
 
38
   /* If the user *does* call delete, that's OK, we will just ralloc_free. */
39
   static void operator delete(void *entry)
40
   {
41
      ralloc_free(entry);
42
   }
43
 
44
   bool add_interface(const glsl_type *i, enum ir_variable_mode mode)
45
   {
46
      const glsl_type **dest;
47
 
48
      switch (mode) {
49
      case ir_var_uniform:
50
         dest = &ibu;
51
         break;
52
      case ir_var_shader_in:
53
         dest = &ibi;
54
         break;
55
      case ir_var_shader_out:
56
         dest = &ibo;
57
         break;
58
      default:
59
         assert(!"Unsupported interface variable mode!");
60
         return false;
61
      }
62
 
63
      if (*dest != NULL) {
64
         return false;
65
      } else {
66
         *dest = i;
67
         return true;
68
      }
69
   }
70
 
71
   const glsl_type *get_interface(enum ir_variable_mode mode)
72
   {
73
      switch (mode) {
74
      case ir_var_uniform:
75
         return ibu;
76
      case ir_var_shader_in:
77
         return ibi;
78
      case ir_var_shader_out:
79
         return ibo;
80
      default:
81
         assert(!"Unsupported interface variable mode!");
82
         return NULL;
83
      }
84
   }
85
 
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)
94
   {
95
      assert(t->is_interface());
96
      add_interface(t, mode);
97
   }
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) {}
100
 
101
   ir_variable *v;
102
   ir_function *f;
103
   const glsl_type *t;
104
   const glsl_type *ibu;
105
   const glsl_type *ibi;
106
   const glsl_type *ibo;
107
   const class ast_type_specifier *a;
108
};
109
 
110
glsl_symbol_table::glsl_symbol_table()
111
{
112
   this->separate_function_namespace = false;
113
   this->table = _mesa_symbol_table_ctor();
114
   this->mem_ctx = ralloc_context(NULL);
115
}
116
 
117
glsl_symbol_table::~glsl_symbol_table()
118
{
119
   _mesa_symbol_table_dtor(table);
120
   ralloc_free(mem_ctx);
121
}
122
 
123
void glsl_symbol_table::push_scope()
124
{
125
   _mesa_symbol_table_push_scope(table);
126
}
127
 
128
void glsl_symbol_table::pop_scope()
129
{
130
   _mesa_symbol_table_pop_scope(table);
131
}
132
 
133
bool glsl_symbol_table::name_declared_this_scope(const char *name)
134
{
135
   return _mesa_symbol_table_symbol_scope(table, -1, name) == 0;
136
}
137
 
138
bool glsl_symbol_table::add_variable(ir_variable *v)
139
{
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'.
146
	  */
147
	 if (existing->v == NULL && existing->t == NULL) {
148
	    existing->v = v;
149
	    return true;
150
	 }
151
      } else {
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.
155
	  */
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);
160
	 assert(added == 0);
161
	 (void)added;
162
	 return true;
163
      }
164
      return false;
165
   }
166
 
167
   /* 1.20+ rules: */
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;
170
}
171
 
172
bool glsl_symbol_table::add_type(const char *name, const glsl_type *t)
173
{
174
   symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(t);
175
   return _mesa_symbol_table_add_symbol(table, -1, name, entry) == 0;
176
}
177
 
178
static char *make_ast_name(const char *name)
179
{
180
   char *ast_name = new char[strlen("#ast.") + strlen(name) + 1];
181
   strcpy(ast_name, "#ast.");
182
   strcat(ast_name + strlen("#ast."), name);
183
   return ast_name;
184
}
185
 
186
bool glsl_symbol_table::add_type_ast(const char *name, const class ast_type_specifier *a)
187
{
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;
191
   delete [] ast_name;
192
   return ret;
193
}
194
 
195
bool glsl_symbol_table::add_interface(const char *name, const glsl_type *i,
196
                                      enum ir_variable_mode mode)
197
{
198
   assert(i->is_interface());
199
   symbol_table_entry *entry = get_entry(name);
200
   if (entry == NULL) {
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;
207
   } else {
208
      return entry->add_interface(i, mode);
209
   }
210
}
211
 
212
bool glsl_symbol_table::add_function(ir_function *f)
213
{
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)) {
218
	 existing->f = f;
219
	 return true;
220
      }
221
   }
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;
224
}
225
 
226
void glsl_symbol_table::add_global_function(ir_function *f)
227
{
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);
230
   assert(added == 0);
231
   (void)added;
232
}
233
 
234
ir_variable *glsl_symbol_table::get_variable(const char *name)
235
{
236
   symbol_table_entry *entry = get_entry(name);
237
   return entry != NULL ? entry->v : NULL;
238
}
239
 
240
const glsl_type *glsl_symbol_table::get_type(const char *name)
241
{
242
   symbol_table_entry *entry = get_entry(name);
243
   return entry != NULL ? entry->t : NULL;
244
}
245
 
246
const class ast_type_specifier *glsl_symbol_table::get_type_ast(const char *name)
247
{
248
   char *ast_name = make_ast_name(name);
249
   symbol_table_entry *entry = get_entry(ast_name);
250
   delete [] ast_name;
251
   return entry != NULL ? entry->a : NULL;
252
}
253
 
254
const glsl_type *glsl_symbol_table::get_interface(const char *name,
255
                                                  enum ir_variable_mode mode)
256
{
257
   symbol_table_entry *entry = get_entry(name);
258
   return entry != NULL ? entry->get_interface(mode) : NULL;
259
}
260
 
261
ir_function *glsl_symbol_table::get_function(const char *name)
262
{
263
   symbol_table_entry *entry = get_entry(name);
264
   return entry != NULL ? entry->f : NULL;
265
}
266
 
267
symbol_table_entry *glsl_symbol_table::get_entry(const char *name)
268
{
269
   return (symbol_table_entry *)
270
      _mesa_symbol_table_find_symbol(table, -1, name);
271
}