19d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org/* -*- c++ -*- */ 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright © 2010 Intel Corporation 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Permission is hereby granted, free of charge, to any person obtaining a 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * copy of this software and associated documentation files (the "Software"), 79d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org * to deal in the Software without restriction, including without limitation 89d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * and/or sell copies of the Software, and to permit persons to whom the 109d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org * Software is furnished to do so, subject to the following conditions: 119d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org * 1269cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com * The above copyright notice and this permission notice (including the next 139d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org * paragraph) shall be included in all copies or substantial portions of the 14181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com * Software. 15383963280ddd13030331765fe88d2aefa3e32130bsalomon@google.com * 16383963280ddd13030331765fe88d2aefa3e32130bsalomon@google.com * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com * DEALINGS IN THE SOFTWARE. 23383963280ddd13030331765fe88d2aefa3e32130bsalomon@google.com */ 24383963280ddd13030331765fe88d2aefa3e32130bsalomon@google.com 25383963280ddd13030331765fe88d2aefa3e32130bsalomon@google.com#include "glsl_symbol_table.h" 26383963280ddd13030331765fe88d2aefa3e32130bsalomon@google.com 27383963280ddd13030331765fe88d2aefa3e32130bsalomon@google.comclass symbol_table_entry { 28383963280ddd13030331765fe88d2aefa3e32130bsalomon@google.compublic: 29383963280ddd13030331765fe88d2aefa3e32130bsalomon@google.com /* Callers of this ralloc-based new need not call delete. It's 30383963280ddd13030331765fe88d2aefa3e32130bsalomon@google.com * easier to just ralloc_free 'ctx' (or any of its ancestors). */ 31383963280ddd13030331765fe88d2aefa3e32130bsalomon@google.com static void* operator new(size_t size, void *ctx) 32181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com { 33181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com void *entry = ralloc_size(ctx, size); 34181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com assert(entry != NULL); 35181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com return entry; 36181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com } 37b5b3168a645802f66233234a06dd5a3764f18018bsalomon@google.com 38181e9bd9484ece4132e0cc5cfcff602134e5489dbsalomon@google.com /* If the user *does* call delete, that's OK, we will just ralloc_free. */ 399d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org static void operator delete(void *entry) 409d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org { 41c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com ralloc_free(entry); 42c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com } 43afec7ba75962517b17293799d3fc70d39fa7dbf2tomhudson@google.com 44c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com symbol_table_entry(ir_variable *v) : v(v), f(0), t(0), u(0) {} 45c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com symbol_table_entry(ir_function *f) : v(0), f(f), t(0), u(0) {} 46c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com symbol_table_entry(const glsl_type *t) : v(0), f(0), t(t), u(0) {} 479d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org symbol_table_entry(struct gl_uniform_block *u) : v(0), f(0), t(0), u(u) {} 48c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com 499d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org ir_variable *v; 509d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org ir_function *f; 519d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org const glsl_type *t; 529d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org struct gl_uniform_block *u; 539d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org}; 549d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 552047f00e4698f83499ab91911999a65c21a951c9epoger@google.comglsl_symbol_table::glsl_symbol_table() 5661f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com{ 5761f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com this->language_version = 120; 5861f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com this->table = _mesa_symbol_table_ctor(); 5961f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com this->mem_ctx = ralloc_context(NULL); 6061f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com} 6161f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com 6261f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.comglsl_symbol_table::~glsl_symbol_table() 6361f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com{ 649d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org _mesa_symbol_table_dtor(table); 659d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org ralloc_free(mem_ctx); 669d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org} 679d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 68c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.comvoid glsl_symbol_table::push_scope() 69c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com{ 70c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com _mesa_symbol_table_push_scope(table); 71c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com} 72c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com 739d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.orgvoid glsl_symbol_table::pop_scope() 749d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org{ 759d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org _mesa_symbol_table_pop_scope(table); 769d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org} 779d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 789d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.orgbool glsl_symbol_table::name_declared_this_scope(const char *name) 799d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org{ 809d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org return _mesa_symbol_table_symbol_scope(table, -1, name) == 0; 817744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com} 827744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com 839d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.orgbool glsl_symbol_table::add_variable(ir_variable *v) 847744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com{ 859d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org if (this->language_version == 110) { 869d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org /* In 1.10, functions and variables have separate namespaces. */ 879d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org symbol_table_entry *existing = get_entry(v->name); 889d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org if (name_declared_this_scope(v->name)) { 899d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org /* If there's already an existing function (not a constructor!) in 909d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org * the current scope, just update the existing entry to include 'v'. 919d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org */ 929d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org if (existing->v == NULL && existing->t == NULL) { 939d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org existing->v = v; 94c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com return true; 95afec7ba75962517b17293799d3fc70d39fa7dbf2tomhudson@google.com } 96c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com } else { 97c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com /* If not declared at this scope, add a new entry. But if an existing 98c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com * entry includes a function, propagate that to this block - otherwise 99c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com * the new variable declaration would shadow the function. 100c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com */ 101c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(v); 1022047f00e4698f83499ab91911999a65c21a951c9epoger@google.com if (existing != NULL) 103c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com entry->f = existing->f; 1049d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org int added = _mesa_symbol_table_add_symbol(table, -1, v->name, entry); 1059d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org assert(added == 0); 1062047f00e4698f83499ab91911999a65c21a951c9epoger@google.com (void)added; 10761f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com return true; 10861f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com } 10961f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com return false; 11061f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com } 11161f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com 11261f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com /* 1.20+ rules: */ 11361f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(v); 11461f3bde1ba114e7b39b53411f4aa31ed0875d159bsalomon@google.com return _mesa_symbol_table_add_symbol(table, -1, v->name, entry) == 0; 1159d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org} 1169d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 1179d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.orgbool glsl_symbol_table::add_type(const char *name, const glsl_type *t) 1189d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org{ 119c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(t); 120c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com return _mesa_symbol_table_add_symbol(table, -1, name, entry) == 0; 121c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com} 122c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com 123c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.combool glsl_symbol_table::add_function(ir_function *f) 124c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com{ 1259d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org if (this->language_version == 110 && name_declared_this_scope(f->name)) { 1269d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org /* In 1.10, functions and variables have separate namespaces. */ 1279d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org symbol_table_entry *existing = get_entry(f->name); 1289d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org if ((existing->f == NULL) && (existing->t == NULL)) { 1299d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org existing->f = f; 1309d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org return true; 1319d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org } 1329d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org } 1337744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(f); 1347744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com return _mesa_symbol_table_add_symbol(table, -1, f->name, entry) == 0; 1357744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com} 1369d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 1379d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.orgbool glsl_symbol_table::add_uniform_block(struct gl_uniform_block *u) 1387744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com{ 1397744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(u); 1409d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org return _mesa_symbol_table_add_symbol(table, -1, u->Name, entry) == 0; 1417744c205f20b5617e83d4af8f97b5771bfa8d671reed@google.com} 1429d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 1439d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.orgvoid glsl_symbol_table::add_global_function(ir_function *f) 1449d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org{ 1459d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(f); 1469d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org int added = _mesa_symbol_table_add_global_symbol(table, -1, f->name, entry); 1479d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org assert(added == 0); 14807f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.com (void)added; 14907f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.com} 150c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com 151afec7ba75962517b17293799d3fc70d39fa7dbf2tomhudson@google.comir_variable *glsl_symbol_table::get_variable(const char *name) 152c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com{ 153c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com symbol_table_entry *entry = get_entry(name); 154c10a88825d119054a9f4e7b7af7a3f887e30ab6btomhudson@google.com return entry != NULL ? entry->v : NULL; 1559d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org} 1569d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 1579d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.orgconst glsl_type *glsl_symbol_table::get_type(const char *name) 1589d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org{ 1599d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org symbol_table_entry *entry = get_entry(name); 160129b8e3237b80b9d258a8f48e8f54c0073cafbdcsenorblanco@chromium.org return entry != NULL ? entry->t : NULL; 1619d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org} 1629d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 1639d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.orgir_function *glsl_symbol_table::get_function(const char *name) 16407f3ee10d34f09342abb93d758b5e151ff78f7a5reed@google.com{ 1659d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org symbol_table_entry *entry = get_entry(name); 1669d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org return entry != NULL ? entry->f : NULL; 1679d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org} 1689d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org 1699d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.orgsymbol_table_entry *glsl_symbol_table::get_entry(const char *name) 1709d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org{ 1719d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org return (symbol_table_entry *) 1729d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org _mesa_symbol_table_find_symbol(table, -1, name); 1739d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org} 1749d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org