2011-01-05 10:09:49 +00:00
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
|
|
|
|
#include "QF/hash.h"
|
|
|
|
|
|
|
|
#include "class.h"
|
|
|
|
#include "def.h"
|
2011-01-13 05:48:38 +00:00
|
|
|
#include "function.h"
|
2011-01-05 10:09:49 +00:00
|
|
|
#include "qfcc.h"
|
|
|
|
#include "symtab.h"
|
|
|
|
#include "type.h"
|
|
|
|
|
|
|
|
static symtab_t *free_symtabs;
|
|
|
|
static symbol_t *free_symbols;
|
|
|
|
|
2011-01-13 05:48:38 +00:00
|
|
|
symbol_t *
|
|
|
|
new_symbol (const char *name)
|
|
|
|
{
|
|
|
|
symbol_t *symbol;
|
|
|
|
ALLOC (256, symbol_t, symbols, symbol);
|
|
|
|
symbol->name = save_string (name);
|
|
|
|
return symbol;
|
|
|
|
}
|
|
|
|
|
2011-01-17 03:04:41 +00:00
|
|
|
symbol_t *
|
|
|
|
new_symbol_type (const char *name, type_t *type)
|
|
|
|
{
|
|
|
|
symbol_t *symbol;
|
|
|
|
symbol = new_symbol (name);
|
|
|
|
symbol->type = type;
|
|
|
|
return symbol;
|
|
|
|
}
|
|
|
|
|
2011-01-05 10:09:49 +00:00
|
|
|
static const char *
|
|
|
|
sym_getkey (void *k, void *unused)
|
|
|
|
{
|
|
|
|
return ((symbol_t *) k)->name;
|
|
|
|
}
|
|
|
|
|
|
|
|
symtab_t *
|
|
|
|
new_symtab (symtab_t *parent, stab_type_e type)
|
|
|
|
{
|
|
|
|
symtab_t *symtab;
|
|
|
|
int tabsize = 63;
|
|
|
|
|
|
|
|
ALLOC (16, symtab_t, symtabs, symtab);
|
|
|
|
|
|
|
|
symtab->parent = parent;
|
|
|
|
symtab->type = type;
|
|
|
|
if (symtab->type == stab_global)
|
|
|
|
tabsize = 1023;
|
|
|
|
symtab->tab = Hash_NewTable (tabsize, sym_getkey, 0, 0);
|
|
|
|
symtab->symtail = &symtab->symbols;
|
|
|
|
return symtab;
|
|
|
|
}
|
|
|
|
|
|
|
|
symbol_t *
|
|
|
|
symtab_lookup (symtab_t *symtab, const char *name)
|
|
|
|
{
|
|
|
|
symbol_t *symbol;
|
|
|
|
while (symtab) {
|
|
|
|
if ((symbol = Hash_Find (symtab->tab, name)))
|
|
|
|
return symbol;
|
|
|
|
symtab = symtab->parent;
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-01-13 05:48:38 +00:00
|
|
|
symbol_t *
|
|
|
|
symtab_addsymbol (symtab_t *symtab, symbol_t *symbol)
|
2011-01-05 10:09:49 +00:00
|
|
|
{
|
2011-01-13 05:48:38 +00:00
|
|
|
symbol_t *s;
|
|
|
|
if ((s = Hash_Find (symtab->tab, symbol->name)))
|
|
|
|
return s;
|
2011-01-05 10:09:49 +00:00
|
|
|
Hash_Add (symtab->tab, symbol);
|
2011-01-13 05:48:38 +00:00
|
|
|
|
2011-01-05 10:09:49 +00:00
|
|
|
symbol->next = *symtab->symtail;
|
|
|
|
*symtab->symtail = symbol;
|
|
|
|
symtab->symtail = &symbol->next;
|
|
|
|
|
2011-01-13 05:48:38 +00:00
|
|
|
symbol->table = symtab;
|
2011-01-05 10:09:49 +00:00
|
|
|
|
|
|
|
return symbol;
|
|
|
|
}
|
|
|
|
|
|
|
|
symbol_t *
|
2011-01-13 05:48:38 +00:00
|
|
|
symtab_removesymbol (symtab_t *symtab, symbol_t *symbol)
|
2011-01-05 10:09:49 +00:00
|
|
|
{
|
2011-01-13 05:48:38 +00:00
|
|
|
symbol_t **s;
|
|
|
|
|
|
|
|
if (!(symbol = Hash_Del (symtab->tab, symbol->name)))
|
|
|
|
return 0;
|
|
|
|
for (s = &symtab->symbols; *s && *s != symbol; s = & (*s)->next)
|
|
|
|
;
|
|
|
|
if (!*s)
|
|
|
|
abort ();
|
|
|
|
*s = (*s)->next;
|
|
|
|
if (symtab->symtail == &symbol->next)
|
|
|
|
symtab->symtail = s;
|
|
|
|
symbol->next = 0;
|
|
|
|
symbol->table = 0;
|
2011-01-05 10:09:49 +00:00
|
|
|
return symbol;
|
|
|
|
}
|
|
|
|
|
|
|
|
symbol_t *
|
2011-01-13 05:48:38 +00:00
|
|
|
copy_symbol (symbol_t *symbol)
|
2011-01-05 10:09:49 +00:00
|
|
|
{
|
2011-01-13 05:48:38 +00:00
|
|
|
symbol_t *sym = new_symbol (symbol->name);
|
|
|
|
sym->type = symbol->type;
|
|
|
|
sym->params = copy_params (symbol->params);
|
2011-01-17 13:33:33 +00:00
|
|
|
sym->sy_type = symbol->sy_type;
|
|
|
|
sym->s = symbol->s;
|
2011-01-13 05:48:38 +00:00
|
|
|
return sym;
|
2011-01-05 10:09:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
symtab_t *
|
|
|
|
symtab_flat_copy (symtab_t *symtab, symtab_t *parent)
|
|
|
|
{
|
|
|
|
symtab_t *newtab;
|
|
|
|
symbol_t *newsym;
|
|
|
|
symbol_t *symbol;
|
|
|
|
|
|
|
|
newtab = new_symtab (parent, stab_local);
|
|
|
|
while (symtab) {
|
|
|
|
for (symbol = symtab->symbols; symbol; symbol = symbol->next) {
|
|
|
|
if (Hash_Find (newtab->tab, symbol->name))
|
|
|
|
continue;
|
2011-01-13 05:48:38 +00:00
|
|
|
newsym = copy_symbol (symbol);
|
|
|
|
symtab_addsymbol (newtab, newsym);
|
2011-01-05 10:09:49 +00:00
|
|
|
}
|
|
|
|
symtab = symtab->parent;
|
|
|
|
// Set the tail pointer so symbols in ancestor tables come before
|
|
|
|
// those in decendent tables.
|
|
|
|
newtab->symtail = &newtab->symbols;
|
|
|
|
}
|
|
|
|
// Reset the tail pointer so any symbols added to newtab come after
|
|
|
|
// those copied from the input symbol table chain.
|
|
|
|
for (symbol = newtab->symbols; symbol && symbol->next;
|
|
|
|
symbol = symbol->next)
|
|
|
|
;
|
|
|
|
newtab->symtail = symbol ? &symbol->next : &newtab->symbols;
|
|
|
|
return newtab;
|
|
|
|
}
|