11591693c7b415e9869157c711fe11263c95d74eDavid Li/* -*- c++ -*- */ 21591693c7b415e9869157c711fe11263c95d74eDavid Li/* 31591693c7b415e9869157c711fe11263c95d74eDavid Li * Copyright © 2010 Intel Corporation 41591693c7b415e9869157c711fe11263c95d74eDavid Li * 51591693c7b415e9869157c711fe11263c95d74eDavid Li * Permission is hereby granted, free of charge, to any person obtaining a 61591693c7b415e9869157c711fe11263c95d74eDavid Li * copy of this software and associated documentation files (the "Software"), 71591693c7b415e9869157c711fe11263c95d74eDavid Li * to deal in the Software without restriction, including without limitation 81591693c7b415e9869157c711fe11263c95d74eDavid Li * the rights to use, copy, modify, merge, publish, distribute, sublicense, 91591693c7b415e9869157c711fe11263c95d74eDavid Li * and/or sell copies of the Software, and to permit persons to whom the 101591693c7b415e9869157c711fe11263c95d74eDavid Li * Software is furnished to do so, subject to the following conditions: 111591693c7b415e9869157c711fe11263c95d74eDavid Li * 121591693c7b415e9869157c711fe11263c95d74eDavid Li * The above copyright notice and this permission notice (including the next 131591693c7b415e9869157c711fe11263c95d74eDavid Li * paragraph) shall be included in all copies or substantial portions of the 141591693c7b415e9869157c711fe11263c95d74eDavid Li * Software. 151591693c7b415e9869157c711fe11263c95d74eDavid Li * 161591693c7b415e9869157c711fe11263c95d74eDavid Li * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 171591693c7b415e9869157c711fe11263c95d74eDavid Li * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 181591693c7b415e9869157c711fe11263c95d74eDavid Li * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 191591693c7b415e9869157c711fe11263c95d74eDavid Li * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 201591693c7b415e9869157c711fe11263c95d74eDavid Li * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 211591693c7b415e9869157c711fe11263c95d74eDavid Li * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 221591693c7b415e9869157c711fe11263c95d74eDavid Li * DEALINGS IN THE SOFTWARE. 231591693c7b415e9869157c711fe11263c95d74eDavid Li */ 241591693c7b415e9869157c711fe11263c95d74eDavid Li 251591693c7b415e9869157c711fe11263c95d74eDavid Li#include "glsl_symbol_table.h" 261591693c7b415e9869157c711fe11263c95d74eDavid Li 271591693c7b415e9869157c711fe11263c95d74eDavid Liclass symbol_table_entry { 281591693c7b415e9869157c711fe11263c95d74eDavid Lipublic: 29d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li /* Callers of this hieralloc-based new need not call delete. It's 30d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li * easier to just hieralloc_free 'ctx' (or any of its ancestors). */ 311591693c7b415e9869157c711fe11263c95d74eDavid Li static void* operator new(size_t size, void *ctx) 321591693c7b415e9869157c711fe11263c95d74eDavid Li { 33d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li void *entry = hieralloc_size(ctx, size); 341591693c7b415e9869157c711fe11263c95d74eDavid Li assert(entry != NULL); 351591693c7b415e9869157c711fe11263c95d74eDavid Li return entry; 361591693c7b415e9869157c711fe11263c95d74eDavid Li } 371591693c7b415e9869157c711fe11263c95d74eDavid Li 381591693c7b415e9869157c711fe11263c95d74eDavid Li /* If the user *does* call delete, that's OK, we will just 39d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li * hieralloc_free in that case. Here, C++ will have already called the 40d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li * destructor so tell hieralloc not to do that again. */ 411591693c7b415e9869157c711fe11263c95d74eDavid Li static void operator delete(void *table) 421591693c7b415e9869157c711fe11263c95d74eDavid Li { 43d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li hieralloc_set_destructor(table, NULL); 44d50d9a90a0df4d706421850e17c0fbd85bf710eeDavid Li hieralloc_free(table); 451591693c7b415e9869157c711fe11263c95d74eDavid Li } 461591693c7b415e9869157c711fe11263c95d74eDavid Li 471591693c7b415e9869157c711fe11263c95d74eDavid Li symbol_table_entry(ir_variable *v) : v(v), f(0), t(0) {} 481591693c7b415e9869157c711fe11263c95d74eDavid Li symbol_table_entry(ir_function *f) : v(0), f(f), t(0) {} 491591693c7b415e9869157c711fe11263c95d74eDavid Li symbol_table_entry(const glsl_type *t) : v(0), f(0), t(t) {} 501591693c7b415e9869157c711fe11263c95d74eDavid Li 511591693c7b415e9869157c711fe11263c95d74eDavid Li ir_variable *v; 521591693c7b415e9869157c711fe11263c95d74eDavid Li ir_function *f; 531591693c7b415e9869157c711fe11263c95d74eDavid Li const glsl_type *t; 543b02c91d7b1fcc777dbdafeb044e0df61e1ff0d8David Li}; 551591693c7b415e9869157c711fe11263c95d74eDavid Li 563b02c91d7b1fcc777dbdafeb044e0df61e1ff0d8David Liglsl_symbol_table::glsl_symbol_table(void * ctx) 571591693c7b415e9869157c711fe11263c95d74eDavid Li{ 581591693c7b415e9869157c711fe11263c95d74eDavid Li this->language_version = 120; 591591693c7b415e9869157c711fe11263c95d74eDavid Li this->table = _mesa_symbol_table_ctor(); 603b02c91d7b1fcc777dbdafeb044e0df61e1ff0d8David Li this->mem_ctx = hieralloc_allocate(ctx, 0, "symbol table entries"); 611591693c7b415e9869157c711fe11263c95d74eDavid Li} 621591693c7b415e9869157c711fe11263c95d74eDavid Li 631591693c7b415e9869157c711fe11263c95d74eDavid Liglsl_symbol_table::~glsl_symbol_table() 641591693c7b415e9869157c711fe11263c95d74eDavid Li{ 651591693c7b415e9869157c711fe11263c95d74eDavid Li _mesa_symbol_table_dtor(table); 663b02c91d7b1fcc777dbdafeb044e0df61e1ff0d8David Li //hieralloc_free(mem_ctx); parent context free will free this 671591693c7b415e9869157c711fe11263c95d74eDavid Li} 681591693c7b415e9869157c711fe11263c95d74eDavid Li 691591693c7b415e9869157c711fe11263c95d74eDavid Livoid glsl_symbol_table::push_scope() 701591693c7b415e9869157c711fe11263c95d74eDavid Li{ 711591693c7b415e9869157c711fe11263c95d74eDavid Li _mesa_symbol_table_push_scope(table); 721591693c7b415e9869157c711fe11263c95d74eDavid Li} 731591693c7b415e9869157c711fe11263c95d74eDavid Li 741591693c7b415e9869157c711fe11263c95d74eDavid Livoid glsl_symbol_table::pop_scope() 751591693c7b415e9869157c711fe11263c95d74eDavid Li{ 761591693c7b415e9869157c711fe11263c95d74eDavid Li _mesa_symbol_table_pop_scope(table); 771591693c7b415e9869157c711fe11263c95d74eDavid Li} 781591693c7b415e9869157c711fe11263c95d74eDavid Li 791591693c7b415e9869157c711fe11263c95d74eDavid Libool glsl_symbol_table::name_declared_this_scope(const char *name) 801591693c7b415e9869157c711fe11263c95d74eDavid Li{ 811591693c7b415e9869157c711fe11263c95d74eDavid Li return _mesa_symbol_table_symbol_scope(table, -1, name) == 0; 821591693c7b415e9869157c711fe11263c95d74eDavid Li} 831591693c7b415e9869157c711fe11263c95d74eDavid Li 841591693c7b415e9869157c711fe11263c95d74eDavid Libool glsl_symbol_table::add_variable(ir_variable *v) 851591693c7b415e9869157c711fe11263c95d74eDavid Li{ 861591693c7b415e9869157c711fe11263c95d74eDavid Li if (this->language_version == 110) { 871591693c7b415e9869157c711fe11263c95d74eDavid Li /* In 1.10, functions and variables have separate namespaces. */ 881591693c7b415e9869157c711fe11263c95d74eDavid Li symbol_table_entry *existing = get_entry(v->name); 891591693c7b415e9869157c711fe11263c95d74eDavid Li if (name_declared_this_scope(v->name)) { 901591693c7b415e9869157c711fe11263c95d74eDavid Li /* If there's already an existing function (not a constructor!) in 911591693c7b415e9869157c711fe11263c95d74eDavid Li * the current scope, just update the existing entry to include 'v'. 921591693c7b415e9869157c711fe11263c95d74eDavid Li */ 931591693c7b415e9869157c711fe11263c95d74eDavid Li if (existing->v == NULL && existing->t == NULL) { 941591693c7b415e9869157c711fe11263c95d74eDavid Li existing->v = v; 951591693c7b415e9869157c711fe11263c95d74eDavid Li return true; 961591693c7b415e9869157c711fe11263c95d74eDavid Li } 971591693c7b415e9869157c711fe11263c95d74eDavid Li } else { 981591693c7b415e9869157c711fe11263c95d74eDavid Li /* If not declared at this scope, add a new entry. But if an existing 991591693c7b415e9869157c711fe11263c95d74eDavid Li * entry includes a function, propagate that to this block - otherwise 1001591693c7b415e9869157c711fe11263c95d74eDavid Li * the new variable declaration would shadow the function. 1011591693c7b415e9869157c711fe11263c95d74eDavid Li */ 1021591693c7b415e9869157c711fe11263c95d74eDavid Li symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(v); 1031591693c7b415e9869157c711fe11263c95d74eDavid Li if (existing != NULL) 1041591693c7b415e9869157c711fe11263c95d74eDavid Li entry->f = existing->f; 1051591693c7b415e9869157c711fe11263c95d74eDavid Li int added = _mesa_symbol_table_add_symbol(table, -1, v->name, entry); 1061591693c7b415e9869157c711fe11263c95d74eDavid Li assert(added == 0); 1071591693c7b415e9869157c711fe11263c95d74eDavid Li (void)added; 1081591693c7b415e9869157c711fe11263c95d74eDavid Li return true; 1091591693c7b415e9869157c711fe11263c95d74eDavid Li } 1101591693c7b415e9869157c711fe11263c95d74eDavid Li return false; 1111591693c7b415e9869157c711fe11263c95d74eDavid Li } 1121591693c7b415e9869157c711fe11263c95d74eDavid Li 1131591693c7b415e9869157c711fe11263c95d74eDavid Li /* 1.20+ rules: */ 1141591693c7b415e9869157c711fe11263c95d74eDavid Li symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(v); 1151591693c7b415e9869157c711fe11263c95d74eDavid Li return _mesa_symbol_table_add_symbol(table, -1, v->name, entry) == 0; 1161591693c7b415e9869157c711fe11263c95d74eDavid Li} 1171591693c7b415e9869157c711fe11263c95d74eDavid Li 1181591693c7b415e9869157c711fe11263c95d74eDavid Libool glsl_symbol_table::add_type(const char *name, const glsl_type *t) 1191591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1201591693c7b415e9869157c711fe11263c95d74eDavid Li symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(t); 1211591693c7b415e9869157c711fe11263c95d74eDavid Li return _mesa_symbol_table_add_symbol(table, -1, name, entry) == 0; 1221591693c7b415e9869157c711fe11263c95d74eDavid Li} 1231591693c7b415e9869157c711fe11263c95d74eDavid Li 1241591693c7b415e9869157c711fe11263c95d74eDavid Libool glsl_symbol_table::add_function(ir_function *f) 1251591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1261591693c7b415e9869157c711fe11263c95d74eDavid Li if (this->language_version == 110 && name_declared_this_scope(f->name)) { 1271591693c7b415e9869157c711fe11263c95d74eDavid Li /* In 1.10, functions and variables have separate namespaces. */ 1281591693c7b415e9869157c711fe11263c95d74eDavid Li symbol_table_entry *existing = get_entry(f->name); 1291591693c7b415e9869157c711fe11263c95d74eDavid Li if ((existing->f == NULL) && (existing->t == NULL)) { 1301591693c7b415e9869157c711fe11263c95d74eDavid Li existing->f = f; 1311591693c7b415e9869157c711fe11263c95d74eDavid Li return true; 1321591693c7b415e9869157c711fe11263c95d74eDavid Li } 1331591693c7b415e9869157c711fe11263c95d74eDavid Li } 1341591693c7b415e9869157c711fe11263c95d74eDavid Li symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(f); 1351591693c7b415e9869157c711fe11263c95d74eDavid Li return _mesa_symbol_table_add_symbol(table, -1, f->name, entry) == 0; 1361591693c7b415e9869157c711fe11263c95d74eDavid Li} 1371591693c7b415e9869157c711fe11263c95d74eDavid Li 1381591693c7b415e9869157c711fe11263c95d74eDavid Livoid glsl_symbol_table::add_global_function(ir_function *f) 1391591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1401591693c7b415e9869157c711fe11263c95d74eDavid Li symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(f); 1411591693c7b415e9869157c711fe11263c95d74eDavid Li int added = _mesa_symbol_table_add_global_symbol(table, -1, f->name, entry); 1421591693c7b415e9869157c711fe11263c95d74eDavid Li assert(added == 0); 1431591693c7b415e9869157c711fe11263c95d74eDavid Li} 1441591693c7b415e9869157c711fe11263c95d74eDavid Li 1451591693c7b415e9869157c711fe11263c95d74eDavid Liir_variable *glsl_symbol_table::get_variable(const char *name) 1461591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1471591693c7b415e9869157c711fe11263c95d74eDavid Li symbol_table_entry *entry = get_entry(name); 1481591693c7b415e9869157c711fe11263c95d74eDavid Li return entry != NULL ? entry->v : NULL; 1491591693c7b415e9869157c711fe11263c95d74eDavid Li} 1501591693c7b415e9869157c711fe11263c95d74eDavid Li 1511591693c7b415e9869157c711fe11263c95d74eDavid Liconst glsl_type *glsl_symbol_table::get_type(const char *name) 1521591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1531591693c7b415e9869157c711fe11263c95d74eDavid Li symbol_table_entry *entry = get_entry(name); 1541591693c7b415e9869157c711fe11263c95d74eDavid Li return entry != NULL ? entry->t : NULL; 1551591693c7b415e9869157c711fe11263c95d74eDavid Li} 1561591693c7b415e9869157c711fe11263c95d74eDavid Li 1571591693c7b415e9869157c711fe11263c95d74eDavid Liir_function *glsl_symbol_table::get_function(const char *name) 1581591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1591591693c7b415e9869157c711fe11263c95d74eDavid Li symbol_table_entry *entry = get_entry(name); 1601591693c7b415e9869157c711fe11263c95d74eDavid Li return entry != NULL ? entry->f : NULL; 1611591693c7b415e9869157c711fe11263c95d74eDavid Li} 1621591693c7b415e9869157c711fe11263c95d74eDavid Li 1631591693c7b415e9869157c711fe11263c95d74eDavid Lisymbol_table_entry *glsl_symbol_table::get_entry(const char *name) 1641591693c7b415e9869157c711fe11263c95d74eDavid Li{ 1651591693c7b415e9869157c711fe11263c95d74eDavid Li return (symbol_table_entry *) 1661591693c7b415e9869157c711fe11263c95d74eDavid Li _mesa_symbol_table_find_symbol(table, -1, name); 1671591693c7b415e9869157c711fe11263c95d74eDavid Li} 168