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 { typedef struct symbol_s {
struct symbol_s *next; ///< chain of symbols in symbol table 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 const char *name; ///< symbol name
sym_type_e type; ///< symbol type (typedef, var, struct...) struct type_s *type; ///< symbol type
union { struct param_s *params; ///< the parameters if a function
struct type_s *type; int is_typedef; ///< true if symbol is a typedef
struct def_s *def;
struct enumval_s *enm;
struct class_s *class;
} s;
} symbol_t; } symbol_t;
typedef enum { typedef enum {
@ -71,6 +61,16 @@ typedef struct symtab_s {
symbol_t **symtail; ///< keep chain in declaration order symbol_t **symtail; ///< keep chain in declaration order
} symtab_t; } 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. /** Create a new, empty symbol table.
The symbol tables support scoping via their \c parent pointer. This 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); 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 If there is already a symbol with the same name in the symbol table,
symbol table is checked for duplicate names, not the ancestor chain. 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 symtab The symol table to which the symbol will be added.
\param name The name of the type to be added to the symbol table. \param symbol The symbol to be added to the symbol table.
\param type The type to be added to the symbol table. \return The symbol as in the table, either \a symbol if no
\return The new symbol representing the named type or null if symbol with the same name is already in the symbol
an error occurred. table, or the symbol that was found in the table.
*/ */
symbol_t *symtab_add_type (symtab_t *symtab, const char *name, symbol_t *symtab_addsymbol (symtab_t *symtab, symbol_t *symbol);
struct type_s *type);
/** 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 \param symtab The symol table from which the symbol will be removed.
symbol table is checked for duplicate names, not the ancestor chain. \param symbol The symbol to be removed from the symbol table.
\return The symbol as was in the table, or NULL if not found.
\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.
*/ */
symbol_t *symtab_add_def (symtab_t *symtab, const char *name, symbol_t *symtab_removesymbol (symtab_t *symtab, symbol_t *symbol);
struct def_s *def);
/** 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 The new symbol will not be associated with any table.
symbol table is checked for duplicate names, not the ancestor chain.
\param symtab The symbol table to which the enum will be added. \param symbol The symbol to be copied.
\param name The name of the enum to be added to the symbol table. \return The new symbol.
\param enm The enum to be added to the symbol table.
\return The new symbol representing the enum or null if an
error occurred.
*/ */
symbol_t *symtab_add_enum (symtab_t *symtab, const char *name, symbol_t *copy_symbol (symbol_t *symbol);
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);
/** Create a new single symbol table from the given symbol table chain. /** Create a new single symbol table from the given symbol table chain.

View File

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