mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-01-31 05:00:35 +00:00
Rewrite the symbol (table) management in light of actual usage.
This commit is contained in:
parent
ac14db7b1b
commit
5b8725ca66
2 changed files with 74 additions and 121 deletions
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue