diff options
author | H. Peter Anvin <hpa@linux.intel.com> | 2016-05-09 13:59:44 -0700 |
---|---|---|
committer | H. Peter Anvin <hpa@linux.intel.com> | 2016-05-09 13:59:44 -0700 |
commit | 4def1a8db462548f60b3b5b44c2ee585c21af9e0 (patch) | |
tree | 4d179aa1f1de2a607927cfd0aff0617450c0365c | |
parent | b4f734fb844dbc4cc29304e952b33aa9fc96e398 (diff) | |
download | nasm-4def1a8db462548f60b3b5b44c2ee585c21af9e0.tar.gz |
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>
-rw-r--r-- | nasm.c | 13 | ||||
-rw-r--r-- | nasm.h | 7 | ||||
-rw-r--r-- | nasmlib.c | 6 | ||||
-rw-r--r-- | nasmlib.h | 2 | ||||
-rw-r--r-- | preproc-nop.c | 12 | ||||
-rw-r--r-- | preproc.c | 37 | ||||
-rw-r--r-- | test/macroerr.asm | 11 | ||||
-rw-r--r-- | test/macroerr.inc | 3 |
8 files changed, 78 insertions, 13 deletions
@@ -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 */ @@ -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); /* diff --git a/preproc-nop.c b/preproc-nop.c index 8024cac2..f8513a8a 100644 --- a/preproc-nop.c +++ b/preproc-nop.c @@ -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, }; @@ -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, }; diff --git a/test/macroerr.asm b/test/macroerr.asm new file mode 100644 index 00000000..5f1c93e2 --- /dev/null +++ b/test/macroerr.asm @@ -0,0 +1,11 @@ +%include "macroerr.inc" + +%macro bluttan 1 + mov eax,%1 +%endmacro + + bluttan ptr + blej ptr + dd ptr, ptr + +ptr: diff --git a/test/macroerr.inc b/test/macroerr.inc new file mode 100644 index 00000000..f40f7e60 --- /dev/null +++ b/test/macroerr.inc @@ -0,0 +1,3 @@ +%macro blej 1 + mov eax,%1 +%endmacro |