diff --git a/tools/qfcc/include/symtab.h b/tools/qfcc/include/symtab.h index 37e21f8bd..134bcf1a1 100644 --- a/tools/qfcc/include/symtab.h +++ b/tools/qfcc/include/symtab.h @@ -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. diff --git a/tools/qfcc/source/symtab.c b/tools/qfcc/source/symtab.c index a5a1b3b02..d4eb3a715 100644 --- a/tools/qfcc/source/symtab.c +++ b/tools/qfcc/source/symtab.c @@ -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