mirror of
https://github.com/netwide-assembler/nasm.git
synced 2024-11-27 08:10:07 +08:00
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:
parent
b4f734fb84
commit
4def1a8db4
13
nasm.c
13
nasm.c
@ -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, ¤tfile);
|
||||
src_get(&lineno, ¤tfile);
|
||||
|
||||
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
7
nasm.h
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
/*
|
||||
|
@ -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,
|
||||
};
|
||||
|
37
preproc.c
37
preproc.c
@ -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
11
test/macroerr.asm
Normal 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
3
test/macroerr.inc
Normal file
@ -0,0 +1,3 @@
|
||||
%macro blej 1
|
||||
mov eax,%1
|
||||
%endmacro
|
Loading…
Reference in New Issue
Block a user