This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
support '# line "file" flags' and '# 0 "" 2'
- From: Alexandre Oliva <aoliva at redhat dot com>
- To: binutils at sources dot redhat dot com
- Date: Wed, 07 Mar 2007 04:11:47 -0300
- Subject: support '# line "file" flags' and '# 0 "" 2'
Hi,
In http://gcc.gnu.org/ml/gcc-patches/2007-03/msg00168.html, I proposed
a patch to enable GCC to let the assembler know about source line
numbers in asm statements. It requires some syntax for the assembler
to return to the physical file and line number after temporarily
switching to a different file.
To this end, I've stopped breaking '# <line> "file"' up into separate
.appline and .appfile directives, which corrupted physical line
numbering, introducing .linefile (because .line was already taken in
some back ends).
I've also added support for preprocessor flags added after the
file name, although they aren't very used for much.
The only current use is to check that '# 0 "" 2' is to be interpreted
as returning to the physical file name and line number.
It doesn't check any inclusion stack to this end, although in theory
it could. Messing with the actual inclusion stack wouldn't quite
work, because we'd lose track of physical line numbers.
Here's the patch. No regressions on a x86_64-linux-gnu native. Ok to
install?
for gas/ChangeLog
from Alexandre Oliva <aoliva@redhat.com>
* app.c (do_scrub_chars): Turn #<line>"file"flags into .linefile.
* as.h (new_logical_line_flags): New.
* input-scrub.c (new_logical_line): Turned into wrapper for...
(new_logical_line_flags): this. Handle flags.
* read.c (potable): Add linefile. Adjust appline argument.
(s_app_file): Fake .appfiles no more.
(s_app_line): For .linefile, accept file name and flags.
Index: gas/app.c
===================================================================
--- gas/app.c.orig 2006-06-15 02:27:52.000000000 -0300
+++ gas/app.c 2007-03-07 03:48:29.000000000 -0300
@@ -1,6 +1,6 @@
/* This is the Assembler Pre-Processor
Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2006
+ 1999, 2000, 2001, 2002, 2003, 2006, 2007
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -21,10 +21,10 @@
02110-1301, USA. */
/* Modified by Allen Wirfs-Brock, Instantiations Inc 2/90. */
-/* App, the assembler pre-processor. This pre-processor strips out excess
- spaces, turns single-quoted characters into a decimal constant, and turns
- # <number> <filename> <garbage> into a .line <number>\n.file <filename>
- pair. This needs better error-handling. */
+/* App, the assembler pre-processor. This pre-processor strips out
+ excess spaces, turns single-quoted characters into a decimal
+ constant, and turns the # in # <number> <filename> <garbage> into a
+ .line. This needs better error-handling. */
#include "as.h"
@@ -511,13 +511,8 @@ do_scrub_chars (int (*get) (char *, int)
if (ch == '"')
{
UNGET (ch);
- if (scrub_m68k_mri)
- out_string = "\n\tappfile ";
- else
- out_string = "\n\t.appfile ";
- old_state = 7;
- state = -1;
- PUT (*out_string++);
+ state = 7;
+ PUT (' ');
}
else
{
@@ -648,12 +643,12 @@ do_scrub_chars (int (*get) (char *, int)
case 8:
do
- ch = GET ();
- while (ch != '\n' && ch != EOF);
- if (ch == EOF)
- goto fromeof;
+ if ((ch = GET ()) == EOF)
+ goto fromeof;
+ else
+ PUT (ch);
+ while (ch != '\n');
state = 0;
- PUT (ch);
continue;
#ifdef DOUBLEBAR_PARALLEL
@@ -1196,9 +1191,9 @@ do_scrub_chars (int (*get) (char *, int)
old_state = 4;
state = -1;
if (scrub_m68k_mri)
- out_string = "\tappline ";
+ out_string = "\tlinefile ";
else
- out_string = "\t.appline ";
+ out_string = "\t.linefile ";
PUT (*out_string++);
break;
}
Index: gas/as.h
===================================================================
--- gas/as.h.orig 2007-03-05 05:06:49.000000000 -0300
+++ gas/as.h 2007-03-06 04:43:12.000000000 -0300
@@ -550,6 +550,7 @@ void input_scrub_begin (void);
void input_scrub_close (void);
void input_scrub_end (void);
int new_logical_line (char *, int);
+int new_logical_line_flags (char *, int, int);
void subsegs_begin (void);
void subseg_change (segT, int);
segT subseg_new (const char *, subsegT);
Index: gas/input-scrub.c
===================================================================
--- gas/input-scrub.c.orig 2006-11-01 02:58:49.000000000 -0300
+++ gas/input-scrub.c 2007-03-06 04:44:07.000000000 -0300
@@ -1,6 +1,6 @@
/* input_scrub.c - Break up input buffers into whole numbers of lines.
Copyright 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 2000, 2001, 2003, 2006
+ 2000, 2001, 2003, 2006, 2007
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -435,13 +435,34 @@ bump_line_counters (void)
Returns nonzero if the filename actually changes. */
int
-new_logical_line (char *fname, /* DON'T destroy it! We point to it! */
- int line_number)
-{
+new_logical_line_flags (char *fname, /* DON'T destroy it! We point to it! */
+ int line_number,
+ int flags)
+{
+ switch (flags)
+ {
+ case 0:
+ break;
+ case 1:
+ if (line_number != -1)
+ abort ();
+ break;
+ case 1 << 1:
+ case 1 << 2:
+ /* FIXME: we could check that include nesting is correct. */
+ break;
+ default:
+ abort ();
+ }
+
if (line_number >= 0)
logical_input_line = line_number;
- else if (line_number == -2 && logical_input_line > 0)
- --logical_input_line;
+ else if (line_number == -1 && fname && !*fname && (flags & (1 << 2)))
+ {
+ logical_input_file = physical_input_file;
+ logical_input_line = physical_input_line;
+ fname = NULL;
+ }
if (fname
&& (logical_input_file == NULL
@@ -453,6 +474,13 @@ new_logical_line (char *fname, /* DON'T
else
return 0;
}
+
+int
+new_logical_line (char *fname, int line_number)
+{
+ return new_logical_line_flags (fname, line_number, 0);
+}
+
/* Return the current file name and line number.
namep should be char * const *, but there are compilers which screw
Index: gas/read.c
===================================================================
--- gas/read.c.orig 2006-11-01 02:58:49.000000000 -0300
+++ gas/read.c 2007-03-07 04:03:19.000000000 -0300
@@ -1,6 +1,6 @@
/* read.c - read a source file -
Copyright 1986, 1987, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997,
- 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007
Free Software Foundation, Inc.
This file is part of GAS, the GNU Assembler.
@@ -329,7 +329,7 @@ static const pseudo_typeS potable[] = {
/* extend */
{"extern", s_ignore, 0}, /* We treat all undef as ext. */
{"appfile", s_app_file, 1},
- {"appline", s_app_line, 0},
+ {"appline", s_app_line, 1},
{"fail", s_fail, 0},
{"file", s_app_file, 0},
{"fill", s_fill, 0},
@@ -364,6 +364,7 @@ static const pseudo_typeS potable[] = {
{"irepc", s_irp, 1},
{"lcomm", s_lcomm, 0},
{"lflags", listing_flags, 0}, /* Listing flags. */
+ {"linefile", s_app_line, 0},
{"linkonce", s_linkonce, 0},
{"list", listing_list, 1}, /* Turn listing on. */
{"llen", listing_psize, 1},
@@ -1681,11 +1682,8 @@ s_app_file (int appfile)
/* Some assemblers tolerate immediately following '"'. */
if ((s = demand_copy_string (&length)) != 0)
{
- /* If this is a fake .appfile, a fake newline was inserted into
- the buffer. Passing -2 to new_logical_line tells it to
- account for it. */
int may_omit
- = (!new_logical_line (s, appfile ? -2 : -1) && appfile);
+ = (!new_logical_line_flags (s, -1, 1) && appfile);
/* In MRI mode, the preprocessor may have inserted an extraneous
backquote. */
@@ -1706,7 +1704,7 @@ s_app_file (int appfile)
pseudo-ops. */
void
-s_app_line (int ignore ATTRIBUTE_UNUSED)
+s_app_line (int appline)
{
int l;
@@ -1727,7 +1725,57 @@ s_app_line (int ignore ATTRIBUTE_UNUSED)
l + 1);
else
{
- new_logical_line ((char *) NULL, l);
+ int flags = 0;
+ char *file = NULL;
+ int length = 0;
+
+ if (!appline)
+ {
+ file = demand_copy_string (&length);
+
+ if (file)
+ {
+ int this_flag;
+
+ while ((this_flag = get_absolute_expression ()))
+ switch (this_flag)
+ {
+ /* From GCC's cpp documentation:
+ 1: start of a new file.
+ 2: returning to a file after having included
+ another file.
+ 3: following text comes from a system header file.
+ 4: following text should be treated as extern "C".
+
+ 4 is nonsensical for the assembler; 3, we don't
+ care about, so we ignore it just in case a
+ system header file is included while
+ preprocessing assembly. So 1 and 2 are all we
+ care about, and they are mutually incompatible.
+ new_logical_line_flags() demands this. */
+ case 1:
+ case 2:
+ if (flags && flags != (1 << this_flag))
+ as_warn (_("incompatible flag %i in line directive"),
+ this_flag);
+ else
+ flags |= 1 << this_flag;
+ break;
+
+ case 3:
+ case 4:
+ /* We ignore these. */
+ break;
+
+ default:
+ as_warn (_("unsupported flag %i in line directive"),
+ this_flag);
+ break;
+ }
+ }
+ }
+
+ new_logical_line_flags (file, l, flags);
#ifdef LISTING
if (listing)
listing_source_line (l);
--
Alexandre Oliva http://www.lsd.ic.unicamp.br/~oliva/
FSF Latin America Board Member http://www.fsfla.org/
Red Hat Compiler Engineer aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist oliva@{lsd.ic.unicamp.br, gnu.org}