Rewrite the symbol (table) management in light of actual usage.

This commit is contained in:
Bill Currie 2011-01-13 14:48:38 +09:00
parent ac14db7b1b
commit 5b8725ca66
2 changed files with 74 additions and 121 deletions

View File

@ -37,23 +37,13 @@
*/
//@{
//
typedef enum {
sym_type,
sym_def,
sym_enum,
sym_class,
} sym_type_e;
typedef struct symbol_s {
struct symbol_s *next; ///< chain of symbols in symbol table
struct symtab_s *table; ///< symbol table that owns this symbol
const char *name; ///< symbol name
sym_type_e type; ///< symbol type (typedef, var, struct...)
union {
struct type_s *type;
struct def_s *def;
struct enumval_s *enm;
struct class_s *class;
} s;
struct type_s *type; ///< symbol type
struct param_s *params; ///< the parameters if a function
int is_typedef; ///< true if symbol is a typedef
} symbol_t;
typedef enum {
@ -71,6 +61,16 @@ typedef struct symtab_s {
symbol_t **symtail; ///< keep chain in declaration order
} symtab_t;
/** Create a new, empty named symbol.
Only the symbol name field will be filled in. \a name will be copied
using save_string().
\param name The name of the symbol.
\return The new symbol.
*/
symbol_t *new_symbol (const char *name);
/** Create a new, empty symbol table.
The symbol tables support scoping via their \c parent pointer. This
@ -95,61 +95,36 @@ symtab_t *new_symtab (symtab_t *parent, stab_type_e type);
*/
symbol_t *symtab_lookup (symtab_t *symtab, const char *name);
/** Add a named type (\c typedef) to the symbol table.
/** Add a symbol to the symbol table.
Duplicate names will not be inserted (an error), but only the given
symbol table is checked for duplicate names, not the ancestor chain.
If there is already a symbol with the same name in the symbol table,
the symbol will not be added to the table, and the symbol that was
found in the table witll be returned.
\param symtab The symbol table to which the named type will be added.
\param name The name of the type to be added to the symbol table.
\param type The type to be added to the symbol table.
\return The new symbol representing the named type or null if
an error occurred.
\param symtab The symol table to which the symbol will be added.
\param symbol The symbol to be added to the symbol table.
\return The symbol as in the table, either \a symbol if no
symbol with the same name is already in the symbol
table, or the symbol that was found in the table.
*/
symbol_t *symtab_add_type (symtab_t *symtab, const char *name,
struct type_s *type);
symbol_t *symtab_addsymbol (symtab_t *symtab, symbol_t *symbol);
/** Add a def to the symbol table.
/** Remove a symbol from the symbol table.
Duplicate names will not be inserted (an error), but only the given
symbol table is checked for duplicate names, not the ancestor chain.
\param symtab The symbol table to which the def will be added.
\param name The name of the def to be added to the symbol table.
\param def The def to be added to the symbol table.
\return The new symbol representing the def or null if an
error occurred.
\param symtab The symol table from which the symbol will be removed.
\param symbol The symbol to be removed from the symbol table.
\return The symbol as was in the table, or NULL if not found.
*/
symbol_t *symtab_add_def (symtab_t *symtab, const char *name,
struct def_s *def);
symbol_t *symtab_removesymbol (symtab_t *symtab, symbol_t *symbol);
/** Add an enum to the symbol table.
/** Make a copy of a symbol.
Duplicate names will not be inserted (an error), but only the given
symbol table is checked for duplicate names, not the ancestor chain.
The new symbol will not be associated with any table.
\param symtab The symbol table to which the enum will be added.
\param name The name of the enum to be added to the symbol table.
\param enm The enum to be added to the symbol table.
\return The new symbol representing the enum or null if an
error occurred.
\param symbol The symbol to be copied.
\return The new symbol.
*/
symbol_t *symtab_add_enum (symtab_t *symtab, const char *name,
struct enumval_s *enm);
/** Add a class to the symbol table.
Duplicate names will not be inserted (an error), but only the given
symbol table is checked for duplicate names, not the ancestor chain.
\param symtab The symbol table to which the class will be added.
\param name The name of the class to be added to the symbol table.
\param class The class to be added to the symbol table.
\return The new symbol representing the class or null if an
error occurred.
*/
symbol_t *symtab_add_class (symtab_t *symtab, const char *name,
struct class_s *class);
symbol_t *copy_symbol (symbol_t *symbol);
/** Create a new single symbol table from the given symbol table chain.

View File

@ -5,6 +5,7 @@
#include "class.h"
#include "def.h"
#include "function.h"
#include "qfcc.h"
#include "symtab.h"
#include "type.h"
@ -12,6 +13,15 @@
static symtab_t *free_symtabs;
static symbol_t *free_symbols;
symbol_t *
new_symbol (const char *name)
{
symbol_t *symbol;
ALLOC (256, symbol_t, symbols, symbol);
symbol->name = save_string (name);
return symbol;
}
static const char *
sym_getkey (void *k, void *unused)
{
@ -47,81 +57,50 @@ symtab_lookup (symtab_t *symtab, const char *name)
return 0;
}
static symbol_t *
new_symbol (void)
{
symbol_t *symbol;
ALLOC (256, symbol_t, symbols, symbol);
return symbol;
}
static void
add_symbol (symtab_t *symtab, symbol_t *symbol)
symbol_t *
symtab_addsymbol (symtab_t *symtab, symbol_t *symbol)
{
symbol_t *s;
if ((s = Hash_Find (symtab->tab, symbol->name)))
return s;
Hash_Add (symtab->tab, symbol);
symbol->next = *symtab->symtail;
*symtab->symtail = symbol;
symtab->symtail = &symbol->next;
}
symbol_t *
symtab_add_type (symtab_t *symtab, const char *name, type_t *type)
{
symbol_t *symbol;
if ((symbol = Hash_Find (symtab->tab, name))) {
// duplicate symbol
}
symbol = new_symbol ();
symbol->name = name;
symbol->type = sym_type;
symbol->s.type = type;
add_symbol (symtab, symbol);
symbol->table = symtab;
return symbol;
}
symbol_t *
symtab_add_def (symtab_t *symtab, const char *name, def_t *def)
symtab_removesymbol (symtab_t *symtab, symbol_t *symbol)
{
symbol_t *symbol;
if ((symbol = Hash_Find (symtab->tab, name))) {
// duplicate symbol
}
symbol = new_symbol ();
symbol->name = name;
symbol->type = sym_def;
symbol->s.def = def;
add_symbol (symtab, symbol);
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;
return symbol;
}
symbol_t *
symtab_add_enum (symtab_t *symtab, const char *name, struct enumval_s *enm)
copy_symbol (symbol_t *symbol)
{
symbol_t *symbol;
if ((symbol = Hash_Find (symtab->tab, name))) {
// duplicate symbol
}
symbol = new_symbol ();
symbol->name = name;
symbol->type = sym_enum;
symbol->s.enm = enm;
add_symbol (symtab, symbol);
return symbol;
}
symbol_t *
symtab_add_class (symtab_t *symtab, const char *name, class_t *class)
{
symbol_t *symbol;
if ((symbol = Hash_Find (symtab->tab, name))) {
// duplicate symbol
}
symbol = new_symbol ();
symbol->name = name;
symbol->type = sym_class;
symbol->s.class = class;
add_symbol (symtab, symbol);
return symbol;
symbol_t *sym = new_symbol (symbol->name);
sym->type = symbol->type;
sym->params = copy_params (symbol->params);
sym->is_typedef = symbol->is_typedef;
return sym;
}
symtab_t *
@ -136,9 +115,8 @@ symtab_flat_copy (symtab_t *symtab, symtab_t *parent)
for (symbol = symtab->symbols; symbol; symbol = symbol->next) {
if (Hash_Find (newtab->tab, symbol->name))
continue;
newsym = new_symbol ();
*newsym = *symbol;
add_symbol (newtab, newsym);
newsym = copy_symbol (symbol);
symtab_addsymbol (newtab, newsym);
}
symtab = symtab->parent;
// Set the tail pointer so symbols in ancestor tables come before