summaryrefslogtreecommitdiff
path: root/gas/input-scrub.c
diff options
context:
space:
mode:
authorJan Beulich <jbeulich@suse.com>2022-12-13 09:11:53 +0100
committerJan Beulich <jbeulich@suse.com>2022-12-13 09:11:53 +0100
commit969b9a36506bfb386f8ce30f88f1a6a6ebbaca6e (patch)
tree7cc916e6db68595bb894cd1675fb0112038ab218 /gas/input-scrub.c
parentf2e469cb476a8fff9841914af6f8b5dead5c553a (diff)
downloadbinutils-gdb-969b9a36506bfb386f8ce30f88f1a6a6ebbaca6e.tar.gz
gas: re-work line number tracking for macros and their expansions
The PR gas/16908 workaround aimed at uniformly reporting line numbers to reference macro invocation sites. As mentioned in a comment this may be desirable for small macros, but often isn't for larger ones. As a first step improve diagnostics to report both locations, while aiming at leaving generated debug info unaltered. Note that macro invocation context is lost for any diagnostics issued only after all input was processed (or more generally for any use of as_*_where(), as the functions can't know whether the passed in location is related to [part of] the present stack of locations). To maintain the intended workaround behavior for PR gas/16908, a new as_where() is introduced to "look through" macro invocations, while the existing as_where() is renamed (and used in only very few places for now). Down the road as_where() will likely want to return a list of (file,line) pairs.
Diffstat (limited to 'gas/input-scrub.c')
-rw-r--r--gas/input-scrub.c102
1 files changed, 79 insertions, 23 deletions
diff --git a/gas/input-scrub.c b/gas/input-scrub.c
index 650e3e38bbd..6791ef27749 100644
--- a/gas/input-scrub.c
+++ b/gas/input-scrub.c
@@ -104,6 +104,9 @@ static const char *logical_input_file;
static unsigned int physical_input_line;
static unsigned int logical_input_line;
+/* Indicator whether the origin of an update was a .linefile directive. */
+static bool is_linefile;
+
/* Struct used to save the state of the input handler during include files */
struct input_save {
char * buffer_start;
@@ -115,6 +118,7 @@ struct input_save {
const char * logical_input_file;
unsigned int physical_input_line;
unsigned int logical_input_line;
+ bool is_linefile;
size_t sb_index;
sb from_sb;
enum expansion from_sb_expansion; /* Should we do a conditional check? */
@@ -166,6 +170,7 @@ input_scrub_push (char *saved_position)
saved->logical_input_file = logical_input_file;
saved->physical_input_line = physical_input_line;
saved->logical_input_line = logical_input_line;
+ saved->is_linefile = is_linefile;
saved->sb_index = sb_index;
saved->from_sb = from_sb;
saved->from_sb_expansion = from_sb_expansion;
@@ -193,6 +198,7 @@ input_scrub_pop (struct input_save *saved)
logical_input_file = saved->logical_input_file;
physical_input_line = saved->physical_input_line;
logical_input_line = saved->logical_input_line;
+ is_linefile = saved->is_linefile;
sb_index = saved->sb_index;
from_sb = saved->from_sb;
from_sb_expansion = saved->from_sb_expansion;
@@ -267,8 +273,6 @@ input_scrub_include_sb (sb *from, char *position, enum expansion expansion)
as_fatal (_("macros nested too deeply"));
++macro_nest;
- gas_assert (expansion < expanding_nested);
-
#ifdef md_macro_start
if (expansion == expanding_macro)
{
@@ -283,8 +287,6 @@ input_scrub_include_sb (sb *from, char *position, enum expansion expansion)
expansion. */
newline = from->len >= 1 && from->ptr[0] != '\n';
sb_build (&from_sb, from->len + newline + 2 * sizeof (".linefile") + 30);
- if (expansion == expanding_repeat && from_sb_expansion >= expanding_macro)
- expansion = expanding_nested;
from_sb_expansion = expansion;
if (newline)
{
@@ -437,10 +439,7 @@ bump_line_counters (void)
if (sb_index == (size_t) -1)
++physical_input_line;
- /* PR gas/16908 workaround: Don't bump logical line numbers while
- expanding macros, unless file (and maybe line; see as_where()) are
- used inside the macro. */
- if (logical_input_line != -1u && from_sb_expansion < expanding_macro)
+ if (logical_input_line != -1u)
++logical_input_line;
}
@@ -471,10 +470,6 @@ new_logical_line_flags (const char *fname, /* DON'T destroy it! We point to it!
case 1 << 3:
if (line_number < 0 || fname != NULL)
abort ();
- /* PR gas/16908 workaround: Ignore updates when nested inside a macro
- expansion. */
- if (from_sb_expansion == expanding_nested)
- return;
if (next_saved_file == NULL)
fname = physical_input_file;
else if (next_saved_file->logical_input_file)
@@ -486,6 +481,8 @@ new_logical_line_flags (const char *fname, /* DON'T destroy it! We point to it!
abort ();
}
+ is_linefile = flags != 1 && (flags != 0 || fname);
+
if (line_number >= 0)
logical_input_line = line_number;
else if (line_number == -1 && fname && !*fname && (flags & (1 << 2)))
@@ -499,15 +496,6 @@ new_logical_line_flags (const char *fname, /* DON'T destroy it! We point to it!
&& (logical_input_file == NULL
|| filename_cmp (logical_input_file, fname)))
logical_input_file = fname;
-
- /* When encountering file or line changes inside a macro, arrange for
- bump_line_counters() to henceforth increment the logical line number
- again, just like it does when expanding repeats. See as_where() for
- why changing file or line alone doesn't alter expansion mode. */
- if (from_sb_expansion == expanding_macro
- && logical_input_file != NULL
- && logical_input_line != -1u)
- from_sb_expansion = expanding_repeat;
}
void
@@ -516,6 +504,33 @@ new_logical_line (const char *fname, int line_number)
new_logical_line_flags (fname, line_number, 0);
}
+void
+as_report_context (void)
+{
+ const struct input_save *saved = next_saved_file;
+ enum expansion expansion = from_sb_expansion;
+ int indent = 1;
+
+ if (!macro_nest)
+ return;
+
+ do
+ {
+ if (expansion != expanding_macro)
+ /* Nothing. */;
+ else if (saved->logical_input_file != NULL
+ && saved->logical_input_line != -1u)
+ as_info_where (saved->logical_input_file, saved->logical_input_line,
+ indent, _("macro invoked from here"));
+ else
+ as_info_where (saved->physical_input_file, saved->physical_input_line,
+ indent, _("macro invoked from here"));
+
+ expansion = saved->from_sb_expansion;
+ ++indent;
+ }
+ while ((saved = saved->next_saved_file) != NULL);
+}
/* Return the current physical input file name and line number, if known */
@@ -534,11 +549,53 @@ as_where_physical (unsigned int *linep)
return NULL;
}
-/* Return the current file name and line number. */
+/* Return the file name and line number at the top most macro
+ invocation, unless .file / .line were used inside a macro. */
const char *
as_where (unsigned int *linep)
{
+ const char *file = as_where_top (linep);
+
+ if (macro_nest && is_linefile)
+ {
+ const struct input_save *saved = next_saved_file;
+ enum expansion expansion = from_sb_expansion;
+
+ do
+ {
+ if (!saved->is_linefile)
+ break;
+
+ if (expansion != expanding_macro)
+ /* Nothing. */;
+ else if (saved->logical_input_file != NULL
+ && (linep == NULL || saved->logical_input_line != -1u))
+ {
+ if (linep != NULL)
+ *linep = saved->logical_input_line;
+ file = saved->logical_input_file;
+ }
+ else if (saved->physical_input_file != NULL)
+ {
+ if (linep != NULL)
+ *linep = saved->physical_input_line;
+ file = saved->physical_input_file;
+ }
+
+ expansion = saved->from_sb_expansion;
+ }
+ while ((saved = saved->next_saved_file) != NULL);
+ }
+
+ return file;
+}
+
+/* Return the current file name and line number. */
+
+const char *
+as_where_top (unsigned int *linep)
+{
if (logical_input_file != NULL
&& (linep == NULL || logical_input_line != -1u))
{
@@ -549,4 +606,3 @@ as_where (unsigned int *linep)
return as_where_physical (linep);
}
-