This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]