Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Blame | Last modification | View Log | RSS feed

  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. }
  272.