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]

Re: support '# line "file" flags' and '# 0 "" 2'


On Mar  8, 2007, Alan Modra <amodra@bigpond.net.au> wrote:

> On Wed, Mar 07, 2007 at 04:11:47AM -0300, Alexandre Oliva wrote:
>> numbering, introducing .linefile (because .line was already taken in

>> +   constant, and turns the # in # <number> <filename> <garbage> into a
>> +   .line.  This needs better error-handling.  */

> Please fix the comment.  Please also fix the do_scrub_chars state
> machine comments.

Oops, thanks for catching this.

> Hmm, it seems to me that you could remove state 7 from the machine
> with this change too.  Any simplification would be welcome.

Rats.  I guessed wrong ;-)

I actually removed it, then thought I'd better not mess with it
because it was so complex and reverted that bit of the change ;-)

I've made it again, but I left an opening rather than renumbering the
states.  I hope this is what you had in mind.

> That chunk of code gives me a headache any time I look at it.  ;-)

/me feels lonely no longer ;-)

> Otherwise looks OK to me.

Thanks, here's what I'm checking in.  Please let me know if you'd like
any further changes.

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	2007-03-07 04:13:25.000000000 -0300
+++ gas/app.c	2007-03-09 04:01:07.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
+   .linefile.  This needs better error-handling.  */
 
 #include "as.h"
 
@@ -351,10 +351,10 @@ do_scrub_chars (int (*get) (char *, int)
 	  1: After first whitespace on line (flush more white)
 	  2: After first non-white (opcode) on line (keep 1white)
 	  3: after second white on line (into operands) (flush white)
-	  4: after putting out a .line, put out digits
+	  4: after putting out a .linefile, put out digits
 	  5: parsing a string, then go to old-state
 	  6: putting out \ escape in a "d string.
-	  7: After putting out a .appfile, put out string.
+	  7: no longer used
 	  8: After putting out a .appfile string, flush until newline.
 	  9: After seeing symbol char in state 3 (keep 1white after symchar)
 	 10: After seeing whitespace in state 9 (keep white before symchar)
@@ -510,14 +510,11 @@ do_scrub_chars (int (*get) (char *, int)
 		ch = GET ();
 	      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++);
+		  PUT (' ');
+		  PUT (ch);
+		  quotechar = ch;
+		  state = 5;
+		  old_state = 8;
 		}
 	      else
 		{
@@ -638,22 +635,14 @@ do_scrub_chars (int (*get) (char *, int)
 	  PUT (ch);
 	  continue;
 
-	case 7:
-	  ch = GET ();
-	  quotechar = ch;
-	  state = 5;
-	  old_state = 8;
-	  PUT (ch);
-	  continue;
-
 	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 +1185,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-07 04:13:25.000000000 -0300
+++ gas/as.h	2007-03-09 03:58:13.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	2007-03-07 04:13:25.000000000 -0300
+++ gas/input-scrub.c	2007-03-09 03:58:13.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	2007-03-07 04:13:25.000000000 -0300
+++ gas/read.c	2007-03-09 03:58:13.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]