diff options
author | Ian Romanick <[email protected]> | 2010-03-19 15:32:57 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2010-06-24 14:56:26 -0700 |
commit | 84341f4b2014810b2964230384fe76338be1d78e (patch) | |
tree | c1434f4b61d6a26d8fea5e397c264b531764fd30 /src/mesa/shader/symbol_table.c | |
parent | b5e381d9783f17c9a527ac38122444eac6807566 (diff) |
Make sure that symbols aren't multiply defined in the same scope.
The assembly parser is already checking this, but we're relying on the
symbol table handling it in glsl2.
Diffstat (limited to 'src/mesa/shader/symbol_table.c')
-rw-r--r-- | src/mesa/shader/symbol_table.c | 52 |
1 files changed, 51 insertions, 1 deletions
diff --git a/src/mesa/shader/symbol_table.c b/src/mesa/shader/symbol_table.c index 6a5d6868974..3fea5ee1f1f 100644 --- a/src/mesa/shader/symbol_table.c +++ b/src/mesa/shader/symbol_table.c @@ -58,7 +58,9 @@ struct symbol { */ int name_space; - + /** Scope depth where this symbol was defined. */ + unsigned depth; + /** * Arbitrary user supplied data. */ @@ -104,6 +106,9 @@ struct _mesa_symbol_table { /** List of all symbol headers in the table. */ struct symbol_header *hdr; + + /** Current scope depth. */ + unsigned depth; }; @@ -157,6 +162,7 @@ _mesa_symbol_table_pop_scope(struct _mesa_symbol_table *table) struct symbol *sym = scope->symbols; table->current_scope = scope->next; + table->depth--; free(scope); @@ -184,6 +190,7 @@ _mesa_symbol_table_push_scope(struct _mesa_symbol_table *table) scope->next = table->current_scope; table->current_scope = scope; + table->depth++; } @@ -261,6 +268,36 @@ _mesa_symbol_table_iterator_next(struct _mesa_symbol_table_iterator *iter) } +/** + * Determine the scope "distance" of a symbol from the current scope + * + * \return + * A non-negative number for the number of scopes between the current scope + * and the scope where a symbol was defined. A value of zero means the current + * scope. A negative number if the symbol does not exist. + */ +int +_mesa_symbol_table_symbol_scope(struct _mesa_symbol_table *table, + int name_space, const char *name) +{ + struct symbol_header *const hdr = find_symbol(table, name); + struct symbol *sym; + + if (hdr != NULL) { + for (sym = hdr->symbols; sym != NULL; sym = sym->next_with_same_name) { + assert(sym->hdr == hdr); + + if ((name_space == -1) || (sym->name_space == name_space)) { + assert(sym->depth <= table->depth); + return sym->depth - table->depth; + } + } + } + + return -1; +} + + void * _mesa_symbol_table_find_symbol(struct _mesa_symbol_table *table, int name_space, const char *name) @@ -309,12 +346,25 @@ _mesa_symbol_table_add_symbol(struct _mesa_symbol_table *table, check_symbol_table(table); + /* If the symbol already exists in this namespace at this scope, it cannot + * be added to the table. + */ + for (sym = hdr->symbols + ; (sym != NULL) && (sym->name_space != name_space) + ; sym = sym->next_with_same_name) { + /* empty */ + } + + if (sym && (sym->depth == table->depth)) + return -1; + sym = calloc(1, sizeof(*sym)); sym->next_with_same_name = hdr->symbols; sym->next_with_same_scope = table->current_scope->symbols; sym->hdr = hdr; sym->name_space = name_space; sym->data = declaration; + sym->depth = table->depth; assert(sym->hdr == hdr); |