From 2f05bb60997488703c97838ee2c50059f73c3892 Mon Sep 17 00:00:00 2001 From: Peter Johnson Date: Sun, 25 Sep 2005 01:01:02 +0000 Subject: [PATCH] * symrec.h (yasm_symtab_parser_finalize): Add function to declare all undefined symbols extern if unused rather than causing undef errors. * symrec.c (yasm_symtab_parser_finalize): Implement. (symtab_finalize_info): New (more data to pass to (symtab_parser_finalize_checksym): Update finalize helper. * yasm.c (main): Update call to yasm_symtab_parser_finalize(). svn path=/trunk/yasm/; revision=1232 --- frontends/yasm/yasm.c | 2 +- libyasm/symrec.c | 30 ++++++++++++++++++++++++------ libyasm/symrec.h | 7 ++++++- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/frontends/yasm/yasm.c b/frontends/yasm/yasm.c index b338f0ce..10e39c8f 100644 --- a/frontends/yasm/yasm.c +++ b/frontends/yasm/yasm.c @@ -611,7 +611,7 @@ main(int argc, char *argv[]) fclose(in); /* Check for undefined symbols */ - yasm_symtab_parser_finalize(yasm_object_get_symtab(object)); + yasm_symtab_parser_finalize(yasm_object_get_symtab(object), 0, NULL); if (yasm_get_num_errors(warning_error) > 0) { yasm_errwarn_output_all(yasm_object_get_linemap(object), warning_error, diff --git a/libyasm/symrec.c b/libyasm/symrec.c index fac2fbd3..2fab0e82 100644 --- a/libyasm/symrec.c +++ b/libyasm/symrec.c @@ -282,10 +282,17 @@ yasm_symrec_declare(yasm_symrec *rec, yasm_sym_vis vis, unsigned long line) rec->name, rec->line); } +typedef struct symtab_finalize_info { + unsigned long firstundef_line; + int undef_extern; + /*@null@*/ yasm_objfmt *objfmt; +} symtab_finalize_info; + static int symtab_parser_finalize_checksym(yasm_symrec *sym, /*@null@*/ void *d) { unsigned long *firstundef_line = d; + symtab_finalize_info *info = (symtab_finalize_info *)d; /* error if a symbol is used but never defined or extern/common declared */ if ((sym->status & SYM_USED) && !(sym->status & SYM_DEFINED) && !(sym->visibility & (YASM_SYM_EXTERN | YASM_SYM_COMMON))) { @@ -293,19 +300,30 @@ symtab_parser_finalize_checksym(yasm_symrec *sym, /*@null@*/ void *d) sym->name); if (sym->line < *firstundef_line) *firstundef_line = sym->line; + if (info->undef_extern && info->objfmt) + yasm_objfmt_extern_declare(info->objfmt, sym->name, NULL, 1); + else { + yasm__error(sym->line, N_("undefined symbol `%s' (first use)"), + sym->name); + if (sym->line < info->firstundef_line) + info->firstundef_line = sym->line; + } } return 1; } void -yasm_symtab_parser_finalize(yasm_symtab *symtab) +yasm_symtab_parser_finalize(yasm_symtab *symtab, int undef_extern, + yasm_objfmt *objfmt) { - unsigned long firstundef_line = ULONG_MAX; - yasm_symtab_traverse(symtab, &firstundef_line, - symtab_parser_finalize_checksym); - if (firstundef_line < ULONG_MAX) - yasm__error(firstundef_line, + symtab_finalize_info info; + info.firstundef_line = ULONG_MAX; + info.undef_extern = undef_extern; + info.objfmt = objfmt; + yasm_symtab_traverse(symtab, &info, symtab_parser_finalize_checksym); + if (info.firstundef_line < ULONG_MAX) + yasm__error(info.firstundef_line, N_(" (Each undefined symbol is reported only once.)")); } diff --git a/libyasm/symrec.h b/libyasm/symrec.h index 64b1ef04..4d4a879d 100644 --- a/libyasm/symrec.h +++ b/libyasm/symrec.h @@ -144,8 +144,13 @@ int /*@alt void@*/ yasm_symtab_traverse /** Finalize symbol table after parsing stage. Checks for symbols that are * used but never defined or declared #YASM_SYM_EXTERN or #YASM_SYM_COMMON. + * \param symtab symbol table + * \param undef_extern if nonzero, all undef syms should be declared extern + * \param objfmt object format to notify about new extern decls + * (may be NULL if undef_extern is 0) */ -void yasm_symtab_parser_finalize(yasm_symtab *symtab); +void yasm_symtab_parser_finalize(yasm_symtab *symtab, int undef_extern, + /*@null@*/ yasm_objfmt *objfmt); /** Print the symbol table. For debugging purposes. * \param symtab symbol table -- 2.40.0