Show the expanded macro stack when displaying diagnostics

It can be hard to find errors inside potentially nested macros.
Show the mmacro expansion stack when printing diagnostics.
Note that a list file doesn't help for errors that are detected
before the code-generation pass.

Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
This commit is contained in:
H. Peter Anvin 2016-05-09 13:59:44 -07:00
parent b4f734fb84
commit 4def1a8db4
8 changed files with 78 additions and 13 deletions

13
nasm.c
View file

@ -128,7 +128,7 @@ static struct RAA *offsets;
static struct SAA *forwrefs; /* keep track of forward references */
static const struct forwrefinfo *forwref;
static struct preproc_ops *preproc;
static const struct preproc_ops *preproc;
#define OP_NORMAL (1u << 0)
#define OP_PREPROCESS (1u << 1)
@ -1876,12 +1876,11 @@ static void nasm_verror_gnu(int severity, const char *fmt, va_list ap)
return;
if (!(severity & ERR_NOFILE))
src_get(&lineno, &currentfile);
src_get(&lineno, &currentfile);
if (!skip_this_pass(severity)) {
if (currentfile) {
fprintf(error_file, "%s:%"PRId32": ", currentfile, lineno);
nasm_free(currentfile);
} else {
fputs("nasm: ", error_file);
}
@ -2002,7 +2001,7 @@ static void nasm_verror_common(int severity, const char *fmt, va_list args)
}
vsnprintf(msg, sizeof msg - 64, fmt, args);
if (severity & ERR_WARN_MASK) {
if ((severity & (ERR_WARN_MASK|ERR_PP_LISTMACRO)) == ERR_WARN_MASK) {
char *p = strchr(msg, '\0');
snprintf(p, 64, " [-w+%s]", warnings[WARN_IDX(severity)].name);
}
@ -2010,6 +2009,10 @@ static void nasm_verror_common(int severity, const char *fmt, va_list args)
if (!skip_this_pass(severity))
fprintf(error_file, "%s%s\n", pfx, msg);
/* Are we recursing from error_list_macros? */
if (severity & ERR_PP_LISTMACRO)
return;
/*
* Don't suppress this with skip_this_pass(), or we don't get
* pass1 or preprocessor warnings in the list file
@ -2020,6 +2023,8 @@ static void nasm_verror_common(int severity, const char *fmt, va_list args)
if (severity & ERR_USAGE)
want_usage = true;
preproc->error_list_macros(severity);
switch (severity & ERR_MASK) {
case ERR_DEBUG:
/* no further action, by definition */

7
nasm.h
View file

@ -342,10 +342,13 @@ struct preproc_ops {
/* Include path from command line */
void (*include_path)(char *path);
/* Unwind the macro stack when printing an error message */
void (*error_list_macros)(int severity);
};
extern struct preproc_ops nasmpp;
extern struct preproc_ops preproc_nop;
extern const struct preproc_ops nasmpp;
extern const struct preproc_ops preproc_nop;
/*
* Some lexical properties of the NASM source language, included

View file

@ -570,6 +570,12 @@ int32_t src_set_linnum(int32_t newline)
return oldline;
}
/* This returns a pointer, not a copy, to the current fname */
const char *src_get_fname(void)
{
return file_name;
}
int32_t src_get_linnum(void)
{
return line_number;

View file

@ -107,6 +107,7 @@ static inline vefunc nasm_set_verror(vefunc ve)
#define ERR_NO_SEVERITY 0x00000100 /* suppress printing severity */
#define ERR_PP_PRECOND 0x00000200 /* for preprocessor use */
#define ERR_PP_LISTMACRO 0x00000400 /* from preproc->error_list_macros() */
/*
* These codes define specific types of suppressible warning.
@ -392,6 +393,7 @@ int bsi(const char *string, const char **array, int size);
int bsii(const char *string, const char **array, int size);
char *src_set_fname(char *newname);
const char *src_get_fname(void);
int32_t src_set_linnum(int32_t newline);
int32_t src_get_linnum(void);
/*

View file

@ -1,6 +1,6 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2012 The NASM Authors - All Rights Reserved
* Copyright 1996-2016 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
@ -170,7 +170,12 @@ static void nop_include_path(char *path)
(void)path;
}
struct preproc_ops preproc_nop = {
static void nop_error_list_macros(int severity)
{
(void)severity;
}
const struct preproc_ops preproc_nop = {
nop_reset,
nop_getline,
nop_cleanup,
@ -178,5 +183,6 @@ struct preproc_ops preproc_nop = {
nop_pre_define,
nop_pre_undefine,
nop_pre_include,
nop_include_path
nop_include_path,
nop_error_list_macros,
};

View file

@ -155,6 +155,9 @@ struct MMacro {
uint64_t unique;
int lineno; /* Current line number on expansion */
uint64_t condcnt; /* number of if blocks... */
char *fname; /* File where defined */
int32_t xline; /* First line in macro */
};
@ -625,6 +628,7 @@ static void free_mmacro(MMacro * m)
free_tlist(m->dlist);
nasm_free(m->defaults);
free_llist(m->expansion);
nasm_free(m->fname);
nasm_free(m);
}
@ -2738,7 +2742,7 @@ issue_error:
pp_directives[i]);
return DIRECTIVE_FOUND;
}
defining = nasm_malloc(sizeof(MMacro));
defining = nasm_zalloc(sizeof(MMacro));
defining->max_depth =
(i == PP_RMACRO) || (i == PP_IRMACRO) ? DEADMAN_LIMIT : 0;
defining->casesense = (i == PP_MACRO) || (i == PP_RMACRO);
@ -2748,6 +2752,8 @@ issue_error:
return DIRECTIVE_FOUND;
}
src_get(&defining->xline, &defining->fname);
mmac = (MMacro *) hash_findix(&mmacros, defining->name);
while (mmac) {
if (!strcmp(mmac->name, defining->name) &&
@ -5011,7 +5017,7 @@ static char *pp_getline(void)
/* only set line and file name if there's a next node */
if (i->next) {
src_set_linnum(i->lineno);
nasm_free(src_set_fname(nasm_strdup(i->fname)));
src_set_fname(nasm_strdup(i->fname));
}
istk = i->next;
lfmt->downlevel(LIST_INCLUDE);
@ -5237,7 +5243,29 @@ static void make_tok_num(Token * tok, int64_t val)
tok->type = TOK_NUMBER;
}
struct preproc_ops nasmpp = {
static void pp_error_list_macros(int severity)
{
MMacro *m;
int32_t saved_line;
const char *saved_fname = NULL;
severity |= ERR_PP_LISTMACRO | ERR_NO_SEVERITY;
saved_line = src_get_linnum();
saved_fname = src_get_fname();
list_for_each(m, istk->mstk) {
if (m->name && !m->nolist) {
src_set_linnum(m->xline + m->lineno);
src_set_fname(m->fname);
nasm_error(severity, "from macro `%s' defined here", m->name);
}
}
src_set_fname((char *)saved_fname);
src_set_linnum(saved_line);
}
const struct preproc_ops nasmpp = {
pp_reset,
pp_getline,
pp_cleanup,
@ -5245,5 +5273,6 @@ struct preproc_ops nasmpp = {
pp_pre_define,
pp_pre_undefine,
pp_pre_include,
pp_include_path
pp_include_path,
pp_error_list_macros,
};

11
test/macroerr.asm Normal file
View file

@ -0,0 +1,11 @@
%include "macroerr.inc"
%macro bluttan 1
mov eax,%1
%endmacro
bluttan ptr
blej ptr
dd ptr, ptr
ptr:

3
test/macroerr.inc Normal file
View file

@ -0,0 +1,3 @@
%macro blej 1
mov eax,%1
%endmacro