1770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick/*
2770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick * Copyright © 2008 Intel Corporation
3770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick *
4770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick * Permission is hereby granted, free of charge, to any person obtaining a
5770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick * copy of this software and associated documentation files (the "Software"),
6770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick * to deal in the Software without restriction, including without limitation
7770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick * and/or sell copies of the Software, and to permit persons to whom the
9770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick * Software is furnished to do so, subject to the following conditions:
10770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick *
11770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick * The above copyright notice and this permission notice (including the next
12770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick * paragraph) shall be included in all copies or substantial portions of the
13770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick * Software.
14770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick *
15770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
18770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick * DEALINGS IN THE SOFTWARE.
22770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick */
23770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
245e3b2baae74e6cde494b2fe5c6b32e3e8ef0ce87Brian Paul#include "main/imports.h"
25770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick#include "symbol_table.h"
26ec453979db90e30243851b2dc8024e3d9aeceb62Thomas Helland#include "../../util/hash_table.h"
27770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
28770cebbc29863ae944a31463ee4bdeb789105abaIan Romanickstruct symbol {
296dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   /** Symbol name. */
306dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   char *name;
316dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri
32770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    /**
33770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick     * Link to the next symbol in the table with the same name
34770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick     *
35770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick     * The linked list of symbols with the same name is ordered by scope
36770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick     * from inner-most to outer-most.
37770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick     */
38770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    struct symbol *next_with_same_name;
39770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
40770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    /**
41770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick     * Link to the next symbol in the table with the same scope
42770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick     *
43770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick     * The linked list of symbols with the same scope is unordered.  Symbols
44770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick     * in this list my have unique names.
45770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick     */
46770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    struct symbol *next_with_same_scope;
47770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
4884341f4b2014810b2964230384fe76338be1d78eIan Romanick    /** Scope depth where this symbol was defined. */
4984341f4b2014810b2964230384fe76338be1d78eIan Romanick    unsigned depth;
5084341f4b2014810b2964230384fe76338be1d78eIan Romanick
51770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    /**
52770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick     * Arbitrary user supplied data.
53770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick     */
54770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    void *data;
55770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick};
56770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
57770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
58770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick/**
59770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick * Element of the scope stack.
60770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick */
61770cebbc29863ae944a31463ee4bdeb789105abaIan Romanickstruct scope_level {
62770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    /** Link to next (inner) scope level. */
63770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    struct scope_level *next;
64770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
65770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    /** Linked list of symbols with the same scope. */
66770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    struct symbol *symbols;
67770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick};
68770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
69770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
70770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick/**
71770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick *
72770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick */
73770cebbc29863ae944a31463ee4bdeb789105abaIan Romanickstruct _mesa_symbol_table {
74770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    /** Hash table containing all symbols in the symbol table. */
75770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    struct hash_table *ht;
76770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
77770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    /** Top of scope stack. */
78770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    struct scope_level *current_scope;
790f255d195651f104a0c0bed84039b656d94ac4ccIan Romanick
8084341f4b2014810b2964230384fe76338be1d78eIan Romanick    /** Current scope depth. */
8184341f4b2014810b2964230384fe76338be1d78eIan Romanick    unsigned depth;
82770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick};
83770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
84770cebbc29863ae944a31463ee4bdeb789105abaIan Romanickvoid
85770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick_mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table)
86770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick{
87770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    struct scope_level *const scope = table->current_scope;
88770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    struct symbol *sym = scope->symbols;
89770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
90770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    table->current_scope = scope->next;
9184341f4b2014810b2964230384fe76338be1d78eIan Romanick    table->depth--;
92770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
93770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    free(scope);
94770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
95770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    while (sym != NULL) {
96770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick        struct symbol *const next = sym->next_with_same_scope;
976dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri        struct hash_entry *hte = _mesa_hash_table_search(table->ht,
986dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri                                                         sym->name);
996dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri        if (sym->next_with_same_name) {
1006dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri           /* If there is a symbol with this name in an outer scope update
1016dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri            * the hash table to point to it.
1026dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri            */
1036dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri           hte->key = sym->next_with_same_name->name;
1046dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri           hte->data = sym->next_with_same_name;
1056dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri        } else {
1066dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri           _mesa_hash_table_remove(table->ht, hte);
1076dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri           free(sym->name);
1086dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri        }
109770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
110770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick        free(sym);
111770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick        sym = next;
112770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    }
113770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick}
114770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
115770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
116770cebbc29863ae944a31463ee4bdeb789105abaIan Romanickvoid
117770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick_mesa_symbol_table_push_scope(struct _mesa_symbol_table *table)
118770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick{
119770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    struct scope_level *const scope = calloc(1, sizeof(*scope));
12036f8042e8c4fc60533db299078cd25e13e1d0626Juha-Pekka Heikkila    if (scope == NULL) {
12136f8042e8c4fc60533db299078cd25e13e1d0626Juha-Pekka Heikkila       _mesa_error_no_memory(__func__);
12236f8042e8c4fc60533db299078cd25e13e1d0626Juha-Pekka Heikkila       return;
12336f8042e8c4fc60533db299078cd25e13e1d0626Juha-Pekka Heikkila    }
12436f8042e8c4fc60533db299078cd25e13e1d0626Juha-Pekka Heikkila
125770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    scope->next = table->current_scope;
126770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    table->current_scope = scope;
12784341f4b2014810b2964230384fe76338be1d78eIan Romanick    table->depth++;
128770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick}
129770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
130770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
1316dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceristatic struct symbol *
132770cebbc29863ae944a31463ee4bdeb789105abaIan Romanickfind_symbol(struct _mesa_symbol_table *table, const char *name)
133770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick{
134ec453979db90e30243851b2dc8024e3d9aeceb62Thomas Helland   struct hash_entry *entry = _mesa_hash_table_search(table->ht, name);
1356dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   return entry ? (struct symbol *) entry->data : NULL;
136770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick}
137770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
138770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
13984341f4b2014810b2964230384fe76338be1d78eIan Romanick/**
14084341f4b2014810b2964230384fe76338be1d78eIan Romanick * Determine the scope "distance" of a symbol from the current scope
14184341f4b2014810b2964230384fe76338be1d78eIan Romanick *
14284341f4b2014810b2964230384fe76338be1d78eIan Romanick * \return
14384341f4b2014810b2964230384fe76338be1d78eIan Romanick * A non-negative number for the number of scopes between the current scope
14484341f4b2014810b2964230384fe76338be1d78eIan Romanick * and the scope where a symbol was defined.  A value of zero means the current
14584341f4b2014810b2964230384fe76338be1d78eIan Romanick * scope.  A negative number if the symbol does not exist.
14684341f4b2014810b2964230384fe76338be1d78eIan Romanick */
14784341f4b2014810b2964230384fe76338be1d78eIan Romanickint
14884341f4b2014810b2964230384fe76338be1d78eIan Romanick_mesa_symbol_table_symbol_scope(struct _mesa_symbol_table *table,
1496dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri                                const char *name)
15084341f4b2014810b2964230384fe76338be1d78eIan Romanick{
1516dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   struct symbol *const sym = find_symbol(table, name);
15284341f4b2014810b2964230384fe76338be1d78eIan Romanick
1536dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   if (sym) {
1546dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      assert(sym->depth <= table->depth);
1556dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      return sym->depth - table->depth;
1566dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   }
1576dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri
1586dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   return -1;
15984341f4b2014810b2964230384fe76338be1d78eIan Romanick}
16084341f4b2014810b2964230384fe76338be1d78eIan Romanick
16184341f4b2014810b2964230384fe76338be1d78eIan Romanick
162770cebbc29863ae944a31463ee4bdeb789105abaIan Romanickvoid *
163770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick_mesa_symbol_table_find_symbol(struct _mesa_symbol_table *table,
1646dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri                               const char *name)
165770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick{
1666dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   struct symbol *const sym = find_symbol(table, name);
1676dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   if (sym)
1686dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      return sym->data;
169770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
1706dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   return NULL;
171770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick}
172770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
173770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
174770cebbc29863ae944a31463ee4bdeb789105abaIan Romanickint
175770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick_mesa_symbol_table_add_symbol(struct _mesa_symbol_table *table,
1766dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri                              const char *name, void *declaration)
177770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick{
1786dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   struct symbol *new_sym;
1796dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   struct symbol *sym = find_symbol(table, name);
180770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
1816dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   if (sym && sym->depth == table->depth)
1826dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      return -1;
183770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
1846dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   new_sym = calloc(1, sizeof(*sym));
1856dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   if (new_sym == NULL) {
1866dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      _mesa_error_no_memory(__func__);
1876dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      return -1;
1886dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   }
18984341f4b2014810b2964230384fe76338be1d78eIan Romanick
1906dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   if (sym) {
1916dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      /* Store link to symbol in outer scope with the same name */
1926dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      new_sym->next_with_same_name = sym;
1936dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      new_sym->name = sym->name;
1946dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   } else {
1956dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      new_sym->name = strdup(name);
1966dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      if (new_sym->name == NULL) {
1976dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri         free(new_sym);
1986dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri         _mesa_error_no_memory(__func__);
1996dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri         return -1;
2006dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      }
2016dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   }
20236f8042e8c4fc60533db299078cd25e13e1d0626Juha-Pekka Heikkila
2036dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   new_sym->next_with_same_scope = table->current_scope->symbols;
2046dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   new_sym->data = declaration;
2056dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   new_sym->depth = table->depth;
206770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
2076dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   table->current_scope->symbols = new_sym;
208770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
2096dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   _mesa_hash_table_insert(table->ht, new_sym->name, new_sym);
210770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
2116dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   return 0;
212770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick}
213770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
214dfbdb2c0b3559c46d93f10d636a88b9541304fc7Samuel Iglesias Gonsálvezint
215dfbdb2c0b3559c46d93f10d636a88b9541304fc7Samuel Iglesias Gonsálvez_mesa_symbol_table_replace_symbol(struct _mesa_symbol_table *table,
216dfbdb2c0b3559c46d93f10d636a88b9541304fc7Samuel Iglesias Gonsálvez                                  const char *name,
217dfbdb2c0b3559c46d93f10d636a88b9541304fc7Samuel Iglesias Gonsálvez                                  void *declaration)
218dfbdb2c0b3559c46d93f10d636a88b9541304fc7Samuel Iglesias Gonsálvez{
219dfbdb2c0b3559c46d93f10d636a88b9541304fc7Samuel Iglesias Gonsálvez    struct symbol *sym = find_symbol(table, name);
220dfbdb2c0b3559c46d93f10d636a88b9541304fc7Samuel Iglesias Gonsálvez
221dfbdb2c0b3559c46d93f10d636a88b9541304fc7Samuel Iglesias Gonsálvez    /* If the symbol doesn't exist, it cannot be replaced. */
222dfbdb2c0b3559c46d93f10d636a88b9541304fc7Samuel Iglesias Gonsálvez    if (sym == NULL)
223dfbdb2c0b3559c46d93f10d636a88b9541304fc7Samuel Iglesias Gonsálvez       return -1;
224dfbdb2c0b3559c46d93f10d636a88b9541304fc7Samuel Iglesias Gonsálvez
225dfbdb2c0b3559c46d93f10d636a88b9541304fc7Samuel Iglesias Gonsálvez    sym->data = declaration;
226dfbdb2c0b3559c46d93f10d636a88b9541304fc7Samuel Iglesias Gonsálvez    return 0;
227dfbdb2c0b3559c46d93f10d636a88b9541304fc7Samuel Iglesias Gonsálvez}
228770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
229a8f52647b045b5400ebcfc58ba235599a6e9ad87Kenneth Graunkeint
230a8f52647b045b5400ebcfc58ba235599a6e9ad87Kenneth Graunke_mesa_symbol_table_add_global_symbol(struct _mesa_symbol_table *table,
2316dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri                                     const char *name, void *declaration)
232a8f52647b045b5400ebcfc58ba235599a6e9ad87Kenneth Graunke{
2336dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   struct scope_level *top_scope;
2346dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   struct symbol *inner_sym = NULL;
2356dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   struct symbol *sym = find_symbol(table, name);
236a8f52647b045b5400ebcfc58ba235599a6e9ad87Kenneth Graunke
2376dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   while (sym) {
2386dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      if (sym->depth == 0)
2396dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri         return -1;
240a8f52647b045b5400ebcfc58ba235599a6e9ad87Kenneth Graunke
2416dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      inner_sym = sym;
242a8f52647b045b5400ebcfc58ba235599a6e9ad87Kenneth Graunke
2436dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      /* Get symbol from the outer scope with the same name */
2446dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      sym = sym->next_with_same_name;
2456dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   }
246a8f52647b045b5400ebcfc58ba235599a6e9ad87Kenneth Graunke
2476dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   /* Find the top-level scope */
2486dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   for (top_scope = table->current_scope; top_scope->next != NULL;
2496dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri        top_scope = top_scope->next) {
2506dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      /* empty */
2516dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   }
252a8f52647b045b5400ebcfc58ba235599a6e9ad87Kenneth Graunke
2536dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   sym = calloc(1, sizeof(*sym));
2546dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   if (sym == NULL) {
2556dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      _mesa_error_no_memory(__func__);
2566dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      return -1;
2576dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   }
258a8f52647b045b5400ebcfc58ba235599a6e9ad87Kenneth Graunke
2596dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   if (inner_sym) {
2606dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      /* In case we add the global out of order store a link to the global
2616dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri       * symbol in global.
2626dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri       */
2636dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      inner_sym->next_with_same_name = sym;
2646dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri
2656dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      sym->name = inner_sym->name;
2666dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   } else {
2676dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      sym->name = strdup(name);
2686dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      if (sym->name == NULL) {
2696dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri         free(sym);
2706dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri         _mesa_error_no_memory(__func__);
2716dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri         return -1;
2726dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri      }
2736dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   }
27436f8042e8c4fc60533db299078cd25e13e1d0626Juha-Pekka Heikkila
2756dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   sym->next_with_same_scope = top_scope->symbols;
2766dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   sym->data = declaration;
277a8f52647b045b5400ebcfc58ba235599a6e9ad87Kenneth Graunke
2786dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   top_scope->symbols = sym;
279a8f52647b045b5400ebcfc58ba235599a6e9ad87Kenneth Graunke
2806dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   _mesa_hash_table_insert(table->ht, sym->name, sym);
281a8f52647b045b5400ebcfc58ba235599a6e9ad87Kenneth Graunke
2826dbe8a1b9fd750b4c1bb600a0bb43129d95e6ecaTimothy Arceri   return 0;
283a8f52647b045b5400ebcfc58ba235599a6e9ad87Kenneth Graunke}
284a8f52647b045b5400ebcfc58ba235599a6e9ad87Kenneth Graunke
285a8f52647b045b5400ebcfc58ba235599a6e9ad87Kenneth Graunke
286a8f52647b045b5400ebcfc58ba235599a6e9ad87Kenneth Graunke
287770cebbc29863ae944a31463ee4bdeb789105abaIan Romanickstruct _mesa_symbol_table *
288770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick_mesa_symbol_table_ctor(void)
289770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick{
290770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    struct _mesa_symbol_table *table = calloc(1, sizeof(*table));
291770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
292946ea82bff530ac7aa8f5ebe56704fde62e14e86Ian Romanick    if (table != NULL) {
293ec453979db90e30243851b2dc8024e3d9aeceb62Thomas Helland       table->ht = _mesa_hash_table_create(NULL, _mesa_key_hash_string,
294ec453979db90e30243851b2dc8024e3d9aeceb62Thomas Helland                                           _mesa_key_string_equal);
295770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
296946ea82bff530ac7aa8f5ebe56704fde62e14e86Ian Romanick       _mesa_symbol_table_push_scope(table);
297946ea82bff530ac7aa8f5ebe56704fde62e14e86Ian Romanick    }
298770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick
299770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick    return table;
300770cebbc29863ae944a31463ee4bdeb789105abaIan Romanick}
301946ea82bff530ac7aa8f5ebe56704fde62e14e86Ian Romanick
302946ea82bff530ac7aa8f5ebe56704fde62e14e86Ian Romanick
303946ea82bff530ac7aa8f5ebe56704fde62e14e86Ian Romanickvoid
304946ea82bff530ac7aa8f5ebe56704fde62e14e86Ian Romanick_mesa_symbol_table_dtor(struct _mesa_symbol_table *table)
305946ea82bff530ac7aa8f5ebe56704fde62e14e86Ian Romanick{
306946ea82bff530ac7aa8f5ebe56704fde62e14e86Ian Romanick   while (table->current_scope != NULL) {
307946ea82bff530ac7aa8f5ebe56704fde62e14e86Ian Romanick      _mesa_symbol_table_pop_scope(table);
308946ea82bff530ac7aa8f5ebe56704fde62e14e86Ian Romanick   }
309946ea82bff530ac7aa8f5ebe56704fde62e14e86Ian Romanick
310ec453979db90e30243851b2dc8024e3d9aeceb62Thomas Helland   _mesa_hash_table_destroy(table->ht, NULL);
311946ea82bff530ac7aa8f5ebe56704fde62e14e86Ian Romanick   free(table);
312946ea82bff530ac7aa8f5ebe56704fde62e14e86Ian Romanick}
313