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,
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))) {
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.)"));
}
/** 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