From: Peter Johnson Date: Sun, 26 Nov 2006 20:50:23 +0000 (-0000) Subject: GAS parser: match .file and .line handling to that of GAS. In GAS, both X-Git-Tag: v0.6.0~82 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=9da99362c9eca819a26709b1ecf3d185623a3cc6;p=yasm GAS parser: match .file and .line handling to that of GAS. In GAS, both .file (sans file number) and .line need to be given before error messages start having the file/line numbers specified. This temporarily breaks .rept error reporting somewhat (as the current code outputs just .line for .rept expansion), but this will be fixed soon. svn path=/trunk/yasm/; revision=1700 --- diff --git a/modules/parsers/gas/gas-bison.y b/modules/parsers/gas/gas-bison.y index 0a4d01cc..0f636270 100644 --- a/modules/parsers/gas/gas-bison.y +++ b/modules/parsers/gas/gas-bison.y @@ -148,6 +148,7 @@ input: /* empty */ parser_gas->prev_bc, (char *)parser_gas->save_line[parser_gas->save_last ^ 1]); yasm_linemap_goto_next(parser_gas->linemap); + parser_gas->dir_line++; /* keep track for .line followed by .file */ } ; @@ -194,9 +195,24 @@ lineexp: instr $$ = (yasm_bytecode *)NULL; if (yasm_intnum_sign($2) < 0) yasm_error_set(YASM_ERROR_SYNTAX, N_("line number is negative")); - else - yasm_linemap_set(parser_gas->linemap, NULL, - yasm_intnum_get_uint($2), 1); + else { + parser_gas->dir_line = yasm_intnum_get_uint($2); + yasm_intnum_destroy($2); + + if (parser_gas->dir_fileline == 3) { + /* Have both file and line */ + yasm_linemap_set(parser_gas->linemap, NULL, + parser_gas->dir_line, 1); + } else if (parser_gas->dir_fileline == 1) { + /* Had previous file directive only */ + parser_gas->dir_fileline = 3; + yasm_linemap_set(parser_gas->linemap, parser_gas->dir_file, + parser_gas->dir_line, 1); + } else { + /* Didn't see file yet */ + parser_gas->dir_fileline = 2; + } + } } /* Macro directives */ | DIR_REPT expr { @@ -490,6 +506,30 @@ lineexp: instr yasm_valparamhead vps; yasm_valparam *vp; + /* This form also sets the assembler's internal line number */ + if (parser_gas->dir_fileline == 3) { + /* Have both file and line */ + const char *old_fn; + unsigned long old_line; + + yasm_linemap_lookup(parser_gas->linemap, cur_line, &old_fn, + &old_line); + yasm_linemap_set(parser_gas->linemap, $2.contents, + old_line, 1); + } else if (parser_gas->dir_fileline == 2) { + /* Had previous line directive only */ + parser_gas->dir_fileline = 3; + yasm_linemap_set(parser_gas->linemap, $2.contents, + parser_gas->dir_line, 1); + } else { + /* Didn't see line yet, save file */ + parser_gas->dir_fileline = 1; + if (parser_gas->dir_file) + yasm_xfree(parser_gas->dir_file); + parser_gas->dir_file = yasm__xstrdup($2.contents); + } + + /* Pass change along to debug format */ yasm_vps_initialize(&vps); vp = yasm_vp_create($2.contents, NULL); yasm_vps_append(&vps, vp); diff --git a/modules/parsers/gas/gas-parser.c b/modules/parsers/gas/gas-parser.c index a6c9574a..8160fc16 100644 --- a/modules/parsers/gas/gas-parser.c +++ b/modules/parsers/gas/gas-parser.c @@ -53,6 +53,10 @@ gas_parser_do_parse(yasm_object *object, yasm_preproc *pp, yasm_arch *a, parser_gas.locallabel_base = (char *)NULL; parser_gas.locallabel_base_len = 0; + parser_gas.dir_fileline = 0; + parser_gas.dir_file = NULL; + parser_gas.dir_line = 0; + parser_gas.preproc = pp; parser_gas.arch = a; parser_gas.objfmt = of; @@ -98,6 +102,9 @@ gas_parser_do_parse(yasm_object *object, yasm_preproc *pp, yasm_arch *a, /* Free locallabel base if necessary */ if (parser_gas.locallabel_base) yasm_xfree(parser_gas.locallabel_base); + + if (parser_gas.dir_file) + yasm_xfree(parser_gas.dir_file); } /* Define valid preprocessors to use with this parser */ diff --git a/modules/parsers/gas/gas-parser.h b/modules/parsers/gas/gas-parser.h index e81ab15b..4105d5b1 100644 --- a/modules/parsers/gas/gas-parser.h +++ b/modules/parsers/gas/gas-parser.h @@ -67,6 +67,11 @@ typedef struct yasm_parser_gas { /*@null@*/ char *locallabel_base; size_t locallabel_base_len; + /* .line/.file: we have to see both to start setting linemap versions */ + int dir_fileline; + /*@null@*/ char *dir_file; + unsigned long dir_line; + /*@dependent@*/ yasm_preproc *preproc; /*@dependent@*/ yasm_arch *arch; /*@dependent@*/ yasm_objfmt *objfmt; diff --git a/modules/parsers/gas/tests/Makefile.inc b/modules/parsers/gas/tests/Makefile.inc index d1570360..44827334 100644 --- a/modules/parsers/gas/tests/Makefile.inc +++ b/modules/parsers/gas/tests/Makefile.inc @@ -16,6 +16,10 @@ EXTRA_DIST += modules/parsers/gas/tests/gas-fill.asm EXTRA_DIST += modules/parsers/gas/tests/gas-fill.hex EXTRA_DIST += modules/parsers/gas/tests/gas-instlabel.asm EXTRA_DIST += modules/parsers/gas/tests/gas-instlabel.hex +EXTRA_DIST += modules/parsers/gas/tests/gas-line-err.asm +EXTRA_DIST += modules/parsers/gas/tests/gas-line-err.errwarn +EXTRA_DIST += modules/parsers/gas/tests/gas-line2-err.asm +EXTRA_DIST += modules/parsers/gas/tests/gas-line2-err.errwarn EXTRA_DIST += modules/parsers/gas/tests/gas-push.asm EXTRA_DIST += modules/parsers/gas/tests/gas-push.hex EXTRA_DIST += modules/parsers/gas/tests/gas-semi.asm diff --git a/modules/parsers/gas/tests/bin/reptwarn.asm b/modules/parsers/gas/tests/bin/reptwarn.asm index 826bd81d..0935c491 100644 --- a/modules/parsers/gas/tests/bin/reptwarn.asm +++ b/modules/parsers/gas/tests/bin/reptwarn.asm @@ -1,3 +1,4 @@ +.file "-" .byte 1000 .rept 3 .byte 1000 diff --git a/modules/parsers/gas/tests/bin/reptwarn.errwarn b/modules/parsers/gas/tests/bin/reptwarn.errwarn index bd1611d8..974f1161 100644 --- a/modules/parsers/gas/tests/bin/reptwarn.errwarn +++ b/modules/parsers/gas/tests/bin/reptwarn.errwarn @@ -1,9 +1,9 @@ --:1: warning: value does not fit in 8 bit field --:3: warning: value does not fit in 8 bit field --:6: warning: value does not fit in 8 bit field --:3: warning: value does not fit in 8 bit field --:6: warning: value does not fit in 8 bit field --:3: warning: value does not fit in 8 bit field --:6: warning: value does not fit in 8 bit field --:9: warning: value does not fit in 8 bit field +-:2: warning: value does not fit in 8 bit field +-:4: warning: value does not fit in 8 bit field +-:7: warning: value does not fit in 8 bit field +-:4: warning: value does not fit in 8 bit field +-:7: warning: value does not fit in 8 bit field +-:4: warning: value does not fit in 8 bit field +-:7: warning: value does not fit in 8 bit field -:10: warning: value does not fit in 8 bit field +-:11: warning: value does not fit in 8 bit field diff --git a/modules/parsers/gas/tests/gas-line-err.asm b/modules/parsers/gas/tests/gas-line-err.asm new file mode 100644 index 00000000..ce5ea4c5 --- /dev/null +++ b/modules/parsers/gas/tests/gas-line-err.asm @@ -0,0 +1,11 @@ +movw +.file "bar1.s" +movw +.line 600 +movw +.line 200 +movw +.file "bar2.s" +movw +.file 5 "bar3.s" +movw diff --git a/modules/parsers/gas/tests/gas-line-err.errwarn b/modules/parsers/gas/tests/gas-line-err.errwarn new file mode 100644 index 00000000..8f92ad62 --- /dev/null +++ b/modules/parsers/gas/tests/gas-line-err.errwarn @@ -0,0 +1,6 @@ +-:1: invalid number of operands +-:3: invalid number of operands +bar1.s:601: invalid number of operands +bar1.s:201: invalid number of operands +bar2.s:203: invalid number of operands +bar2.s:205: invalid number of operands diff --git a/modules/parsers/gas/tests/gas-line2-err.asm b/modules/parsers/gas/tests/gas-line2-err.asm new file mode 100644 index 00000000..48b9e623 --- /dev/null +++ b/modules/parsers/gas/tests/gas-line2-err.asm @@ -0,0 +1,5 @@ +movw +.line 600 +movw +.file "bar1.s" +movw diff --git a/modules/parsers/gas/tests/gas-line2-err.errwarn b/modules/parsers/gas/tests/gas-line2-err.errwarn new file mode 100644 index 00000000..4cfc626f --- /dev/null +++ b/modules/parsers/gas/tests/gas-line2-err.errwarn @@ -0,0 +1,3 @@ +-:1: invalid number of operands +-:3: invalid number of operands +bar1.s:603: invalid number of operands