1e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke/* -*- c++ -*- */ 2e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke/* 3e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke * Copyright © 2010 Intel Corporation 4e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke * 5e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke * Permission is hereby granted, free of charge, to any person obtaining a 6e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke * copy of this software and associated documentation files (the "Software"), 7e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke * to deal in the Software without restriction, including without limitation 8e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke * the rights to use, copy, modify, merge, publish, distribute, sublicense, 9e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke * and/or sell copies of the Software, and to permit persons to whom the 10e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke * Software is furnished to do so, subject to the following conditions: 11e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke * 12e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke * The above copyright notice and this permission notice (including the next 13e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke * paragraph) shall be included in all copies or substantial portions of the 14e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke * Software. 15e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke * 16e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 19e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 22e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke * DEALINGS IN THE SOFTWARE. 23e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke */ 24e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke 25e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke#include "glsl_symbol_table.h" 26e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke 27e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunkeclass symbol_table_entry { 28e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunkepublic: 29d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke /* Callers of this ralloc-based new need not call delete. It's 30d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke * easier to just ralloc_free 'ctx' (or any of its ancestors). */ 31e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke static void* operator new(size_t size, void *ctx) 32e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke { 33d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke void *entry = ralloc_size(ctx, size); 34e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke assert(entry != NULL); 35e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke return entry; 36e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke } 37e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke 38d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke /* If the user *does* call delete, that's OK, we will just ralloc_free. */ 3921031b4e887a4bd5563130d54a11972b69cb2645Kenneth Graunke static void operator delete(void *entry) 40e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke { 41d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke ralloc_free(entry); 42e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke } 43e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke 44765221c0d5fdb0357bf6fae3220c7d57d93f938dKenneth Graunke symbol_table_entry(ir_variable *v) : v(v), f(0), t(0), u(0) {} 45765221c0d5fdb0357bf6fae3220c7d57d93f938dKenneth Graunke symbol_table_entry(ir_function *f) : v(0), f(f), t(0), u(0) {} 46765221c0d5fdb0357bf6fae3220c7d57d93f938dKenneth Graunke symbol_table_entry(const glsl_type *t) : v(0), f(0), t(t), u(0) {} 47765221c0d5fdb0357bf6fae3220c7d57d93f938dKenneth Graunke symbol_table_entry(struct gl_uniform_block *u) : v(0), f(0), t(0), u(u) {} 48e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke 49e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke ir_variable *v; 50e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke ir_function *f; 51e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke const glsl_type *t; 52765221c0d5fdb0357bf6fae3220c7d57d93f938dKenneth Graunke struct gl_uniform_block *u; 53e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke}; 54e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke 55e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunkeglsl_symbol_table::glsl_symbol_table() 56e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke{ 57e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke this->language_version = 120; 58e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke this->table = _mesa_symbol_table_ctor(); 59d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke this->mem_ctx = ralloc_context(NULL); 60e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke} 61e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke 62e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunkeglsl_symbol_table::~glsl_symbol_table() 63e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke{ 64e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke _mesa_symbol_table_dtor(table); 65d3073f58c17d8675a2ecdd5dfa83e5520c78e1a8Kenneth Graunke ralloc_free(mem_ctx); 66e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke} 67e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke 68e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunkevoid glsl_symbol_table::push_scope() 69e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke{ 70e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke _mesa_symbol_table_push_scope(table); 71e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke} 72e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke 73e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunkevoid glsl_symbol_table::pop_scope() 74e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke{ 75e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke _mesa_symbol_table_pop_scope(table); 76e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke} 77e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke 78e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunkebool glsl_symbol_table::name_declared_this_scope(const char *name) 79e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke{ 80e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke return _mesa_symbol_table_symbol_scope(table, -1, name) == 0; 81e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke} 82e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke 83001eee52d461233b1e1d6ed3577965e9bcb209e8Eric Anholtbool glsl_symbol_table::add_variable(ir_variable *v) 84e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke{ 85e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke if (this->language_version == 110) { 86e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke /* In 1.10, functions and variables have separate namespaces. */ 87001eee52d461233b1e1d6ed3577965e9bcb209e8Eric Anholt symbol_table_entry *existing = get_entry(v->name); 88001eee52d461233b1e1d6ed3577965e9bcb209e8Eric Anholt if (name_declared_this_scope(v->name)) { 89e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke /* If there's already an existing function (not a constructor!) in 90e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke * the current scope, just update the existing entry to include 'v'. 91e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke */ 92e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke if (existing->v == NULL && existing->t == NULL) { 93e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke existing->v = v; 94e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke return true; 95e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke } 96e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke } else { 97e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke /* If not declared at this scope, add a new entry. But if an existing 98e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke * entry includes a function, propagate that to this block - otherwise 99e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke * the new variable declaration would shadow the function. 100e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke */ 101e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(v); 102e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke if (existing != NULL) 103e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke entry->f = existing->f; 104001eee52d461233b1e1d6ed3577965e9bcb209e8Eric Anholt int added = _mesa_symbol_table_add_symbol(table, -1, v->name, entry); 105e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke assert(added == 0); 106ccd8b935e484d267ea864b5e8c65f826d015f708José Fonseca (void)added; 107e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke return true; 108e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke } 109e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke return false; 110e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke } 111e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke 112e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke /* 1.20+ rules: */ 113e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(v); 114001eee52d461233b1e1d6ed3577965e9bcb209e8Eric Anholt return _mesa_symbol_table_add_symbol(table, -1, v->name, entry) == 0; 115e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke} 116e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke 11716d9ebb35771af2bc27024bb4b788ef6427a4f23Ian Romanickbool glsl_symbol_table::add_type(const char *name, const glsl_type *t) 118e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke{ 11916d9ebb35771af2bc27024bb4b788ef6427a4f23Ian Romanick symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(t); 120e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke return _mesa_symbol_table_add_symbol(table, -1, name, entry) == 0; 121e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke} 122e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke 123e8f5ebf313da3ce33ccbbcf9b72946853035fbddEric Anholtbool glsl_symbol_table::add_function(ir_function *f) 124e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke{ 125e8f5ebf313da3ce33ccbbcf9b72946853035fbddEric Anholt if (this->language_version == 110 && name_declared_this_scope(f->name)) { 126e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke /* In 1.10, functions and variables have separate namespaces. */ 127e8f5ebf313da3ce33ccbbcf9b72946853035fbddEric Anholt symbol_table_entry *existing = get_entry(f->name); 128a789ca649cb143c0c5bf3209ff1bde398fbd777eIan Romanick if ((existing->f == NULL) && (existing->t == NULL)) { 129e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke existing->f = f; 130e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke return true; 131e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke } 132e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke } 133e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(f); 134e8f5ebf313da3ce33ccbbcf9b72946853035fbddEric Anholt return _mesa_symbol_table_add_symbol(table, -1, f->name, entry) == 0; 135e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke} 136e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke 137765221c0d5fdb0357bf6fae3220c7d57d93f938dKenneth Graunkebool glsl_symbol_table::add_uniform_block(struct gl_uniform_block *u) 138765221c0d5fdb0357bf6fae3220c7d57d93f938dKenneth Graunke{ 139765221c0d5fdb0357bf6fae3220c7d57d93f938dKenneth Graunke symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(u); 140765221c0d5fdb0357bf6fae3220c7d57d93f938dKenneth Graunke return _mesa_symbol_table_add_symbol(table, -1, u->Name, entry) == 0; 141765221c0d5fdb0357bf6fae3220c7d57d93f938dKenneth Graunke} 142765221c0d5fdb0357bf6fae3220c7d57d93f938dKenneth Graunke 143c17c7903871b031162e41d6495a1bef64844e19bKenneth Graunkevoid glsl_symbol_table::add_global_function(ir_function *f) 144c17c7903871b031162e41d6495a1bef64844e19bKenneth Graunke{ 145c17c7903871b031162e41d6495a1bef64844e19bKenneth Graunke symbol_table_entry *entry = new(mem_ctx) symbol_table_entry(f); 146c17c7903871b031162e41d6495a1bef64844e19bKenneth Graunke int added = _mesa_symbol_table_add_global_symbol(table, -1, f->name, entry); 147c17c7903871b031162e41d6495a1bef64844e19bKenneth Graunke assert(added == 0); 1486b3713f8b864cbe238b0e7efb28bca54b91ef0f8José Fonseca (void)added; 149c17c7903871b031162e41d6495a1bef64844e19bKenneth Graunke} 150c17c7903871b031162e41d6495a1bef64844e19bKenneth Graunke 151e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunkeir_variable *glsl_symbol_table::get_variable(const char *name) 152e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke{ 153e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke symbol_table_entry *entry = get_entry(name); 154e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke return entry != NULL ? entry->v : NULL; 155e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke} 156e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke 157e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunkeconst glsl_type *glsl_symbol_table::get_type(const char *name) 158e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke{ 159e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke symbol_table_entry *entry = get_entry(name); 160e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke return entry != NULL ? entry->t : NULL; 161e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke} 162e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke 163e466b182bbf21f62fe6542091f4af3275555db80Ian Romanickir_function *glsl_symbol_table::get_function(const char *name) 164e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke{ 165e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke symbol_table_entry *entry = get_entry(name); 166e466b182bbf21f62fe6542091f4af3275555db80Ian Romanick return entry != NULL ? entry->f : NULL; 167e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke} 168e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke 169e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunkesymbol_table_entry *glsl_symbol_table::get_entry(const char *name) 170e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke{ 171e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke return (symbol_table_entry *) 172e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke _mesa_symbol_table_find_symbol(table, -1, name); 173e9c7ceed27f6811ad1cae46c93ce9bc3fb3668d8Kenneth Graunke} 174