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